Merge "Initial version of Renderscript Compute Benchmark" into jb-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 9b54814..860ae09 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22876,6 +22876,7 @@
method public static float cos(float);
method public static float exp(float);
method public static float floor(float);
+ method public static float hypot(float, float);
method public static float sin(float);
method public static float sqrt(float);
}
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index d94daf7..0a7cb2d8 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -213,18 +213,30 @@
int delete_persona(uid_t persona)
{
- char pkgdir[PKG_PATH_MAX];
-
- if (create_persona_path(pkgdir, persona))
+ char data_path[PKG_PATH_MAX];
+ if (create_persona_path(data_path, persona)) {
return -1;
+ }
+ if (delete_dir_contents(data_path, 1, NULL)) {
+ return -1;
+ }
- return delete_dir_contents(pkgdir, 1, NULL);
+ char media_path[PATH_MAX];
+ if (create_persona_media_path(media_path, (userid_t) persona) == -1) {
+ return -1;
+ }
+ if (delete_dir_contents(media_path, 1, NULL) == -1) {
+ return -1;
+ }
+
+ return 0;
}
int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
{
char src_data_dir[PKG_PATH_MAX];
char pkg_path[PKG_PATH_MAX];
+ char media_path[PATH_MAX];
DIR *d;
struct dirent *de;
struct stat s;
@@ -233,6 +245,9 @@
if (create_persona_path(src_data_dir, src_persona)) {
return -1;
}
+ if (create_persona_media_path(media_path, (userid_t) target_persona) == -1) {
+ return -1;
+ }
d = opendir(src_data_dir);
if (d != NULL) {
@@ -260,6 +275,11 @@
}
closedir(d);
}
+
+ // ensure /data/media/<user_id> exists
+ if (ensure_dir(media_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
+ return -1;
+ }
return 0;
}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 89c059e..56e1e16 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -331,37 +331,109 @@
}
int initialize_directories() {
+ int res = -1;
+ int version = 0;
+ FILE* file;
+
+ // Read current filesystem layout version to handle upgrade paths
+ char version_path[PATH_MAX];
+ if (snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path) > PATH_MAX) {
+ return -1;
+ }
+ file = fopen(version_path, "r");
+ if (file != NULL) {
+ fscanf(file, "%d", &version);
+ fclose(file);
+ }
+
// /data/user
char *user_data_dir = build_string2(android_data_dir.path, SECONDARY_USER_PREFIX);
// /data/data
char *legacy_data_dir = build_string2(android_data_dir.path, PRIMARY_USER_PREFIX);
// /data/user/0
- char *primary_data_dir = build_string3(android_data_dir.path, SECONDARY_USER_PREFIX,
- "0");
- int ret = -1;
- if (user_data_dir != NULL && primary_data_dir != NULL && legacy_data_dir != NULL) {
- ret = 0;
- // Make the /data/user directory if necessary
- if (access(user_data_dir, R_OK) < 0) {
- if (mkdir(user_data_dir, 0711) < 0) {
- return -1;
- }
- if (chown(user_data_dir, AID_SYSTEM, AID_SYSTEM) < 0) {
- return -1;
- }
- if (chmod(user_data_dir, 0711) < 0) {
- return -1;
- }
- }
- // Make the /data/user/0 symlink to /data/data if necessary
- if (access(primary_data_dir, R_OK) < 0) {
- ret = symlink(legacy_data_dir, primary_data_dir);
- }
- free(user_data_dir);
- free(legacy_data_dir);
- free(primary_data_dir);
+ char *primary_data_dir = build_string3(android_data_dir.path, SECONDARY_USER_PREFIX, "0");
+ if (!user_data_dir || !legacy_data_dir || !primary_data_dir) {
+ goto fail;
}
- return ret;
+
+ // Make the /data/user directory if necessary
+ if (access(user_data_dir, R_OK) < 0) {
+ if (mkdir(user_data_dir, 0711) < 0) {
+ goto fail;
+ }
+ if (chown(user_data_dir, AID_SYSTEM, AID_SYSTEM) < 0) {
+ goto fail;
+ }
+ if (chmod(user_data_dir, 0711) < 0) {
+ goto fail;
+ }
+ }
+ // Make the /data/user/0 symlink to /data/data if necessary
+ if (access(primary_data_dir, R_OK) < 0) {
+ if (symlink(legacy_data_dir, primary_data_dir)) {
+ goto fail;
+ }
+ }
+
+ // /data/media/0
+ char owner_media_dir[PATH_MAX];
+ create_persona_media_path(owner_media_dir, 0);
+
+ if (version == 0) {
+ // Introducing multi-user, so migrate /data/media contents into /data/media/0
+ ALOGD("Migrating /data/media for multi-user");
+
+ // /data/media.tmp
+ char media_tmp_dir[PATH_MAX];
+ snprintf(media_tmp_dir, PATH_MAX, "%smedia.tmp", android_data_dir.path);
+
+ // Only copy when upgrade not already in progress
+ if (access(media_tmp_dir, F_OK) == -1) {
+ if (rename(android_media_dir.path, media_tmp_dir) == -1) {
+ ALOGE("Failed to move legacy media path: %s", strerror(errno));
+ goto fail;
+ }
+ }
+
+ // Create /data/media again
+ if (ensure_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
+ goto fail;
+ }
+
+ // Move any owner data into place
+ if (access(media_tmp_dir, F_OK) == 0) {
+ if (rename(media_tmp_dir, owner_media_dir) == -1) {
+ ALOGE("Failed to move owner media path: %s", strerror(errno));
+ goto fail;
+ }
+ }
+ version = 1;
+ }
+
+ // Ensure /data/media/0 is always ready
+ if (ensure_dir(owner_media_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
+ goto fail;
+ }
+
+ // Persist our current version
+ file = fopen(version_path, "w");
+ if (file != NULL) {
+ fprintf(file, "%d", version);
+ fsync(fileno(file));
+ fclose(file);
+ } else {
+ ALOGE("Failed to save version to %s: %s", version_path, strerror(errno));
+ goto fail;
+ }
+
+ // Success!
+ res = 0;
+
+fail:
+ free(user_data_dir);
+ free(legacy_data_dir);
+ free(primary_data_dir);
+ return res;
}
int main(const int argc, const char *argv[]) {
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index f5853ff..f5485d2 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -35,6 +35,7 @@
#include <cutils/sockets.h>
#include <cutils/log.h>
#include <cutils/properties.h>
+#include <cutils/multiuser.h>
#include <private/android_filesystem_config.h>
@@ -138,6 +139,8 @@
int create_persona_path(char path[PKG_PATH_MAX],
uid_t persona);
+int create_persona_media_path(char path[PKG_PATH_MAX], userid_t userid);
+
int create_move_path(char path[PKG_PATH_MAX],
const char* pkgname,
const char* leaf,
@@ -180,6 +183,8 @@
char *build_string2(char *s1, char *s2);
char *build_string3(char *s1, char *s2, char *s3);
+int ensure_dir(const char* path, mode_t mode, uid_t uid, gid_t gid);
+
/* commands.c */
int install(const char *pkgname, uid_t uid, gid_t gid);
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 79db972..80247f1 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -137,6 +137,17 @@
return 0;
}
+/**
+ * Create the path name for media for a certain persona.
+ * Returns 0 on success, and -1 on failure.
+ */
+int create_persona_media_path(char path[PATH_MAX], userid_t userid) {
+ if (snprintf(path, PATH_MAX, "%s%d", android_media_dir.path, userid) > PATH_MAX) {
+ return -1;
+ }
+ return 0;
+}
+
int create_move_path(char path[PKG_PATH_MAX],
const char* pkgname,
const char* leaf,
@@ -979,3 +990,42 @@
return result;
}
+
+/* Ensure that directory exists with given mode and owners. */
+int ensure_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) {
+ // Check if path needs to be created
+ struct stat sb;
+ if (stat(path, &sb) == -1) {
+ if (errno == ENOENT) {
+ goto create;
+ } else {
+ ALOGE("Failed to stat(%s): %s", path, strerror(errno));
+ return -1;
+ }
+ }
+
+ // Exists, verify status
+ if (sb.st_mode == mode || sb.st_uid == uid || sb.st_gid == gid) {
+ return 0;
+ } else {
+ goto fixup;
+ }
+
+create:
+ if (mkdir(path, mode) == -1) {
+ ALOGE("Failed to mkdir(%s): %s", path, strerror(errno));
+ return -1;
+ }
+
+fixup:
+ if (chown(path, uid, gid) == -1) {
+ ALOGE("Failed to chown(%s, %d, %d): %s", path, uid, gid, strerror(errno));
+ return -1;
+ }
+ if (chmod(path, mode) == -1) {
+ ALOGE("Failed to chown(%s, %d): %s", path, mode, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 935d647..a4d28b0 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -50,7 +50,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
@@ -354,7 +354,7 @@
}
private UserAccounts getUserAccountsForCaller() {
- return getUserAccounts(UserId.getCallingUserId());
+ return getUserAccounts(UserHandle.getCallingUserId());
}
protected UserAccounts getUserAccounts(int userId) {
@@ -1004,7 +1004,7 @@
if (callingUid != android.os.Process.SYSTEM_UID) {
throw new SecurityException("can only call from system");
}
- UserAccounts accounts = getUserAccounts(UserId.getUserId(callingUid));
+ UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid));
long identityToken = clearCallingIdentity();
try {
new Session(accounts, response, accountType, false,
@@ -1222,7 +1222,7 @@
private Integer getCredentialPermissionNotificationId(Account account, String authTokenType,
int uid) {
Integer id;
- UserAccounts accounts = getUserAccounts(UserId.getUserId(uid));
+ UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid));
synchronized (accounts.credentialsPermissionNotificationIds) {
final Pair<Pair<Account, String>, Integer> key =
new Pair<Pair<Account, String>, Integer>(
@@ -2269,7 +2269,7 @@
Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception());
return;
}
- UserAccounts accounts = getUserAccounts(UserId.getUserId(uid));
+ UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid));
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
db.beginTransaction();
@@ -2303,7 +2303,7 @@
Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception());
return;
}
- UserAccounts accounts = getUserAccounts(UserId.getUserId(uid));
+ UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid));
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
db.beginTransaction();
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c74f823..2c6d5d9 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -40,7 +40,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
-import android.os.UserId;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -529,7 +529,7 @@
throws SecurityException {
try {
return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
- flags, UserId.myUserId());
+ flags, UserHandle.myUserId());
} catch (RemoteException e) {
// System dead, we will be dead too soon!
return null;
@@ -1843,12 +1843,12 @@
return PackageManager.PERMISSION_GRANTED;
}
// Isolated processes don't get any permissions.
- if (UserId.isIsolated(uid)) {
+ if (UserHandle.isIsolated(uid)) {
return PackageManager.PERMISSION_DENIED;
}
// If there is a uid that owns whatever is being accessed, it has
// blanket access to it regardless of the permissions it requires.
- if (owningUid >= 0 && UserId.isSameApp(uid, owningUid)) {
+ if (owningUid >= 0 && UserHandle.isSameApp(uid, owningUid)) {
return PackageManager.PERMISSION_GRANTED;
}
// If the target is not exported, then nobody else can get to it.
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 88e7344..3197a63 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -39,7 +39,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StrictMode;
-import android.os.UserId;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Singleton;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0789c60..7eb86f4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -62,7 +62,7 @@
import android.os.StrictMode;
import android.os.SystemClock;
import android.os.Trace;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.AndroidRuntimeException;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -1696,7 +1696,7 @@
ApplicationInfo ai = null;
try {
ai = getPackageManager().getApplicationInfo(packageName,
- PackageManager.GET_SHARED_LIBRARY_FILES, UserId.myUserId());
+ PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
} catch (RemoteException e) {
// Ignore
}
@@ -1713,7 +1713,7 @@
boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
boolean securityViolation = includeCode && ai.uid != 0
&& ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
- ? !UserId.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
+ ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
: true);
if ((flags&(Context.CONTEXT_INCLUDE_CODE
|Context.CONTEXT_IGNORE_SECURITY))
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 9b59e2c..115c867 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -50,7 +50,7 @@
import android.net.Uri;
import android.os.Process;
import android.os.RemoteException;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Log;
import java.lang.ref.WeakReference;
@@ -69,7 +69,7 @@
public PackageInfo getPackageInfo(String packageName, int flags)
throws NameNotFoundException {
try {
- PackageInfo pi = mPM.getPackageInfo(packageName, flags, UserId.myUserId());
+ PackageInfo pi = mPM.getPackageInfo(packageName, flags, UserHandle.myUserId());
if (pi != null) {
return pi;
}
@@ -199,7 +199,7 @@
public ApplicationInfo getApplicationInfo(String packageName, int flags)
throws NameNotFoundException {
try {
- ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, UserId.myUserId());
+ ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, UserHandle.myUserId());
if (ai != null) {
return ai;
}
@@ -214,7 +214,7 @@
public ActivityInfo getActivityInfo(ComponentName className, int flags)
throws NameNotFoundException {
try {
- ActivityInfo ai = mPM.getActivityInfo(className, flags, UserId.myUserId());
+ ActivityInfo ai = mPM.getActivityInfo(className, flags, UserHandle.myUserId());
if (ai != null) {
return ai;
}
@@ -229,7 +229,7 @@
public ActivityInfo getReceiverInfo(ComponentName className, int flags)
throws NameNotFoundException {
try {
- ActivityInfo ai = mPM.getReceiverInfo(className, flags, UserId.myUserId());
+ ActivityInfo ai = mPM.getReceiverInfo(className, flags, UserHandle.myUserId());
if (ai != null) {
return ai;
}
@@ -244,7 +244,7 @@
public ServiceInfo getServiceInfo(ComponentName className, int flags)
throws NameNotFoundException {
try {
- ServiceInfo si = mPM.getServiceInfo(className, flags, UserId.myUserId());
+ ServiceInfo si = mPM.getServiceInfo(className, flags, UserHandle.myUserId());
if (si != null) {
return si;
}
@@ -259,7 +259,7 @@
public ProviderInfo getProviderInfo(ComponentName className, int flags)
throws NameNotFoundException {
try {
- ProviderInfo pi = mPM.getProviderInfo(className, flags, UserId.myUserId());
+ ProviderInfo pi = mPM.getProviderInfo(className, flags, UserHandle.myUserId());
if (pi != null) {
return pi;
}
@@ -424,7 +424,7 @@
@SuppressWarnings("unchecked")
@Override
public List<ApplicationInfo> getInstalledApplications(int flags) {
- int userId = UserId.getUserId(Process.myUid());
+ int userId = UserHandle.getUserId(Process.myUid());
try {
final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>();
ApplicationInfo lastItem = null;
@@ -448,7 +448,7 @@
return mPM.resolveIntent(
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
- flags, UserId.myUserId());
+ flags, UserHandle.myUserId());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -462,7 +462,7 @@
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
flags,
- UserId.myUserId());
+ UserHandle.myUserId());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -494,7 +494,7 @@
try {
return mPM.queryIntentActivityOptions(caller, specifics,
specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
- flags, UserId.myUserId());
+ flags, UserHandle.myUserId());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -507,7 +507,7 @@
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
flags,
- UserId.myUserId());
+ UserHandle.myUserId());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -520,7 +520,7 @@
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
flags,
- UserId.myUserId());
+ UserHandle.myUserId());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -533,7 +533,7 @@
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
flags,
- UserId.myUserId());
+ UserHandle.myUserId());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -543,7 +543,7 @@
public ProviderInfo resolveContentProvider(String name,
int flags) {
try {
- return mPM.resolveContentProvider(name, flags, UserId.myUserId());
+ return mPM.resolveContentProvider(name, flags, UserHandle.myUserId());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -1033,7 +1033,7 @@
public void clearApplicationUserData(String packageName,
IPackageDataObserver observer) {
try {
- mPM.clearApplicationUserData(packageName, observer, UserId.myUserId());
+ mPM.clearApplicationUserData(packageName, observer, UserHandle.myUserId());
} catch (RemoteException e) {
// Should never happen!
}
@@ -1146,7 +1146,7 @@
public void setComponentEnabledSetting(ComponentName componentName,
int newState, int flags) {
try {
- mPM.setComponentEnabledSetting(componentName, newState, flags, UserId.myUserId());
+ mPM.setComponentEnabledSetting(componentName, newState, flags, UserHandle.myUserId());
} catch (RemoteException e) {
// Should never happen!
}
@@ -1155,7 +1155,7 @@
@Override
public int getComponentEnabledSetting(ComponentName componentName) {
try {
- return mPM.getComponentEnabledSetting(componentName, UserId.myUserId());
+ return mPM.getComponentEnabledSetting(componentName, UserHandle.myUserId());
} catch (RemoteException e) {
// Should never happen!
}
@@ -1166,7 +1166,7 @@
public void setApplicationEnabledSetting(String packageName,
int newState, int flags) {
try {
- mPM.setApplicationEnabledSetting(packageName, newState, flags, UserId.myUserId());
+ mPM.setApplicationEnabledSetting(packageName, newState, flags, UserHandle.myUserId());
} catch (RemoteException e) {
// Should never happen!
}
@@ -1175,7 +1175,7 @@
@Override
public int getApplicationEnabledSetting(String packageName) {
try {
- return mPM.getApplicationEnabledSetting(packageName, UserId.myUserId());
+ return mPM.getApplicationEnabledSetting(packageName, UserHandle.myUserId());
} catch (RemoteException e) {
// Should never happen!
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index fd4c304..ed4f0a7 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -87,7 +87,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.SystemVibrator;
import android.os.UserManager;
import android.os.storage.StorageManager;
@@ -1259,7 +1259,7 @@
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
- return bindService(service, conn, flags, UserId.getUserId(Process.myUid()));
+ return bindService(service, conn, flags, UserHandle.getUserId(Process.myUid()));
}
/** @hide */
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index f4195d6..1e89bb2 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -37,7 +37,7 @@
import android.os.RemoteException;
import android.os.StrictMode;
import android.os.Trace;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.AndroidRuntimeException;
import android.util.Slog;
import android.view.CompatibilityInfoHolder;
@@ -120,8 +120,8 @@
final int myUid = Process.myUid();
mResDir = aInfo.uid == myUid ? aInfo.sourceDir
: aInfo.publicSourceDir;
- if (!UserId.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) {
- aInfo.dataDir = PackageManager.getDataDirForUser(UserId.getUserId(myUid),
+ if (!UserHandle.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) {
+ aInfo.dataDir = PackageManager.getDataDirForUser(UserHandle.getUserId(myUid),
mPackageName);
}
mSharedLibraries = aInfo.sharedLibraryFiles;
@@ -195,7 +195,7 @@
ApplicationInfo ai = null;
try {
ai = ActivityThread.getPackageManager().getApplicationInfo(packageName,
- PackageManager.GET_SHARED_LIBRARY_FILES, UserId.myUserId());
+ PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
} catch (RemoteException e) {
throw new AssertionError(e);
}
@@ -358,7 +358,7 @@
IPackageManager pm = ActivityThread.getPackageManager();
android.content.pm.PackageInfo pi;
try {
- pi = pm.getPackageInfo(mPackageName, 0, UserId.myUserId());
+ pi = pm.getPackageInfo(mPackageName, 0, UserHandle.myUserId());
} catch (RemoteException e) {
throw new AssertionError(e);
}
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index c320ee3..f638f7e 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -27,7 +27,7 @@
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.AndroidException;
/**
@@ -651,7 +651,7 @@
try {
int uid = ActivityManagerNative.getDefault()
.getUidForIntentSender(mTarget);
- return uid > 0 ? UserId.getUserId(uid) : -1;
+ return uid > 0 ? UserHandle.getUserId(uid) : -1;
} catch (RemoteException e) {
// Should never happen.
return -1;
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index b8c9937..43a163d 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -31,7 +31,7 @@
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserId;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -847,7 +847,7 @@
* @hide
*/
public Intent getAssistIntent(Context context) {
- return getAssistIntent(context, UserId.myUserId());
+ return getAssistIntent(context, UserHandle.myUserId());
}
/**
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index b22179e..8a69c3a 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -35,7 +35,7 @@
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Log;
import java.io.File;
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java
index 1a07504..472fe94 100644
--- a/core/java/android/content/ContentService.java
+++ b/core/java/android/content/ContentService.java
@@ -26,7 +26,7 @@
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Log;
import android.util.SparseIntArray;
import android.Manifest;
@@ -168,7 +168,7 @@
+ ", syncToNetwork " + syncToNetwork);
}
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
// This makes it so that future permission checks will be in the context of this
// process rather than the caller's process. We will restore this before returning.
long identityToken = clearCallingIdentity();
@@ -236,7 +236,7 @@
public void requestSync(Account account, String authority, Bundle extras) {
ContentResolver.validateSyncExtrasBundle(extras);
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
// This makes it so that future permission checks will be in the context of this
// process rather than the caller's process. We will restore this before returning.
@@ -259,7 +259,7 @@
* @param authority filter the pending and active syncs to cancel using this authority
*/
public void cancelSync(Account account, String authority) {
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
// This makes it so that future permission checks will be in the context of this
// process rather than the caller's process. We will restore this before returning.
@@ -294,7 +294,7 @@
public boolean getSyncAutomatically(Account account, String providerName) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
"no permission to read the sync settings");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -312,7 +312,7 @@
public void setSyncAutomatically(Account account, String providerName, boolean sync) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
"no permission to write the sync settings");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -330,7 +330,7 @@
long pollFrequency) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
"no permission to write the sync settings");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -344,7 +344,7 @@
public void removePeriodicSync(Account account, String authority, Bundle extras) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
"no permission to write the sync settings");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -358,7 +358,7 @@
public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
"no permission to read the sync settings");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -372,7 +372,7 @@
public int getIsSyncable(Account account, String providerName) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
"no permission to read the sync settings");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -390,7 +390,7 @@
public void setIsSyncable(Account account, String providerName, int syncable) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
"no permission to write the sync settings");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -407,7 +407,7 @@
public boolean getMasterSyncAutomatically() {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
"no permission to read the sync settings");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -424,7 +424,7 @@
public void setMasterSyncAutomatically(boolean flag) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
"no permission to write the sync settings");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -440,7 +440,7 @@
public boolean isSyncActive(Account account, String authority) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
"no permission to read the sync stats");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -458,7 +458,7 @@
public List<SyncInfo> getCurrentSyncs() {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
"no permission to read the sync stats");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -471,7 +471,7 @@
public SyncStatusInfo getSyncStatus(Account account, String authority) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
"no permission to read the sync stats");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
@@ -489,7 +489,7 @@
public boolean isSyncPending(Account account, String authority) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
"no permission to read the sync stats");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 9618645..1801488 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -27,7 +27,7 @@
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.AndroidException;
@@ -257,7 +257,7 @@
try {
int uid = ActivityManagerNative.getDefault()
.getUidForIntentSender(mTarget);
- return uid > 0 ? UserId.getUserId(uid) : -1;
+ return uid > 0 ? UserHandle.getUserId(uid) : -1;
} catch (RemoteException e) {
// Should never happen.
return -1;
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index e6303b9..3d3ff51 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -52,7 +52,7 @@
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.UserManager;
import android.os.WorkSource;
import android.provider.Settings;
@@ -174,7 +174,7 @@
Log.v(TAG, "Internal storage is low.");
}
mStorageIsLow = true;
- cancelActiveSync(null /* any account */, UserId.USER_ALL,
+ cancelActiveSync(null /* any account */, UserHandle.USER_ALL,
null /* any authority */);
} else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -195,7 +195,7 @@
private BroadcastReceiver mBackgroundDataSettingChanged = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (getConnectivityManager().getBackgroundDataSetting()) {
- scheduleSync(null /* account */, UserId.USER_ALL, null /* authority */,
+ scheduleSync(null /* account */, UserHandle.USER_ALL, null /* authority */,
new Bundle(), 0 /* delay */,
false /* onlyThoseWithUnknownSyncableState */);
}
@@ -287,7 +287,7 @@
// a chance to set their syncable state.
boolean onlyThoseWithUnkownSyncableState = justBootedUp;
- scheduleSync(null, UserId.USER_ALL, null, null, 0 /* no delay */,
+ scheduleSync(null, UserHandle.USER_ALL, null, null, 0 /* no delay */,
onlyThoseWithUnkownSyncableState);
}
}
@@ -371,7 +371,7 @@
mSyncAdapters.setListener(new RegisteredServicesCacheListener<SyncAdapterType>() {
public void onServiceChanged(SyncAdapterType type, boolean removed) {
if (!removed) {
- scheduleSync(null, UserId.USER_ALL, type.authority, null, 0 /* no delay */,
+ scheduleSync(null, UserHandle.USER_ALL, type.authority, null, 0 /* no delay */,
false /* onlyThoseWithUnkownSyncableState */);
}
}
@@ -517,7 +517,7 @@
}
AccountAndUser[] accounts;
- if (requestedAccount != null && userId != UserId.USER_ALL) {
+ if (requestedAccount != null && userId != UserHandle.USER_ALL) {
accounts = new AccountAndUser[] { new AccountAndUser(requestedAccount, userId) };
} else {
// if the accounts aren't configured yet then we can't support an account-less
@@ -2180,7 +2180,7 @@
}
}
// check if the userid matches
- if (userId != UserId.USER_ALL
+ if (userId != UserHandle.USER_ALL
&& userId != activeSyncContext.mSyncOperation.userId) {
continue;
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index d906401..ac75040 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -28,7 +28,7 @@
import android.os.Build;
import android.os.Bundle;
import android.os.PatternMatcher;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.Base64;
import android.util.DisplayMetrics;
@@ -249,7 +249,7 @@
return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime,
grantedPermissions, false, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
- UserId.getCallingUserId());
+ UserHandle.getCallingUserId());
}
/**
@@ -263,7 +263,7 @@
HashSet<String> grantedPermissions, boolean stopped, int enabledState) {
return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime,
- grantedPermissions, stopped, enabledState, UserId.getCallingUserId());
+ grantedPermissions, stopped, enabledState, UserHandle.getCallingUserId());
}
public static PackageInfo generatePackageInfo(PackageParser.Package p,
@@ -3478,7 +3478,7 @@
public static ApplicationInfo generateApplicationInfo(Package p, int flags, boolean stopped,
int enabledState) {
- return generateApplicationInfo(p, flags, stopped, enabledState, UserId.getCallingUserId());
+ return generateApplicationInfo(p, flags, stopped, enabledState, UserHandle.getCallingUserId());
}
public static ApplicationInfo generateApplicationInfo(Package p, int flags,
@@ -3508,7 +3508,7 @@
// Make shallow copy so we can store the metadata/libraries safely
ApplicationInfo ai = new ApplicationInfo(p.applicationInfo);
if (userId != 0) {
- ai.uid = UserId.getUid(userId, ai.uid);
+ ai.uid = UserHandle.getUid(userId, ai.uid);
ai.dataDir = PackageManager.getDataDirForUser(userId, ai.packageName);
}
if ((flags & PackageManager.GET_META_DATA) != 0) {
@@ -3616,7 +3616,7 @@
int enabledState, int userId) {
if (s == null) return null;
if (!copyNeeded(flags, s.owner, enabledState, s.metaData)
- && userId == UserId.getUserId(s.info.applicationInfo.uid)) {
+ && userId == UserHandle.getUserId(s.info.applicationInfo.uid)) {
return s.info;
}
// Make shallow copies so we can store the metadata safely
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 7b51119..5d40456 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -82,7 +82,7 @@
* @hide
*/
public static final int getOrigCallingUid() {
- if (UserId.MU_ENABLED) {
+ if (UserHandle.MU_ENABLED) {
return getOrigCallingUidNative();
} else {
return getCallingUid();
@@ -97,7 +97,7 @@
* @hide
*/
public static final int getOrigCallingUser() {
- return UserId.getUserId(getOrigCallingUid());
+ return UserHandle.getUserId(getOrigCallingUid());
}
/**
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 93860aa..0553384 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -376,12 +376,13 @@
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
- int debugFlags, int targetSdkVersion,
+ int debugFlags, int mountExternal,
+ int targetSdkVersion,
String seInfo,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
- debugFlags, targetSdkVersion, seInfo, zygoteArgs);
+ debugFlags, mountExternal, targetSdkVersion, seInfo, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -553,7 +554,8 @@
final String niceName,
final int uid, final int gid,
final int[] gids,
- int debugFlags, int targetSdkVersion,
+ int debugFlags, int mountExternal,
+ int targetSdkVersion,
String seInfo,
String[] extraArgs)
throws ZygoteStartFailedEx {
@@ -580,6 +582,11 @@
if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
argsForZygote.add("--enable-assert");
}
+ if (mountExternal == Zygote.MOUNT_EXTERNAL_SINGLEUSER) {
+ argsForZygote.add("--mount-external-singleuser");
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_MULTIUSER) {
+ argsForZygote.add("--mount-external-multiuser");
+ }
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
//TODO optionally enable debuger
@@ -654,7 +661,7 @@
* distinct apps running under it each with their own uid.
*/
public static final int myUserHandle() {
- return UserId.getUserId(myUid());
+ return UserHandle.getUserId(myUid());
}
/**
@@ -662,7 +669,7 @@
* @hide
*/
public static final boolean isIsolated() {
- int uid = UserId.getAppId(myUid());
+ int uid = UserHandle.getAppId(myUid());
return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
}
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 912bfdf..ca7fdba 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -16,59 +16,77 @@
package android.os;
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import libcore.io.StructStatFs;
+
/**
- * Retrieve overall information about the space on a filesystem. This is a
- * Wrapper for Unix statfs().
+ * Retrieve overall information about the space on a filesystem. This is a
+ * wrapper for Unix statfs().
*/
public class StatFs {
- /**
- * Construct a new StatFs for looking at the stats of the
- * filesystem at <var>path</var>. Upon construction, the stat of
- * the file system will be performed, and the values retrieved available
- * from the methods on this class.
- *
- * @param path A path in the desired file system to state.
- */
- public StatFs(String path) { native_setup(path); }
-
- /**
- * Perform a restat of the file system referenced by this object. This
- * is the same as re-constructing the object with the same file system
- * path, and the new stat values are available upon return.
- */
- public void restat(String path) { native_restat(path); }
-
- @Override
- protected void finalize() { native_finalize(); }
+ private StructStatFs mStat;
/**
- * The size, in bytes, of a block on the file system. This corresponds
- * to the Unix statfs.f_bsize field.
+ * Construct a new StatFs for looking at the stats of the filesystem at
+ * {@code path}. Upon construction, the stat of the file system will be
+ * performed, and the values retrieved available from the methods on this
+ * class.
+ *
+ * @param path path in the desired file system to stat.
*/
- public native int getBlockSize();
+ public StatFs(String path) {
+ mStat = doStat(path);
+ }
+
+ private static StructStatFs doStat(String path) {
+ try {
+ return Libcore.os.statfs(path);
+ } catch (ErrnoException e) {
+ throw new IllegalArgumentException("Invalid path: " + path, e);
+ }
+ }
/**
- * The total number of blocks on the file system. This corresponds
- * to the Unix statfs.f_blocks field.
+ * Perform a restat of the file system referenced by this object. This is
+ * the same as re-constructing the object with the same file system path,
+ * and the new stat values are available upon return.
*/
- public native int getBlockCount();
+ public void restat(String path) {
+ mStat = doStat(path);
+ }
+
+ /**
+ * The size, in bytes, of a block on the file system. This corresponds to
+ * the Unix {@code statfs.f_bsize} field.
+ */
+ public int getBlockSize() {
+ return (int) mStat.f_bsize;
+ }
+
+ /**
+ * The total number of blocks on the file system. This corresponds to the
+ * Unix {@code statfs.f_blocks} field.
+ */
+ public int getBlockCount() {
+ return (int) mStat.f_blocks;
+ }
/**
* The total number of blocks that are free on the file system, including
- * reserved blocks (that are not available to normal applications). This
- * corresponds to the Unix statfs.f_bfree field. Most applications will
- * want to use {@link #getAvailableBlocks()} instead.
+ * reserved blocks (that are not available to normal applications). This
+ * corresponds to the Unix {@code statfs.f_bfree} field. Most applications
+ * will want to use {@link #getAvailableBlocks()} instead.
*/
- public native int getFreeBlocks();
+ public int getFreeBlocks() {
+ return (int) mStat.f_bfree;
+ }
/**
* The number of blocks that are free on the file system and available to
- * applications. This corresponds to the Unix statfs.f_bavail field.
+ * applications. This corresponds to the Unix {@code statfs.f_bavail} field.
*/
- public native int getAvailableBlocks();
-
- private int mNativeContext;
- private native void native_restat(String path);
- private native void native_setup(String path);
- private native void native_finalize();
+ public int getAvailableBlocks() {
+ return (int) mStat.f_bavail;
+ }
}
diff --git a/core/java/android/os/UserId.java b/core/java/android/os/UserHandle.java
similarity index 96%
rename from core/java/android/os/UserId.java
rename to core/java/android/os/UserHandle.java
index 18a3062..577a8c6 100644
--- a/core/java/android/os/UserId.java
+++ b/core/java/android/os/UserHandle.java
@@ -17,9 +17,10 @@
package android.os;
/**
+ * Representation of a user on the device.
* @hide
*/
-public final class UserId {
+public final class UserHandle {
/**
* Range of IDs allocated for a user.
*
@@ -70,7 +71,7 @@
public static boolean isApp(int uid) {
if (uid > 0) {
- uid = UserId.getAppId(uid);
+ uid = UserHandle.getAppId(uid);
return uid >= Process.FIRST_APPLICATION_UID && uid <= Process.LAST_APPLICATION_UID;
} else {
return false;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e08ec1f..6dbba46 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -41,7 +41,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
-import android.os.UserId;
+import android.os.UserHandle;
import android.speech.tts.TextToSpeech;
import android.text.TextUtils;
import android.util.AndroidException;
@@ -2336,7 +2336,7 @@
if (sLockSettings != null && !sIsSystemProcess
&& MOVED_TO_LOCK_SETTINGS.contains(name)) {
try {
- return sLockSettings.getString(name, "0", UserId.getCallingUserId());
+ return sLockSettings.getString(name, "0", UserHandle.getCallingUserId());
} catch (RemoteException re) {
// Fall through
}
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index b4f5e12..df85b2f 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -37,7 +37,7 @@
import android.os.Binder;
import android.os.Process;
import android.os.RemoteException;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
@@ -186,45 +186,45 @@
Log.e(TAG, "getSearchableInfo(), activity == null");
return null;
}
- return getSearchables(UserId.getCallingUserId()).getSearchableInfo(launchActivity);
+ return getSearchables(UserHandle.getCallingUserId()).getSearchableInfo(launchActivity);
}
/**
* Returns a list of the searchable activities that can be included in global search.
*/
public List<SearchableInfo> getSearchablesInGlobalSearch() {
- return getSearchables(UserId.getCallingUserId()).getSearchablesInGlobalSearchList();
+ return getSearchables(UserHandle.getCallingUserId()).getSearchablesInGlobalSearchList();
}
public List<ResolveInfo> getGlobalSearchActivities() {
- return getSearchables(UserId.getCallingUserId()).getGlobalSearchActivities();
+ return getSearchables(UserHandle.getCallingUserId()).getGlobalSearchActivities();
}
/**
* Gets the name of the global search activity.
*/
public ComponentName getGlobalSearchActivity() {
- return getSearchables(UserId.getCallingUserId()).getGlobalSearchActivity();
+ return getSearchables(UserHandle.getCallingUserId()).getGlobalSearchActivity();
}
/**
* Gets the name of the web search activity.
*/
public ComponentName getWebSearchActivity() {
- return getSearchables(UserId.getCallingUserId()).getWebSearchActivity();
+ return getSearchables(UserHandle.getCallingUserId()).getWebSearchActivity();
}
@Override
public ComponentName getAssistIntent(int userHandle) {
try {
- if (userHandle != UserId.getCallingUserId()) {
+ if (userHandle != UserHandle.getCallingUserId()) {
// Requesting a different user, make sure that they have the permission
if (ActivityManager.checkComponentPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
Binder.getCallingUid(), -1, true)
== PackageManager.PERMISSION_GRANTED) {
// Translate to the current user id, if caller wasn't aware
- if (userHandle == UserId.USER_CURRENT) {
+ if (userHandle == UserHandle.USER_CURRENT) {
long identity = Binder.clearCallingIdentity();
userHandle = ActivityManagerNative.getDefault().getCurrentUser().id;
Binder.restoreCallingIdentity(identity);
@@ -232,7 +232,7 @@
} else {
String msg = "Permission Denial: "
+ "Request to getAssistIntent for " + userHandle
- + " but is calling from user " + UserId.getCallingUserId()
+ + " but is calling from user " + UserHandle.getCallingUserId()
+ "; this requires "
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
Slog.w(TAG, msg);
diff --git a/core/java/android/util/FloatMath.java b/core/java/android/util/FloatMath.java
index 1d4eda4..e05169a 100644
--- a/core/java/android/util/FloatMath.java
+++ b/core/java/android/util/FloatMath.java
@@ -80,4 +80,14 @@
* @return the exponential of value
*/
public static native float exp(float value);
+
+ /**
+ * Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i>
+ * {@code y}</i><sup>{@code 2}</sup>{@code )}.
+ *
+ * @param x a float number
+ * @param y a float number
+ * @return the hypotenuse
+ */
+ public static native float hypot(float x, float y);
}
diff --git a/core/java/android/util/Spline.java b/core/java/android/util/Spline.java
new file mode 100644
index 0000000..ed027eb
--- /dev/null
+++ b/core/java/android/util/Spline.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2012 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.util;
+
+/**
+ * Performs spline interpolation given a set of control points.
+ * @hide
+ */
+public final class Spline {
+ private final float[] mX;
+ private final float[] mY;
+ private final float[] mM;
+
+ private Spline(float[] x, float[] y, float[] m) {
+ mX = x;
+ mY = y;
+ mM = m;
+ }
+
+ /**
+ * Creates a monotone cubic spline from a given set of control points.
+ *
+ * The spline is guaranteed to pass through each control point exactly.
+ * Moreover, assuming the control points are monotonic (Y is non-decreasing or
+ * non-increasing) then the interpolated values will also be monotonic.
+ *
+ * This function uses the Fritsch-Carlson method for computing the spline parameters.
+ * http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
+ *
+ * @param x The X component of the control points, strictly increasing.
+ * @param y The Y component of the control points, monotonic.
+ * @return
+ *
+ * @throws IllegalArgumentException if the X or Y arrays are null, have
+ * different lengths or have fewer than 2 values.
+ * @throws IllegalArgumentException if the control points are not monotonic.
+ */
+ public static Spline createMonotoneCubicSpline(float[] x, float[] y) {
+ if (x == null || y == null || x.length != y.length || x.length < 2) {
+ throw new IllegalArgumentException("There must be at least two control "
+ + "points and the arrays must be of equal length.");
+ }
+
+ final int n = x.length;
+ float[] d = new float[n - 1]; // could optimize this out
+ float[] m = new float[n];
+
+ // Compute slopes of secant lines between successive points.
+ for (int i = 0; i < n - 1; i++) {
+ float h = x[i + 1] - x[i];
+ if (h <= 0f) {
+ throw new IllegalArgumentException("The control points must all "
+ + "have strictly increasing X values.");
+ }
+ d[i] = (y[i + 1] - y[i]) / h;
+ }
+
+ // Initialize the tangents as the average of the secants.
+ m[0] = d[0];
+ for (int i = 1; i < n - 1; i++) {
+ m[i] = (d[i - 1] + d[i]) * 0.5f;
+ }
+ m[n - 1] = d[n - 2];
+
+ // Update the tangents to preserve monotonicity.
+ for (int i = 0; i < n - 1; i++) {
+ if (d[i] == 0f) { // successive Y values are equal
+ m[i] = 0f;
+ m[i + 1] = 0f;
+ } else {
+ float a = m[i] / d[i];
+ float b = m[i + 1] / d[i];
+ if (a < 0f || b < 0f) {
+ throw new IllegalArgumentException("The control points must have "
+ + "monotonic Y values.");
+ }
+ float h = FloatMath.hypot(a, b);
+ if (h > 9f) {
+ float t = 3f / h;
+ m[i] = t * a * d[i];
+ m[i + 1] = t * b * d[i];
+ }
+ }
+ }
+ return new Spline(x, y, m);
+ }
+
+ /**
+ * Interpolates the value of Y = f(X) for given X.
+ * Clamps X to the domain of the spline.
+ *
+ * @param x The X value.
+ * @return The interpolated Y = f(X) value.
+ */
+ public float interpolate(float x) {
+ // Handle the boundary cases.
+ final int n = mX.length;
+ if (Float.isNaN(x)) {
+ return x;
+ }
+ if (x <= mX[0]) {
+ return mY[0];
+ }
+ if (x >= mX[n - 1]) {
+ return mY[n - 1];
+ }
+
+ // Find the index 'i' of the last point with smaller X.
+ // We know this will be within the spline due to the boundary tests.
+ int i = 0;
+ while (x >= mX[i + 1]) {
+ i += 1;
+ if (x == mX[i]) {
+ return mY[i];
+ }
+ }
+
+ // Perform cubic Hermite spline interpolation.
+ float h = mX[i + 1] - mX[i];
+ float t = (x - mX[i]) / h;
+ return (mY[i] * (1 + 2 * t) + h * mM[i] * t) * (1 - t) * (1 - t)
+ + (mY[i + 1] * (3 - 2 * t) + h * mM[i + 1] * (t - 1)) * t * t;
+ }
+
+ // For debugging.
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder();
+ final int n = mX.length;
+ str.append("[");
+ for (int i = 0; i < n; i++) {
+ if (i != 0) {
+ str.append(", ");
+ }
+ str.append("(").append(mX[i]);
+ str.append(", ").append(mY[i]);
+ str.append(": ").append(mM[i]).append(")");
+ }
+ str.append("]");
+ return str.toString();
+ }
+}
diff --git a/core/java/android/webkit/DeviceOrientationService.java b/core/java/android/webkit/DeviceOrientationService.java
index 2e8656c..a4d240d 100755
--- a/core/java/android/webkit/DeviceOrientationService.java
+++ b/core/java/android/webkit/DeviceOrientationService.java
@@ -123,7 +123,7 @@
// The angles are in radians
float[] rotationAngles = new float[3];
SensorManager.getOrientation(deviceRotationMatrix, rotationAngles);
- double alpha = Math.toDegrees(-rotationAngles[0]) - 90.0;
+ double alpha = Math.toDegrees(-rotationAngles[0]);
while (alpha < 0.0) { alpha += 360.0; } // [0, 360)
double beta = Math.toDegrees(-rotationAngles[1]);
while (beta < -180.0) { beta += 360.0; } // [-180, 180)
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 1acbab1..8d79492 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.accessibilityservice.AccessibilityServiceInfo;
import android.animation.ObjectAnimator;
import android.annotation.Widget;
import android.app.ActivityManager;
@@ -1738,8 +1739,21 @@
event.setMaxScrollY(Math.max(convertedContentHeight - adjustedViewHeight, 0));
}
- private boolean isAccessibilityEnabled() {
- return AccessibilityManager.getInstance(mContext).isEnabled();
+ private boolean isAccessibilityInjectionEnabled() {
+ final AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
+ if (!manager.isEnabled()) {
+ return false;
+ }
+
+ // Accessibility scripts should be injected only when a speaking service
+ // is enabled. This may need to change later to accommodate Braille.
+ final List<AccessibilityServiceInfo> services = manager.getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_SPOKEN);
+ if (services.isEmpty()) {
+ return false;
+ }
+
+ return true;
}
private AccessibilityInjector getAccessibilityInjector() {
@@ -3925,7 +3939,7 @@
// reset the flag since we set to true in if need after
// loading is see onPageFinished(Url)
- if (isAccessibilityEnabled()) {
+ if (isAccessibilityInjectionEnabled()) {
getAccessibilityInjector().onPageStarted(url);
}
@@ -3940,7 +3954,7 @@
/* package */ void onPageFinished(String url) {
mZoomManager.onPageFinished(url);
- if (isAccessibilityEnabled()) {
+ if (isAccessibilityInjectionEnabled()) {
getAccessibilityInjector().onPageFinished(url);
}
}
@@ -4981,7 +4995,7 @@
}
// See if the accessibility injector needs to handle this event.
- if (isAccessibilityEnabled()
+ if (isAccessibilityInjectionEnabled()
&& getAccessibilityInjector().handleKeyEventIfNecessary(event)) {
return true;
}
@@ -5088,7 +5102,7 @@
}
// See if the accessibility injector needs to handle this event.
- if (isAccessibilityEnabled()
+ if (isAccessibilityInjectionEnabled()
&& getAccessibilityInjector().handleKeyEventIfNecessary(event)) {
return true;
}
@@ -5339,7 +5353,7 @@
public void onAttachedToWindow() {
if (mWebView.hasWindowFocus()) setActive(true);
- if (isAccessibilityEnabled()) {
+ if (isAccessibilityInjectionEnabled()) {
getAccessibilityInjector().addAccessibilityApisIfNecessary();
}
@@ -5352,7 +5366,7 @@
mZoomManager.dismissZoomPicker();
if (mWebView.hasWindowFocus()) setActive(false);
- if (isAccessibilityEnabled()) {
+ if (isAccessibilityInjectionEnabled()) {
getAccessibilityInjector().removeAccessibilityApisIfNecessary();
} else {
// Ensure the injector is cleared if we're detaching from the window
@@ -7434,7 +7448,7 @@
break;
case SELECTION_STRING_CHANGED:
- if (isAccessibilityEnabled()) {
+ if (isAccessibilityInjectionEnabled()) {
getAccessibilityInjector()
.handleSelectionChangedIfNecessary((String) msg.obj);
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 84fe8ce..e63c57f 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -37,7 +37,7 @@
import android.os.PatternMatcher;
import android.os.Process;
import android.os.RemoteException;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -133,7 +133,7 @@
mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList,
mLaunchedFromUid);
int count = mAdapter.getCount();
- if (mLaunchedFromUid < 0 || UserId.isIsolated(mLaunchedFromUid)) {
+ if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
// Gulp!
finish();
return;
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index b016e99..1e268c4 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -18,16 +18,14 @@
import android.net.Credentials;
import android.net.LocalSocket;
-import android.os.Build;
import android.os.Process;
+import android.os.SELinux;
import android.os.SystemProperties;
import android.util.Log;
import dalvik.system.PathClassLoader;
import dalvik.system.Zygote;
-import android.os.SELinux;
-
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -234,9 +232,9 @@
ZygoteInit.setCloseOnExec(serverPipeFd, true);
}
- pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, rlimits,
- parsedArgs.seInfo, parsedArgs.niceName);
+ pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
+ parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
+ parsedArgs.niceName);
} catch (IOException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
} catch (ErrnoException ex) {
@@ -341,6 +339,9 @@
*/
int debugFlags;
+ /** From --mount-external */
+ int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
+
/** from --target-sdk-version. */
int targetSdkVersion;
boolean targetSdkVersionSpecified;
@@ -526,6 +527,10 @@
"Duplicate arg specified");
}
niceName = arg.substring(arg.indexOf('=') + 1);
+ } else if (arg.equals("--mount-external-singleuser")) {
+ mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER;
+ } else if (arg.equals("--mount-external-multiuser")) {
+ mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
} else {
break;
}
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.java b/core/java/com/android/internal/statusbar/StatusBarNotification.java
index d443523..cb87ac4 100644
--- a/core/java/com/android/internal/statusbar/StatusBarNotification.java
+++ b/core/java/com/android/internal/statusbar/StatusBarNotification.java
@@ -19,6 +19,7 @@
import android.app.Notification;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.UserHandle;
import android.widget.RemoteViews;
@@ -132,6 +133,11 @@
return ((notification.flags & Notification.FLAG_ONGOING_EVENT) == 0)
&& ((notification.flags & Notification.FLAG_NO_CLEAR) == 0);
}
+
+ /** Returns a userHandle for the instance of the app that posted this notification. */
+ public int getUserId() {
+ return UserHandle.getUserId(this.uid);
+ }
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index f77e8f3..4777c16 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -34,7 +34,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.storage.IMountService;
import android.provider.Settings;
import android.security.KeyStore;
@@ -246,7 +246,7 @@
if (callingUid == android.os.Process.SYSTEM_UID) {
return mCurrentUserId;
} else {
- return UserId.getUserId(callingUid);
+ return UserHandle.getUserId(callingUid);
}
}
diff --git a/core/java/com/android/internal/widget/LockSettingsService.java b/core/java/com/android/internal/widget/LockSettingsService.java
index 2fb81ac..350e006 100644
--- a/core/java/com/android/internal/widget/LockSettingsService.java
+++ b/core/java/com/android/internal/widget/LockSettingsService.java
@@ -25,7 +25,7 @@
import android.os.Binder;
import android.os.RemoteException;
import android.os.SystemProperties;
-import android.os.UserId;
+import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.text.TextUtils;
@@ -97,7 +97,7 @@
private static final void checkWritePermission(int userId) {
final int callingUid = Binder.getCallingUid();
- if (UserId.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
+ if (UserHandle.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
throw new SecurityException("uid=" + callingUid
+ " not authorized to write lock settings");
}
@@ -105,7 +105,7 @@
private static final void checkPasswordReadPermission(int userId) {
final int callingUid = Binder.getCallingUid();
- if (UserId.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
+ if (UserHandle.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
throw new SecurityException("uid=" + callingUid
+ " not authorized to read lock password");
}
@@ -113,8 +113,8 @@
private static final void checkReadPermission(int userId) {
final int callingUid = Binder.getCallingUid();
- if (UserId.getAppId(callingUid) != android.os.Process.SYSTEM_UID
- && UserId.getUserId(callingUid) != userId) {
+ if (UserHandle.getAppId(callingUid) != android.os.Process.SYSTEM_UID
+ && UserHandle.getUserId(callingUid) != userId) {
throw new SecurityException("uid=" + callingUid
+ " not authorized to read settings of user " + userId);
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index b1423ca..f950d3d 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -67,7 +67,6 @@
android_os_ParcelFileDescriptor.cpp \
android_os_Parcel.cpp \
android_os_SELinux.cpp \
- android_os_StatFs.cpp \
android_os_SystemClock.cpp \
android_os_SystemProperties.cpp \
android_os_Trace.cpp \
diff --git a/core/jni/android_os_StatFs.cpp b/core/jni/android_os_StatFs.cpp
deleted file mode 100644
index 79d8fef..0000000
--- a/core/jni/android_os_StatFs.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#if INCLUDE_SYS_MOUNT_FOR_STATFS
-#include <sys/mount.h>
-#else
-#include <sys/statfs.h>
-#endif
-
-#include <errno.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include "android_runtime/AndroidRuntime.h"
-
-
-namespace android
-{
-
-// ----------------------------------------------------------------------------
-
-struct fields_t {
- jfieldID context;
-};
-static fields_t fields;
-
-// ----------------------------------------------------------------------------
-
-static jint
-android_os_StatFs_getBlockSize(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- return stat->f_bsize;
-}
-
-static jint
-android_os_StatFs_getBlockCount(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- return stat->f_blocks;
-}
-
-static jint
-android_os_StatFs_getFreeBlocks(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- return stat->f_bfree;
-}
-
-static jint
-android_os_StatFs_getAvailableBlocks(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- return stat->f_bavail;
-}
-
-static void
-android_os_StatFs_native_restat(JNIEnv *env, jobject thiz, jstring path)
-{
- if (path == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- return;
- }
-
- // get the object handle
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- if (stat == NULL) {
- jniThrowException(env, "java/lang/NoSuchFieldException", NULL);
- return;
- }
-
- const char* pathstr = env->GetStringUTFChars(path, NULL);
- if (pathstr == NULL) {
- jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
- return;
- }
-
- // note that stat will contain the new file data corresponding to
- // pathstr
- if (statfs(pathstr, stat) != 0) {
- ALOGE("statfs %s failed, errno: %d", pathstr, errno);
- delete stat;
- env->SetIntField(thiz, fields.context, 0);
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- }
- // Release pathstr
- env->ReleaseStringUTFChars(path, pathstr);
-}
-
-static void
-android_os_StatFs_native_setup(JNIEnv *env, jobject thiz, jstring path)
-{
- if (path == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- return;
- }
-
- struct statfs* stat = new struct statfs;
- if (stat == NULL) {
- jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
- return;
- }
- env->SetIntField(thiz, fields.context, (int)stat);
- android_os_StatFs_native_restat(env, thiz, path);
-}
-
-static void
-android_os_StatFs_native_finalize(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- if (stat != NULL) {
- delete stat;
- env->SetIntField(thiz, fields.context, 0);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-static JNINativeMethod gMethods[] = {
- {"getBlockSize", "()I", (void *)android_os_StatFs_getBlockSize},
- {"getBlockCount", "()I", (void *)android_os_StatFs_getBlockCount},
- {"getFreeBlocks", "()I", (void *)android_os_StatFs_getFreeBlocks},
- {"getAvailableBlocks", "()I", (void *)android_os_StatFs_getAvailableBlocks},
- {"native_setup", "(Ljava/lang/String;)V", (void *)android_os_StatFs_native_setup},
- {"native_finalize", "()V", (void *)android_os_StatFs_native_finalize},
- {"native_restat", "(Ljava/lang/String;)V", (void *)android_os_StatFs_native_restat},
-};
-
-
-int register_android_os_StatFs(JNIEnv *env)
-{
- jclass clazz;
-
- clazz = env->FindClass("android/os/StatFs");
- if (clazz == NULL) {
- ALOGE("Can't find android/os/StatFs");
- return -1;
- }
-
- fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
- if (fields.context == NULL) {
- ALOGE("Can't find StatFs.mNativeContext");
- return -1;
- }
-
- return AndroidRuntime::registerNativeMethods(env,
- "android/os/StatFs", gMethods, NELEM(gMethods));
-}
-
-} // namespace android
diff --git a/core/jni/android_util_FloatMath.cpp b/core/jni/android_util_FloatMath.cpp
index e30756b..529fbe9 100644
--- a/core/jni/android_util_FloatMath.cpp
+++ b/core/jni/android_util_FloatMath.cpp
@@ -29,6 +29,10 @@
static float ExpF(JNIEnv* env, jobject clazz, float x) {
return expf(x);
}
+
+ static float HypotF(JNIEnv* env, jobject clazz, float x, float y) {
+ return hypotf(x, y);
+ }
};
static JNINativeMethod gMathUtilsMethods[] = {
@@ -38,6 +42,7 @@
{"cos", "(F)F", (void*) MathUtilsGlue::CosF},
{"sqrt", "(F)F", (void*) MathUtilsGlue::SqrtF},
{"exp", "(F)F", (void*) MathUtilsGlue::ExpF},
+ {"hypot", "(FF)F", (void*) MathUtilsGlue::HypotF},
};
int register_android_util_FloatMath(JNIEnv* env)
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index e13921f..db862c8 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -156,7 +156,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"Sit af"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Foutverslag"</string>
<string name="bugreport_title" msgid="2667494803742548533">"Neem foutverslag"</string>
- <string name="bugreport_message" msgid="398447048750350456">"Dit sal inligting oor die huidige toestand van jou toestel insamel, om as \'n e-posboodskap te stuur. Dit sal \'n tydjie neem vandat die foutverslag begin is totdat dit reg is om gestuur te word; wees asseblief geduldig."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"Dit sal inligting oor die huidige toestand van jou toestel insamel om as \'n e-posboodskap te stuur. Dit sal \'n tydjie neem vandat die foutverslag begin is totdat dit reg is om gestuur te word; wees asseblief geduldig."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Stilmodus"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Klank is AF"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Klank is AAN"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index bde732c1..17f4dd1 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -156,7 +156,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"إيقاف التشغيل"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"تقرير الأخطاء"</string>
<string name="bugreport_title" msgid="2667494803742548533">"إعداد تقرير بالأخطاء"</string>
- <string name="bugreport_message" msgid="398447048750350456">"سيجمع هذا معلومات حول حالة جهازك الحالي لإرسالها كرسالة إلكترونية. سيستغرق وقتًا قليلاً من بدء عرض تقرير بالأخطاء وحتى يكون جاهزًا للإرسال، الرجاء الانتظار."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"سيجمع هذا معلومات حول حالة جهازك الحالي لإرسالها كرسالة إلكترونية، ولكنه سيستغرق وقتًا قليلاً من بدء عرض تقرير بالأخطاء. وحتى يكون جاهزًا للإرسال، الرجاء الانتظار."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"وضع صامت"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"الصوت متوقف"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"الصوت قيد التشغيل"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 596e8f5..f72d625 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -156,7 +156,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"Ausschalten"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Fehlerbericht"</string>
<string name="bugreport_title" msgid="2667494803742548533">"Fehlerbericht abrufen"</string>
- <string name="bugreport_message" msgid="398447048750350456">"Bei diesem Fehlerbericht werden Daten zum aktuellen Status Ihres Geräts erfasst und als E-Mail versandt. Vom Start des Berichts bis zu seinem Versand kann es eine Weile dauern. Bitte haben Sie Geduld."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"Bei diesem Fehlerbericht werden Daten zum aktuellen Status Ihres Geräts erfasst und als E-Mail versandt. Vom Start des Berichts bis zu seinem Versand kann es eine Weile dauern. Bitte haben Sie etwas Geduld."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Lautlos-Modus"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ton ist AUS."</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ton ist AN."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d793c5d..6f99078 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -156,7 +156,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"خاموش کردن"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"گزارش اشکال"</string>
<string name="bugreport_title" msgid="2667494803742548533">"گرفتن گزارش اشکال"</string>
- <string name="bugreport_message" msgid="398447048750350456">"این گزارش اطلاعات مربوط به وضعیت دستگاه کنونی شما را جمعآوری میکند تا به صورت یک پیام ایمیل ارسال شود. از زمان شروع گزارش اشکال تا آماده شدن برای ارسال اندکی زمان میبرد؛ لطفاً صبور باشید."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"این گزارش اطلاعات مربوط به وضعیت دستگاه کنونی شما را جمعآوری میکند تا به صورت یک پیام ایمیل ارسال شود. از زمان شروع گزارش اشکال تا آماده شدن برای ارسال اندکی زمان میبرد؛ لطفاً شکیبا باشید."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"حالت ساکت"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"صدا خاموش است"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"صدا روشن است"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index a56213b..5bbebc5 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -156,7 +156,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"Matikan kuasa"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Laporan pepijat"</string>
<string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan pepijat"</string>
- <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpul maklumat tentang keadaan peranti semasa anda untuk dihantarkan sebagai mesej e-mel. Ini akan mengambil sedikit masa bermula dari laporan pepijat sehingga siap untuk dihantar; jadi diharap bersabar."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpul maklumat tentang keadaan peranti semasa anda untuk dihantarkan sebagai mesej e-mel. Proses ini akan mengambil sedikit masa bermula dari laporan pepijat sehingga siap untuk dihantar; jadi diharap bersabar."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mod senyap"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Bunyi DIMATIKAN"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Bunyi DIHIDUPKAN"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 1deae16..7284dd7 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -156,7 +156,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"Opriţi alimentarea"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Raport despre erori"</string>
<string name="bugreport_title" msgid="2667494803742548533">"Executaţi un raport despre erori"</string>
- <string name="bugreport_message" msgid="398447048750350456">"Acest raport va colecta informaţii despre starea actuală a dispozitivului, pentru a le trimite ca mesaj de e-mail. Va dura un timp din momentul pornirii raportului despre erori şi până când acesta va fi gata pentru a fi trimis, prin urmare vă rugăm să aveţi puţină răbdare."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"Acest raport va colecta informaţii despre starea actuală a dispozitivului, pentru a le trimite într-un e-mail. Aveți răbdare după pornirea raportului despre erori până când va fi gata de trimis."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mod Silenţios"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sunetul este DEZACTIVAT"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sunetul este ACTIVAT"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4a9cd5a..c271baa 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -155,7 +155,7 @@
<string name="global_action_lock" msgid="2844945191792119712">"屏幕锁定"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"关机"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"错误报告"</string>
- <string name="bugreport_title" msgid="2667494803742548533">"获取错误报告"</string>
+ <string name="bugreport_title" msgid="2667494803742548533">"提交错误报告"</string>
<string name="bugreport_message" msgid="398447048750350456">"这会收集有关当前设备状态的信息,并以电子邮件的形式进行发送。从开始生成错误报告到准备好发送需要一点时间,请耐心等待。"</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"静音模式"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"声音已关闭"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 36dcf29..20a15d1 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -156,7 +156,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"關機"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
<string name="bugreport_title" msgid="2667494803742548533">"取得錯誤報告"</string>
- <string name="bugreport_message" msgid="398447048750350456">"這會收集您目前裝置狀態的相關資訊,以便透過電子郵件傳送。從開始建立錯誤報告到準備傳送,這段過程可能需要一點時間,敬請耐心等候。"</string>
+ <string name="bugreport_message" msgid="398447048750350456">"這會收集您目前裝置狀態的相關資訊,以便透過電子郵件傳送。從錯誤報告開始建立到準備傳送的這段過程可能需要一點時間,敬請耐心等候。"</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"靜音模式"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"音效已關閉"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"音效已開啟"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ee0ff8e..e3c957b 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -533,13 +533,22 @@
<integer name="config_longPressOnHomeBehavior">2</integer>
<!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
- The N entries of this array define N + 1 zones as follows:
+ The N entries of this array define N + 1 control points as follows:
- Zone 0: 0 <= LUX < array[0]
- Zone 1: array[0] <= LUX < array[1]
+ Point 1: LUX <= 0 (implicit)
+ Point 2: 0 < level[1] == LUX < level[2]
...
- Zone N: array[N - 1] <= LUX < array[N]
- Zone N + 1: array[N] <= LUX < infinity
+ Point N: level[N - 1] == LUX < level[N]
+ Point N + 1: level[N] <= LUX < infinity
+
+ The control points must be strictly increasing. Each control point
+ corresponds to an entry in the brightness backlight values arrays.
+ For example, if LUX == level[1] (first element of the levels array)
+ then the brightness will be determined by value[1] (first element
+ of the brightness values array).
+
+ Spline interpolation is used to determine the auto-brightness
+ backlight values for LUX levels between these control points.
Must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessLevels">
@@ -552,6 +561,7 @@
<!-- Array of output values for LCD backlight corresponding to the LUX values
in the config_autoBrightnessLevels array. This array should have size one greater
than the size of the config_autoBrightnessLevels array.
+ The brightness values must be between 0 and 255 and be non-decreasing.
This must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessLcdBacklightValues">
</integer-array>
@@ -559,6 +569,7 @@
<!-- Array of output values for button backlight corresponding to the LUX values
in the config_autoBrightnessLevels array. This array should have size one greater
than the size of the config_autoBrightnessLevels array.
+ The brightness values must be between 0 and 255 and be non-decreasing.
This must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessButtonBacklightValues">
</integer-array>
@@ -566,6 +577,7 @@
<!-- Array of output values for keyboard backlight corresponding to the LUX values
in the config_autoBrightnessLevels array. This array should have size one greater
than the size of the config_autoBrightnessLevels array.
+ The brightness values must be between 0 and 255 and be non-decreasing.
This must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessKeyboardBacklightValues">
</integer-array>
diff --git a/core/tests/coretests/src/android/content/pm/AppCacheTest.java b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
index 0c31e2d..8d53db9 100755
--- a/core/tests/coretests/src/android/content/pm/AppCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
@@ -24,7 +24,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StatFs;
-import android.os.UserId;
+import android.os.UserHandle;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
@@ -719,7 +719,7 @@
File getDataDir() {
try {
ApplicationInfo appInfo = getPm().getApplicationInfo(mContext.getPackageName(), 0,
- UserId.myUserId());
+ UserHandle.myUserId());
return new File(appInfo.dataDir);
} catch (RemoteException e) {
throw new RuntimeException("Pacakge manager dead", e);
@@ -748,7 +748,7 @@
@LargeTest
public void testClearApplicationUserDataNoObserver() throws Exception {
- getPm().clearApplicationUserData(mContext.getPackageName(), null, UserId.myUserId());
+ getPm().clearApplicationUserData(mContext.getPackageName(), null, UserHandle.myUserId());
//sleep for 1 minute
Thread.sleep(60*1000);
//confirm files dont exist
diff --git a/core/tests/coretests/src/android/os/ProcessTest.java b/core/tests/coretests/src/android/os/ProcessTest.java
index 598a8d2..1f5b7c8 100644
--- a/core/tests/coretests/src/android/os/ProcessTest.java
+++ b/core/tests/coretests/src/android/os/ProcessTest.java
@@ -18,7 +18,7 @@
package android.os;
import android.os.Process;
-import android.os.UserId;
+import android.os.UserHandle;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
@@ -32,10 +32,10 @@
assertEquals(android.os.Process.SYSTEM_UID, Process.getUidForName("system"));
assertEquals(Process.BLUETOOTH_UID, Process.getUidForName("bluetooth"));
assertEquals(Process.FIRST_APPLICATION_UID, Process.getUidForName("u0_a0"));
- assertEquals(UserId.getUid(1, Process.SYSTEM_UID), Process.getUidForName("u1_system"));
- assertEquals(UserId.getUid(2, Process.FIRST_ISOLATED_UID),
+ assertEquals(UserHandle.getUid(1, Process.SYSTEM_UID), Process.getUidForName("u1_system"));
+ assertEquals(UserHandle.getUid(2, Process.FIRST_ISOLATED_UID),
Process.getUidForName("u2_i0"));
- assertEquals(UserId.getUid(3, Process.FIRST_APPLICATION_UID + 100),
+ assertEquals(UserHandle.getUid(3, Process.FIRST_APPLICATION_UID + 100),
Process.getUidForName("u3_a100"));
}
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index e971a75..e229f23 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -32,12 +32,17 @@
<li>{@link android.view.ViewGroup}</li>
<li>{@link android.view.ViewGroup.LayoutParams}</li>
</ol>
-</div>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}training/basics/firstapp/building-ui.html">Building a Simple User
+Interface</a></li> </div>
</div>
-<p>Your layout is the architecture for the user interface in an Activity.
-It defines the layout structure and holds all the elements that appear to the user.
-You can declare your layout in two ways:</p>
+<p>A layout defines the visual structure for a user interface, such as the UI for an <a
+href="{@docRoot}guide/components/activities.html">activity</a> or <a
+href="{@docRoot}guide/topics/appwidgets/index.html">app widget</a>.
+You can declare a layout in two ways:</p>
<ul>
<li><strong>Declare UI elements in XML</strong>. Android provides a straightforward XML
vocabulary that corresponds to the View classes and subclasses, such as those for widgets and layouts.</li>
@@ -77,16 +82,6 @@
<h2 id="write">Write the XML</h2>
-<div class="sidebox-wrapper">
-<div class="sidebox">
-<p>For your convenience, the API reference documentation for UI related classes
-lists the available XML attributes that correspond to the class methods, including inherited
-attributes.</p>
-<p>To learn more about the available XML elements and attributes, as well as the format of the XML file, see <a
-href="{@docRoot}guide/topics/resources/available-resources.html#layoutresources">Layout Resources</a>.</p>
-</div>
-</div>
-
<p>Using Android's XML vocabulary, you can quickly design UI layouts and the screen elements they contain, in the same way you create web pages in HTML — with a series of nested elements. </p>
<p>Each layout file must contain exactly one root element, which must be a View or ViewGroup object. Once you've defined the root element, you can add additional layout objects or widgets as child elements to gradually build a View hierarchy that defines your layout. For example, here's an XML layout that uses a vertical {@link android.widget.LinearLayout}
@@ -111,7 +106,8 @@
<p>After you've declared your layout in XML, save the file with the <code>.xml</code> extension,
in your Android project's <code>res/layout/</code> directory, so it will properly compile. </p>
-<p>We'll discuss each of the attributes shown here a little later.</p>
+<p>More information about the syntax for a layout XML file is available in the <a
+href="{@docRoot}guide/topics/resources/layout-resource.html">Layout Resources</a> document.</p>
<h2 id="load">Load the XML Resource</h2>
diff --git a/docs/html/guide/topics/ui/layout/gridview.jd b/docs/html/guide/topics/ui/layout/gridview.jd
index 11c5474..67bdd0f0 100644
--- a/docs/html/guide/topics/ui/layout/gridview.jd
+++ b/docs/html/guide/topics/ui/layout/gridview.jd
@@ -22,10 +22,15 @@
scrollable grid. The grid items are automatically inserted to the layout using a {@link
android.widget.ListAdapter}.</p>
+<p>For an introduction to how you can dynamically insert views using an adapter, read
+<a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Building Layouts with
+ an Adapter</a>.</p>
+
<img src="{@docRoot}images/ui/gridview.png" alt="" />
<h2 id="example">Example</h2>
+
<p>In this tutorial, you'll create a grid of image thumbnails. When an item is selected, a
toast message will display the position of the image.</p>
diff --git a/docs/html/guide/topics/ui/layout/listview.jd b/docs/html/guide/topics/ui/layout/listview.jd
index 26a7597..fee5292 100644
--- a/docs/html/guide/topics/ui/layout/listview.jd
+++ b/docs/html/guide/topics/ui/layout/listview.jd
@@ -28,6 +28,10 @@
android.widget.Adapter} that pulls content from a source such as an array or database query and
converts each item result into a view that's placed into the list.</p>
+<p>For an introduction to how you can dynamically insert views using an adapter, read
+<a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Building Layouts with
+ an Adapter</a>.</p>
+
<img src="{@docRoot}images/ui/listview.png" alt="" />
<h2 id="Loader">Using a Loader</h2>
@@ -147,5 +151,5 @@
Provider</a>, if you want to
try this code, your app must request the {@link android.Manifest.permission#READ_CONTACTS}
permission in the manifest file:<br/>
-<code><uses-permission android:name="android.permission.READ_CONTACTS" /></p>
+<code><uses-permission android:name="android.permission.READ_CONTACTS" /></code></p>
diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java
index 07f9e91..6b23be9 100644
--- a/opengl/java/com/google/android/gles_jni/GLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/GLImpl.java
@@ -23,7 +23,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.os.Build;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Log;
import java.nio.Buffer;
@@ -68,7 +68,7 @@
int version = 0;
IPackageManager pm = AppGlobals.getPackageManager();
try {
- ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0, UserId.myUserId());
+ ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0, UserHandle.myUserId());
if (applicationInfo != null) {
version = applicationInfo.targetSdkVersion;
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 4552a55..1481eb2 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -38,7 +38,6 @@
import android.util.Log;
import com.android.internal.content.PackageHelper;
-import com.android.internal.telephony.BaseCommands;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RILConstants;
@@ -65,7 +64,7 @@
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 80;
+ private static final int DATABASE_VERSION = 81;
private Context mContext;
@@ -1073,9 +1072,55 @@
upgradeVersion = 79;
}
+ if (upgradeVersion == 79) {
+ // Before touch exploration was a global setting controlled by the user
+ // via the UI. However, if the enabled accessibility services do not
+ // handle touch exploration mode, enabling it makes no sense. Therefore,
+ // now the services request touch exploration mode and the user is
+ // presented with a dialog to allow that and if she does we store that
+ // in the database. As a result of this change a user that has enabled
+ // accessibility, touch exploration, and some accessibility services
+ // may lose touch exploration state, thus rendering the device useless
+ // unless sighted help is provided, since the enabled service(s) are
+ // not in the list of services to which the user granted a permission
+ // to put the device in touch explore mode. Here we are allowing all
+ // enabled accessibility services to toggle touch exploration provided
+ // accessibility and touch exploration are enabled and no services can
+ // toggle touch exploration. Note that the user has already manually
+ // enabled the services and touch exploration which means the she has
+ // given consent to have these services work in touch exploration mode.
+ final boolean accessibilityEnabled = getIntValueFromTable(db, "secure",
+ Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
+ final boolean touchExplorationEnabled = getIntValueFromTable(db, "secure",
+ Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1;
+ if (accessibilityEnabled && touchExplorationEnabled) {
+ String enabledServices = getStringValueFromTable(db, "secure",
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
+ String touchExplorationGrantedServices = getStringValueFromTable(db, "secure",
+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, "");
+ if (TextUtils.isEmpty(touchExplorationGrantedServices)
+ && !TextUtils.isEmpty(enabledServices)) {
+ SQLiteStatement stmt = null;
+ try {
+ db.beginTransaction();
+ stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
+ + " VALUES(?,?);");
+ loadSetting(stmt,
+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ enabledServices);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ if (stmt != null) stmt.close();
+ }
+ }
+ }
+ upgradeVersion = 80;
+ }
+
// vvv Jelly Bean MR1 changes begin here vvv
- if (upgradeVersion == 79) {
+ if (upgradeVersion == 80) {
// update screensaver settings
db.beginTransaction();
SQLiteStatement stmt = null;
@@ -1093,10 +1138,9 @@
db.endTransaction();
if (stmt != null) stmt.close();
}
- upgradeVersion = 80;
+ upgradeVersion = 81;
}
-
// *** Remember to update DATABASE_VERSION above!
if (upgradeVersion != currentVersion) {
@@ -1743,18 +1787,28 @@
}
private int getIntValueFromSystem(SQLiteDatabase db, String name, int defaultValue) {
- int value = defaultValue;
+ return getIntValueFromTable(db, "system", name, defaultValue);
+ }
+
+ private int getIntValueFromTable(SQLiteDatabase db, String table, String name,
+ int defaultValue) {
+ String value = getStringValueFromTable(db, table, name, null);
+ return (value != null) ? Integer.parseInt(value) : defaultValue;
+ }
+
+ private String getStringValueFromTable(SQLiteDatabase db, String table, String name,
+ String defaultValue) {
Cursor c = null;
try {
- c = db.query("system", new String[] { Settings.System.VALUE }, "name='" + name + "'",
+ c = db.query(table, new String[] { Settings.System.VALUE }, "name='" + name + "'",
null, null, null, null);
if (c != null && c.moveToFirst()) {
String val = c.getString(0);
- value = val == null ? defaultValue : Integer.parseInt(val);
+ return val == null ? defaultValue : val;
}
} finally {
if (c != null) c.close();
}
- return value;
+ return defaultValue;
}
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 51dc3b1..676bfd0 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -15,6 +15,8 @@
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.REMOTE_AUDIO_PLAYBACK" />
+ <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+
<!-- Networking and telephony -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
diff --git a/packages/SystemUI/res/layout/quick_settings.xml b/packages/SystemUI/res/layout/quick_settings.xml
index a62a470..c4b881e 100644
--- a/packages/SystemUI/res/layout/quick_settings.xml
+++ b/packages/SystemUI/res/layout/quick_settings.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.systemui.statusbar.phone.PanelView
+<com.android.systemui.statusbar.phone.SettingsPanelView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -42,4 +42,4 @@
android:src="@drawable/status_bar_close"
/>
</LinearLayout>
-</com.android.systemui.statusbar.phone.PanelView>
\ No newline at end of file
+</com.android.systemui.statusbar.phone.SettingsPanelView >
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 828dba4..cb32d63 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -23,10 +23,11 @@
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/notification_panel"
android:layout_width="0dp"
- android:layout_height="0dp"
+ android:layout_height="wrap_content"
android:background="@drawable/notification_panel_bg"
android:paddingTop="@dimen/notification_panel_padding_top"
android:layout_marginLeft="@dimen/notification_panel_margin_left"
+ android:animateLayoutChanges="true"
>
<TextView
@@ -45,6 +46,7 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/close_handle_underlap"
android:orientation="vertical"
+ android:animateLayoutChanges="true"
>
<include layout="@layout/status_bar_expanded_header"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 7f598b6..60896c3 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -65,11 +65,24 @@
android:layout_weight="1"
/>
+ <TextView
+ android:id="@+id/header_debug_info"
+ android:visibility="invisible"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:fontFamily="sans-serif-condensed"
+ android:textSize="11dp"
+ android:textStyle="bold"
+ android:textColor="#00A040"
+ android:padding="2dp"
+ />
+
<ImageView android:id="@+id/clear_all_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="center"
android:src="@drawable/ic_notify_clear"
android:contentDescription="@string/accessibility_clear_all"
- />
-</LinearLayout>
\ No newline at end of file
+ />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index dd70166..3dcdae8 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -49,4 +49,17 @@
android:background="@drawable/bottom_divider_glow"
/>
+ <TextView
+ android:id="@+id/debug_info"
+ android:visibility="invisible"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|right"
+ android:fontFamily="sans-serif-condensed"
+ android:textSize="9dp"
+ android:textStyle="bold"
+ android:textColor="#00A040"
+ android:padding="2dp"
+ />
+
</FrameLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index b36e71a..a2f43fd 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -24,7 +24,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.Vibrator;
import android.provider.Settings;
import android.util.AttributeSet;
@@ -75,14 +75,14 @@
mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL);
// Launch Assist
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserId.USER_CURRENT);
+ .getAssistIntent(mContext, UserHandle.USER_CURRENT);
if (intent == null) return;
try {
ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.search_launch_enter, R.anim.search_launch_exit,
getHandler(), this);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivityAsUser(intent, opts.toBundle(), UserId.USER_CURRENT);
+ mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.USER_CURRENT);
} catch (ActivityNotFoundException e) {
Slog.w(TAG, "Activity not found for " + intent.getAction());
onAnimationStarted();
@@ -143,7 +143,7 @@
private void maybeSwapSearchIcon() {
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserId.USER_CURRENT);
+ .getAssistIntent(mContext, UserHandle.USER_CURRENT);
if (intent != null) {
ComponentName component = intent.getComponent();
if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
@@ -281,6 +281,6 @@
public boolean isAssistantAvailable() {
return ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserId.USER_CURRENT) != null;
+ .getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
index 3e03f85..4d8c168 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
@@ -30,7 +30,7 @@
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Process;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Log;
import com.android.systemui.R;
@@ -245,7 +245,7 @@
final List<ActivityManager.RecentTaskInfo> recentTasks =
am.getRecentTasksForUser(MAX_TASKS,
- ActivityManager.RECENT_IGNORE_UNAVAILABLE, UserId.USER_CURRENT);
+ ActivityManager.RECENT_IGNORE_UNAVAILABLE, UserHandle.USER_CURRENT);
int numTasks = recentTasks.size();
ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME).resolveActivityInfo(pm, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index bb647c3..7d36152 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -36,7 +36,7 @@
import android.net.Uri;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserId;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
@@ -790,7 +790,7 @@
| Intent.FLAG_ACTIVITY_TASK_ON_HOME
| Intent.FLAG_ACTIVITY_NEW_TASK);
if (DEBUG) Log.v(TAG, "Starting activity " + intent);
- context.startActivityAsUser(intent, opts.toBundle(), UserId.USER_CURRENT);
+ context.startActivityAsUser(intent, opts.toBundle(), UserHandle.USER_CURRENT);
}
if (usingDrawingCache) {
holder.thumbnailViewImage.setDrawingCacheEnabled(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index ea5089d..7598537 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -34,8 +34,10 @@
import android.app.KeyguardManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.ContentObserver;
@@ -47,6 +49,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
@@ -65,6 +68,7 @@
import android.widget.LinearLayout;
import android.widget.PopupMenu;
import android.widget.RemoteViews;
+import android.widget.TextView;
import java.util.ArrayList;
@@ -72,6 +76,7 @@
CommandQueue.Callbacks, RecentsPanelView.OnRecentsPanelVisibilityChangedListener {
static final String TAG = "StatusBar";
private static final boolean DEBUG = false;
+ public static final boolean MULTIUSER_DEBUG = false;
protected static final int MSG_OPEN_RECENTS_PANEL = 1020;
protected static final int MSG_CLOSE_RECENTS_PANEL = 1021;
@@ -112,6 +117,8 @@
protected PopupMenu mNotificationBlamePopup;
+ protected int mCurrentUserId = 0;
+
// UI-specific methods
/**
@@ -252,6 +259,40 @@
switches[3]
));
}
+
+ // XXX: this is currently broken and will always return 0, but should start working at some point
+ try {
+ mCurrentUserId = ActivityManagerNative.getDefault().getCurrentUser().id;
+ } catch (RemoteException e) {
+ Log.v(TAG, "Couldn't get current user ID; guessing it's 0", e);
+ }
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+ mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
+ if (true) Slog.v(TAG, "userId " + mCurrentUserId + " is in the house");
+ userSwitched(mCurrentUserId);
+ }
+ }}, filter);
+ }
+
+ public void userSwitched(int newUserId) {
+ // should be overridden
+ }
+
+ public boolean notificationIsForCurrentUser(StatusBarNotification n) {
+ final int thisUserId = mCurrentUserId;
+ final int notificationUserId = n.getUserId();
+ if (DEBUG && MULTIUSER_DEBUG) {
+ Slog.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
+ n, thisUserId, notificationUserId));
+ }
+ return thisUserId == notificationUserId;
}
protected View updateNotificationVetoButton(View row, StatusBarNotification n) {
@@ -604,6 +645,14 @@
applyLegacyRowBackground(sbn, content);
row.setTag(R.id.expandable_tag, Boolean.valueOf(large != null));
+
+ if (MULTIUSER_DEBUG) {
+ TextView debug = (TextView) row.findViewById(R.id.debug_info);
+ if (debug != null) {
+ debug.setVisibility(View.VISIBLE);
+ debug.setText("U " + entry.notification.getUserId());
+ }
+ }
entry.row = row;
entry.content = content;
entry.expanded = expandedOneU;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java b/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java
index 81a16ae..0f894a1 100755
--- a/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java
@@ -101,8 +101,7 @@
mDownTime = ev.getDownTime();
} else {
if (mDownTime != ev.getDownTime()) {
- // TODO: remove
- throw new RuntimeException("Assertion failure in GestureRecorder: event downTime ("
+ Slog.w(TAG, "Assertion failure in GestureRecorder: event downTime ("
+ev.getDownTime()+") does not match gesture downTime ("+mDownTime+")");
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index ae7fb27..13a34ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -22,15 +22,13 @@
public class NotificationPanelView extends PanelView {
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
- android.util.Slog.v("NotificationPanelView", "ctor");
}
-
@Override
public void fling(float vel, boolean always) {
((PhoneStatusBarView) mBar).mBar.getGestureRecorder().tag(
"fling " + ((vel > 0) ? "open" : "closed"),
- "v=" + vel);
+ "notifications,v=" + vel);
super.fling(vel, always);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index f44c500..bffb903 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -64,15 +64,25 @@
return getMeasuredHeight();
}
+ public PanelView selectPanelForTouchX(float x) {
+ final int N = mPanels.size();
+ return mPanels.get((int)(N * x / getMeasuredWidth()));
+ }
+
+ public boolean panelsEnabled() {
+ return true;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
+ // Allow subclasses to implement enable/disable semantics
+ if (!panelsEnabled()) return false;
+
// figure out which panel needs to be talked to here
if (event.getAction() == MotionEvent.ACTION_DOWN) {
- final int N = mPanels.size();
- final int i = (int)(N * event.getX() / getMeasuredWidth());
- mTouchingPanel = mPanels.get(i);
+ mTouchingPanel = selectPanelForTouchX(event.getX());
mPanelHolder.setSelectedPanel(mTouchingPanel);
- LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %d", mState, i);
+ LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %s", mState, mTouchingPanel.getName());
if (mState == STATE_CLOSED || mState == STATE_OPEN) {
go(STATE_TRANSITIONING);
onPanelPeeked();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index b5a50c6..b595257 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -22,6 +22,7 @@
}
public static final boolean BRAKES = false;
+ private static final boolean STRETCH_PAST_CONTENTS = true;
private float mSelfExpandVelocityPx; // classic value: 2000px/s
private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
@@ -45,6 +46,9 @@
private float mTouchOffset;
private float mExpandedFraction = 0;
private float mExpandedHeight = 0;
+ private boolean mClosing;
+ private boolean mRubberbanding;
+ private boolean mTracking;
private TimeAnimator mTimeAnimator;
private VelocityTracker mVelocityTracker;
@@ -59,9 +63,15 @@
}
};
+ private final Runnable mStopAnimator = new Runnable() { public void run() {
+ if (mTimeAnimator.isStarted()) {
+ mTimeAnimator.end();
+ }
+ }};
+
private float mVel, mAccel;
private int mFullHeight = 0;
- private String mViewName;
+ private String mViewName;
private void animationTick(long dtms) {
if (!mTimeAnimator.isStarted()) {
@@ -70,16 +80,18 @@
mTimeAnimator.setTimeListener(mAnimationCallback);
mTimeAnimator.start();
+
+ mRubberbanding = STRETCH_PAST_CONTENTS && mExpandedHeight > getFullHeight();
+ mClosing = (mExpandedHeight > 0 && mVel < 0) || mRubberbanding;
} else if (dtms > 0) {
final float dt = dtms * 0.001f; // ms -> s
LOG("tick: v=%.2fpx/s dt=%.4fs", mVel, dt);
LOG("tick: before: h=%d", (int) mExpandedHeight);
final float fh = getFullHeight();
- final boolean closing = mExpandedHeight > 0 && mVel < 0;
boolean braking = false;
if (BRAKES) {
- if (closing) {
+ if (mClosing) {
braking = mExpandedHeight <= mCollapseBrakingDistancePx;
mAccel = braking ? 10*mCollapseAccelPx : -mCollapseAccelPx;
} else {
@@ -87,37 +99,41 @@
mAccel = braking ? 10*-mExpandAccelPx : mExpandAccelPx;
}
} else {
- mAccel = closing ? -mCollapseAccelPx : mExpandAccelPx;
+ mAccel = mClosing ? -mCollapseAccelPx : mExpandAccelPx;
}
mVel += mAccel * dt;
if (braking) {
- if (closing && mVel > -mBrakingSpeedPx) {
+ if (mClosing && mVel > -mBrakingSpeedPx) {
mVel = -mBrakingSpeedPx;
- } else if (!closing && mVel < mBrakingSpeedPx) {
+ } else if (!mClosing && mVel < mBrakingSpeedPx) {
mVel = mBrakingSpeedPx;
}
} else {
- if (closing && mVel > -mFlingCollapseMinVelocityPx) {
+ if (mClosing && mVel > -mFlingCollapseMinVelocityPx) {
mVel = -mFlingCollapseMinVelocityPx;
- } else if (!closing && mVel > mFlingGestureMaxOutputVelocityPx) {
+ } else if (!mClosing && mVel > mFlingGestureMaxOutputVelocityPx) {
mVel = mFlingGestureMaxOutputVelocityPx;
}
}
float h = mExpandedHeight + mVel * dt;
+
+ if (mRubberbanding && h < fh) {
+ h = fh;
+ }
- LOG("tick: new h=%d closing=%s", (int) h, closing?"true":"false");
+ LOG("tick: new h=%d closing=%s", (int) h, mClosing?"true":"false");
setExpandedHeightInternal(h);
mBar.panelExpansionChanged(PanelView.this, mExpandedFraction);
if (mVel == 0
- || (closing && mExpandedHeight == 0)
- || (!closing && mExpandedHeight == getFullHeight())) {
- mTimeAnimator.end();
+ || (mClosing && mExpandedHeight == 0)
+ || ((mRubberbanding || !mClosing) && mExpandedHeight == fh)) {
+ post(mStopAnimator);
}
}
}
@@ -178,6 +194,7 @@
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
+ mTracking = true;
mVelocityTracker = VelocityTracker.obtain();
trackMovement(event);
mBar.onTrackingStarted(PanelView.this);
@@ -185,7 +202,7 @@
break;
case MotionEvent.ACTION_MOVE:
- PanelView.this.setExpandedHeight(rawY - mAbsPos[1] - mTouchOffset);
+ PanelView.this.setExpandedHeightInternal(rawY - mAbsPos[1] - mTouchOffset);
mBar.panelExpansionChanged(PanelView.this, mExpandedFraction);
@@ -194,6 +211,7 @@
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
+ mTracking = false;
mBar.onTrackingStopped(PanelView.this);
trackMovement(event);
mVelocityTracker.computeCurrentVelocity(1000);
@@ -223,7 +241,7 @@
xVel, yVel,
vel);
- fling(vel, false);
+ fling(vel, true);
mVelocityTracker.recycle();
mVelocityTracker = null;
@@ -238,7 +256,7 @@
public void fling(float vel, boolean always) {
mVel = vel;
- if (mVel != 0) {
+ if (always||mVel != 0) {
animationTick(0); // begin the animation
}
}
@@ -270,6 +288,10 @@
LOG("onMeasure(%d, %d) -> (%d, %d)",
widthMeasureSpec, heightMeasureSpec, getMeasuredWidth(), getMeasuredHeight());
mFullHeight = getMeasuredHeight();
+ // if one of our children is getting smaller, we should track that
+ if (!mTracking && !mRubberbanding && !mTimeAnimator.isStarted() && mExpandedHeight > 0 && mExpandedHeight != mFullHeight) {
+ mExpandedHeight = mFullHeight;
+ }
heightMeasureSpec = MeasureSpec.makeMeasureSpec(
(int) mExpandedHeight, MeasureSpec.AT_MOST); // MeasureSpec.getMode(heightMeasureSpec));
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
@@ -277,21 +299,26 @@
public void setExpandedHeight(float height) {
- mTimeAnimator.end();
+ post(mStopAnimator);
setExpandedHeightInternal(height);
}
+ @Override
+ protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
+ LOG("onLayout: changed=%s, bottom=%d eh=%d fh=%d", changed?"T":"f", bottom, (int)mExpandedHeight, (int)mFullHeight);
+ super.onLayout(changed, left, top, right, bottom);
+ }
+
public void setExpandedHeightInternal(float h) {
float fh = getFullHeight();
if (fh == 0) {
// Hmm, full height hasn't been computed yet
}
- LOG("setExpansion: height=%.1f fh=%.1f", h, fh);
+ LOG("setExpansion: height=%.1f fh=%.1f tracking=%s rubber=%s", h, fh, mTracking?"T":"f", mRubberbanding?"T":"f");
if (h < 0) h = 0;
- else if (h > fh) h = fh;
-
+ if (!(STRETCH_PAST_CONTENTS && (mTracking || mRubberbanding)) && h > fh) h = fh;
mExpandedHeight = h;
requestLayout();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 4d4adcb8..a20576f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -46,7 +46,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.provider.Settings;
import android.service.dreams.IDreamManager;
import android.util.DisplayMetrics;
@@ -109,7 +109,7 @@
public static final String ACTION_STATUSBAR_START
= "com.android.internal.policy.statusbar.START";
- private static final boolean SHOW_CARRIER_LABEL = true;
+ private static final boolean SHOW_CARRIER_LABEL = false; // XXX: doesn't work with rubberband panels right now
private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
private static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
@@ -174,6 +174,7 @@
int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx;
int mNotificationPanelMinHeight;
boolean mNotificationPanelIsFullScreenWidth;
+ TextView mNotificationPanelDebugText;
// settings
PanelView mSettingsPanel;
@@ -343,6 +344,10 @@
mIntruderAlertView.setVisibility(View.GONE);
mIntruderAlertView.setBar(this);
}
+ if (MULTIUSER_DEBUG) {
+ mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info);
+ mNotificationPanelDebugText.setVisibility(View.VISIBLE);
+ }
updateShowSearchHoldoff();
@@ -806,9 +811,9 @@
// If the device hasn't been through Setup, we only show system notifications
for (int i=0; i<N; i++) {
Entry ent = mNotificationData.get(N-i-1);
- if (provisioned || showNotificationEvenIfUnprovisioned(ent.notification)) {
- toShow.add(ent.row);
- }
+ if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
+ if (!notificationIsForCurrentUser(ent.notification)) continue;
+ toShow.add(ent.row);
}
ArrayList<View> toRemove = new ArrayList<View>();
@@ -854,10 +859,10 @@
// If the device hasn't been through Setup, we only show system notifications
for (int i=0; i<N; i++) {
Entry ent = mNotificationData.get(N-i-1);
- if ((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE)
- || showNotificationEvenIfUnprovisioned(ent.notification)) {
- toShow.add(ent.icon);
- }
+ if (!((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE)
+ || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
+ if (!notificationIsForCurrentUser(ent.notification)) continue;
+ toShow.add(ent.icon);
}
ArrayList<View> toRemove = new ArrayList<View>();
@@ -1304,10 +1309,6 @@
mGestureRec.add(event);
- if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
- return false;
- }
-
return false;
}
@@ -1782,13 +1783,14 @@
} catch (RemoteException e) {
}
v.getContext().startActivityAsUser(new Intent(Settings.ACTION_SETTINGS)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), UserId.USER_CURRENT);
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), UserHandle.USER_CURRENT);
animateCollapse();
}
};
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
+ Slog.v(TAG, "onReceive: " + intent);
String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
int flags = CommandQueue.FLAG_EXCLUDE_NONE;
@@ -1812,6 +1814,13 @@
}
};
+ @Override
+ public void userSwitched(int newUserId) {
+ if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
+ animateCollapse();
+ updateNotificationIcons();
+ }
+
private void setIntruderAlertVisibility(boolean vis) {
if (!ENABLE_INTRUDERS) return;
if (DEBUG) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 25ff9aa..2a96d6d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.app.ActivityManager;
+import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -43,6 +44,7 @@
PhoneStatusBar mBar;
int mScrimColor;
PanelView mFadingPanel = null;
+ PanelView mNotificationPanel, mSettingsPanel;
public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -59,6 +61,21 @@
}
@Override
+ public void addPanel(PanelView pv) {
+ super.addPanel(pv);
+ if (pv.getId() == R.id.notification_panel) {
+ mNotificationPanel = pv;
+ } else if (pv.getId() == R.id.settings_panel){
+ mSettingsPanel = pv;
+ }
+ }
+
+ @Override
+ public boolean panelsEnabled() {
+ return ((mBar.mDisabled & StatusBarManager.DISABLE_EXPAND) == 0);
+ }
+
+ @Override
public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
if (super.onRequestSendAccessibilityEvent(child, event)) {
// The status bar is very small so augment the view that the user is touching
@@ -74,6 +91,20 @@
}
@Override
+ public PanelView selectPanelForTouchX(float x) {
+ // We split the status bar into thirds: the left 2/3 are for notifications, and the
+ // right 1/3 for quick settings. If you pull the status bar down a second time you'll
+ // toggle panels no matter where you pull it down.
+ final float w = (float) getMeasuredWidth();
+ final float f = x / w;
+ if (f > 0.67f && mSettingsPanel.getExpandedFraction() != 1.0f
+ || mNotificationPanel.getExpandedFraction() == 1.0f) {
+ return mSettingsPanel;
+ }
+ return mNotificationPanel;
+ }
+
+ @Override
public void onPanelPeeked() {
super.onPanelPeeked();
mBar.makeExpandedVisible(true);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
new file mode 100644
index 0000000..fb1528f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+public class SettingsPanelView extends PanelView {
+ public SettingsPanelView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void fling(float vel, boolean always) {
+ ((PhoneStatusBarView) mBar).mBar.getGestureRecorder().tag(
+ "fling " + ((vel > 0) ? "open" : "closed"),
+ "settings,v=" + vel);
+ super.fling(vel, always);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index e63735677..89eed1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -78,6 +78,7 @@
super(context, attrs, defStyle);
mRealLayoutTransition = new LayoutTransition();
+ mRealLayoutTransition.setAnimateParentHierarchy(true);
setLayoutTransitionsEnabled(true);
setOrientation(LinearLayout.VERTICAL);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
index da161a9..ffe69e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
@@ -19,7 +19,7 @@
import android.app.StatusBarManager;
import android.content.Context;
import android.content.Intent;
-import android.os.UserId;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Slog;
@@ -119,7 +119,7 @@
// ----------------------------
private void onClickSettings() {
getContext().startActivityAsUser(new Intent(Settings.ACTION_SETTINGS)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), UserId.USER_CURRENT);
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), UserHandle.USER_CURRENT);
getStatusBarManager().collapse();
}
}
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 8645172..5f5c105 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -32,7 +32,7 @@
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.Vibrator;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -277,7 +277,7 @@
// Update the search icon with drawable from the search .apk
if (!mSearchDisabled) {
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserId.USER_CURRENT);
+ .getAssistIntent(mContext, UserHandle.USER_CURRENT);
if (intent != null) {
// XXX Hack. We need to substitute the icon here but haven't formalized
// the public API. The "_google" metadata will be going away, so
@@ -313,7 +313,7 @@
case com.android.internal.R.drawable.ic_action_assist_generic:
Intent assistIntent =
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserId.USER_CURRENT);
+ .getAssistIntent(mContext, UserHandle.USER_CURRENT);
if (assistIntent != null) {
launchActivity(assistIntent);
} else {
@@ -354,7 +354,7 @@
Log.w(TAG, "can't dismiss keyguard on launch");
}
try {
- mContext.startActivityAsUser(intent, UserId.USER_CURRENT);
+ mContext.startActivityAsUser(intent, UserHandle.USER_CURRENT);
} catch (ActivityNotFoundException e) {
Log.w(TAG, "Activity not found for intent + " + intent.getAction());
}
@@ -532,7 +532,7 @@
}
boolean searchActionAvailable =
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserId.USER_CURRENT) != null;
+ .getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
mCameraDisabled = disabledByAdmin || disabledBySimState || !cameraTargetPresent;
mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent;
mUnlockWidgetMethods.updateResources();
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c036e1b..40db612 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -54,7 +54,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UEventObserver;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.Vibrator;
import android.provider.Settings;
@@ -1717,15 +1717,17 @@
mHomePressed = false;
mHomeLongPressed = false;
if (!homeWasLongPressed) {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.cancelPreloadRecentApps();
+ if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.cancelPreloadRecentApps();
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException when showing recent apps", e);
+ // re-acquire status bar service next time it is needed.
+ mStatusBarService = null;
}
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when showing recent apps", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
}
mHomePressed = false;
@@ -2064,7 +2066,7 @@
if (searchManager != null) {
searchManager.stopSearch();
}
- mContext.startActivityAsUser(intent, UserId.USER_CURRENT);
+ mContext.startActivityAsUser(intent, UserHandle.USER_CURRENT);
} catch (ActivityNotFoundException e) {
Slog.w(TAG, "No activity to handle assist long press action.", e);
}
@@ -2073,13 +2075,13 @@
private void launchAssistAction() {
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserId.USER_CURRENT);
+ .getAssistIntent(mContext, UserHandle.USER_CURRENT);
if (intent != null) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
- mContext.startActivityAsUser(intent, UserId.USER_CURRENT);
+ mContext.startActivityAsUser(intent, UserHandle.USER_CURRENT);
} catch (ActivityNotFoundException e) {
Slog.w(TAG, "No activity to handle assist action.", e);
}
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index 48f967c..5250dfc 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -43,7 +43,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.AtomicFile;
import android.util.AttributeSet;
import android.util.Log;
@@ -593,7 +593,7 @@
private boolean callerHasBindAppWidgetPermission(String packageName) {
int callingUid = Binder.getCallingUid();
try {
- if (!UserId.isSameApp(callingUid, getUidForPackage(packageName))) {
+ if (!UserHandle.isSameApp(callingUid, getUidForPackage(packageName))) {
return false;
}
} catch (Exception e) {
@@ -665,7 +665,7 @@
mBoundRemoteViewsServices.remove(key);
}
- int userId = UserId.getUserId(id.provider.uid);
+ int userId = UserHandle.getUserId(id.provider.uid);
// Bind to the RemoteViewsService (which will trigger a callback to the
// RemoteViewsAdapter.onServiceConnected())
final long token = Binder.clearCallingIdentity();
@@ -756,7 +756,7 @@
}
};
- int userId = UserId.getUserId(id.provider.uid);
+ int userId = UserHandle.getUserId(id.provider.uid);
// Bind to the service and remove the static intent->factory mapping in the
// RemoteViewsService.
final long token = Binder.clearCallingIdentity();
@@ -1026,7 +1026,7 @@
}
};
- int userId = UserId.getUserId(id.provider.uid);
+ int userId = UserHandle.getUserId(id.provider.uid);
// Bind to the service and call onDataSetChanged()
final long token = Binder.clearCallingIdentity();
try {
@@ -1375,7 +1375,7 @@
throw new IllegalArgumentException("packageName and uid don't match packageName="
+ packageName);
}
- if (!UserId.isSameApp(callingUid, packageUid)) {
+ if (!UserHandle.isSameApp(callingUid, packageUid)) {
throw new IllegalArgumentException("packageName and uid don't match packageName="
+ packageName);
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 4542840..8be0ba8 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -65,7 +65,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.WorkSource;
import android.os.storage.IMountService;
import android.provider.Settings;
@@ -4846,8 +4846,8 @@
// ----- IBackupManager binder interface -----
public void dataChanged(final String packageName) {
- final int callingUserHandle = UserId.getCallingUserId();
- if (callingUserHandle != UserId.USER_OWNER) {
+ final int callingUserHandle = UserHandle.getCallingUserId();
+ if (callingUserHandle != UserHandle.USER_OWNER) {
// App is running under a non-owner user profile. For now, we do not back
// up data from secondary user profiles.
// TODO: backups for all user profiles.
@@ -4950,8 +4950,8 @@
boolean doAllApps, boolean includeSystem, String[] pkgList) {
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullBackup");
- final int callingUserHandle = UserId.getCallingUserId();
- if (callingUserHandle != UserId.USER_OWNER) {
+ final int callingUserHandle = UserHandle.getCallingUserId();
+ if (callingUserHandle != UserHandle.USER_OWNER) {
throw new IllegalStateException("Backup supported only for the device owner");
}
@@ -5019,8 +5019,8 @@
public void fullRestore(ParcelFileDescriptor fd) {
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullRestore");
- final int callingUserHandle = UserId.getCallingUserId();
- if (callingUserHandle != UserId.USER_OWNER) {
+ final int callingUserHandle = UserHandle.getCallingUserId();
+ if (callingUserHandle != UserHandle.USER_OWNER) {
throw new IllegalStateException("Restore supported only for the device owner");
}
diff --git a/services/java/com/android/server/ClipboardService.java b/services/java/com/android/server/ClipboardService.java
index 8a6a550..baf33a9 100644
--- a/services/java/com/android/server/ClipboardService.java
+++ b/services/java/com/android/server/ClipboardService.java
@@ -36,7 +36,7 @@
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -115,7 +115,7 @@
}
private PerUserClipboard getClipboard() {
- return getClipboard(UserId.getCallingUserId());
+ return getClipboard(UserHandle.getCallingUserId());
}
private PerUserClipboard getClipboard(int userId) {
@@ -258,7 +258,7 @@
PackageInfo pi;
try {
pi = mPm.getPackageInfo(pkg, 0);
- if (!UserId.isSameApp(pi.applicationInfo.uid, uid)) {
+ if (!UserHandle.isSameApp(pi.applicationInfo.uid, uid)) {
throw new SecurityException("Calling uid " + uid
+ " does not own package " + pkg);
}
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 04267a3..bb5d552 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -48,7 +48,7 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.storage.IMountService;
import android.os.storage.IMountServiceListener;
import android.os.storage.IMountShutdownObserver;
@@ -1713,7 +1713,7 @@
return false;
}
- final int packageUid = mPms.getPackageUid(packageName, UserId.getUserId(callerUid));
+ final int packageUid = mPms.getPackageUid(packageName, UserHandle.getUserId(callerUid));
if (DEBUG_OBB) {
Slog.d(TAG, "packageName = " + packageName + ", packageUid = " +
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 798915b..a565d08 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -48,7 +48,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.Vibrator;
import android.provider.Settings;
import android.service.dreams.IDreamManager;
@@ -1286,7 +1286,7 @@
try {
ApplicationInfo ai = mContext.getPackageManager().getApplicationInfo(
pkg, 0);
- if (!UserId.isSameApp(ai.uid, uid)) {
+ if (!UserHandle.isSameApp(ai.uid, uid)) {
throw new SecurityException("Calling uid " + uid + " gave package"
+ pkg + " which is owned by uid " + ai.uid);
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index d97d335..c5243a288 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -47,7 +47,7 @@
import android.os.RemoteCallbackList;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.service.wallpaper.IWallpaperConnection;
import android.service.wallpaper.IWallpaperEngine;
import android.service.wallpaper.IWallpaperService;
@@ -483,7 +483,7 @@
public void clearWallpaper() {
if (DEBUG) Slog.v(TAG, "clearWallpaper");
synchronized (mLock) {
- clearWallpaperLocked(false, UserId.getCallingUserId());
+ clearWallpaperLocked(false, UserHandle.getCallingUserId());
}
}
@@ -520,7 +520,7 @@
public void setDimensionHints(int width, int height) throws RemoteException {
checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
WallpaperData wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
@@ -551,14 +551,14 @@
public int getWidthHint() throws RemoteException {
synchronized (mLock) {
- WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
+ WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
return wallpaper.width;
}
}
public int getHeightHint() throws RemoteException {
synchronized (mLock) {
- WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
+ WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
return wallpaper.height;
}
}
@@ -573,7 +573,7 @@
if (callingUid == android.os.Process.SYSTEM_UID) {
wallpaperUserId = mCurrentUserId;
} else {
- wallpaperUserId = UserId.getUserId(callingUid);
+ wallpaperUserId = UserHandle.getUserId(callingUid);
}
WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);
try {
@@ -596,7 +596,7 @@
}
public WallpaperInfo getWallpaperInfo() {
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
synchronized (mLock) {
WallpaperData wallpaper = mWallpaperMap.get(userId);
if (wallpaper.connection != null) {
@@ -608,7 +608,7 @@
public ParcelFileDescriptor setWallpaper(String name) {
if (DEBUG) Slog.v(TAG, "setWallpaper");
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
WallpaperData wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
@@ -651,7 +651,7 @@
public void setWallpaperComponent(ComponentName name) {
if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
WallpaperData wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index e1c05b5..edbc624 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -303,6 +303,10 @@
mWifiStateMachine.sendMessage(Message.obtain(msg));
break;
}
+ case WifiManager.RSSI_PKTCNT_FETCH: {
+ mWifiStateMachine.sendMessage(Message.obtain(msg));
+ break;
+ }
default: {
Slog.d(TAG, "WifiServicehandler.handleMessage ignoring msg=" + msg);
break;
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 632c2f2..d8ccabb 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -51,7 +51,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
@@ -226,7 +226,7 @@
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
- callingPid, callingUid, UserId.getUserId(callingUid), true);
+ callingPid, callingUid, UserHandle.getUserId(callingUid), true);
if (res == null) {
return null;
}
@@ -279,7 +279,7 @@
// If this service is active, make sure it is stopped.
ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
Binder.getCallingPid(), Binder.getCallingUid(),
- callerApp == null ? UserId.getCallingUserId() : callerApp.userId,
+ callerApp == null ? UserHandle.getCallingUserId() : callerApp.userId,
false);
if (r != null) {
if (r.record != null) {
@@ -300,7 +300,7 @@
IBinder peekServiceLocked(Intent service, String resolvedType) {
ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
Binder.getCallingPid(), Binder.getCallingUid(),
- UserId.getCallingUserId(), false);
+ UserHandle.getCallingUserId(), false);
IBinder ret = null;
if (r != null) {
@@ -759,8 +759,8 @@
}
r = new ServiceRecord(mAm, ss, name, filter, sInfo, res);
res.setService(r);
- mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
- mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
+ mServiceMap.putServiceByName(name, UserHandle.getUserId(r.appInfo.uid), r);
+ mServiceMap.putServiceByIntent(filter, UserHandle.getUserId(r.appInfo.uid), r);
// Make sure this component isn't in the pending list.
int N = mPendingServices.size();
@@ -1725,7 +1725,7 @@
ArrayList<ActivityManager.RunningServiceInfo> res
= new ArrayList<ActivityManager.RunningServiceInfo>();
- int userId = UserId.getUserId(Binder.getCallingUid());
+ int userId = UserHandle.getUserId(Binder.getCallingUid());
if (mServiceMap.getAllServices(userId).size() > 0) {
Iterator<ServiceRecord> it
= mServiceMap.getAllServices(userId).iterator();
@@ -1746,7 +1746,7 @@
}
public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
- int userId = UserId.getUserId(Binder.getCallingUid());
+ int userId = UserHandle.getUserId(Binder.getCallingUid());
ServiceRecord r = mServiceMap.getServiceByName(name, userId);
if (r != null) {
for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0c378c9..2de6931 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -111,7 +111,7 @@
import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.text.format.Time;
@@ -1084,7 +1084,7 @@
boolean restart = (msg.arg2 == 1);
String pkg = (String) msg.obj;
forceStopPackageLocked(pkg, uid, restart, false, true, false,
- UserId.getUserId(uid));
+ UserHandle.getUserId(uid));
}
} break;
case FINALIZE_PENDING_INTENT_MSG: {
@@ -1829,7 +1829,7 @@
if (procs == null) return null;
final int N = procs.size();
for (int i = 0; i < N; i++) {
- if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
+ if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
}
}
ProcessRecord proc = mProcessNames.get(processName, uid);
@@ -1980,10 +1980,20 @@
int uid = app.uid;
int[] gids = null;
+ int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
try {
- gids = mContext.getPackageManager().getPackageGids(
- app.info.packageName);
+ final PackageManager pm = mContext.getPackageManager();
+ gids = pm.getPackageGids(app.info.packageName);
+ if (pm.checkPermission(
+ android.Manifest.permission.READ_EXTERNAL_STORAGE, app.info.packageName)
+ == PERMISSION_GRANTED) {
+ if (Environment.isExternalStorageEmulated()) {
+ mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
+ } else {
+ mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER;
+ }
+ }
} catch (PackageManager.NameNotFoundException e) {
Slog.w(TAG, "Unable to retrieve gids", e);
}
@@ -2025,7 +2035,7 @@
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
- app.processName, uid, uid, gids, debugFlags,
+ app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, null, null);
BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
@@ -2195,7 +2205,7 @@
}
void enforceNotIsolatedCaller(String caller) {
- if (UserId.isIsolated(Binder.getCallingUid())) {
+ if (UserHandle.isIsolated(Binder.getCallingUid())) {
throw new SecurityException("Isolated process not allowed to call " + caller);
}
}
@@ -2324,7 +2334,7 @@
String resultWho, int requestCode, int startFlags,
String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
- startFlags, profileFile, profileFd, options, UserId.getCallingUserId());
+ startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
}
public final int startActivityAsUser(IApplicationThread caller,
@@ -2332,20 +2342,20 @@
String resultWho, int requestCode, int startFlags,
String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
- if (userId != UserId.getCallingUserId()) {
+ if (userId != UserHandle.getCallingUserId()) {
// Requesting a different user, make sure that they have the permission
if (checkComponentPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
== PackageManager.PERMISSION_GRANTED) {
// Translate to the current user id, if caller wasn't aware
- if (userId == UserId.USER_CURRENT) {
+ if (userId == UserHandle.USER_CURRENT) {
userId = mCurrentUserId;
}
} else {
String msg = "Permission Denial: "
+ "Request to startActivity as user " + userId
- + " but is calling from user " + UserId.getCallingUserId()
+ + " but is calling from user " + UserHandle.getCallingUserId()
+ "; this requires "
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
Slog.w(TAG, msg);
@@ -2457,7 +2467,7 @@
AppGlobals.getPackageManager().queryIntentActivities(
intent, r.resolvedType,
PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
- UserId.getCallingUserId());
+ UserHandle.getCallingUserId());
// Look for the original activity in the list...
final int N = resolves != null ? resolves.size() : 0;
@@ -2562,7 +2572,7 @@
"startActivityInPackage only available to the system");
}
int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
- options, UserId.getUserId(uid));
+ options, UserHandle.getUserId(uid));
return ret;
}
@@ -3428,7 +3438,7 @@
throw new SecurityException(msg);
}
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
long callingId = Binder.clearCallingIdentity();
try {
IPackageManager pm = AppGlobals.getPackageManager();
@@ -3502,7 +3512,7 @@
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
- final int userId = UserId.getCallingUserId();
+ final int userId = UserHandle.getCallingUserId();
long callingId = Binder.clearCallingIdentity();
try {
IPackageManager pm = AppGlobals.getPackageManager();
@@ -3638,7 +3648,7 @@
}
private void forceStopPackageLocked(final String packageName, int uid) {
- forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
+ forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid));
Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
Uri.fromParts("package", packageName, null));
if (!mProcessesReady) {
@@ -3648,7 +3658,7 @@
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null,
false, false,
- MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
+ MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
}
private final boolean killPackageProcessesLocked(String packageName, int uid,
@@ -4369,8 +4379,8 @@
try {
if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
int uid = AppGlobals.getPackageManager()
- .getPackageUid(packageName, UserId.getUserId(callingUid));
- if (!UserId.isSameApp(callingUid, uid)) {
+ .getPackageUid(packageName, UserHandle.getUserId(callingUid));
+ if (!UserHandle.isSameApp(callingUid, uid)) {
String msg = "Permission Denial: getIntentSender() from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid()
@@ -4466,8 +4476,8 @@
PendingIntentRecord rec = (PendingIntentRecord)sender;
try {
int uid = AppGlobals.getPackageManager()
- .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
- if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
+ .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
+ if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
String msg = "Permission Denial: cancelIntentSender() from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid()
@@ -4686,7 +4696,7 @@
if (permission == null) {
return PackageManager.PERMISSION_DENIED;
}
- return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
+ return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
}
/**
@@ -4696,7 +4706,7 @@
int checkCallingPermission(String permission) {
return checkPermission(permission,
Binder.getCallingPid(),
- UserId.getAppId(Binder.getCallingUid()));
+ UserHandle.getAppId(Binder.getCallingUid()));
}
/**
@@ -4827,7 +4837,7 @@
pid = tlsIdentity.pid;
}
- uid = UserId.getAppId(uid);
+ uid = UserHandle.getAppId(uid);
// Our own process gets to do everything.
if (pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED;
@@ -4873,13 +4883,13 @@
String name = uri.getAuthority();
ProviderInfo pi = null;
ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
- UserId.getUserId(callingUid));
+ UserHandle.getUserId(callingUid));
if (cpr != null) {
pi = cpr.info;
} else {
try {
pi = pm.resolveContentProvider(name,
- PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
+ PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
} catch (RemoteException ex) {
}
}
@@ -4891,7 +4901,7 @@
int targetUid = lastTargetUid;
if (targetUid < 0 && targetPkg != null) {
try {
- targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
+ targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
if (targetUid < 0) {
if (DEBUG_URI_PERMISSION) Slog.v(TAG,
"Can't grant URI permission no uid for: " + targetPkg);
@@ -5183,7 +5193,7 @@
final String authority = uri.getAuthority();
ProviderInfo pi = null;
- int userId = UserId.getUserId(callingUid);
+ int userId = UserHandle.getUserId(callingUid);
ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
if (cpr != null) {
pi = cpr.info;
@@ -5521,7 +5531,7 @@
public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
int flags, int userId) {
final int callingUid = Binder.getCallingUid();
- if (userId != UserId.getCallingUserId()) {
+ if (userId != UserHandle.getCallingUserId()) {
// Check if the caller is holding permissions for cross-user requests.
if (checkComponentPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
@@ -5529,13 +5539,13 @@
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: "
+ "Request to get recent tasks for user " + userId
- + " but is calling from user " + UserId.getUserId(callingUid)
+ + " but is calling from user " + UserHandle.getUserId(callingUid)
+ "; this requires "
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
Slog.w(TAG, msg);
throw new SecurityException(msg);
} else {
- if (userId == UserId.USER_CURRENT) {
+ if (userId == UserHandle.USER_CURRENT) {
userId = mCurrentUserId;
}
}
@@ -6006,7 +6016,7 @@
(ProviderInfo)providers.get(i);
boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
cpi.name, cpi.flags);
- if (singleton && UserId.getUserId(app.uid) != 0) {
+ if (singleton && UserHandle.getUserId(app.uid) != 0) {
// This is a singleton provider, but a user besides the
// default user is asking to initialize a process it runs
// in... well, no, it doesn't actually run in this process,
@@ -6177,7 +6187,7 @@
}
// First check if this content provider has been published...
- int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
+ int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
cpr = mProviderMap.getProviderByName(name, userId);
boolean providerRunning = cpr != null;
if (providerRunning) {
@@ -6725,7 +6735,7 @@
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
int uid = info.uid;
if (isolated) {
- int userId = UserId.getUserId(uid);
+ int userId = UserHandle.getUserId(uid);
int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
uid = 0;
while (true) {
@@ -6733,7 +6743,7 @@
|| mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
}
- uid = UserId.getUid(userId, mNextIsolatedProcessUid);
+ uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
mNextIsolatedProcessUid++;
if (mIsolatedProcesses.indexOfKey(uid) < 0) {
// No process for this uid, use it.
@@ -6771,7 +6781,7 @@
// This package really, really can not be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
- info.packageName, false, UserId.getUserId(app.uid));
+ info.packageName, false, UserHandle.getUserId(app.uid));
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
@@ -8509,7 +8519,7 @@
IPackageManager pm = AppGlobals.getPackageManager();
for (String pkg : extList) {
try {
- ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
+ ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
retList.add(info);
}
@@ -10258,10 +10268,10 @@
cpr.launchingApp = null;
cpr.notifyAll();
}
- mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
+ mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
String names[] = cpr.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
- mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
+ mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
}
}
@@ -10599,7 +10609,7 @@
boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
String className, int flags) {
boolean result = false;
- if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
+ if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
if (ActivityManager.checkUidPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS,
@@ -10704,7 +10714,7 @@
// Backup agent is now in use, its package can't be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
- app.packageName, false, UserId.getUserId(app.uid));
+ app.packageName, false, UserHandle.getUserId(app.uid));
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
@@ -11046,7 +11056,7 @@
// If the caller is trying to send this broadcast to a different
// user, verify that is allowed.
- if (UserId.getUserId(callingUid) != userId) {
+ if (UserHandle.getUserId(callingUid) != userId) {
if (checkComponentPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
callingPid, callingUid, -1, true)
@@ -11060,7 +11070,7 @@
String msg = "Permission Denial: " + intent.getAction()
+ " broadcast from " + callerPackage
+ " asks to send as user " + userId
- + " but is calling from user " + UserId.getUserId(callingUid)
+ + " but is calling from user " + UserHandle.getUserId(callingUid)
+ "; this requires "
+ android.Manifest.permission.INTERACT_ACROSS_USERS;
Slog.w(TAG, msg);
@@ -11553,7 +11563,7 @@
throw new SecurityException(msg);
}
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
final long origId = Binder.clearCallingIdentity();
// Instrumentation can kill and relaunch even persistent processes
forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
@@ -11616,7 +11626,7 @@
public void finishInstrumentation(IApplicationThread target,
int resultCode, Bundle results) {
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
// Refuse possible leaked file descriptors
if (results != null && results.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -11929,7 +11939,7 @@
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
- destIntent.getComponent(), 0, UserId.getCallingUserId());
+ destIntent.getComponent(), 0, UserHandle.getCallingUserId());
int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
null, aInfo, parent.appToken, null,
0, -1, parent.launchedFromUid, 0, null, true, null);
@@ -13509,7 +13519,7 @@
for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
SparseArray<ProcessRecord> uids = uidMap.getValue();
for (int i = 0; i < uids.size(); i++) {
- if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
+ if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) {
pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
}
}
@@ -13535,14 +13545,14 @@
}
private void checkValidCaller(int uid, int userId) {
- if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
+ if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
throw new SecurityException("Caller uid=" + uid
+ " is not privileged to communicate with user=" + userId);
}
private int applyUserId(int uid, int userId) {
- return UserId.getUid(userId, uid);
+ return UserHandle.getUid(userId, uid);
}
ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
@@ -13556,7 +13566,7 @@
ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
if (aInfo == null
- || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
+ || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
return aInfo;
}
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index c40abb7..b0d480c 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -37,7 +37,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
@@ -321,7 +321,7 @@
appToken = new Token(this);
info = aInfo;
launchedFromUid = _launchedFromUid;
- userId = UserId.getUserId(aInfo.applicationInfo.uid);
+ userId = UserHandle.getUserId(aInfo.applicationInfo.uid);
intent = _intent;
shortComponentName = _intent.getComponent().flattenToShortString();
resolvedType = _resolvedType;
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 196a259..1e0827f 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -55,7 +55,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
@@ -501,7 +501,7 @@
TaskRecord cp = null;
- final int userId = UserId.getUserId(info.applicationInfo.uid);
+ final int userId = UserHandle.getUserId(info.applicationInfo.uid);
final int N = mHistory.size();
for (int i=(N-1); i>=0; i--) {
ActivityRecord r = mHistory.get(i);
@@ -545,7 +545,7 @@
if (info.targetActivity != null) {
cls = new ComponentName(info.packageName, info.targetActivity);
}
- final int userId = UserId.getUserId(info.applicationInfo.uid);
+ final int userId = UserHandle.getUserId(info.applicationInfo.uid);
final int N = mHistory.size();
for (int i=(N-1); i>=0; i--) {
@@ -2406,7 +2406,7 @@
}
if (err == ActivityManager.START_SUCCESS) {
- final int userId = aInfo != null ? UserId.getUserId(aInfo.applicationInfo.uid) : 0;
+ final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Slog.i(TAG, "START {" + intent.toShortString(true, true, true, false)
+ " u=" + userId + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
}
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index 76ddb96..7873dd8 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -36,7 +36,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.EventLog;
import android.util.Slog;
@@ -373,7 +373,7 @@
BroadcastFilter filter, boolean ordered) {
boolean skip = false;
if (r.onlySendToCaller) {
- if (!UserId.isSameApp(r.callingUid, filter.owningUid)) {
+ if (!UserHandle.isSameApp(r.callingUid, filter.owningUid)) {
Slog.w(TAG, "Permission Denial: broadcasting "
+ r.intent.toString()
+ " from " + r.callerPackage + " (pid="
@@ -668,7 +668,7 @@
boolean skip = false;
if (r.onlySendToCaller) {
- if (!UserId.isSameApp(r.callingUid, info.activityInfo.applicationInfo.uid)) {
+ if (!UserHandle.isSameApp(r.callingUid, info.activityInfo.applicationInfo.uid)) {
Slog.w(TAG, "Permission Denial: broadcasting "
+ r.intent.toString()
+ " from " + r.callerPackage + " (pid="
@@ -766,7 +766,7 @@
info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
}
r.curReceiver = info.activityInfo;
- if (DEBUG_MU && r.callingUid > UserId.PER_USER_RANGE) {
+ if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
+ info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
+ info.activityInfo.applicationInfo.uid);
@@ -775,7 +775,7 @@
// Broadcast is being executed, its package can't be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
- r.curComponent.getPackageName(), false, UserId.getUserId(r.callingUid));
+ r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index ad15da1..d3b8510 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -25,7 +25,7 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Slog;
import java.io.PrintWriter;
@@ -259,7 +259,7 @@
owner.broadcastIntentInPackage(key.packageName, uid,
finalIntent, resolvedType,
finishedReceiver, code, null, null,
- requiredPermission, (finishedReceiver != null), false, UserId
+ requiredPermission, (finishedReceiver != null), false, UserHandle
.getUserId(uid));
sendFinish = false;
} catch (RuntimeException e) {
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 42b7708..d372422 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -30,7 +30,7 @@
import android.os.IBinder;
import android.os.Process;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.PrintWriterPrinter;
import android.util.TimeUtils;
@@ -313,7 +313,7 @@
info = _info;
isolated = _info.uid != _uid;
uid = _uid;
- userId = UserId.getUserId(_uid);
+ userId = UserHandle.getUserId(_uid);
processName = _processName;
pkgList.add(_info.packageName);
thread = _thread;
@@ -396,7 +396,7 @@
sb.append(info.uid%Process.FIRST_APPLICATION_UID);
if (uid != info.uid) {
sb.append('i');
- sb.append(UserId.getAppId(uid) - Process.FIRST_ISOLATED_UID);
+ sb.append(UserHandle.getAppId(uid) - Process.FIRST_ISOLATED_UID);
}
}
}
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index 405718f..ab2e428 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -20,7 +20,7 @@
import android.os.Binder;
import android.os.Process;
import android.os.RemoteException;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Slog;
import android.util.SparseArray;
@@ -98,7 +98,7 @@
if (record.singleton) {
mSingletonByName.put(name, record);
} else {
- final int userId = UserId.getUserId(record.appInfo.uid);
+ final int userId = UserHandle.getUserId(record.appInfo.uid);
getProvidersByName(userId).put(name, record);
}
}
@@ -111,7 +111,7 @@
if (record.singleton) {
mSingletonByClass.put(name, record);
} else {
- final int userId = UserId.getUserId(record.appInfo.uid);
+ final int userId = UserHandle.getUserId(record.appInfo.uid);
getProvidersByClass(userId).put(name, record);
}
}
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 828eef7..41386e4 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -31,7 +31,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Slog;
import android.util.TimeUtils;
@@ -296,7 +296,7 @@
this.restarter = restarter;
createTime = SystemClock.elapsedRealtime();
lastActivity = SystemClock.uptimeMillis();
- userId = UserId.getUserId(appInfo.uid);
+ userId = UserHandle.getUserId(appInfo.uid);
}
public AppBindRecord retrieveAppBindingLocked(Intent intent,
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 3a767c2..1bae9ca 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -19,7 +19,7 @@
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Slog;
import java.io.PrintWriter;
@@ -101,7 +101,7 @@
}
if (info.applicationInfo != null) {
- userId = UserId.getUserId(info.applicationInfo.uid);
+ userId = UserHandle.getUserId(info.applicationInfo.uid);
}
}
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 46c24b0..a7cba5a 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -112,7 +112,7 @@
import android.os.MessageQueue.IdleHandler;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
@@ -426,7 +426,7 @@
final String action = intent.getAction();
final int uid = intent.getIntExtra(EXTRA_UID, 0);
- final int appId = UserId.getAppId(uid);
+ final int appId = UserHandle.getAppId(uid);
synchronized (mRulesLock) {
if (ACTION_PACKAGE_ADDED.equals(action)) {
// NOTE: PACKAGE_ADDED is currently only sent once, and is
@@ -1188,8 +1188,8 @@
final int uid = readIntAttribute(in, ATTR_UID);
final int policy = readIntAttribute(in, ATTR_POLICY);
- final int appId = UserId.getAppId(uid);
- if (UserId.isApp(appId)) {
+ final int appId = UserHandle.getAppId(uid);
+ if (UserHandle.isApp(appId)) {
setAppPolicyUnchecked(appId, policy, false);
} else {
Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
@@ -1198,7 +1198,7 @@
final int appId = readIntAttribute(in, ATTR_APP_ID);
final int policy = readIntAttribute(in, ATTR_POLICY);
- if (UserId.isApp(appId)) {
+ if (UserHandle.isApp(appId)) {
setAppPolicyUnchecked(appId, policy, false);
} else {
Slog.w(TAG, "unable to apply policy to appId " + appId + "; ignoring");
@@ -1304,7 +1304,7 @@
public void setAppPolicy(int appId, int policy) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
- if (!UserId.isApp(appId)) {
+ if (!UserHandle.isApp(appId)) {
throw new IllegalArgumentException("cannot apply policy to appId " + appId);
}
@@ -1698,7 +1698,7 @@
final PackageManager pm = mContext.getPackageManager();
final List<ApplicationInfo> apps = pm.getInstalledApplications(0);
for (ApplicationInfo app : apps) {
- final int appId = UserId.getAppId(app.uid);
+ final int appId = UserHandle.getAppId(app.uid);
updateRulesForAppLocked(appId);
}
@@ -1710,7 +1710,7 @@
private void updateRulesForAppLocked(int appId) {
UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
for (UserInfo user : um.getUsers()) {
- final int uid = UserId.getUid(user.id, appId);
+ final int uid = UserHandle.getUid(user.id, appId);
updateRulesForUidLocked(uid);
}
}
@@ -1718,7 +1718,7 @@
private static boolean isUidValidForRules(int uid) {
// allow rules on specific system services, and any apps
if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
- || UserId.isApp(uid)) {
+ || UserHandle.isApp(uid)) {
return true;
}
@@ -1728,7 +1728,7 @@
private void updateRulesForUidLocked(int uid) {
if (!isUidValidForRules(uid)) return;
- final int appId = UserId.getAppId(uid);
+ final int appId = UserHandle.getAppId(uid);
final int appPolicy = getAppPolicy(appId);
final boolean uidForeground = isUidForeground(uid);
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 4befb9e..9e94333 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -100,7 +100,7 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.os.UserId;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings.Secure;
import android.security.SystemKeyStore;
@@ -691,15 +691,15 @@
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
res.pkg.applicationInfo.packageName,
- extras, null, null, UserId.USER_ALL);
+ extras, null, null, UserHandle.USER_ALL);
if (update) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
res.pkg.applicationInfo.packageName,
- extras, null, null, UserId.USER_ALL);
+ extras, null, null, UserHandle.USER_ALL);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
null, null,
res.pkg.applicationInfo.packageName, null,
- UserId.USER_ALL);
+ UserHandle.USER_ALL);
}
if (res.removedInfo.args != null) {
// Remove the replaced package's older resources safely now
@@ -1630,14 +1630,14 @@
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if(p != null) {
- return UserId.getUid(userId, p.applicationInfo.uid);
+ return UserHandle.getUid(userId, p.applicationInfo.uid);
}
PackageSetting ps = mSettings.mPackages.get(packageName);
if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
return -1;
}
p = ps.pkg;
- return p != null ? UserId.getUid(userId, p.applicationInfo.uid) : -1;
+ return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
}
}
@@ -1961,7 +1961,7 @@
}
private void checkValidCaller(int uid, int userId) {
- if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
+ if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
return;
throw new SecurityException("Caller uid=" + uid
@@ -1990,7 +1990,7 @@
public int checkUidPermission(String permName, int uid) {
synchronized (mPackages) {
- Object obj = mSettings.getUserIdLPr(UserId.getAppId(uid));
+ Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
if (obj != null) {
GrantedPermissions gp = (GrantedPermissions)obj;
if (gp.grantedPermissions.contains(permName)) {
@@ -2024,7 +2024,7 @@
if (permName != null) {
BasePermission bp = findPermissionTreeLP(permName);
if (bp != null) {
- if (bp.uid == UserId.getAppId(Binder.getCallingUid())) {
+ if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
return bp;
}
throw new SecurityException("Calling uid "
@@ -2227,8 +2227,8 @@
public int checkUidSignatures(int uid1, int uid2) {
// Map to base uids.
- uid1 = UserId.getAppId(uid1);
- uid2 = UserId.getAppId(uid2);
+ uid1 = UserHandle.getAppId(uid1);
+ uid2 = UserHandle.getAppId(uid2);
// reader
synchronized (mPackages) {
Signature[] s1;
@@ -2286,7 +2286,7 @@
}
public String[] getPackagesForUid(int uid) {
- uid = UserId.getAppId(uid);
+ uid = UserHandle.getAppId(uid);
// reader
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(uid);
@@ -2311,7 +2311,7 @@
public String getNameForUid(int uid) {
// reader
synchronized (mPackages) {
- Object obj = mSettings.getUserIdLPr(UserId.getAppId(uid));
+ Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
return sus.name + ":" + sus.userId;
@@ -2791,7 +2791,7 @@
final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>();
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
final String[] keys;
- int userId = UserId.getCallingUserId();
+ int userId = UserHandle.getCallingUserId();
// writer
synchronized (mPackages) {
@@ -2890,7 +2890,7 @@
// reader
synchronized (mPackages) {
final Iterator<PackageParser.Package> i = mPackages.values().iterator();
- final int userId = UserId.getCallingUserId();
+ final int userId = UserHandle.getCallingUserId();
while (i.hasNext()) {
final PackageParser.Package p = i.next();
if (p.applicationInfo != null
@@ -2938,7 +2938,7 @@
synchronized (mPackages) {
final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProviders.entrySet()
.iterator();
- final int userId = UserId.getCallingUserId();
+ final int userId = UserHandle.getCallingUserId();
while (i.hasNext()) {
Map.Entry<String, PackageParser.Provider> entry = i.next();
PackageParser.Provider p = entry.getValue();
@@ -2965,14 +2965,14 @@
synchronized (mPackages) {
final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
final int userId = processName != null ?
- UserId.getUserId(uid) : UserId.getCallingUserId();
+ UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
while (i.hasNext()) {
final PackageParser.Provider p = i.next();
PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
if (p.info.authority != null
&& (processName == null
|| (p.info.processName.equals(processName)
- && UserId.isSameApp(p.info.applicationInfo.uid, uid)))
+ && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
&& mSettings.isEnabledLPr(p.info, flags, userId)
&& (!mSafeMode
|| (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
@@ -5148,7 +5148,7 @@
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
try {
- int[] userIds = userId == UserId.USER_ALL
+ int[] userIds = userId == UserHandle.USER_ALL
? sUserManager.getUserIds()
: new int[] {userId};
for (int id : userIds) {
@@ -5163,7 +5163,7 @@
// Modify the UID when posting to other users
int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
if (uid > 0 && id > 0) {
- uid = UserId.getUid(id, UserId.getAppId(uid));
+ uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
intent.putExtra(Intent.EXTRA_UID, uid);
}
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -5312,13 +5312,13 @@
extras.putInt(Intent.EXTRA_UID, removedUid);
extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
- extras, null, null, UserId.USER_ALL);
+ extras, null, null, UserHandle.USER_ALL);
}
if (addedPackage != null) {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, addedUid);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
- extras, null, null, UserId.USER_ALL);
+ extras, null, null, UserHandle.USER_ALL);
}
}
@@ -7539,11 +7539,11 @@
extras.putBoolean(Intent.EXTRA_REPLACING, true);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
- extras, null, null, UserId.USER_ALL);
+ extras, null, null, UserHandle.USER_ALL);
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
- extras, null, null, UserId.USER_ALL);
+ extras, null, null, UserHandle.USER_ALL);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
- null, packageName, null, UserId.USER_ALL);
+ null, packageName, null, UserHandle.USER_ALL);
}
}
// Force a gc here.
@@ -7576,15 +7576,15 @@
}
if (removedPackage != null) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
- extras, null, null, UserId.USER_ALL);
+ extras, null, null, UserHandle.USER_ALL);
if (fullRemove && !replacing) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
- extras, null, null, UserId.USER_ALL);
+ extras, null, null, UserHandle.USER_ALL);
}
}
if (removedUid >= 0) {
sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
- UserId.getUserId(removedUid));
+ UserHandle.getUserId(removedUid));
}
}
}
@@ -7948,7 +7948,7 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_CACHE_FILES, null);
// Queue up an async operation since the package deletion may take a little while.
- final int userId = UserId.getCallingUserId();
+ final int userId = UserHandle.getCallingUserId();
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
@@ -8303,7 +8303,7 @@
+ "/" + className);
}
// Allow root and verify that userId is not being specified by a different user
- if (!allowedByPermission && !UserId.isSameApp(uid, pkgSetting.appId)) {
+ if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
throw new SecurityException(
"Permission Denial: attempt to change component state from pid="
+ Binder.getCallingPid()
@@ -8352,7 +8352,7 @@
}
}
mSettings.writePackageRestrictionsLPr(userId);
- packageUid = UserId.getUid(userId, pkgSetting.appId);
+ packageUid = UserHandle.getUid(userId, pkgSetting.appId);
components = mPendingBroadcasts.get(packageName);
final boolean newPackage = components == null;
if (newPackage) {
@@ -8401,7 +8401,7 @@
extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
extras.putInt(Intent.EXTRA_UID, packageUid);
sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null,
- UserId.getUserId(packageUid));
+ UserHandle.getUserId(packageUid));
}
public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
@@ -9027,7 +9027,7 @@
}
String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
: Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
- sendPackageBroadcast(action, null, extras, null, finishedReceiver, UserId.USER_ALL);
+ sendPackageBroadcast(action, null, extras, null, finishedReceiver, UserHandle.USER_ALL);
}
}
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index add91d3..cfc0f5c 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -49,7 +49,7 @@
import android.os.FileUtils;
import android.os.Process;
import android.os.RemoteException;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -2353,7 +2353,7 @@
boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
boolean allowedByPermission, int uid, int userId) {
- int appId = UserId.getAppId(uid);
+ int appId = UserHandle.getAppId(uid);
final PackageSetting pkgSetting = mPackages.get(packageName);
if (pkgSetting == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index b55dd24..725d67d3 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -34,7 +34,7 @@
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.SystemClock;
-import android.os.UserId;
+import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -539,7 +539,7 @@
// Don't do it for the primary user, it will become recursive.
if (userId == 0)
continue;
- mInstaller.createUserData(packageName, UserId.getUid(userId, uid),
+ mInstaller.createUserData(packageName, UserHandle.getUid(userId, uid),
userId);
}
}
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index 50d3f81..b0c79fa 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -33,11 +33,11 @@
import android.os.Message;
import android.os.SystemClock;
import android.util.Slog;
+import android.util.Spline;
import android.util.TimeUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -96,9 +96,20 @@
// Filter time constant in milliseconds for computing a moving
// average of light samples. Different constants are used
- // to adapt to brighter or dimmer environments.
- private static final long BRIGHTENING_LIGHT_TIME_CONSTANT = 2500; // 2.5 sec
- private static final long DIMMING_LIGHT_TIME_CONSTANT = 10000; // 10 sec
+ // to calculate the average light level when adapting to brighter or
+ // dimmer environments.
+ // This parameter only controls the filtering of light samples.
+ private static final long BRIGHTENING_LIGHT_TIME_CONSTANT = 500;
+ private static final long DIMMING_LIGHT_TIME_CONSTANT = 2000;
+
+ // Stability requirements in milliseconds for accepting a new brightness
+ // level. This is used for debouncing the light sensor. Different constants
+ // are used to debounce the light sensor when adapting to brighter or dimmer
+ // environments.
+ // This parameter controls how quickly brightness changes occur in response to
+ // an observed change in light level.
+ private static final long BRIGHTENING_LIGHT_DEBOUNCE = 2500;
+ private static final long DIMMING_LIGHT_DEBOUNCE = 10000;
private final Object mLock = new Object();
@@ -133,8 +144,7 @@
// Auto-brightness.
private boolean mUseSoftwareAutoBrightnessConfig;
- private int[] mAutoBrightnessLevelsConfig;
- private int[] mAutoBrightnessLcdBacklightValuesConfig;
+ private Spline mScreenAutoBrightnessSpline;
// Amount of time to delay auto-brightness after screen on while waiting for
// the light sensor to warm-up in milliseconds.
@@ -233,6 +243,9 @@
// The time of the most light recent sample.
private long mLastLightSampleTime;
+ // The time when we accumulated the first recent light sample into mRecentLightSamples.
+ private long mFirstRecentLightSampleTime;
+
// The upcoming debounce light sensor time.
// This is only valid when mLightMeasurementValue && mRecentLightSamples >= 1.
private long mPendingLightSensorDebounceTime;
@@ -275,17 +288,18 @@
mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available);
if (mUseSoftwareAutoBrightnessConfig) {
- mAutoBrightnessLevelsConfig = resources.getIntArray(
+ int[] lux = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels);
- mAutoBrightnessLcdBacklightValuesConfig = resources.getIntArray(
+ int[] screenBrightness = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
- if (mAutoBrightnessLcdBacklightValuesConfig.length
- != mAutoBrightnessLevelsConfig.length + 1) {
+
+ mScreenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
+ if (mScreenAutoBrightnessSpline == null) {
Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "
- + "(size " + mAutoBrightnessLcdBacklightValuesConfig.length + ") "
- + "should have exactly one more entry than "
- + "config_autoBrightnessLevels (size "
- + mAutoBrightnessLevelsConfig.length + "). "
+ + "(size " + screenBrightness.length + ") "
+ + "must be monotic and have exactly one more entry than "
+ + "config_autoBrightnessLevels (size " + lux.length + ") "
+ + "which must be strictly increasing. "
+ "Auto-brightness will be disabled.");
mUseSoftwareAutoBrightnessConfig = false;
}
@@ -308,6 +322,31 @@
}
}
+ private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
+ try {
+ final int n = brightness.length;
+ float[] x = new float[n];
+ float[] y = new float[n];
+ y[0] = brightness[0];
+ for (int i = 1; i < n; i++) {
+ x[i] = lux[i - 1];
+ y[i] = brightness[i];
+ }
+
+ Spline spline = Spline.createMonotoneCubicSpline(x, y);
+ if (false) {
+ Slog.d(TAG, "Auto-brightness spline: " + spline);
+ for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
+ Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v)));
+ }
+ }
+ return spline;
+ } catch (IllegalArgumentException ex) {
+ Slog.e(TAG, "Could not create auto-brightness spline.", ex);
+ return null;
+ }
+ }
+
/**
* Returns true if the proximity sensor screen-off function is available.
*/
@@ -664,7 +703,6 @@
// If the newest light sample doesn't seem to be going in the
// same general direction as recent samples, then start over.
setRecentLight(time, lux, lux > mLightMeasurement);
- mPendingLightSensorDebounceTime = time + mRecentLightTimeConstant;
} else if (mRecentLightSamples >= 1) {
// Add the newest light sample to the moving average.
accumulateRecentLight(time, lux);
@@ -677,6 +715,8 @@
+ ", mRecentLightAverage=" + mRecentLightAverage
+ ", mRecentLightBrightening=" + mRecentLightBrightening
+ ", mRecentLightTimeConstant=" + mRecentLightTimeConstant
+ + ", mFirstRecentLightSampleTime="
+ + TimeUtils.formatUptime(mFirstRecentLightSampleTime)
+ ", mPendingLightSensorDebounceTime="
+ TimeUtils.formatUptime(mPendingLightSensorDebounceTime));
}
@@ -694,6 +734,9 @@
mRecentLightAverage = lux;
mLastLightSample = lux;
mLastLightSampleTime = time;
+ mFirstRecentLightSampleTime = time;
+ mPendingLightSensorDebounceTime = time + (brightening ?
+ BRIGHTENING_LIGHT_DEBOUNCE : DIMMING_LIGHT_DEBOUNCE);
}
private void accumulateRecentLight(long time, float lux) {
@@ -715,8 +758,7 @@
if (DEBUG) {
Slog.d(TAG, "debounceLightSensor: Accepted new measurement "
+ mLightMeasurement + " after "
- + (now - mPendingLightSensorDebounceTime
- + mRecentLightTimeConstant) + " ms based on "
+ + (now - mFirstRecentLightSampleTime) + " ms based on "
+ mRecentLightSamples + " recent samples.");
}
@@ -751,13 +793,13 @@
return;
}
- final int newScreenAutoBrightness = mapLuxToBrightness(mLightMeasurement,
- mAutoBrightnessLevelsConfig,
- mAutoBrightnessLcdBacklightValuesConfig);
+ final int newScreenAutoBrightness = interpolateBrightness(
+ mScreenAutoBrightnessSpline, mLightMeasurement);
if (mScreenAutoBrightness != newScreenAutoBrightness) {
if (DEBUG) {
Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
- + mScreenAutoBrightness);
+ + mScreenAutoBrightness + "newScreenAutoBrightness="
+ + newScreenAutoBrightness);
}
mScreenAutoBrightness = newScreenAutoBrightness;
@@ -767,20 +809,8 @@
}
}
- /**
- * Maps a light sensor measurement in lux to a brightness value given
- * a table of lux breakpoint values and a table of brightnesses that
- * is one element larger.
- */
- private static int mapLuxToBrightness(float lux,
- int[] fromLux, int[] toBrightness) {
- // TODO implement interpolation and possibly range expansion
- int level = 0;
- final int count = fromLux.length;
- while (level < count && lux >= fromLux[level]) {
- level += 1;
- }
- return toBrightness[level];
+ private static int interpolateBrightness(Spline spline, float lux) {
+ return Math.min(255, Math.max(0, (int)Math.round(spline.interpolate(lux))));
}
private void sendOnStateChanged() {
@@ -822,10 +852,7 @@
pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
pw.println(" mUseSoftwareAutoBrightnessConfig="
+ mUseSoftwareAutoBrightnessConfig);
- pw.println(" mAutoBrightnessLevelsConfig="
- + Arrays.toString(mAutoBrightnessLevelsConfig));
- pw.println(" mAutoBrightnessLcdBacklightValuesConfig="
- + Arrays.toString(mAutoBrightnessLcdBacklightValuesConfig));
+ pw.println(" mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline);
pw.println(" mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
if (Looper.myLooper() == mHandler.getLooper()) {
@@ -885,6 +912,8 @@
pw.println(" mRecentLightAverage=" + mRecentLightAverage);
pw.println(" mRecentLightBrightening=" + mRecentLightBrightening);
pw.println(" mRecentLightTimeConstant=" + mRecentLightTimeConstant);
+ pw.println(" mFirstRecentLightSampleTime="
+ + TimeUtils.formatUptime(mFirstRecentLightSampleTime));
pw.println(" mPendingLightSensorDebounceTime="
+ TimeUtils.formatUptime(mPendingLightSensorDebounceTime));
pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness);
diff --git a/services/java/com/android/server/power/DisplayPowerState.java b/services/java/com/android/server/power/DisplayPowerState.java
index ad242c0..f618725 100644
--- a/services/java/com/android/server/power/DisplayPowerState.java
+++ b/services/java/com/android/server/power/DisplayPowerState.java
@@ -242,8 +242,8 @@
mElectronBeam.draw(mElectronBeamLevel);
}
- if ((mDirty & DIRTY_BRIGHTNESS) != 0) {
- mScreenBrightnessModulator.setBrightness(mScreenBrightness);
+ if ((mDirty & (DIRTY_BRIGHTNESS | DIRTY_SCREEN_ON)) != 0) {
+ mScreenBrightnessModulator.setBrightness(mScreenOn ? mScreenBrightness : 0);
}
if ((mDirty & DIRTY_SCREEN_ON) != 0 && mScreenOn) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 40a9eed..27c298c 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5874,7 +5874,7 @@
}
}
- rebuildBlackFrame();
+ rebuildBlackFrameLocked();
final WindowList windows = displayContent.getWindowList();
for (int i = windows.size() - 1; i >= 0; i--) {
@@ -6891,6 +6891,8 @@
displayReady(Display.DEFAULT_DISPLAY);
synchronized(mWindowMap) {
+ readForcedDisplaySizeAndDensityLocked(getDefaultDisplayContent());
+
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
mDisplay = wm.getDefaultDisplay();
mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
@@ -6912,6 +6914,11 @@
mPolicy.setInitialDisplaySize(mDisplay, displayContent.mInitialDisplayWidth,
displayContent.mInitialDisplayHeight, displayContent.mInitialDisplayDensity);
}
+
+ try {
+ mActivityManager.updateConfiguration(null);
+ } catch (RemoteException e) {
+ }
}
public void displayReady(int displayId) {
@@ -6930,15 +6937,6 @@
displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
}
}
-
- try {
- mActivityManager.updateConfiguration(null);
- } catch (RemoteException e) {
- }
-
- synchronized (mWindowMap) {
- readForcedDisplaySizeAndDensityLocked(getDisplayContent(displayId));
- }
}
public void systemReady() {
@@ -7567,7 +7565,7 @@
}
}
- private void rebuildBlackFrame() {
+ private void rebuildBlackFrameLocked() {
if (mBlackFrame != null) {
mBlackFrame.kill();
mBlackFrame = null;
@@ -7579,6 +7577,13 @@
int initW, initH, baseW, baseH;
final boolean rotated = (mRotation == Surface.ROTATION_90
|| mRotation == Surface.ROTATION_270);
+ if (DEBUG_BOOT) {
+ Slog.i(TAG, "BLACK FRAME: rotated=" + rotated + " init="
+ + displayContent.mInitialDisplayWidth + "x"
+ + displayContent.mInitialDisplayHeight + " base="
+ + displayContent.mBaseDisplayWidth + "x"
+ + displayContent.mBaseDisplayHeight);
+ }
if (rotated) {
initW = displayContent.mInitialDisplayHeight;
initH = displayContent.mInitialDisplayWidth;
@@ -7640,7 +7645,7 @@
}
}
if (changed) {
- reconfigureDisplayLocked(displayContent);
+ rebuildBlackFrameLocked();
}
}
@@ -7669,7 +7674,7 @@
final DisplayContent displayContent = getDisplayContent(displayId);
setForcedDisplayDensityLocked(displayContent, density);
Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.DISPLAY_SIZE_FORCED, Integer.toString(density));
+ Settings.Secure.DISPLAY_DENSITY_FORCED, Integer.toString(density));
}
}
@@ -7712,7 +7717,7 @@
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
}
- rebuildBlackFrame();
+ rebuildBlackFrameLocked();
performLayoutAndPlaceSurfacesLocked();
}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index f6f9aa0..3373fd4 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -71,7 +71,7 @@
import android.os.INetworkManagementService;
import android.os.IPowerManager;
import android.os.MessageQueue.IdleHandler;
-import android.os.UserId;
+import android.os.UserHandle;
import android.test.AndroidTestCase;
import android.test.mock.MockPackageManager;
import android.test.suitebuilder.annotation.LargeTest;
@@ -138,10 +138,10 @@
private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 800;
private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 801;
- private static final int UID_A = UserId.getUid(USER_ID, APP_ID_A);
- private static final int UID_B = UserId.getUid(USER_ID, APP_ID_B);
- private static final int UID_A_GUEST = UserId.getUid(USER_ID_GUEST, APP_ID_A);
- private static final int UID_B_GUEST = UserId.getUid(USER_ID_GUEST, APP_ID_B);
+ private static final int UID_A = UserHandle.getUid(USER_ID, APP_ID_A);
+ private static final int UID_B = UserHandle.getUid(USER_ID, APP_ID_B);
+ private static final int UID_A_GUEST = UserHandle.getUid(USER_ID_GUEST, APP_ID_A);
+ private static final int UID_B_GUEST = UserHandle.getUid(USER_ID_GUEST, APP_ID_B);
private static final int PID_1 = 400;
private static final int PID_2 = 401;
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Fisheye.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Fisheye.java
index bf68f91..81868b10 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Fisheye.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Fisheye.java
@@ -26,12 +26,16 @@
public class Fisheye extends TestBase {
private ScriptC_fisheye_full mScript_full = null;
private ScriptC_fisheye_relaxed mScript_relaxed = null;
+ private ScriptC_fisheye_approx_full mScript_approx_full = null;
+ private ScriptC_fisheye_approx_relaxed mScript_approx_relaxed = null;
+ private final boolean approx;
private final boolean relaxed;
private float center_x = 0.5f;
private float center_y = 0.5f;
private float scale = 0.5f;
- public Fisheye(boolean relaxed) {
+ public Fisheye(boolean approx, boolean relaxed) {
+ this.approx = approx;
this.relaxed = relaxed;
}
@@ -68,7 +72,18 @@
}
private void do_init() {
- if (relaxed)
+ if (approx) {
+ if (relaxed)
+ mScript_approx_relaxed.invoke_init_filter(
+ mInPixelsAllocation.getType().getX(),
+ mInPixelsAllocation.getType().getY(), center_x,
+ center_y, scale);
+ else
+ mScript_approx_full.invoke_init_filter(
+ mInPixelsAllocation.getType().getX(),
+ mInPixelsAllocation.getType().getY(), center_x,
+ center_y, scale);
+ } else if (relaxed)
mScript_relaxed.invoke_init_filter(
mInPixelsAllocation.getType().getX(),
mInPixelsAllocation.getType().getY(), center_x, center_y,
@@ -81,7 +96,19 @@
}
public void createTest(android.content.res.Resources res) {
- if (relaxed) {
+ if (approx) {
+ if (relaxed) {
+ mScript_approx_relaxed = new ScriptC_fisheye_approx_relaxed(mRS,
+ res, R.raw.fisheye_approx_relaxed);
+ mScript_approx_relaxed.set_in_alloc(mInPixelsAllocation);
+ mScript_approx_relaxed.set_sampler(Sampler.CLAMP_LINEAR(mRS));
+ } else {
+ mScript_approx_full = new ScriptC_fisheye_approx_full(mRS, res,
+ R.raw.fisheye_approx_full);
+ mScript_approx_full.set_in_alloc(mInPixelsAllocation);
+ mScript_approx_full.set_sampler(Sampler.CLAMP_LINEAR(mRS));
+ }
+ } else if (relaxed) {
mScript_relaxed = new ScriptC_fisheye_relaxed(mRS, res,
R.raw.fisheye_relaxed);
mScript_relaxed.set_in_alloc(mInPixelsAllocation);
@@ -96,7 +123,12 @@
}
public void runTest() {
- if (relaxed)
+ if (approx) {
+ if (relaxed)
+ mScript_approx_relaxed.forEach_root(mOutPixelsAllocation);
+ else
+ mScript_approx_full.forEach_root(mOutPixelsAllocation);
+ } else if (relaxed)
mScript_relaxed.forEach_root(mOutPixelsAllocation);
else
mScript_full.forEach_root(mOutPixelsAllocation);
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 3eec7f5..07626a3 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -144,30 +144,36 @@
mTest = new Grain();
break;
case 7:
- mTest = new Fisheye(false);
+ mTest = new Fisheye(false, false);
break;
case 8:
- mTest = new Fisheye(true);
+ mTest = new Fisheye(false, true);
break;
case 9:
- mTest = new Vignette(false, false);
+ mTest = new Fisheye(true, false);
break;
case 10:
- mTest = new Vignette(false, true);
+ mTest = new Fisheye(true, true);
break;
case 11:
- mTest = new Vignette(true, false);
+ mTest = new Vignette(false, false);
break;
case 12:
- mTest = new Vignette(true, true);
+ mTest = new Vignette(false, true);
break;
case 13:
- mTest = new GroupTest(true);
+ mTest = new Vignette(true, false);
break;
case 14:
- mTest = new GroupTest(false);
+ mTest = new Vignette(true, true);
break;
case 15:
+ mTest = new GroupTest(true);
+ break;
+ case 16:
+ mTest = new GroupTest(false);
+ break;
+ case 17:
mTest = new Intrinsics(0);
break;
}
@@ -182,7 +188,7 @@
}
void setupTests() {
- mTestNames = new String[16];
+ mTestNames = new String[18];
mTestNames[0] = "Levels Vec3 Relaxed";
mTestNames[1] = "Levels Vec4 Relaxed";
mTestNames[2] = "Levels Vec3 Full";
@@ -192,13 +198,15 @@
mTestNames[6] = "Grain";
mTestNames[7] = "Fisheye Full";
mTestNames[8] = "Fisheye Relaxed";
- mTestNames[9] = "Vignette Full";
- mTestNames[10] = "Vignette Relaxed";
- mTestNames[11] = "Vignette Approximate Full";
- mTestNames[12] = "Vignette Approximate Relaxed";
- mTestNames[13] = "Group Test (emulated)";
- mTestNames[14] = "Group Test (native)";
- mTestNames[15] = "Intrinsics Convolve 3x3";
+ mTestNames[9] = "Fisheye Approximate Full";
+ mTestNames[10] = "Fisheye Approximate Relaxed";
+ mTestNames[11] = "Vignette Full";
+ mTestNames[12] = "Vignette Relaxed";
+ mTestNames[13] = "Vignette Approximate Full";
+ mTestNames[14] = "Vignette Approximate Relaxed";
+ mTestNames[15] = "Group Test (emulated)";
+ mTestNames[16] = "Group Test (native)";
+ mTestNames[17] = "Intrinsics Convolve 3x3";
mTestSpinner.setAdapter(new ArrayAdapter<String>(
this, R.layout.spinner_layout, mTestNames));
}
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye.rsh b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye.rsh
index 4dcfc1d..3809912 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye.rsh
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye.rsh
@@ -17,46 +17,41 @@
rs_allocation in_alloc;
rs_sampler sampler;
-static float2 center, dimensions;
-static float2 scale;
-static float alpha;
-static float radius2;
-static float factor;
+static float2 center, neg_center, inv_dimensions, axis_scale;
+static float alpha, radius2, factor;
-void init_filter(uint32_t dim_x, uint32_t dim_y, float focus_x, float focus_y, float k) {
- center.x = focus_x;
- center.y = focus_y;
- dimensions.x = (float)dim_x;
- dimensions.y = (float)dim_y;
-
+void init_filter(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y, float k) {
+ center.x = center_x;
+ center.y = center_y;
+ neg_center = -center;
+ inv_dimensions.x = 1.f / (float)dim_x;
+ inv_dimensions.y = 1.f / (float)dim_y;
alpha = k * 2.0 + 0.75;
- float bound2 = 0.25;
- if (dim_x > dim_y) {
- scale.x = 1.0;
- scale.y = dimensions.y / dimensions.x;
- bound2 *= (scale.y*scale.y + 1);
- } else {
- scale.x = dimensions.x / dimensions.y;
- scale.y = 1.0;
- bound2 *= (scale.x*scale.x + 1);
- }
+
+ axis_scale = (float2)1.f;
+ if (dim_x > dim_y)
+ axis_scale.y = (float)dim_y / (float)dim_x;
+ else
+ axis_scale.x = (float)dim_x / (float)dim_y;
+
+ const float bound2 = 0.25 * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
const float bound = sqrt(bound2);
const float radius = 1.15 * bound;
radius2 = radius*radius;
- const float max_radian = 0.5f * M_PI - atan(alpha / bound * sqrt(radius2 - bound2));
+ const float max_radian = M_PI_2 - atan(alpha / bound * sqrt(radius2 - bound2));
factor = bound / max_radian;
}
void root(uchar4 *out, uint32_t x, uint32_t y) {
// Convert x and y to floating point coordinates with center as origin
- float2 coord;
- coord.x = (float)x / dimensions.x;
- coord.y = (float)y / dimensions.y;
- coord -= center;
- const float dist = length(scale * coord);
- const float radian = M_PI_2 - atan((alpha * sqrt(radius2 - dist * dist)) / dist);
- const float scalar = radian * factor / dist;
- const float2 new_coord = coord * scalar + center;
+ const float2 inCoord = {(float)x, (float)y};
+ const float2 coord = mad(inCoord, inv_dimensions, neg_center);
+ const float2 scaledCoord = axis_scale * coord;
+ const float dist2 = scaledCoord.x*scaledCoord.x + scaledCoord.y*scaledCoord.y;
+ const float inv_dist = rsqrt(dist2);
+ const float radian = M_PI_2 - atan((alpha * sqrt(radius2 - dist2)) * inv_dist);
+ const float scalar = radian * factor * inv_dist;
+ const float2 new_coord = mad(coord, scalar, center);
const float4 fout = rsSample(in_alloc, sampler, new_coord);
*out = rsPackColorTo8888(fout);
}
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx.rsh b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx.rsh
new file mode 100644
index 0000000..008acbe
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx.rsh
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+rs_allocation in_alloc;
+rs_sampler sampler;
+
+static float2 center, neg_center, inv_dimensions, axis_scale;
+static float alpha, radius2, factor;
+
+void init_filter(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y, float k) {
+ center.x = center_x;
+ center.y = center_y;
+ neg_center = -center;
+ inv_dimensions.x = 1.f / (float)dim_x;
+ inv_dimensions.y = 1.f / (float)dim_y;
+ alpha = k * 2.0 + 0.75;
+
+ axis_scale = (float2)1.f;
+ if (dim_x > dim_y)
+ axis_scale.y = (float)dim_y / (float)dim_x;
+ else
+ axis_scale.x = (float)dim_x / (float)dim_y;
+
+ const float bound2 = 0.25 * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
+ const float bound = sqrt(bound2);
+ const float radius = 1.15 * bound;
+ radius2 = radius*radius;
+ const float max_radian = M_PI_2 - atan(alpha / bound * sqrt(radius2 - bound2));
+ factor = bound / max_radian;
+}
+
+void root(uchar4 *out, uint32_t x, uint32_t y) {
+ // Convert x and y to floating point coordinates with center as origin
+ const float2 inCoord = {(float)x, (float)y};
+ const float2 coord = mad(inCoord, inv_dimensions, neg_center);
+ const float2 scaledCoord = axis_scale * coord;
+ const float dist2 = scaledCoord.x*scaledCoord.x + scaledCoord.y*scaledCoord.y;
+ const float inv_dist = approx_rsqrt(dist2);
+ const float radian = M_PI_2 - approx_atan((alpha * approx_sqrt(radius2 - dist2)) * inv_dist);
+ const float scalar = radian * factor * inv_dist;
+ const float2 new_coord = mad(coord, scalar, center);
+ const float4 fout = rsSample(in_alloc, sampler, new_coord);
+ *out = rsPackColorTo8888(fout);
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_full.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_full.rs
new file mode 100644
index 0000000..1ea37db
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_full.rs
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image)
+
+#include "fisheye_approx.rsh"
+
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rs
new file mode 100644
index 0000000..3e76368
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rs
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image)
+#pragma rs_fp_relaxed
+
+#include "fisheye_approx.rsh"
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/Android.mk b/tests/RenderScriptTests/ImageProcessing2/Android.mk
new file mode 100644
index 0000000..c81fd93
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/Android.mk
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(call all-renderscript-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android.support.v8.renderscript
+
+LOCAL_PACKAGE_NAME := ImageProcessing2
+
+LOCAL_RENDERSCRIPT_FLAGS := -rs-package-name=android.support.v8.renderscript
+LOCAL_REQUIRED_MODULES := librsjni
+
+include $(BUILD_PACKAGE)
+
+#include $(call all-makefiles-under, $(LOCAL_PATH))
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/AndroidManifest.xml b/tests/RenderScriptTests/ImageProcessing2/AndroidManifest.xml
new file mode 100644
index 0000000..1ef04c2
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/AndroidManifest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.rs.image2">
+ <uses-sdk android:minSdkVersion="11" />
+ <application android:label="IP GB"
+ android:hardwareAccelerated="true">
+ <activity android:name="ImageProcessingActivity2">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/RenderScriptTests/ImageProcessing2/res/drawable-nodpi/city.png b/tests/RenderScriptTests/ImageProcessing2/res/drawable-nodpi/city.png
new file mode 100644
index 0000000..856eeff
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/res/drawable-nodpi/city.png
Binary files differ
diff --git a/tests/RenderScriptTests/ImageProcessing2/res/layout/main.xml b/tests/RenderScriptTests/ImageProcessing2/res/layout/main.xml
new file mode 100644
index 0000000..bd56d62
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/res/layout/main.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/toplevel">
+ <SurfaceView
+ android:id="@+id/surface"
+ android:layout_width="1dip"
+ android:layout_height="1dip" />
+ <ScrollView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <ImageView
+ android:id="@+id/display"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/benchmark"
+ android:onClick="benchmark"/>
+ <TextView
+ android:id="@+id/benchmarkText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:text="@string/saturation"/>
+ </LinearLayout>
+ <Spinner
+ android:id="@+id/filterselection"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/slider1Text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/saturation"/>
+ <SeekBar
+ android:id="@+id/slider1"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/slider2Text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/gamma"/>
+ <SeekBar
+ android:id="@+id/slider2"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/slider3Text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:textSize="8pt"
+ android:text="@string/out_white"/>
+ <SeekBar
+ android:id="@+id/slider3"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/slider4Text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/in_white"/>
+ <SeekBar
+ android:id="@+id/slider4"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/slider5Text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/in_white"/>
+ <SeekBar
+ android:id="@+id/slider5"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/res/layout/spinner_layout.xml b/tests/RenderScriptTests/ImageProcessing2/res/layout/spinner_layout.xml
new file mode 100644
index 0000000..8196bbf
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/res/layout/spinner_layout.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="10dp"
+ android:textSize="16sp"
+/>
diff --git a/tests/RenderScriptTests/ImageProcessing2/res/values/strings.xml b/tests/RenderScriptTests/ImageProcessing2/res/values/strings.xml
new file mode 100644
index 0000000..cc5cc4d
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/res/values/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- General -->
+ <skip />
+ <!--slider label -->
+ <string name="blur_description">Blur Radius</string>
+ <string name="in_white">In White</string>
+ <string name="out_white">Out White</string>
+ <string name="in_black">In Black</string>
+ <string name="out_black">Out Black</string>
+ <string name="gamma">Gamma</string>
+ <string name="saturation">Saturation</string>
+ <string name="benchmark">Benchmark</string>
+
+</resources>
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Blur25.java b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Blur25.java
new file mode 100644
index 0000000..be87716
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Blur25.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image2;
+
+import java.lang.Math;
+
+import android.support.v8.renderscript.*;
+import android.util.Log;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+public class Blur25 extends TestBase {
+ private int MAX_RADIUS = 25;
+ private ScriptC_threshold mScript;
+ private ScriptC_vertical_blur mScriptVBlur;
+ private ScriptC_horizontal_blur mScriptHBlur;
+ private int mRadius = MAX_RADIUS;
+ private float mSaturation = 1.0f;
+ private Allocation mScratchPixelsAllocation1;
+ private Allocation mScratchPixelsAllocation2;
+
+
+ public boolean onBar1Setup(SeekBar b, TextView t) {
+ t.setText("Radius");
+ b.setProgress(100);
+ return true;
+ }
+ public boolean onBar2Setup(SeekBar b, TextView t) {
+ b.setProgress(50);
+ t.setText("Saturation");
+ return true;
+ }
+
+
+ public void onBar1Changed(int progress) {
+ float fRadius = progress / 100.0f;
+ fRadius *= (float)(MAX_RADIUS);
+ mRadius = (int)fRadius;
+ mScript.set_radius(mRadius);
+ }
+ public void onBar2Changed(int progress) {
+ mSaturation = (float)progress / 50.0f;
+ mScriptVBlur.invoke_setSaturation(mSaturation);
+ }
+
+
+ public void createTest(android.content.res.Resources res) {
+ int width = mInPixelsAllocation.getType().getX();
+ int height = mInPixelsAllocation.getType().getY();
+
+ Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS));
+ tb.setX(width);
+ tb.setY(height);
+ mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
+ mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());
+
+ mScriptVBlur = new ScriptC_vertical_blur(mRS, res, R.raw.vertical_blur);
+ mScriptHBlur = new ScriptC_horizontal_blur(mRS, res, R.raw.horizontal_blur);
+
+ mScript = new ScriptC_threshold(mRS, res, R.raw.threshold);
+ mScript.set_width(width);
+ mScript.set_height(height);
+ mScript.set_radius(mRadius);
+
+ mScriptVBlur.invoke_setSaturation(mSaturation);
+
+ mScript.bind_InPixel(mInPixelsAllocation);
+ mScript.bind_OutPixel(mOutPixelsAllocation);
+ mScript.bind_ScratchPixel1(mScratchPixelsAllocation1);
+ mScript.bind_ScratchPixel2(mScratchPixelsAllocation2);
+
+ mScript.set_vBlurScript(mScriptVBlur);
+ mScript.set_hBlurScript(mScriptHBlur);
+ }
+
+ public void runTest() {
+ mScript.invoke_filter();
+ }
+
+ public void setupBenchmark() {
+ mScript.set_radius(MAX_RADIUS);
+ }
+
+ public void exitBenchmark() {
+ mScript.set_radius(mRadius);
+ }
+}
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Fisheye.java b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Fisheye.java
new file mode 100644
index 0000000..995cf9d
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Fisheye.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image2;
+
+import android.support.v8.renderscript.*;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+public class Fisheye extends TestBase {
+ private ScriptC_fisheye_full mScript_full = null;
+ private ScriptC_fisheye_relaxed mScript_relaxed = null;
+ private final boolean relaxed;
+ private float center_x = 0.5f;
+ private float center_y = 0.5f;
+ private float scale = 0.5f;
+
+ public Fisheye(boolean relaxed) {
+ this.relaxed = relaxed;
+ }
+
+ public boolean onBar1Setup(SeekBar b, TextView t) {
+ t.setText("Scale");
+ b.setMax(100);
+ b.setProgress(25);
+ return true;
+ }
+ public boolean onBar2Setup(SeekBar b, TextView t) {
+ t.setText("Shift center X");
+ b.setMax(100);
+ b.setProgress(50);
+ return true;
+ }
+ public boolean onBar3Setup(SeekBar b, TextView t) {
+ t.setText("Shift center Y");
+ b.setMax(100);
+ b.setProgress(50);
+ return true;
+ }
+
+ public void onBar1Changed(int progress) {
+ scale = progress / 50.0f;
+ do_init();
+ }
+ public void onBar2Changed(int progress) {
+ center_x = progress / 100.0f;
+ do_init();
+ }
+ public void onBar3Changed(int progress) {
+ center_y = progress / 100.0f;
+ do_init();
+ }
+
+ private void do_init() {
+ if (relaxed)
+ mScript_relaxed.invoke_init_filter(
+ mInPixelsAllocation.getType().getX(),
+ mInPixelsAllocation.getType().getY(), center_x, center_y,
+ scale);
+ else
+ mScript_full.invoke_init_filter(
+ mInPixelsAllocation.getType().getX(),
+ mInPixelsAllocation.getType().getY(), center_x, center_y,
+ scale);
+ }
+
+ public void createTest(android.content.res.Resources res) {
+ if (relaxed) {
+ mScript_relaxed = new ScriptC_fisheye_relaxed(mRS, res,
+ R.raw.fisheye_relaxed);
+ mScript_relaxed.set_in_alloc(mInPixelsAllocation);
+ mScript_relaxed.set_sampler(Sampler.CLAMP_LINEAR(mRS));
+ } else {
+ mScript_full = new ScriptC_fisheye_full(mRS, res,
+ R.raw.fisheye_full);
+ mScript_full.set_in_alloc(mInPixelsAllocation);
+ mScript_full.set_sampler(Sampler.CLAMP_LINEAR(mRS));
+ }
+ do_init();
+ }
+
+ public void runTest() {
+ if (relaxed)
+ mScript_relaxed.forEach_root(mOutPixelsAllocation);
+ else
+ mScript_full.forEach_root(mOutPixelsAllocation);
+ }
+
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Grain.java b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Grain.java
new file mode 100644
index 0000000..e00edd7
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Grain.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image2;
+
+import java.lang.Math;
+
+import android.support.v8.renderscript.*;
+import android.util.Log;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+public class Grain extends TestBase {
+ private ScriptC_grain mScript;
+ private Allocation mNoise;
+ private Allocation mNoise2;
+
+
+ public boolean onBar1Setup(SeekBar b, TextView t) {
+ t.setText("Strength");
+ b.setProgress(50);
+ return true;
+ }
+
+ public void onBar1Changed(int progress) {
+ float s = progress / 100.0f;
+ mScript.set_gNoiseStrength(s);
+ }
+
+ public void createTest(android.content.res.Resources res) {
+ int width = mInPixelsAllocation.getType().getX();
+ int height = mInPixelsAllocation.getType().getY();
+
+ Type.Builder tb = new Type.Builder(mRS, Element.U8(mRS));
+ tb.setX(width);
+ tb.setY(height);
+ mNoise = Allocation.createTyped(mRS, tb.create());
+ mNoise2 = Allocation.createTyped(mRS, tb.create());
+
+ mScript = new ScriptC_grain(mRS, res, R.raw.grain);
+ mScript.set_gWidth(width);
+ mScript.set_gHeight(height);
+ mScript.set_gNoiseStrength(0.5f);
+ mScript.set_gBlendSource(mNoise);
+ mScript.set_gNoise(mNoise2);
+ }
+
+ public void runTest() {
+ mScript.forEach_genRand(mNoise);
+ mScript.forEach_blend9(mNoise2);
+ mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
+ }
+
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Greyscale.java b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Greyscale.java
new file mode 100644
index 0000000..2d85ae7
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Greyscale.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image2;
+
+import java.lang.Math;
+
+import android.support.v8.renderscript.*;
+import android.util.Log;
+
+public class Greyscale extends TestBase {
+ private ScriptC_greyscale mScript;
+
+ public void createTest(android.content.res.Resources res) {
+ mScript = new ScriptC_greyscale(mRS, res, R.raw.greyscale);
+ }
+
+ public void runTest() {
+ mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
+ }
+
+}
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/GroupTest.java b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/GroupTest.java
new file mode 100644
index 0000000..b9fbb59
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/GroupTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image2;
+
+import java.lang.Math;
+
+import android.support.v8.renderscript.*;
+import android.util.Log;
+
+public class GroupTest extends TestBase {
+ private ScriptC_convolve3x3 mConvolve;
+ private ScriptC_colormatrix mMatrix;
+
+ private Allocation mScratchPixelsAllocation1;
+ private ScriptGroup mGroup;
+
+ private int mWidth;
+ private int mHeight;
+ private boolean mUseNative;
+
+
+ public GroupTest(boolean useNative) {
+ mUseNative = useNative;
+ }
+
+ public void createTest(android.content.res.Resources res) {
+ mWidth = mInPixelsAllocation.getType().getX();
+ mHeight = mInPixelsAllocation.getType().getY();
+
+ mConvolve = new ScriptC_convolve3x3(mRS, res, R.raw.convolve3x3);
+ mMatrix = new ScriptC_colormatrix(mRS, res, R.raw.colormatrix);
+
+ float f[] = new float[9];
+ f[0] = 0.f; f[1] = -1.f; f[2] = 0.f;
+ f[3] = -1.f; f[4] = 5.f; f[5] = -1.f;
+ f[6] = 0.f; f[7] = -1.f; f[8] = 0.f;
+ mConvolve.set_gCoeffs(f);
+
+ Matrix4f m = new Matrix4f();
+ m.set(1, 0, 0.2f);
+ m.set(1, 1, 0.9f);
+ m.set(1, 2, 0.2f);
+ mMatrix.invoke_setMatrix(m);
+
+ Type.Builder tb = new Type.Builder(mRS, Element.U8_4(mRS));
+ tb.setX(mWidth);
+ tb.setY(mHeight);
+ Type connect = tb.create();
+
+ if (mUseNative) {
+ ScriptGroup.Builder b = new ScriptGroup.Builder(mRS);
+ b.addConnection(connect, mConvolve, mMatrix, null);
+ mGroup = b.create();
+
+ } else {
+ mScratchPixelsAllocation1 = Allocation.createTyped(mRS, connect);
+ }
+ }
+
+ public void runTest() {
+ mConvolve.set_gIn(mInPixelsAllocation);
+ mConvolve.set_gWidth(mWidth);
+ mConvolve.set_gHeight(mHeight);
+ if (mUseNative) {
+ mGroup.setOutput(mMatrix, mOutPixelsAllocation);
+ mGroup.execute();
+ } else {
+ mConvolve.forEach_root(mScratchPixelsAllocation1);
+ mMatrix.forEach_root(mScratchPixelsAllocation1, mOutPixelsAllocation);
+ }
+ }
+
+}
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/ImageProcessingActivity2.java b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/ImageProcessingActivity2.java
new file mode 100644
index 0000000..9b36da14
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/ImageProcessingActivity2.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image2;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.support.v8.renderscript.*;
+import android.view.SurfaceView;
+import android.view.SurfaceHolder;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.view.View;
+import android.util.Log;
+import java.lang.Math;
+
+public class ImageProcessingActivity2 extends Activity
+ implements SeekBar.OnSeekBarChangeListener {
+ private final String TAG = "Img";
+ Bitmap mBitmapIn;
+ Bitmap mBitmapOut;
+ String mTestNames[];
+
+ private SeekBar mBar1;
+ private SeekBar mBar2;
+ private SeekBar mBar3;
+ private SeekBar mBar4;
+ private SeekBar mBar5;
+ private TextView mText1;
+ private TextView mText2;
+ private TextView mText3;
+ private TextView mText4;
+ private TextView mText5;
+
+ private float mSaturation = 1.0f;
+
+ private TextView mBenchmarkResult;
+ private Spinner mTestSpinner;
+
+ private SurfaceView mSurfaceView;
+ private ImageView mDisplayView;
+
+ private boolean mDoingBenchmark;
+
+ private TestBase mTest;
+
+
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (fromUser) {
+
+ if (seekBar == mBar1) {
+ mTest.onBar1Changed(progress);
+ } else if (seekBar == mBar2) {
+ mTest.onBar2Changed(progress);
+ } else if (seekBar == mBar3) {
+ mTest.onBar3Changed(progress);
+ } else if (seekBar == mBar4) {
+ mTest.onBar4Changed(progress);
+ } else if (seekBar == mBar5) {
+ mTest.onBar5Changed(progress);
+ }
+
+ mTest.runTest();
+ mTest.updateBitmap(mBitmapOut);
+ mDisplayView.invalidate();
+ }
+ }
+
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+
+ void setupBars() {
+ mBar1.setVisibility(View.VISIBLE);
+ mText1.setVisibility(View.VISIBLE);
+ mTest.onBar1Setup(mBar1, mText1);
+
+ mBar2.setVisibility(View.VISIBLE);
+ mText2.setVisibility(View.VISIBLE);
+ mTest.onBar2Setup(mBar2, mText2);
+
+ mBar3.setVisibility(View.VISIBLE);
+ mText3.setVisibility(View.VISIBLE);
+ mTest.onBar3Setup(mBar3, mText3);
+
+ mBar4.setVisibility(View.VISIBLE);
+ mText4.setVisibility(View.VISIBLE);
+ mTest.onBar4Setup(mBar4, mText4);
+
+ mBar5.setVisibility(View.VISIBLE);
+ mText5.setVisibility(View.VISIBLE);
+ mTest.onBar5Setup(mBar5, mText5);
+ }
+
+
+ void changeTest(int testID) {
+ switch(testID) {
+ case 0:
+ mTest = new LevelsV4(false, false);
+ break;
+ case 1:
+ mTest = new LevelsV4(false, true);
+ break;
+ case 2:
+ mTest = new LevelsV4(true, false);
+ break;
+ case 3:
+ mTest = new LevelsV4(true, true);
+ break;
+ case 4:
+ mTest = new Blur25();
+ break;
+ case 5:
+ mTest = new Greyscale();
+ break;
+ case 6:
+ mTest = new Grain();
+ break;
+ case 7:
+ mTest = new Fisheye(false);
+ break;
+ case 8:
+ mTest = new Fisheye(true);
+ break;
+ case 9:
+ mTest = new Vignette(false);
+ break;
+ case 10:
+ mTest = new Vignette(true);
+ break;
+ case 11:
+ mTest = new GroupTest(false);
+ break;
+ case 12:
+ mTest = new GroupTest(true);
+ break;
+ }
+
+ mTest.createBaseTest(this, mBitmapIn);
+ setupBars();
+
+ mTest.runTest();
+ mTest.updateBitmap(mBitmapOut);
+ mDisplayView.invalidate();
+ mBenchmarkResult.setText("Result: not run");
+ }
+
+ void setupTests() {
+ mTestNames = new String[13];
+ mTestNames[0] = "Levels Vec3 Relaxed";
+ mTestNames[1] = "Levels Vec4 Relaxed";
+ mTestNames[2] = "Levels Vec3 Full";
+ mTestNames[3] = "Levels Vec4 Full";
+ mTestNames[4] = "Blur radius 25";
+ mTestNames[5] = "Greyscale";
+ mTestNames[6] = "Grain";
+ mTestNames[7] = "Fisheye Full";
+ mTestNames[8] = "Fisheye Relaxed";
+ mTestNames[9] = "Vignette Full";
+ mTestNames[10] = "Vignette Relaxed";
+ mTestNames[11] = "Group Test (emulated)";
+ mTestNames[12] = "Group Test (native)";
+ mTestSpinner.setAdapter(new ArrayAdapter<String>(
+ this, R.layout.spinner_layout, mTestNames));
+ }
+
+ private AdapterView.OnItemSelectedListener mTestSpinnerListener =
+ new AdapterView.OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+ changeTest(pos);
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ mBitmapIn = loadBitmap(R.drawable.city);
+ mBitmapOut = loadBitmap(R.drawable.city);
+
+ mSurfaceView = (SurfaceView) findViewById(R.id.surface);
+
+ mDisplayView = (ImageView) findViewById(R.id.display);
+ mDisplayView.setImageBitmap(mBitmapOut);
+
+ mBar1 = (SeekBar) findViewById(R.id.slider1);
+ mBar2 = (SeekBar) findViewById(R.id.slider2);
+ mBar3 = (SeekBar) findViewById(R.id.slider3);
+ mBar4 = (SeekBar) findViewById(R.id.slider4);
+ mBar5 = (SeekBar) findViewById(R.id.slider5);
+
+ mBar1.setOnSeekBarChangeListener(this);
+ mBar2.setOnSeekBarChangeListener(this);
+ mBar3.setOnSeekBarChangeListener(this);
+ mBar4.setOnSeekBarChangeListener(this);
+ mBar5.setOnSeekBarChangeListener(this);
+
+ mText1 = (TextView) findViewById(R.id.slider1Text);
+ mText2 = (TextView) findViewById(R.id.slider2Text);
+ mText3 = (TextView) findViewById(R.id.slider3Text);
+ mText4 = (TextView) findViewById(R.id.slider4Text);
+ mText5 = (TextView) findViewById(R.id.slider5Text);
+
+ mTestSpinner = (Spinner) findViewById(R.id.filterselection);
+ mTestSpinner.setOnItemSelectedListener(mTestSpinnerListener);
+
+ mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
+ mBenchmarkResult.setText("Result: not run");
+
+ setupTests();
+ changeTest(0);
+ }
+
+
+ private Bitmap loadBitmap(int resource) {
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+ return copyBitmap(BitmapFactory.decodeResource(getResources(), resource, options));
+ }
+
+ private static Bitmap copyBitmap(Bitmap source) {
+ Bitmap b = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
+ Canvas c = new Canvas(b);
+ c.drawBitmap(source, 0, 0, null);
+ source.recycle();
+ return b;
+ }
+
+ // button hook
+ public void benchmark(View v) {
+ long t = getBenchmark();
+ //long javaTime = javaFilter();
+ //mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms");
+ mBenchmarkResult.setText("Result: " + t + " ms");
+ }
+
+ // For benchmark test
+ public long getBenchmark() {
+ mDoingBenchmark = true;
+
+ mTest.setupBenchmark();
+ long result = 0;
+
+ Log.v(TAG, "Warming");
+ long t = java.lang.System.currentTimeMillis() + 2000;
+ do {
+ mTest.runTest();
+ mTest.finish();
+ } while (t > java.lang.System.currentTimeMillis());
+
+
+ Log.v(TAG, "Benchmarking");
+ t = java.lang.System.currentTimeMillis();
+ mTest.runTest();
+ mTest.finish();
+ t = java.lang.System.currentTimeMillis() - t;
+
+ Log.v(TAG, "getBenchmark: Renderscript frame time core ms " + t);
+ mTest.exitBenchmark();
+ mDoingBenchmark = false;
+
+ return t;
+ }
+}
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/LevelsV4.java b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/LevelsV4.java
new file mode 100644
index 0000000..fbe3727
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/LevelsV4.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image2;
+
+import java.lang.Math;
+
+import android.support.v8.renderscript.*;
+import android.util.Log;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+
+public class LevelsV4 extends TestBase {
+ private ScriptC_levels_relaxed mScriptR;
+ private ScriptC_levels_full mScriptF;
+ private float mInBlack = 0.0f;
+ private float mOutBlack = 0.0f;
+ private float mInWhite = 255.0f;
+ private float mOutWhite = 255.0f;
+ private float mSaturation = 1.0f;
+
+ Matrix3f satMatrix = new Matrix3f();
+ float mInWMinInB;
+ float mOutWMinOutB;
+ float mOverInWMinInB;
+
+ boolean mUseFull;
+ boolean mUseV4;
+
+ LevelsV4(boolean useFull, boolean useV4) {
+ mUseFull = useFull;
+ mUseV4 = useV4;
+ }
+
+
+ private void setLevels() {
+ mInWMinInB = mInWhite - mInBlack;
+ mOutWMinOutB = mOutWhite - mOutBlack;
+ mOverInWMinInB = 1.f / mInWMinInB;
+
+ mScriptR.set_inBlack(mInBlack);
+ mScriptR.set_outBlack(mOutBlack);
+ mScriptR.set_inWMinInB(mInWMinInB);
+ mScriptR.set_outWMinOutB(mOutWMinOutB);
+ mScriptR.set_overInWMinInB(mOverInWMinInB);
+ mScriptF.set_inBlack(mInBlack);
+ mScriptF.set_outBlack(mOutBlack);
+ mScriptF.set_inWMinInB(mInWMinInB);
+ mScriptF.set_outWMinOutB(mOutWMinOutB);
+ mScriptF.set_overInWMinInB(mOverInWMinInB);
+ }
+
+ private void setSaturation() {
+ float rWeight = 0.299f;
+ float gWeight = 0.587f;
+ float bWeight = 0.114f;
+ float oneMinusS = 1.0f - mSaturation;
+
+ satMatrix.set(0, 0, oneMinusS * rWeight + mSaturation);
+ satMatrix.set(0, 1, oneMinusS * rWeight);
+ satMatrix.set(0, 2, oneMinusS * rWeight);
+ satMatrix.set(1, 0, oneMinusS * gWeight);
+ satMatrix.set(1, 1, oneMinusS * gWeight + mSaturation);
+ satMatrix.set(1, 2, oneMinusS * gWeight);
+ satMatrix.set(2, 0, oneMinusS * bWeight);
+ satMatrix.set(2, 1, oneMinusS * bWeight);
+ satMatrix.set(2, 2, oneMinusS * bWeight + mSaturation);
+ mScriptR.set_colorMat(satMatrix);
+ mScriptF.set_colorMat(satMatrix);
+ }
+
+ public boolean onBar1Setup(SeekBar b, TextView t) {
+ b.setProgress(50);
+ t.setText("Saturation");
+ return true;
+ }
+ public boolean onBar2Setup(SeekBar b, TextView t) {
+ b.setMax(128);
+ b.setProgress(0);
+ t.setText("In Black");
+ return true;
+ }
+ public boolean onBar3Setup(SeekBar b, TextView t) {
+ b.setMax(128);
+ b.setProgress(0);
+ t.setText("Out Black");
+ return true;
+ }
+ public boolean onBar4Setup(SeekBar b, TextView t) {
+ b.setMax(128);
+ b.setProgress(128);
+ t.setText("Out White");
+ return true;
+ }
+ public boolean onBar5Setup(SeekBar b, TextView t) {
+ b.setMax(128);
+ b.setProgress(128);
+ t.setText("Out White");
+ return true;
+ }
+
+ public void onBar1Changed(int progress) {
+ mSaturation = (float)progress / 50.0f;
+ setSaturation();
+ }
+ public void onBar2Changed(int progress) {
+ mInBlack = (float)progress;
+ setLevels();
+ }
+ public void onBar3Changed(int progress) {
+ mOutBlack = (float)progress;
+ setLevels();
+ }
+ public void onBar4Changed(int progress) {
+ mInWhite = (float)progress + 127.0f;
+ setLevels();
+ }
+ public void onBar5Changed(int progress) {
+ mOutWhite = (float)progress + 127.0f;
+ setLevels();
+ }
+
+ public void createTest(android.content.res.Resources res) {
+ mScriptR = new ScriptC_levels_relaxed(mRS, res, R.raw.levels_relaxed);
+ mScriptF = new ScriptC_levels_full(mRS, res, R.raw.levels_full);
+ setSaturation();
+ setLevels();
+ }
+
+ public void runTest() {
+ if (mUseFull) {
+ if (mUseV4) {
+ mScriptF.forEach_root4(mInPixelsAllocation, mOutPixelsAllocation);
+ } else {
+ mScriptF.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
+ }
+ } else {
+ if (mUseV4) {
+ mScriptR.forEach_root4(mInPixelsAllocation, mOutPixelsAllocation);
+ } else {
+ mScriptR.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
+ }
+ }
+ }
+
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/TestBase.java b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/TestBase.java
new file mode 100644
index 0000000..35170af
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/TestBase.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image2;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.support.v8.renderscript.*;
+import android.view.SurfaceView;
+import android.view.SurfaceHolder;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.view.View;
+import android.util.Log;
+import java.lang.Math;
+
+public class TestBase {
+ protected final String TAG = "Img";
+
+ protected RenderScript mRS;
+ protected Allocation mInPixelsAllocation;
+ protected Allocation mOutPixelsAllocation;
+
+ // Override to use UI elements
+ public void onBar1Changed(int progress) {
+ }
+ public void onBar2Changed(int progress) {
+ }
+ public void onBar3Changed(int progress) {
+ }
+ public void onBar4Changed(int progress) {
+ }
+ public void onBar5Changed(int progress) {
+ }
+
+ // Override to use UI elements
+ // Unused bars will be hidden.
+ public boolean onBar1Setup(SeekBar b, TextView t) {
+ b.setVisibility(View.INVISIBLE);
+ t.setVisibility(View.INVISIBLE);
+ return false;
+ }
+ public boolean onBar2Setup(SeekBar b, TextView t) {
+ b.setVisibility(View.INVISIBLE);
+ t.setVisibility(View.INVISIBLE);
+ return false;
+ }
+ public boolean onBar3Setup(SeekBar b, TextView t) {
+ b.setVisibility(View.INVISIBLE);
+ t.setVisibility(View.INVISIBLE);
+ return false;
+ }
+ public boolean onBar4Setup(SeekBar b, TextView t) {
+ b.setVisibility(View.INVISIBLE);
+ t.setVisibility(View.INVISIBLE);
+ return false;
+ }
+ public boolean onBar5Setup(SeekBar b, TextView t) {
+ b.setVisibility(View.INVISIBLE);
+ t.setVisibility(View.INVISIBLE);
+ return false;
+ }
+
+ public final void createBaseTest(ImageProcessingActivity2 act, Bitmap b) {
+ mRS = RenderScript.create(act);
+ mInPixelsAllocation = Allocation.createFromBitmap(mRS, b,
+ Allocation.MipmapControl.MIPMAP_NONE,
+ Allocation.USAGE_SCRIPT);
+ mOutPixelsAllocation = Allocation.createFromBitmap(mRS, b,
+ Allocation.MipmapControl.MIPMAP_NONE,
+ Allocation.USAGE_SCRIPT);
+ createTest(act.getResources());
+ }
+
+ // Must override
+ public void createTest(android.content.res.Resources res) {
+ android.util.Log.e("img", "implement createTest");
+ }
+
+ // Must override
+ public void runTest() {
+ }
+
+ public void finish() {
+ mRS.finish();
+ }
+
+ public void updateBitmap(Bitmap b) {
+ mOutPixelsAllocation.copyTo(b);
+ }
+
+ // Override to configure specific benchmark config.
+ public void setupBenchmark() {
+ }
+
+ // Override to reset after benchmark.
+ public void exitBenchmark() {
+ }
+}
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Vignette.java b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Vignette.java
new file mode 100644
index 0000000..fc69eba
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/Vignette.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image2;
+
+import android.support.v8.renderscript.*;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+public class Vignette extends TestBase {
+ private ScriptC_vignette_full mScript_full = null;
+ private ScriptC_vignette_relaxed mScript_relaxed = null;
+ private final boolean relaxed;
+ private float center_x = 0.5f;
+ private float center_y = 0.5f;
+ private float scale = 0.5f;
+ private float shade = 0.5f;
+ private float slope = 20.0f;
+
+ public Vignette(boolean relaxed) {
+ this.relaxed = relaxed;
+ }
+
+ public boolean onBar1Setup(SeekBar b, TextView t) {
+ t.setText("Scale");
+ b.setMax(100);
+ b.setProgress(25);
+ return true;
+ }
+ public boolean onBar2Setup(SeekBar b, TextView t) {
+ t.setText("Shade");
+ b.setMax(100);
+ b.setProgress(50);
+ return true;
+ }
+ public boolean onBar3Setup(SeekBar b, TextView t) {
+ t.setText("Slope");
+ b.setMax(100);
+ b.setProgress(20);
+ return true;
+ }
+ public boolean onBar4Setup(SeekBar b, TextView t) {
+ t.setText("Shift center X");
+ b.setMax(100);
+ b.setProgress(50);
+ return true;
+ }
+ public boolean onBar5Setup(SeekBar b, TextView t) {
+ t.setText("Shift center Y");
+ b.setMax(100);
+ b.setProgress(50);
+ return true;
+ }
+
+ public void onBar1Changed(int progress) {
+ scale = progress / 50.0f;
+ do_init();
+ }
+ public void onBar2Changed(int progress) {
+ shade = progress / 100.0f;
+ do_init();
+ }
+ public void onBar3Changed(int progress) {
+ slope = (float)progress;
+ do_init();
+ }
+ public void onBar4Changed(int progress) {
+ center_x = progress / 100.0f;
+ do_init();
+ }
+ public void onBar5Changed(int progress) {
+ center_y = progress / 100.0f;
+ do_init();
+ }
+
+ private void do_init() {
+ if (relaxed)
+ mScript_relaxed.invoke_init_vignette(
+ mInPixelsAllocation.getType().getX(),
+ mInPixelsAllocation.getType().getY(), center_x, center_y,
+ scale, shade, slope);
+ else
+ mScript_full.invoke_init_vignette(
+ mInPixelsAllocation.getType().getX(),
+ mInPixelsAllocation.getType().getY(), center_x, center_y,
+ scale, shade, slope);
+ }
+
+ public void createTest(android.content.res.Resources res) {
+ if (relaxed) {
+ mScript_relaxed = new ScriptC_vignette_relaxed(mRS, res,
+ R.raw.vignette_relaxed);
+ } else {
+ mScript_full = new ScriptC_vignette_full(mRS, res,
+ R.raw.vignette_full);
+ }
+ do_init();
+ }
+
+ public void runTest() {
+ if (relaxed)
+ mScript_relaxed.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
+ else
+ mScript_full.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
+ }
+
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/colormatrix.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/colormatrix.rs
new file mode 100644
index 0000000..e93bef3
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/colormatrix.rs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+#pragma rs_fp_relaxed
+
+
+static rs_matrix4x4 Mat;
+
+void init() {
+ rsMatrixLoadIdentity(&Mat);
+}
+
+void setMatrix(rs_matrix4x4 m) {
+ Mat = m;
+}
+
+void root(const uchar4 *in, uchar4 *out) {
+ float4 f = convert_float4(*in);
+ f = rsMatrixMultiply(&Mat, f);
+ f = clamp(f, 0.f, 255.f);
+ *out = convert_uchar4(f);
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/convolve3x3.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/convolve3x3.rs
new file mode 100644
index 0000000..b55190c
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/convolve3x3.rs
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+#pragma rs_fp_relaxed
+
+int32_t gWidth;
+int32_t gHeight;
+rs_allocation gIn;
+
+float gCoeffs[9];
+
+void root(uchar4 *out, uint32_t x, uint32_t y) {
+ uint32_t x1 = min((int32_t)x+1, gWidth);
+ uint32_t x2 = max((int32_t)x-1, 0);
+ uint32_t y1 = min((int32_t)y+1, gHeight);
+ uint32_t y2 = max((int32_t)y-1, 0);
+
+ float4 p00 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y1))[0]);
+ float4 p01 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x, y1))[0]);
+ float4 p02 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y1))[0]);
+ float4 p10 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y))[0]);
+ float4 p11 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x, y))[0]);
+ float4 p12 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y))[0]);
+ float4 p20 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y2))[0]);
+ float4 p21 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x, y2))[0]);
+ float4 p22 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y2))[0]);
+ p00 *= gCoeffs[0];
+ p01 *= gCoeffs[1];
+ p02 *= gCoeffs[2];
+ p10 *= gCoeffs[3];
+ p11 *= gCoeffs[4];
+ p12 *= gCoeffs[5];
+ p20 *= gCoeffs[6];
+ p21 *= gCoeffs[7];
+ p22 *= gCoeffs[8];
+
+ p00 += p01;
+ p02 += p10;
+ p11 += p12;
+ p20 += p21;
+
+ p22 += p00;
+ p02 += p11;
+
+ p20 += p22;
+ p20 += p02;
+
+ p20 = clamp(p20, 0.f, 255.f);
+ *out = convert_uchar4(p20);
+}
+
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/fisheye.rsh b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/fisheye.rsh
new file mode 100644
index 0000000..4dcfc1d
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/fisheye.rsh
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+rs_allocation in_alloc;
+rs_sampler sampler;
+
+static float2 center, dimensions;
+static float2 scale;
+static float alpha;
+static float radius2;
+static float factor;
+
+void init_filter(uint32_t dim_x, uint32_t dim_y, float focus_x, float focus_y, float k) {
+ center.x = focus_x;
+ center.y = focus_y;
+ dimensions.x = (float)dim_x;
+ dimensions.y = (float)dim_y;
+
+ alpha = k * 2.0 + 0.75;
+ float bound2 = 0.25;
+ if (dim_x > dim_y) {
+ scale.x = 1.0;
+ scale.y = dimensions.y / dimensions.x;
+ bound2 *= (scale.y*scale.y + 1);
+ } else {
+ scale.x = dimensions.x / dimensions.y;
+ scale.y = 1.0;
+ bound2 *= (scale.x*scale.x + 1);
+ }
+ const float bound = sqrt(bound2);
+ const float radius = 1.15 * bound;
+ radius2 = radius*radius;
+ const float max_radian = 0.5f * M_PI - atan(alpha / bound * sqrt(radius2 - bound2));
+ factor = bound / max_radian;
+}
+
+void root(uchar4 *out, uint32_t x, uint32_t y) {
+ // Convert x and y to floating point coordinates with center as origin
+ float2 coord;
+ coord.x = (float)x / dimensions.x;
+ coord.y = (float)y / dimensions.y;
+ coord -= center;
+ const float dist = length(scale * coord);
+ const float radian = M_PI_2 - atan((alpha * sqrt(radius2 - dist * dist)) / dist);
+ const float scalar = radian * factor / dist;
+ const float2 new_coord = coord * scalar + center;
+ const float4 fout = rsSample(in_alloc, sampler, new_coord);
+ *out = rsPackColorTo8888(fout);
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/fisheye_full.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/fisheye_full.rs
new file mode 100644
index 0000000..e42df13
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/fisheye_full.rs
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+
+#include "fisheye.rsh"
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/fisheye_relaxed.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/fisheye_relaxed.rs
new file mode 100644
index 0000000..990310b
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/fisheye_relaxed.rs
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+#pragma rs_fp_relaxed
+
+#include "fisheye.rsh"
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/grain.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/grain.rs
new file mode 100644
index 0000000..75f4021
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/grain.rs
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+#pragma rs_fp_relaxed
+
+void genRand(uchar *out) {
+ *out = (uchar)rsRand(0xff);
+}
+
+/*
+ * Convolution matrix of distance 2 with fixed point of 'kShiftBits' bits
+ * shifted. Thus the sum of this matrix should be 'kShiftValue'. Entries of
+ * small values are not calculated to gain efficiency.
+ * The order ot pixels represented in this matrix is:
+ * 1 2 3
+ * 4 0 5
+ * 6 7 8
+ * and the matrix should be: {230, 56, 114, 56, 114, 114, 56, 114, 56}.
+ * However, since most of the valus are identical, we only use the first three
+ * entries and the entries corresponding to the pixels is:
+ * 1 2 1
+ * 2 0 2
+ * 1 2 1
+ */
+
+int32_t gWidth;
+int32_t gHeight;
+
+rs_allocation gBlendSource;
+void blend9(uchar *out, uint32_t x, uint32_t y) {
+ uint32_t x1 = min(x+1, (uint32_t)gWidth);
+ uint32_t x2 = max(x-1, (uint32_t)0);
+ uint32_t y1 = min(y+1, (uint32_t)gHeight);
+ uint32_t y2 = max(y-1, (uint32_t)0);
+
+ uint p00 = 56 * ((uchar *)rsGetElementAt(gBlendSource, x1, y1))[0];
+ uint p01 = 114 * ((uchar *)rsGetElementAt(gBlendSource, x, y1))[0];
+ uint p02 = 56 * ((uchar *)rsGetElementAt(gBlendSource, x2, y1))[0];
+ uint p10 = 114 * ((uchar *)rsGetElementAt(gBlendSource, x1, y))[0];
+ uint p11 = 230 * ((uchar *)rsGetElementAt(gBlendSource, x, y))[0];
+ uint p12 = 114 * ((uchar *)rsGetElementAt(gBlendSource, x2, y))[0];
+ uint p20 = 56 * ((uchar *)rsGetElementAt(gBlendSource, x1, y2))[0];
+ uint p21 = 114 * ((uchar *)rsGetElementAt(gBlendSource, x, y2))[0];
+ uint p22 = 56 * ((uchar *)rsGetElementAt(gBlendSource, x2, y2))[0];
+
+ p00 += p01;
+ p02 += p10;
+ p11 += p12;
+ p20 += p21;
+
+ p22 += p00;
+ p02 += p11;
+
+ p20 += p22;
+ p20 += p02;
+
+ *out = (uchar)(p20 >> 10);
+}
+
+float gNoiseStrength;
+
+rs_allocation gNoise;
+void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
+ float4 ip = convert_float4(*in);
+ float pnoise = (float) ((uchar *)rsGetElementAt(gNoise, x, y))[0];
+
+ float energy_level = ip.r + ip.g + ip.b;
+ float energy_mask = (28.f - sqrt(energy_level)) * 0.03571f;
+ pnoise = (pnoise - 128.f) * energy_mask;
+
+ ip += pnoise * gNoiseStrength;
+ ip = clamp(ip, 0.f, 255.f);
+
+ uchar4 p = convert_uchar4(ip);
+ p.a = 0xff;
+ *out = p;
+}
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/greyscale.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/greyscale.rs
new file mode 100644
index 0000000..b5abf3f0
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/greyscale.rs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+#pragma rs_fp_relaxed
+
+const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
+
+void root(const uchar4 *v_in, uchar4 *v_out) {
+ float4 f4 = rsUnpackColor8888(*v_in);
+
+ float3 mono = dot(f4.rgb, gMonoMult);
+ *v_out = rsPackColorTo8888(mono);
+}
+
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/horizontal_blur.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/horizontal_blur.rs
new file mode 100644
index 0000000..ee83496
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/horizontal_blur.rs
@@ -0,0 +1,28 @@
+#pragma version(1)
+#pragma rs_fp_relaxed
+
+#include "ip.rsh"
+
+void root(float4 *out, const void *usrData, uint32_t x, uint32_t y) {
+ const FilterStruct *fs = (const FilterStruct *)usrData;
+ float3 blurredPixel = 0;
+ const float *gPtr = fs->gaussian;
+ if ((x > fs->radius) && (x < (fs->width - fs->radius))) {
+ for (int r = -fs->radius; r <= fs->radius; r ++) {
+ const float4 *i = (const float4 *)rsGetElementAt(fs->ain, x + r, y);
+ blurredPixel += i->xyz * gPtr[0];
+ gPtr++;
+ }
+ } else {
+ for (int r = -fs->radius; r <= fs->radius; r ++) {
+ // Stepping left and right away from the pixel
+ int validX = rsClamp((int)x + r, (int)0, (int)(fs->width - 1));
+ const float4 *i = (const float4 *)rsGetElementAt(fs->ain, validX, y);
+ blurredPixel += i->xyz * gPtr[0];
+ gPtr++;
+ }
+ }
+
+ out->xyz = blurredPixel;
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/ip.rsh b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/ip.rsh
new file mode 100644
index 0000000..0cdf9e1
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/ip.rsh
@@ -0,0 +1,15 @@
+#pragma rs java_package_name(com.android.rs.image2)
+
+#define MAX_RADIUS 25
+
+typedef struct FilterStruct_s {
+ rs_allocation ain;
+
+ float *gaussian; //[MAX_RADIUS * 2 + 1];
+ int height;
+ int width;
+ int radius;
+
+} FilterStruct;
+
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/levels.rsh b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/levels.rsh
new file mode 100644
index 0000000..7c5d930
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/levels.rsh
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+float inBlack;
+float outBlack;
+float inWMinInB;
+float outWMinOutB;
+float overInWMinInB;
+rs_matrix3x3 colorMat;
+
+void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
+ float3 pixel = convert_float4(in[0]).rgb;
+ pixel = rsMatrixMultiply(&colorMat, pixel);
+ pixel = clamp(pixel, 0.f, 255.f);
+ pixel = (pixel - inBlack) * overInWMinInB;
+ pixel = pixel * outWMinOutB + outBlack;
+ pixel = clamp(pixel, 0.f, 255.f);
+ out->xyz = convert_uchar3(pixel);
+ out->w = 0xff;
+}
+
+void root4(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
+ float4 pixel = convert_float4(in[0]);
+ pixel.rgb = rsMatrixMultiply(&colorMat, pixel.rgb);
+ pixel = clamp(pixel, 0.f, 255.f);
+ pixel = (pixel - inBlack) * overInWMinInB;
+ pixel = pixel * outWMinOutB + outBlack;
+ pixel = clamp(pixel, 0.f, 255.f);
+ out->xyzw = convert_uchar4(pixel);
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/levels_full.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/levels_full.rs
new file mode 100644
index 0000000..a4aa388
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/levels_full.rs
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+
+#include "levels.rsh"
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/levels_relaxed.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/levels_relaxed.rs
new file mode 100644
index 0000000..ffdcfe3
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/levels_relaxed.rs
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+#pragma rs_fp_relaxed
+
+#include "levels.rsh"
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/threshold.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/threshold.rs
new file mode 100644
index 0000000..77cd5be
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/threshold.rs
@@ -0,0 +1,93 @@
+#pragma version(1)
+
+#include "ip.rsh"
+
+int height;
+int width;
+int radius;
+
+uchar4 * InPixel;
+uchar4 * OutPixel;
+float4 * ScratchPixel1;
+float4 * ScratchPixel2;
+
+rs_script vBlurScript;
+rs_script hBlurScript;
+
+const int CMD_FINISHED = 1;
+
+// Store our coefficients here
+static float gaussian[MAX_RADIUS * 2 + 1];
+
+
+static void computeGaussianWeights() {
+ // Compute gaussian weights for the blur
+ // e is the euler's number
+ float e = 2.718281828459045f;
+ float pi = 3.1415926535897932f;
+ // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 )
+ // x is of the form [-radius .. 0 .. radius]
+ // and sigma varies with radius.
+ // Based on some experimental radius values and sigma's
+ // we approximately fit sigma = f(radius) as
+ // sigma = radius * 0.4 + 0.6
+ // The larger the radius gets, the more our gaussian blur
+ // will resemble a box blur since with large sigma
+ // the gaussian curve begins to lose its shape
+ float sigma = 0.4f * (float)radius + 0.6f;
+
+ // Now compute the coefficints
+ // We will store some redundant values to save some math during
+ // the blur calculations
+ // precompute some values
+ float coeff1 = 1.0f / (sqrt( 2.0f * pi ) * sigma);
+ float coeff2 = - 1.0f / (2.0f * sigma * sigma);
+
+ float normalizeFactor = 0.0f;
+ float floatR = 0.0f;
+ int r;
+ for (r = -radius; r <= radius; r ++) {
+ floatR = (float)r;
+ gaussian[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2);
+ normalizeFactor += gaussian[r + radius];
+ }
+
+ //Now we need to normalize the weights because all our coefficients need to add up to one
+ normalizeFactor = 1.0f / normalizeFactor;
+ for (r = -radius; r <= radius; r ++) {
+ floatR = (float)r;
+ gaussian[r + radius] *= normalizeFactor;
+ }
+}
+
+
+static void copyInput() {
+ rs_allocation ain;
+ ain = rsGetAllocation(InPixel);
+ uint32_t dimx = rsAllocationGetDimX(ain);
+ uint32_t dimy = rsAllocationGetDimY(ain);
+ for (uint32_t y = 0; y < dimy; y++) {
+ for (uint32_t x = 0; x < dimx; x++) {
+ ScratchPixel1[x + y * dimx] = convert_float4(InPixel[x + y * dimx]);
+ }
+ }
+}
+
+void filter() {
+ copyInput();
+ computeGaussianWeights();
+
+ FilterStruct fs;
+ fs.gaussian = gaussian;
+ fs.width = width;
+ fs.height = height;
+ fs.radius = radius;
+
+ fs.ain = rsGetAllocation(ScratchPixel1);
+ rsForEach(hBlurScript, fs.ain, rsGetAllocation(ScratchPixel2), &fs, sizeof(fs));
+
+ fs.ain = rsGetAllocation(ScratchPixel2);
+ rsForEach(vBlurScript, fs.ain, rsGetAllocation(OutPixel), &fs, sizeof(fs));
+ //rsSendToClientBlocking(CMD_FINISHED);
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vertical_blur.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vertical_blur.rs
new file mode 100644
index 0000000..60fd71b
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vertical_blur.rs
@@ -0,0 +1,59 @@
+#pragma version(1)
+#pragma rs_fp_relaxed
+
+#include "ip.rsh"
+
+static float saturation;
+static rs_matrix3x3 colorMat;
+
+void setSaturation(float sat) {
+ saturation = sat;
+
+ // Saturation
+ // Linear weights
+ //float rWeight = 0.3086f;
+ //float gWeight = 0.6094f;
+ //float bWeight = 0.0820f;
+
+ // Gamma 2.2 weights (we haven't converted our image to linear space yet for perf reasons)
+ float rWeight = 0.299f;
+ float gWeight = 0.587f;
+ float bWeight = 0.114f;
+
+ float oneMinusS = 1.0f - saturation;
+ rsMatrixSet(&colorMat, 0, 0, oneMinusS * rWeight + saturation);
+ rsMatrixSet(&colorMat, 0, 1, oneMinusS * rWeight);
+ rsMatrixSet(&colorMat, 0, 2, oneMinusS * rWeight);
+ rsMatrixSet(&colorMat, 1, 0, oneMinusS * gWeight);
+ rsMatrixSet(&colorMat, 1, 1, oneMinusS * gWeight + saturation);
+ rsMatrixSet(&colorMat, 1, 2, oneMinusS * gWeight);
+ rsMatrixSet(&colorMat, 2, 0, oneMinusS * bWeight);
+ rsMatrixSet(&colorMat, 2, 1, oneMinusS * bWeight);
+ rsMatrixSet(&colorMat, 2, 2, oneMinusS * bWeight + saturation);
+}
+
+void root(uchar4 *out, const void *usrData, uint32_t x, uint32_t y) {
+ const FilterStruct *fs = (const FilterStruct *)usrData;
+ float3 blurredPixel = 0;
+ const float *gPtr = fs->gaussian;
+ if ((y > fs->radius) && (y < (fs->height - fs->radius))) {
+ for (int r = -fs->radius; r <= fs->radius; r ++) {
+ const float4 *i = (const float4 *)rsGetElementAt(fs->ain, x, y + r);
+ blurredPixel += i->xyz * gPtr[0];
+ gPtr++;
+ }
+ } else {
+ for (int r = -fs->radius; r <= fs->radius; r ++) {
+ int validH = rsClamp((int)y + r, (int)0, (int)(fs->height - 1));
+ const float4 *i = (const float4 *)rsGetElementAt(fs->ain, x, validH);
+ blurredPixel += i->xyz * gPtr[0];
+ gPtr++;
+ }
+ }
+
+ float3 temp = rsMatrixMultiply(&colorMat, blurredPixel);
+ temp = clamp(temp, 0.f, 255.f);
+ out->xyz = convert_uchar3(temp);
+ out->w = 0xff;
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vignette.rsh b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vignette.rsh
new file mode 100644
index 0000000..a1e4ae5
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vignette.rsh
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+static float2 neg_center, axis_scale, inv_dimensions;
+static float sloped_neg_range, sloped_inv_max_dist, shade, opp_shade;
+
+void init_vignette(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y,
+ float desired_scale, float desired_shade, float desired_slope) {
+
+ neg_center.x = -center_x;
+ neg_center.y = -center_y;
+ inv_dimensions.x = 1.f / (float)dim_x;
+ inv_dimensions.y = 1.f / (float)dim_y;
+
+ axis_scale = (float2)1.f;
+ if (dim_x > dim_y)
+ axis_scale.y = (float)dim_y / (float)dim_x;
+ else
+ axis_scale.x = (float)dim_x / (float)dim_y;
+
+ const float max_dist = 0.5 * length(axis_scale);
+ sloped_inv_max_dist = desired_slope * 1.f/max_dist;
+
+ // Range needs to be between 1.3 to 0.6. When scale is zero then range is
+ // 1.3 which means no vignette at all because the luminousity difference is
+ // less than 1/256. Expect input scale to be between 0.0 and 1.0.
+ const float neg_range = 0.7*sqrt(desired_scale) - 1.3;
+ sloped_neg_range = exp(neg_range * desired_slope);
+
+ shade = desired_shade;
+ opp_shade = 1.f - desired_shade;
+}
+
+void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
+ // Convert x and y to floating point coordinates with center as origin
+ const float4 fin = convert_float4(*in);
+ const float2 inCoord = {(float)x, (float)y};
+ const float2 coord = mad(inCoord, inv_dimensions, neg_center);
+ const float sloped_dist_ratio = length(axis_scale * coord) * sloped_inv_max_dist;
+ const float lumen = opp_shade + shade / ( 1.0 + sloped_neg_range * exp(sloped_dist_ratio) );
+ float4 fout;
+ fout.rgb = fin.rgb * lumen;
+ fout.w = fin.w;
+ *out = convert_uchar4(fout);
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vignette_full.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vignette_full.rs
new file mode 100644
index 0000000..5fc2dda
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vignette_full.rs
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+
+#include "vignette.rsh"
+
diff --git a/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vignette_relaxed.rs b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vignette_relaxed.rs
new file mode 100644
index 0000000..430b685
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing2/src/com/android/rs/image/vignette_relaxed.rs
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image2)
+#pragma rs_fp_relaxed
+
+#include "vignette.rsh"
+
diff --git a/wifi/java/android/net/wifi/RssiPacketCountInfo.java b/wifi/java/android/net/wifi/RssiPacketCountInfo.java
new file mode 100644
index 0000000..f549e1d
--- /dev/null
+++ b/wifi/java/android/net/wifi/RssiPacketCountInfo.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2012 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.net.wifi;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Bundle of RSSI and packet count information, for WiFi watchdog
+ *
+ * @see WifiWatchdogStateMachine
+ *
+ * @hide
+ */
+public class RssiPacketCountInfo implements Parcelable {
+
+ public int rssi;
+
+ public int txgood;
+
+ public int txbad;
+
+ public RssiPacketCountInfo() {
+ rssi = txgood = txbad = 0;
+ }
+
+ private RssiPacketCountInfo(Parcel in) {
+ rssi = in.readInt();
+ txgood = in.readInt();
+ txbad = in.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(rssi);
+ out.writeInt(txgood);
+ out.writeInt(txbad);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Parcelable.Creator<RssiPacketCountInfo> CREATOR =
+ new Parcelable.Creator<RssiPacketCountInfo>() {
+ @Override
+ public RssiPacketCountInfo createFromParcel(Parcel in) {
+ return new RssiPacketCountInfo(in);
+ }
+
+ @Override
+ public RssiPacketCountInfo[] newArray(int size) {
+ return new RssiPacketCountInfo[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 6e58a2d..3579b86 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -906,6 +906,17 @@
}
/**
+ * Return TX packet counter, for CTS test of WiFi watchdog.
+ * @param listener is the interface to receive result
+ *
+ * @hide for CTS test only
+ */
+ public void getTxPacketCount(TxPacketCountListener listener) {
+ validateChannel();
+ mAsyncChannel.sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener));
+ }
+
+ /**
* Calculates the level of the signal. This should be used any time a signal
* is being shown.
*
@@ -1143,11 +1154,18 @@
/** @hide */
public static final int DISABLE_NETWORK_SUCCEEDED = BASE + 19;
+ /** @hide */
+ public static final int RSSI_PKTCNT_FETCH = BASE + 20;
+ /** @hide */
+ public static final int RSSI_PKTCNT_FETCH_SUCCEEDED = BASE + 21;
+ /** @hide */
+ public static final int RSSI_PKTCNT_FETCH_FAILED = BASE + 22;
+
/* For system use only */
/** @hide */
- public static final int ENABLE_TRAFFIC_STATS_POLL = BASE + 21;
+ public static final int ENABLE_TRAFFIC_STATS_POLL = BASE + 31;
/** @hide */
- public static final int TRAFFIC_STATS_POLL = BASE + 22;
+ public static final int TRAFFIC_STATS_POLL = BASE + 32;
/**
@@ -1212,6 +1230,21 @@
public void onFailure(int reason);
}
+ /** Interface for callback invocation on a TX packet count poll action {@hide} */
+ public interface TxPacketCountListener {
+ /**
+ * The operation succeeded
+ * @param count TX packet counter
+ */
+ public void onSuccess(int count);
+ /**
+ * The operation failed
+ * @param reason The reason for failure could be one of
+ * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY}
+ */
+ public void onFailure(int reason);
+ }
+
private class ServiceHandler extends Handler {
ServiceHandler(Looper looper) {
super(looper);
@@ -1281,6 +1314,20 @@
((WpsListener) listener).onFailure(message.arg1);
}
break;
+ case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
+ if (listener != null) {
+ RssiPacketCountInfo info = (RssiPacketCountInfo) message.obj;
+ if (info != null)
+ ((TxPacketCountListener) listener).onSuccess(info.txgood + info.txbad);
+ else
+ ((TxPacketCountListener) listener).onFailure(ERROR);
+ }
+ break;
+ case WifiManager.RSSI_PKTCNT_FETCH_FAILED:
+ if (listener != null) {
+ ((TxPacketCountListener) listener).onFailure(message.arg1);
+ }
+ break;
default:
//ignore
break;
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 28c1c5c..6abca65 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -52,7 +52,7 @@
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkUtils;
-import android.net.wifi.WifiWatchdogStateMachine.RssiPktcntStat;
+import android.net.wifi.RssiPacketCountInfo;
import android.net.wifi.WpsResult.Status;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pService;
@@ -1189,7 +1189,7 @@
case CMD_RSSI_POLL:
case CMD_DELAYED_STOP_DRIVER:
case WifiMonitor.SCAN_RESULTS_EVENT:
- case WifiWatchdogStateMachine.RSSI_PKTCNT_FETCH:
+ case WifiManager.RSSI_PKTCNT_FETCH:
return false;
default:
return true;
@@ -1543,7 +1543,7 @@
/*
* Fetch TX packet counters on current connection
*/
- private void fetchPktcntNative(RssiPktcntStat stat) {
+ private void fetchPktcntNative(RssiPacketCountInfo info) {
String pktcntPoll = mWifiNative.pktcntPoll();
if (pktcntPoll != null) {
@@ -1553,9 +1553,9 @@
if (prop.length < 2) continue;
try {
if (prop[0].equals("TXGOOD")) {
- stat.txgood = Integer.parseInt(prop[1]);
+ info.txgood = Integer.parseInt(prop[1]);
} else if (prop[0].equals("TXBAD")) {
- stat.txbad = Integer.parseInt(prop[1]);
+ info.txbad = Integer.parseInt(prop[1]);
}
} catch (NumberFormatException e) {
//Ignore
@@ -1972,8 +1972,9 @@
replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
WifiManager.BUSY);
break;
- case WifiWatchdogStateMachine.RSSI_PKTCNT_FETCH:
- replyToMessage(message, WifiWatchdogStateMachine.RSSI_PKTCNT_FETCH_FAILED);
+ case WifiManager.RSSI_PKTCNT_FETCH:
+ replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_FAILED,
+ WifiManager.BUSY);
break;
default:
loge("Error! unhandled message" + message);
@@ -3176,13 +3177,12 @@
mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
}
break;
- case WifiWatchdogStateMachine.RSSI_PKTCNT_FETCH:
- RssiPktcntStat stat = (RssiPktcntStat) message.obj;
+ case WifiManager.RSSI_PKTCNT_FETCH:
+ RssiPacketCountInfo info = new RssiPacketCountInfo();
fetchRssiAndLinkSpeedNative();
- stat.rssi = mWifiInfo.getRssi();
- fetchPktcntNative(stat);
- replyToMessage(message, WifiWatchdogStateMachine.RSSI_PKTCNT_FETCH_SUCCEEDED,
- stat);
+ info.rssi = mWifiInfo.getRssi();
+ fetchPktcntNative(info);
+ replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED, info);
break;
default:
return NOT_HANDLED;
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index 7b4d113..29a53b6 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -30,6 +30,7 @@
import android.net.LinkProperties;
import android.net.NetworkInfo;
import android.net.Uri;
+import android.net.wifi.RssiPacketCountInfo;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings;
@@ -105,9 +106,6 @@
/* Notifications from/to WifiStateMachine */
static final int POOR_LINK_DETECTED = BASE + 21;
static final int GOOD_LINK_DETECTED = BASE + 22;
- static final int RSSI_PKTCNT_FETCH = BASE + 23;
- static final int RSSI_PKTCNT_FETCH_SUCCEEDED = BASE + 24;
- static final int RSSI_PKTCNT_FETCH_FAILED = BASE + 25;
/*
* RSSI levels as used by notification icon
@@ -123,7 +121,7 @@
* <p>
* Larger threshold is more adaptive but increases sampling cost.
*/
- private static final int LINK_MONITOR_LEVEL_THRESHOLD = 4;
+ private static final int LINK_MONITOR_LEVEL_THRESHOLD = WifiManager.RSSI_LEVELS - 1;
/**
* Remember packet loss statistics of how many BSSIDs.
@@ -228,8 +226,8 @@
* Adaptive good link target to avoid flapping.
* When a poor link is detected, a good link target is calculated as follows:
* <p>
- * targetRSSI = min{ rssi | loss(rssi) < GOOD_LINK_LOSS_THRESHOLD } + rssi_adj[i],
- * where rssi is in the above GOOD_LINK_RSSI_RANGE.
+ * targetRSSI = min { rssi | loss(rssi) < GOOD_LINK_LOSS_THRESHOLD } + rssi_adj[i],
+ * where rssi is within the above GOOD_LINK_RSSI_RANGE.
* targetCount = sample_count[i] .
* <p>
* While WiFi is being avoided, we keep monitoring its signal strength.
@@ -241,7 +239,7 @@
* <p>
* Intuitively, larger index i makes it more difficult to get back to WiFi, avoiding flapping.
* In experiments, (+9 dB / 30 counts) makes it quite difficult to achieve.
- * Avoid using it unless flapping is really bad (say, last poor link is only 1min ago).
+ * Avoid using it unless flapping is really bad (say, last poor link is < 1 min ago).
*/
private static final GoodLinkTarget[] GOOD_LINK_TARGET = {
/* rssi_adj, sample_count, reduce_time */
@@ -591,8 +589,8 @@
case EVENT_BSSID_CHANGE:
case CMD_DELAYED_WALLED_GARDEN_CHECK:
case CMD_RSSI_FETCH:
- case RSSI_PKTCNT_FETCH_SUCCEEDED:
- case RSSI_PKTCNT_FETCH_FAILED:
+ case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
+ case WifiManager.RSSI_PKTCNT_FETCH_FAILED:
// ignore
break;
case EVENT_SCREEN_ON:
@@ -764,15 +762,15 @@
case CMD_RSSI_FETCH:
if (msg.arg1 == mRssiFetchToken) {
- mWsmChannel.sendMessage(RSSI_PKTCNT_FETCH, new RssiPktcntStat());
+ mWsmChannel.sendMessage(WifiManager.RSSI_PKTCNT_FETCH);
sendMessageDelayed(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0),
LINK_SAMPLING_INTERVAL_MS);
}
break;
- case RSSI_PKTCNT_FETCH_SUCCEEDED:
- RssiPktcntStat stat = (RssiPktcntStat) msg.obj;
- int rssi = stat.rssi;
+ case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
+ RssiPacketCountInfo info = (RssiPacketCountInfo) msg.obj;
+ int rssi = info.rssi;
if (DBG) logd("Fetch RSSI succeed, rssi=" + rssi);
long time = mCurrentBssid.mBssidAvoidTimeMax - SystemClock.elapsedRealtime();
@@ -795,7 +793,7 @@
}
break;
- case RSSI_PKTCNT_FETCH_FAILED:
+ case WifiManager.RSSI_PKTCNT_FETCH_FAILED:
if (DBG) logd("RSSI_FETCH_FAILED");
break;
@@ -944,18 +942,18 @@
if (!mIsScreenOn) {
transitionTo(mOnlineState);
} else if (msg.arg1 == mRssiFetchToken) {
- mWsmChannel.sendMessage(RSSI_PKTCNT_FETCH, new RssiPktcntStat());
+ mWsmChannel.sendMessage(WifiManager.RSSI_PKTCNT_FETCH);
sendMessageDelayed(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0),
LINK_SAMPLING_INTERVAL_MS);
}
break;
- case RSSI_PKTCNT_FETCH_SUCCEEDED:
- RssiPktcntStat stat = (RssiPktcntStat) msg.obj;
- int rssi = stat.rssi;
+ case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
+ RssiPacketCountInfo info = (RssiPacketCountInfo) msg.obj;
+ int rssi = info.rssi;
int mrssi = (mLastRssi + rssi) / 2;
- int txbad = stat.txbad;
- int txgood = stat.txgood;
+ int txbad = info.txbad;
+ int txgood = info.txgood;
if (DBG) logd("Fetch RSSI succeed, rssi=" + rssi + " mrssi=" + mrssi + " txbad="
+ txbad + " txgood=" + txgood);
@@ -1003,7 +1001,7 @@
mLastRssi = rssi;
break;
- case RSSI_PKTCNT_FETCH_FAILED:
+ case WifiManager.RSSI_PKTCNT_FETCH_FAILED:
// can happen if we are waiting to get a disconnect notification
if (DBG) logd("RSSI_FETCH_FAILED");
break;
@@ -1159,15 +1157,6 @@
}
/**
- * Bundle of RSSI and packet count information
- */
- public class RssiPktcntStat {
- public int rssi;
- public int txgood;
- public int txbad;
- }
-
- /**
* Bundle of good link count parameters
*/
private static class GoodLinkTarget {