Merge "Make mirroring automatic based on Windows on display." into jb-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 7ad9cad..b89f2f4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6327,6 +6327,7 @@
field public static final int FLAG_FACTORY_TEST = 16; // 0x10
field public static final int FLAG_HAS_CODE = 4; // 0x4
field public static final int FLAG_INSTALLED = 8388608; // 0x800000
+ field public static final int FLAG_IS_DATA_ONLY = 16777216; // 0x1000000
field public static final int FLAG_KILL_AFTER_RESTORE = 65536; // 0x10000
field public static final int FLAG_LARGE_HEAP = 1048576; // 0x100000
field public static final int FLAG_PERSISTENT = 8; // 0x8
@@ -25027,6 +25028,7 @@
method public void setId(int);
method public void setImportantForAccessibility(int);
method public void setKeepScreenOn(boolean);
+ method public void setLayerPaint(android.graphics.Paint);
method public void setLayerType(int, android.graphics.Paint);
method public void setLayoutDirection(int);
method public void setLayoutParams(android.view.ViewGroup.LayoutParams);
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index bcd4588..bb108c8 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -36,6 +36,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.util.AndroidException;
import android.view.Display;
import android.view.IWindowManager;
@@ -147,6 +148,18 @@
}
}
+ int parseUserArg(String arg) {
+ int userId;
+ if ("all".equals(arg)) {
+ userId = UserHandle.USER_ALL;
+ } else if ("current".equals(arg) || "cur".equals(arg)) {
+ userId = UserHandle.USER_CURRENT;
+ } else {
+ userId = Integer.parseInt(arg);
+ }
+ return userId;
+ }
+
private Intent makeIntent() throws URISyntaxException {
Intent intent = new Intent();
Intent baseIntent = intent;
@@ -321,7 +334,7 @@
} else if (opt.equals("--opengl-trace")) {
mStartFlags |= ActivityManager.START_FLAG_OPENGL_TRACES;
} else if (opt.equals("--user")) {
- mUserId = Integer.parseInt(nextArgRequired());
+ mUserId = parseUserArg(nextArgRequired());
} else {
System.err.println("Error: Unknown option: " + opt);
return null;
@@ -392,8 +405,12 @@
private void runStartService() throws Exception {
Intent intent = makeIntent();
+ if (mUserId == UserHandle.USER_ALL) {
+ System.err.println("Error: Can't start activity with user 'all'");
+ return;
+ }
System.out.println("Starting service: " + intent);
- ComponentName cn = mAm.startService(null, intent, intent.getType(), 0);
+ ComponentName cn = mAm.startService(null, intent, intent.getType(), mUserId);
if (cn == null) {
System.err.println("Error: Not found; no service started.");
}
@@ -402,10 +419,15 @@
private void runStart() throws Exception {
Intent intent = makeIntent();
+ if (mUserId == UserHandle.USER_ALL) {
+ System.err.println("Error: Can't start service with user 'all'");
+ return;
+ }
+
String mimeType = intent.getType();
if (mimeType == null && intent.getData() != null
&& "content".equals(intent.getData().getScheme())) {
- mimeType = mAm.getProviderMimeType(intent.getData());
+ mimeType = mAm.getProviderMimeType(intent.getData(), mUserId);
}
do {
@@ -460,11 +482,11 @@
int res;
if (mWaitOption) {
result = mAm.startActivityAndWait(null, intent, mimeType,
- null, null, 0, mStartFlags, mProfileFile, fd, null);
+ null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
res = result.result;
} else {
- res = mAm.startActivity(null, intent, mimeType,
- null, null, 0, mStartFlags, mProfileFile, fd, null);
+ res = mAm.startActivityAsUser(null, intent, mimeType,
+ null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
}
PrintStream out = mWaitOption ? System.out : System.err;
boolean launched = false;
@@ -573,6 +595,7 @@
boolean wait = false;
boolean rawMode = false;
boolean no_window_animation = false;
+ int userId = 0;
Bundle args = new Bundle();
String argKey = null, argValue = null;
IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
@@ -592,12 +615,19 @@
} else if (opt.equals("--no_window_animation")
|| opt.equals("--no-window-animation")) {
no_window_animation = true;
+ } else if (opt.equals("--user")) {
+ userId = parseUserArg(nextArgRequired());
} else {
System.err.println("Error: Unknown option: " + opt);
return;
}
}
+ if (userId == UserHandle.USER_ALL) {
+ System.err.println("Error: Can't start instrumentation with user 'all'");
+ return;
+ }
+
String cnArg = nextArgRequired();
ComponentName cn = ComponentName.unflattenFromString(cnArg);
if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
@@ -614,7 +644,7 @@
wm.setAnimationScale(1, 0.0f);
}
- if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher)) {
+ if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, userId)) {
throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
}
@@ -1188,8 +1218,10 @@
if (data != null) line = line + ", data=\"" + data + "\"";
if (extras != null) line = line + ", extras: " + extras;
System.out.println(line);
- mFinished = true;
- notifyAll();
+ synchronized (this) {
+ mFinished = true;
+ notifyAll();
+ }
}
public synchronized void waitForFinish() {
@@ -1338,6 +1370,7 @@
" am kill-all\n" +
" am broadcast <INTENT>\n" +
" am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
+ " [--user <USER_ID> | all | current]\n" +
" [--no-window-animation] <COMPONENT>\n" +
" am profile start <PROCESS> <FILE>\n" +
" am profile stop [<PROCESS>]\n" +
@@ -1384,6 +1417,7 @@
" -p <FILE>: write profiling data to <FILE>\n" +
" -w: wait for instrumentation to finish before returning. Required for\n" +
" test runners.\n" +
+ " --user [<USER_ID> | all | current]: Specify user instrumentation runs in.\n" +
" --no-window-animation: turn off window animations will running.\n" +
"\n" +
"am profile: start and stop profiler on a process.\n" +
@@ -1431,6 +1465,7 @@
" [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
" [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
" [-n <COMPONENT>] [-f <FLAGS>]\n" +
+ " [--user [<USER_ID> | all | current]\n" +
" [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
" [--debug-log-resolution] [--exclude-stopped-packages]\n" +
" [--include-stopped-packages]\n" +
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 9e83a67..697d8ec 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -420,7 +420,7 @@
return -1;
}
if (chmod(pkgpath, S_IRUSR|S_IWUSR|S_IRGRP) < 0) {
- ALOGE("failed to chmod '%s': %s\n", pkgpath, strerror(errno));
+ ALOGE("protect(): failed to chmod '%s': %s\n", pkgpath, strerror(errno));
return -1;
}
@@ -1014,13 +1014,13 @@
if (stat(dataDir, &s) < 0) return -1;
- if (chown(dataDir, 0, 0) < 0) {
+ if (chown(dataDir, AID_INSTALL, AID_INSTALL) < 0) {
ALOGE("failed to chown '%s': %s\n", dataDir, strerror(errno));
return -1;
}
if (chmod(dataDir, 0700) < 0) {
- ALOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
+ ALOGE("linklib() 1: failed to chmod '%s': %s\n", dataDir, strerror(errno));
rc = -1;
goto out;
}
@@ -1058,7 +1058,7 @@
out:
if (chmod(dataDir, s.st_mode) < 0) {
- ALOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
+ ALOGE("linklib() 2: failed to chmod '%s': %s\n", dataDir, strerror(errno));
rc = -errno;
}
@@ -1091,13 +1091,13 @@
return -1;
}
- if (chown(dataDir, 0, 0) < 0) {
+ if (chown(dataDir, AID_INSTALL, AID_INSTALL) < 0) {
ALOGE("failed to chown '%s': %s\n", dataDir, strerror(errno));
return -1;
}
if (chmod(dataDir, 0700) < 0) {
- ALOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
+ ALOGE("unlinklib() 1: failed to chmod '%s': %s\n", dataDir, strerror(errno));
rc = -1;
goto out;
}
@@ -1140,7 +1140,7 @@
out:
if (chmod(dataDir, s.st_mode) < 0) {
- ALOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno));
+ ALOGE("unlinklib() 2: failed to chmod '%s': %s\n", dataDir, strerror(errno));
rc = -1;
}
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 36bf38a..8570f27 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -20,7 +20,6 @@
import android.app.ActivityManagerNative;
import android.content.ComponentName;
-import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ContainerEncryptionParams;
import android.content.pm.FeatureInfo;
@@ -40,12 +39,9 @@
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.net.Uri;
-import android.os.Binder;
import android.os.IUserManager;
-import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserManager;
import java.io.File;
import java.lang.reflect.Field;
@@ -74,7 +70,6 @@
private static final String PM_NOT_RUNNING_ERR =
"Error: Could not access the Package Manager. Is the system running?";
- private static final int ROOT_UID = 0;
public static void main(String[] args) {
new Pm().run(args);
@@ -1054,11 +1049,16 @@
}
private void runUninstall() {
- int unInstallFlags = 0;
+ int unInstallFlags = PackageManager.DELETE_ALL_USERS;
- String opt = nextOption();
- if (opt != null && opt.equals("-k")) {
- unInstallFlags = PackageManager.DELETE_KEEP_DATA;
+ String opt;
+ while ((opt=nextOption()) != null) {
+ if (opt.equals("-k")) {
+ unInstallFlags |= PackageManager.DELETE_KEEP_DATA;
+ } else {
+ System.err.println("Error: Unknown option: " + opt);
+ return;
+ }
}
String pkg = nextArg();
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index cd22aad..bb3c56a 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1957,4 +1957,21 @@
return false;
}
}
+
+ /**
+ * Return whether the given user is actively running. This means that
+ * the user is in the "started" state, not "stopped" -- it is currently
+ * allowed to run code through scheduled alarms, receiving broadcasts,
+ * etc. A started user may be either the current foreground user or a
+ * background user; the result here does not distinguish between the two.
+ * @param userid the user's id. Zero indicates the default user.
+ * @hide
+ */
+ public boolean isUserRunning(int userid) {
+ try {
+ return ActivityManagerNative.getDefault().isUserRunning(userid);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index eed9254..e5dd7b1 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -177,9 +177,10 @@
? data.readFileDescriptor() : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
+ int userId = data.readInt();
WaitResult result = startActivityAndWait(app, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags,
- profileFile, profileFd, options);
+ profileFile, profileFd, options, userId);
reply.writeNoException();
result.writeToParcel(reply, 0);
return true;
@@ -811,7 +812,8 @@
Bundle arguments = data.readBundle();
IBinder b = data.readStrongBinder();
IInstrumentationWatcher w = IInstrumentationWatcher.Stub.asInterface(b);
- boolean res = startInstrumentation(className, profileFile, fl, arguments, w);
+ int userId = data.readInt();
+ boolean res = startInstrumentation(className, profileFile, fl, arguments, w, userId);
reply.writeNoException();
reply.writeInt(res ? 1 : 0);
return true;
@@ -1323,11 +1325,11 @@
return true;
}
- case KILL_APPLICATION_WITH_UID_TRANSACTION: {
+ case KILL_APPLICATION_WITH_APPID_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
String pkg = data.readString();
- int uid = data.readInt();
- killApplicationWithUid(pkg, uid);
+ int appid = data.readInt();
+ killApplicationWithAppId(pkg, appid);
reply.writeNoException();
return true;
}
@@ -1424,7 +1426,8 @@
case GET_PROVIDER_MIME_TYPE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
Uri uri = Uri.CREATOR.createFromParcel(data);
- String type = getProviderMimeType(uri);
+ int userId = data.readInt();
+ String type = getProviderMimeType(uri, userId);
reply.writeNoException();
reply.writeString(type);
return true;
@@ -1573,6 +1576,15 @@
return true;
}
+ case IS_USER_RUNNING_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int userid = data.readInt();
+ boolean result = isUserRunning(userid);
+ reply.writeNoException();
+ reply.writeInt(result ? 1 : 0);
+ return true;
+ }
+
case REMOVE_SUB_TASK_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
@@ -1827,7 +1839,7 @@
public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent,
String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int startFlags, String profileFile,
- ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
+ ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -1851,6 +1863,7 @@
} else {
data.writeInt(0);
}
+ data.writeInt(userId);
mRemote.transact(START_ACTIVITY_AND_WAIT_TRANSACTION, data, reply, 0);
reply.readException();
WaitResult result = WaitResult.CREATOR.createFromParcel(reply);
@@ -2719,7 +2732,7 @@
}
public boolean startInstrumentation(ComponentName className, String profileFile,
- int flags, Bundle arguments, IInstrumentationWatcher watcher)
+ int flags, Bundle arguments, IInstrumentationWatcher watcher, int userId)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -2729,6 +2742,7 @@
data.writeInt(flags);
data.writeBundle(arguments);
data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
+ data.writeInt(userId);
mRemote.transact(START_INSTRUMENTATION_TRANSACTION, data, reply, 0);
reply.readException();
boolean res = reply.readInt() != 0;
@@ -3366,13 +3380,13 @@
data.recycle();
}
- public void killApplicationWithUid(String pkg, int uid) throws RemoteException {
+ public void killApplicationWithAppId(String pkg, int appid) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeString(pkg);
- data.writeInt(uid);
- mRemote.transact(KILL_APPLICATION_WITH_UID_TRANSACTION, data, reply, 0);
+ data.writeInt(appid);
+ mRemote.transact(KILL_APPLICATION_WITH_APPID_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
@@ -3507,12 +3521,12 @@
reply.recycle();
}
- public String getProviderMimeType(Uri uri)
- throws RemoteException {
+ public String getProviderMimeType(Uri uri, int userId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
uri.writeToParcel(data, 0);
+ data.writeInt(userId);
mRemote.transact(GET_PROVIDER_MIME_TYPE_TRANSACTION, data, reply, 0);
reply.readException();
String res = reply.readString();
@@ -3747,6 +3761,19 @@
return userInfo;
}
+ public boolean isUserRunning(int userid) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(userid);
+ mRemote.transact(IS_USER_RUNNING_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean result = reply.readInt() != 0;
+ reply.recycle();
+ data.recycle();
+ return result;
+ }
+
public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 65ea6a0..3498919 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1428,7 +1428,7 @@
arguments.setAllowFds(false);
}
return ActivityManagerNative.getDefault().startInstrumentation(
- className, profileFile, 0, arguments, null);
+ className, profileFile, 0, arguments, null, UserHandle.myUserId());
} catch (RemoteException e) {
// System has crashed, nothing we can do.
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 7a633ed..9cb3621 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -62,7 +62,7 @@
public WaitResult startActivityAndWait(IApplicationThread caller,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int flags, String profileFile,
- ParcelFileDescriptor profileFd, Bundle options) throws RemoteException;
+ ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
public int startActivityWithConfig(IApplicationThread caller,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int startFlags, Configuration newConfig,
@@ -160,7 +160,7 @@
public void killApplicationProcess(String processName, int uid) throws RemoteException;
public boolean startInstrumentation(ComponentName className, String profileFile,
- int flags, Bundle arguments, IInstrumentationWatcher watcher)
+ int flags, Bundle arguments, IInstrumentationWatcher watcher, int userId)
throws RemoteException;
public void finishInstrumentation(IApplicationThread target,
int resultCode, Bundle results) throws RemoteException;
@@ -275,7 +275,7 @@
public void stopAppSwitches() throws RemoteException;
public void resumeAppSwitches() throws RemoteException;
- public void killApplicationWithUid(String pkg, int uid) throws RemoteException;
+ public void killApplicationWithAppId(String pkg, int appid) throws RemoteException;
public void closeSystemDialogs(String reason) throws RemoteException;
@@ -296,7 +296,7 @@
public void crashApplication(int uid, int initialPid, String packageName,
String message) throws RemoteException;
- public String getProviderMimeType(Uri uri) throws RemoteException;
+ public String getProviderMimeType(Uri uri, int userId) throws RemoteException;
public IBinder newUriPermissionOwner(String name) throws RemoteException;
public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
@@ -328,6 +328,7 @@
public boolean switchUser(int userid) throws RemoteException;
public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
public UserInfo getCurrentUser() throws RemoteException;
+ public boolean isUserRunning(int userid) throws RemoteException;
public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException;
@@ -548,7 +549,7 @@
int GET_UID_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92;
int HANDLE_INCOMING_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93;
- int KILL_APPLICATION_WITH_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
+ int KILL_APPLICATION_WITH_APPID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98;
@@ -574,7 +575,7 @@
int CHECK_GRANT_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+118;
int DUMP_HEAP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+119;
int START_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+120;
-
+ int IS_USER_RUNNING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+121;
int ACTIVITY_SLEPT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+122;
int GET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+123;
int SET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+124;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 0a5a26a..ece8841 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -39,6 +39,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
@@ -230,7 +231,8 @@
}
try {
- String type = ActivityManagerNative.getDefault().getProviderMimeType(url);
+ String type = ActivityManagerNative.getDefault().getProviderMimeType(
+ url, UserHandle.myUserId());
return type;
} catch (RemoteException e) {
// Arbitrary and not worth documenting, as Activity
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 1a82d58..a0283d3 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -308,6 +308,13 @@
public static final int FLAG_INSTALLED = 1<<23;
/**
+ * Value for {@link #flags}: true if the application only has its
+ * data installed; the application package itself does not currently
+ * exist on the device.
+ */
+ public static final int FLAG_IS_DATA_ONLY = 1<<24;
+
+ /**
* Value for {@link #flags}: Set to true if the application has been
* installed using the forward lock option.
*
diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java
index ea47e8e..a977e41 100644
--- a/core/java/android/content/pm/InstrumentationInfo.java
+++ b/core/java/android/content/pm/InstrumentationInfo.java
@@ -18,10 +18,6 @@
import android.os.Parcel;
import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.text.Collator;
-import java.util.Comparator;
/**
* Information you can retrieve about a particular piece of test
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e5b58dc..841a076 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4782,17 +4782,24 @@
/**
* Whether the package manager should send package verification broadcasts for verifiers to
* review apps prior to installation.
- *
+ * @deprecated moved to Settings.Global
* 1 = request apps to be verified prior to installation, if a verifier exists.
* 0 = do not verify apps before installation
* {@hide}
*/
+ @Deprecated
public static final String PACKAGE_VERIFIER_ENABLE = "package_verifier_enable";
- /** Timeout for package verification. {@hide} */
+ /** Timeout for package verification.
+ * @deprecated moved to Settings.Global
+ * {@hide} */
+ @Deprecated
public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
- /** Default response code for package verification. {@hide} */
+ /** Default response code for package verification.
+ * @deprecated moved to Settings.Global
+ * {@hide} */
+ @Deprecated
public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response";
/** {@hide} */
@@ -5272,6 +5279,23 @@
public static final String NTP_TIMEOUT = "ntp_timeout";
/**
+ * Whether the package manager should send package verification broadcasts for verifiers to
+ * review apps prior to installation.
+ * 1 = request apps to be verified prior to installation, if a verifier exists.
+ * 0 = do not verify apps before installation
+ * {@hide}
+ */
+ public static final String PACKAGE_VERIFIER_ENABLE = "package_verifier_enable";
+
+ /** Timeout for package verification.
+ * {@hide} */
+ public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
+
+ /** Default response code for package verification.
+ * {@hide} */
+ public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response";
+
+ /**
* The interval in milliseconds at which to check packet counts on the
* mobile data interface when screen is on, to detect possible data
* connection problems.
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index e9b0d32..b0b18da 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -437,6 +437,9 @@
* @throws android.util.TimeFormatException if s cannot be parsed.
*/
public boolean parse(String s) {
+ if (s == null) {
+ throw new NullPointerException("time string is null");
+ }
if (nativeParse(s)) {
timezone = TIMEZONE_UTC;
return true;
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index f4ab133..869cd00 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -152,6 +152,8 @@
static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo);
static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo);
static native void nSetOpaqueLayer(int layerId, boolean isOpaque);
+ static native void nSetLayerPaint(int layerId, int nativePaint);
+ static native void nSetLayerColorFilter(int layerId, int nativeColorFilter);
static native void nUpdateTextureLayer(int layerId, int width, int height, boolean opaque,
SurfaceTexture surface);
static native void nSetTextureLayerTransform(int layerId, int matrix);
@@ -394,13 +396,8 @@
void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
final GLES20Layer glLayer = (GLES20Layer) layer;
- int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
- try {
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawLayer(mRenderer, glLayer.getLayer(), x, y, nativePaint);
- } finally {
- if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
- }
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ nDrawLayer(mRenderer, glLayer.getLayer(), x, y, nativePaint);
}
private static native void nDrawLayer(int renderer, int layer, float x, float y, int paint);
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
index a0ae379..a462ed6 100644
--- a/core/java/android/view/GLES20Layer.java
+++ b/core/java/android/view/GLES20Layer.java
@@ -18,6 +18,7 @@
package android.view;
import android.graphics.Bitmap;
+import android.graphics.Paint;
/**
* An OpenGL ES 2.0 implementation of {@link HardwareLayer}.
@@ -43,6 +44,15 @@
}
@Override
+ void setLayerPaint(Paint paint) {
+ if (paint != null) {
+ GLES20Canvas.nSetLayerPaint(mLayer, paint.mNativePaint);
+ GLES20Canvas.nSetLayerColorFilter(mLayer, paint.getColorFilter() != null ?
+ paint.getColorFilter().nativeColorFilter : 0);
+ }
+ }
+
+ @Override
boolean copyInto(Bitmap bitmap) {
return GLES20Canvas.nCopyLayer(mLayer, bitmap.mNativeBitmap);
}
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 06c6e7c..6e763b2 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -19,6 +19,7 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
+import android.graphics.Paint;
import android.graphics.Rect;
/**
@@ -62,6 +63,14 @@
}
/**
+ * Update the paint used when drawing this layer.
+ *
+ * @param paint The paint used when the layer is drawn into the destination canvas.
+ * @see View#setLayerPaint(android.graphics.Paint)
+ */
+ void setLayerPaint(Paint paint) {}
+
+ /**
* Returns the minimum width of the layer.
*
* @return The minimum desired width of the hardware layer
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index fe14c88..7e335f0 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -367,6 +367,7 @@
if (mListener != null && !mUpdateSurface) {
mListener.onSurfaceTextureAvailable(mSurface, getWidth(), getHeight());
}
+ mLayer.setLayerPaint(mLayerPaint);
}
if (mUpdateSurface) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d268fd2..236adab 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -11932,13 +11932,13 @@
* {@link #setAlpha(float)}, the alpha value of the layer's paint is replaced by
* this view's alpha value. Calling {@link #setAlpha(float)} is therefore
* equivalent to setting a hardware layer on this view and providing a paint with
- * the desired alpha value.<p>
+ * the desired alpha value.</p>
*
* <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled},
* {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware}
* for more information on when and how to use layers.</p>
*
- * @param layerType The ype of layer to use with this view, must be one of
+ * @param layerType The type of layer to use with this view, must be one of
* {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
* {@link #LAYER_TYPE_HARDWARE}
* @param paint The paint used to compose the layer. This argument is optional
@@ -11990,6 +11990,50 @@
}
/**
+ * Updates the {@link Paint} object used with the current layer (used only if the current
+ * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
+ * provided to {@link #setLayerType(int, android.graphics.Paint)} will be used the next time
+ * the View is redrawn, but {@link #setLayerPaint(android.graphics.Paint)} must be called to
+ * ensure that the view gets redrawn immediately.
+ *
+ * <p>A layer is associated with an optional {@link android.graphics.Paint}
+ * instance that controls how the layer is composed on screen. The following
+ * properties of the paint are taken into account when composing the layer:</p>
+ * <ul>
+ * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
+ * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
+ * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
+ * </ul>
+ *
+ * <p>If this view has an alpha value set to < 1.0 by calling
+ * {@link #setAlpha(float)}, the alpha value of the layer's paint is replaced by
+ * this view's alpha value. Calling {@link #setAlpha(float)} is therefore
+ * equivalent to setting a hardware layer on this view and providing a paint with
+ * the desired alpha value.</p>
+ *
+ * @param paint The paint used to compose the layer. This argument is optional
+ * and can be null. It is ignored when the layer type is
+ * {@link #LAYER_TYPE_NONE}
+ *
+ * @see #setLayerType(int, android.graphics.Paint)
+ */
+ public void setLayerPaint(Paint paint) {
+ int layerType = getLayerType();
+ if (layerType != LAYER_TYPE_NONE) {
+ mLayerPaint = paint == null ? new Paint() : paint;
+ if (layerType == LAYER_TYPE_HARDWARE) {
+ HardwareLayer layer = getHardwareLayer();
+ if (layer != null) {
+ layer.setLayerPaint(paint);
+ }
+ invalidateViewProperty(false, false);
+ } else {
+ invalidate();
+ }
+ }
+ }
+
+ /**
* Indicates whether this view has a static layer. A view with layer type
* {@link #LAYER_TYPE_NONE} is a static layer. Other types of layers are
* dynamic.
@@ -12101,6 +12145,7 @@
if (!mHardwareLayer.isValid()) {
return null;
}
+ mHardwareLayer.setLayerPaint(mLayerPaint);
mHardwareLayer.redraw(getHardwareLayerDisplayList(mHardwareLayer), mLocalDirtyRect);
mLocalDirtyRect.setEmpty();
diff --git a/core/jni/android_text_format_Time.cpp b/core/jni/android_text_format_Time.cpp
index 776733c..bb09421 100644
--- a/core/jni/android_text_format_Time.cpp
+++ b/core/jni/android_text_format_Time.cpp
@@ -23,6 +23,7 @@
#include "jni.h"
#include "utils/misc.h"
#include "android_runtime/AndroidRuntime.h"
+#include "ScopedStringChars.h"
#include "TimeUtils.h"
#include <nativehelper/JNIHelp.h>
#include <cutils/tztime.h>
@@ -71,11 +72,10 @@
t->t.tm_gmtoff = env->GetLongField(o, g_gmtoffField);
bool allDay = env->GetBooleanField(o, g_allDayField);
if (allDay &&
- ((t->t.tm_sec !=0) || (t->t.tm_min != 0) || (t->t.tm_hour != 0))) {
- char msg[100];
- sprintf(msg, "allDay is true but sec, min, hour are not 0.");
- jniThrowException(env, "java/lang/IllegalArgumentException", msg);
- return false;
+ ((t->t.tm_sec !=0) || (t->t.tm_min != 0) || (t->t.tm_hour != 0))) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "allDay is true but sec, min, hour are not 0.");
+ return false;
}
return true;
}
@@ -308,7 +308,7 @@
static jstring android_text_format_Time_toString(JNIEnv* env, jobject This)
{
Time t;
- if (!java2time(env, &t, This)) return env->NewStringUTF("");;
+ if (!java2time(env, &t, This)) return env->NewStringUTF("");
ACQUIRE_TIMEZONE(This, t)
String8 r = t.toString();
@@ -360,32 +360,30 @@
// ============================================================================
// Just do this here because it's not worth recreating the strings
-static int get_char(JNIEnv* env, const jchar *s, int spos, int mul,
- bool *thrown)
+static int get_char(JNIEnv* env, const ScopedStringChars& s, int spos, int mul,
+ bool* thrown)
{
jchar c = s[spos];
if (c >= '0' && c <= '9') {
return (c - '0') * mul;
} else {
if (!*thrown) {
- char msg[100];
- sprintf(msg, "Parse error at pos=%d", spos);
- jniThrowException(env, "android/util/TimeFormatException", msg);
+ jniThrowExceptionFmt(env, "android/util/TimeFormatException",
+ "Parse error at pos=%d", spos);
*thrown = true;
}
return 0;
}
}
-static bool check_char(JNIEnv* env, const jchar *s, int spos, jchar expected)
+static bool check_char(JNIEnv* env, const ScopedStringChars& s, int spos, jchar expected)
{
jchar c = s[spos];
if (c != expected) {
- char msg[100];
- sprintf(msg, "Unexpected character 0x%02x at pos=%d. Expected %c.", c, spos,
- expected);
- jniThrowException(env, "android/util/TimeFormatException", msg);
- return false;
+ jniThrowExceptionFmt(env, "android/util/TimeFormatException",
+ "Unexpected character 0x%02x at pos=%d. Expected %c.",
+ c, spos, expected);
+ return false;
}
return true;
}
@@ -394,20 +392,19 @@
static jboolean android_text_format_Time_parse(JNIEnv* env, jobject This, jstring strObj)
{
jsize len = env->GetStringLength(strObj);
- const jchar *s = env->GetStringChars(strObj, NULL);
-
- bool thrown = false;
- int n;
- jboolean inUtc = false;
-
if (len < 8) {
- char msg[100];
- sprintf(msg, "String too short -- expected at least 8 characters.");
- jniThrowException(env, "android/util/TimeFormatException", msg);
- return false;
+ jniThrowException(env, "android/util/TimeFormatException",
+ "String too short -- expected at least 8 characters.");
+ return false;
}
+ jboolean inUtc = false;
+
+ ScopedStringChars s(env, strObj);
+
// year
+ int n;
+ bool thrown = false;
n = get_char(env, s, 0, 1000, &thrown);
n += get_char(env, s, 1, 100, &thrown);
n += get_char(env, s, 2, 10, &thrown);
@@ -454,7 +451,7 @@
if (len > 15) {
// Z
if (!check_char(env, s, 15, 'Z')) return false;
- inUtc = true;
+ inUtc = true;
}
} else {
env->SetBooleanField(This, g_allDayField, JNI_TRUE);
@@ -467,8 +464,7 @@
env->SetIntField(This, g_ydayField, 0);
env->SetIntField(This, g_isdstField, -1);
env->SetLongField(This, g_gmtoffField, 0);
-
- env->ReleaseStringChars(strObj, s);
+
return inUtc;
}
@@ -477,19 +473,19 @@
jstring strObj)
{
jsize len = env->GetStringLength(strObj);
- const jchar *s = env->GetStringChars(strObj, NULL);
-
- bool thrown = false;
- int n;
- jboolean inUtc = false;
-
if (len < 10) {
jniThrowException(env, "android/util/TimeFormatException",
- "Time input is too short; must be at least 10 characters");
+ "String too short --- expected at least 10 characters.");
return false;
}
+ jboolean inUtc = false;
+
+ ScopedStringChars s(env, strObj);
+
// year
+ int n;
+ bool thrown = false;
n = get_char(env, s, 0, 1000, &thrown);
n += get_char(env, s, 1, 100, &thrown);
n += get_char(env, s, 2, 10, &thrown);
@@ -520,28 +516,28 @@
// T
if (!check_char(env, s, 10, 'T')) return false;
- env->SetBooleanField(This, g_allDayField, JNI_FALSE);
+ env->SetBooleanField(This, g_allDayField, JNI_FALSE);
// hour
n = get_char(env, s, 11, 10, &thrown);
n += get_char(env, s, 12, 1, &thrown);
if (thrown) return false;
- int hour = n;
+ int hour = n;
// env->SetIntField(This, g_hourField, n);
-
- // :
- if (!check_char(env, s, 13, ':')) return false;
- // minute
+ // :
+ if (!check_char(env, s, 13, ':')) return false;
+
+ // minute
n = get_char(env, s, 14, 10, &thrown);
n += get_char(env, s, 15, 1, &thrown);
if (thrown) return false;
- int minute = n;
+ int minute = n;
// env->SetIntField(This, g_minField, n);
- // :
- if (!check_char(env, s, 16, ':')) return false;
+ // :
+ if (!check_char(env, s, 16, ':')) return false;
- // second
+ // second
n = get_char(env, s, 17, 10, &thrown);
n += get_char(env, s, 18, 1, &thrown);
if (thrown) return false;
@@ -561,64 +557,63 @@
if (len > tz_index) {
char c = s[tz_index];
- // NOTE: the offset is meant to be subtracted to get from local time
- // to UTC. we therefore use 1 for '-' and -1 for '+'.
- switch (c) {
- case 'Z':
- // Zulu time -- UTC
- offset = 0;
- break;
- case '-':
+ // NOTE: the offset is meant to be subtracted to get from local time
+ // to UTC. we therefore use 1 for '-' and -1 for '+'.
+ switch (c) {
+ case 'Z':
+ // Zulu time -- UTC
+ offset = 0;
+ break;
+ case '-':
offset = 1;
- break;
- case '+':
+ break;
+ case '+':
offset = -1;
- break;
- default:
- char msg[100];
- sprintf(msg, "Unexpected character 0x%02x at position %d. Expected + or -",
- c, tz_index);
- jniThrowException(env, "android/util/TimeFormatException", msg);
- return false;
- }
+ break;
+ default:
+ jniThrowExceptionFmt(env, "android/util/TimeFormatException",
+ "Unexpected character 0x%02x at position %d. Expected + or -",
+ c, tz_index);
+ return false;
+ }
inUtc = true;
- if (offset != 0) {
- if (len < tz_index + 6) {
- char msg[100];
- sprintf(msg, "Unexpected length; should be %d characters", tz_index + 6);
- jniThrowException(env, "android/util/TimeFormatException", msg);
- return false;
- }
+ if (offset != 0) {
+ if (len < tz_index + 6) {
+ jniThrowExceptionFmt(env, "android/util/TimeFormatException",
+ "Unexpected length; should be %d characters",
+ tz_index + 6);
+ return false;
+ }
- // hour
- n = get_char(env, s, tz_index + 1, 10, &thrown);
- n += get_char(env, s, tz_index + 2, 1, &thrown);
- if (thrown) return false;
- n *= offset;
- hour += n;
+ // hour
+ n = get_char(env, s, tz_index + 1, 10, &thrown);
+ n += get_char(env, s, tz_index + 2, 1, &thrown);
+ if (thrown) return false;
+ n *= offset;
+ hour += n;
- // :
- if (!check_char(env, s, tz_index + 3, ':')) return false;
-
- // minute
- n = get_char(env, s, tz_index + 4, 10, &thrown);
- n += get_char(env, s, tz_index + 5, 1, &thrown);
- if (thrown) return false;
- n *= offset;
- minute += n;
- }
- }
- env->SetIntField(This, g_hourField, hour);
+ // :
+ if (!check_char(env, s, tz_index + 3, ':')) return false;
+
+ // minute
+ n = get_char(env, s, tz_index + 4, 10, &thrown);
+ n += get_char(env, s, tz_index + 5, 1, &thrown);
+ if (thrown) return false;
+ n *= offset;
+ minute += n;
+ }
+ }
+ env->SetIntField(This, g_hourField, hour);
env->SetIntField(This, g_minField, minute);
- if (offset != 0) {
- // we need to normalize after applying the hour and minute offsets
- android_text_format_Time_normalize(env, This, false /* use isdst */);
- // The timezone is set to UTC in the calling Java code.
- }
+ if (offset != 0) {
+ // we need to normalize after applying the hour and minute offsets
+ android_text_format_Time_normalize(env, This, false /* use isdst */);
+ // The timezone is set to UTC in the calling Java code.
+ }
} else {
- env->SetBooleanField(This, g_allDayField, JNI_TRUE);
+ env->SetBooleanField(This, g_allDayField, JNI_TRUE);
env->SetIntField(This, g_hourField, 0);
env->SetIntField(This, g_minField, 0);
env->SetIntField(This, g_secField, 0);
@@ -628,8 +623,7 @@
env->SetIntField(This, g_ydayField, 0);
env->SetIntField(This, g_isdstField, -1);
env->SetLongField(This, g_gmtoffField, 0);
-
- env->ReleaseStringChars(strObj, s);
+
return inUtc;
}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 3538fef..7dbf9ec 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -776,6 +776,20 @@
env->ReleaseIntArrayElements(layerInfo, storage, 0);
}
+static void android_view_GLES20Canvas_setLayerPaint(JNIEnv* env, jobject clazz,
+ Layer* layer, SkPaint* paint) {
+ if (layer) {
+ layer->setPaint(paint);
+ }
+}
+
+static void android_view_GLES20Canvas_setLayerColorFilter(JNIEnv* env, jobject clazz,
+ Layer* layer, SkiaColorFilter* colorFilter) {
+ if (layer) {
+ layer->setColorFilter(colorFilter);
+ }
+}
+
static void android_view_GLES20Canvas_setOpaqueLayer(JNIEnv* env, jobject clazz,
Layer* layer, jboolean isOpaque) {
if (layer) {
@@ -979,6 +993,8 @@
{ "nCreateLayerRenderer", "(I)I", (void*) android_view_GLES20Canvas_createLayerRenderer },
{ "nCreateLayer", "(IIZ[I)I", (void*) android_view_GLES20Canvas_createLayer },
{ "nResizeLayer", "(III[I)V" , (void*) android_view_GLES20Canvas_resizeLayer },
+ { "nSetLayerPaint", "(II)V", (void*) android_view_GLES20Canvas_setLayerPaint },
+ { "nSetLayerColorFilter", "(II)V", (void*) android_view_GLES20Canvas_setLayerColorFilter },
{ "nSetOpaqueLayer", "(IZ)V", (void*) android_view_GLES20Canvas_setOpaqueLayer },
{ "nCreateTextureLayer", "(Z[I)I", (void*) android_view_GLES20Canvas_createTextureLayer },
{ "nUpdateTextureLayer", "(IIIZLandroid/graphics/SurfaceTexture;)V",
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index a1fd14e..607150a 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -395,6 +395,14 @@
assertTrue("The native library path (" + info.nativeLibraryDir
+ ") should start with " + SECURE_CONTAINERS_PREFIX,
info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX));
+ try {
+ String compatLib = new File(info.dataDir + "/lib").getCanonicalPath();
+ assertEquals("The compatibility lib directory should be a symbolic link to "
+ + info.nativeLibraryDir,
+ info.nativeLibraryDir, compatLib);
+ } catch (IOException e) {
+ fail("compat check: Can't read " + info.dataDir + "/lib");
+ }
} else {
assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
assertEquals(srcPath, appInstallPath);
diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java
index a85d464..4600424 100644
--- a/graphics/java/android/renderscript/Matrix4f.java
+++ b/graphics/java/android/renderscript/Matrix4f.java
@@ -113,6 +113,34 @@
}
/**
+ * Sets the values of the matrix to those of the parameter
+ *
+ * @param src matrix to load the values from
+ * @hide
+ */
+ public void load(Matrix3f src) {
+ mMat[0] = src.mMat[0];
+ mMat[1] = src.mMat[1];
+ mMat[2] = src.mMat[2];
+ mMat[3] = 0;
+
+ mMat[4] = src.mMat[3];
+ mMat[5] = src.mMat[4];
+ mMat[6] = src.mMat[5];
+ mMat[7] = 0;
+
+ mMat[8] = src.mMat[6];
+ mMat[9] = src.mMat[7];
+ mMat[10] = src.mMat[8];
+ mMat[11] = 0;
+
+ mMat[12] = 0;
+ mMat[13] = 0;
+ mMat[14] = 0;
+ mMat[15] = 1;
+ }
+
+ /**
* Sets current values to be a rotation matrix of certain angle
* about a given axis
*
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
index 41e7e00..dce1939 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
@@ -39,8 +39,7 @@
}
/**
- * Supported elements types are float, float4, uchar, uchar4
- *
+ * Supported elements types are uchar4
*
* @param rs
* @param e
@@ -53,13 +52,98 @@
}
- public void setColorMatrix(Matrix4f m) {
- mMatrix.load(m);
+ private void setMatrix() {
FieldPacker fp = new FieldPacker(16*4);
- fp.addMatrix(m);
+ fp.addMatrix(mMatrix);
setVar(0, fp);
}
+ /**
+ * Set the color matrix which will be applied to each cell of the image.
+ *
+ * @param m The 4x4 matrix to set.
+ */
+ public void setColorMatrix(Matrix4f m) {
+ mMatrix.load(m);
+ setMatrix();
+ }
+
+ /**
+ * Set the color matrix which will be applied to each cell of the image.
+ * This will set the alpha channel to be a copy.
+ *
+ * @param m The 3x3 matrix to set.
+ */
+ public void setColorMatrix(Matrix3f m) {
+ mMatrix.load(m);
+ setMatrix();
+ }
+
+ /**
+ * Set a color matrix to convert from RGB to luminace. The alpha channel
+ * will be a copy.
+ *
+ */
+ public void setGreyscale() {
+ mMatrix.loadIdentity();
+ mMatrix.set(0, 0, 0.299f);
+ mMatrix.set(1, 0, 0.587f);
+ mMatrix.set(2, 0, 0.114f);
+ mMatrix.set(0, 1, 0.299f);
+ mMatrix.set(1, 1, 0.587f);
+ mMatrix.set(2, 1, 0.114f);
+ mMatrix.set(0, 2, 0.299f);
+ mMatrix.set(1, 2, 0.587f);
+ mMatrix.set(2, 2, 0.114f);
+ setMatrix();
+ }
+
+ /**
+ * Set the matrix to convert from YUV to RGB with a direct copy of the 4th
+ * channel.
+ *
+ */
+ public void setYUVtoRGB() {
+ mMatrix.loadIdentity();
+ mMatrix.set(0, 0, 1.f);
+ mMatrix.set(1, 0, 0.f);
+ mMatrix.set(2, 0, 1.13983f);
+ mMatrix.set(0, 1, 1.f);
+ mMatrix.set(1, 1, -0.39465f);
+ mMatrix.set(2, 1, -0.5806f);
+ mMatrix.set(0, 2, 1.f);
+ mMatrix.set(1, 2, 2.03211f);
+ mMatrix.set(2, 2, 0.f);
+ setMatrix();
+ }
+
+ /**
+ * Set the matrix to convert from RGB to YUV with a direct copy of the 4th
+ * channel.
+ *
+ */
+ public void setRGBtoYUV() {
+ mMatrix.loadIdentity();
+ mMatrix.set(0, 0, 0.299f);
+ mMatrix.set(1, 0, 0.587f);
+ mMatrix.set(2, 0, 0.114f);
+ mMatrix.set(0, 1, -0.14713f);
+ mMatrix.set(1, 1, -0.28886f);
+ mMatrix.set(2, 1, 0.436f);
+ mMatrix.set(0, 2, 0.615f);
+ mMatrix.set(1, 2, -0.51499f);
+ mMatrix.set(2, 2, -0.10001f);
+ setMatrix();
+ }
+
+
+ /**
+ * Invoke the kernel and apply the matrix to each cell of ain and copy to
+ * aout.
+ *
+ * @param ain Input allocation
+ * @param aout Output allocation
+ */
public void forEach(Allocation ain, Allocation aout) {
forEach(0, ain, aout, null);
}
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
index ee5f938..b4a228b 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * 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.
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index c0f79df..e032ae4 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -16,6 +16,7 @@
Dither.cpp \
FboCache.cpp \
GradientCache.cpp \
+ Layer.cpp \
LayerCache.cpp \
LayerRenderer.cpp \
Matrix.cpp \
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 2de70d462..755170f 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -149,6 +149,7 @@
delete mTransformMatrix3D;
delete mStaticMatrix;
delete mAnimationMatrix;
+
mTransformMatrix = NULL;
mTransformCamera = NULL;
mTransformMatrix3D = NULL;
@@ -156,50 +157,54 @@
mAnimationMatrix = NULL;
Caches& caches = Caches::getInstance();
+ caches.resourceCache.lock();
for (size_t i = 0; i < mBitmapResources.size(); i++) {
- caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
+ caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
}
- mBitmapResources.clear();
for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
- caches.resourceCache.decrementRefcount(bitmap);
- caches.resourceCache.destructor(bitmap);
+ caches.resourceCache.decrementRefcountLocked(bitmap);
+ caches.resourceCache.destructorLocked(bitmap);
}
- mOwnedBitmapResources.clear();
for (size_t i = 0; i < mFilterResources.size(); i++) {
- caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
+ caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
}
- mFilterResources.clear();
for (size_t i = 0; i < mShaders.size(); i++) {
- caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
- caches.resourceCache.destructor(mShaders.itemAt(i));
+ caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
+ caches.resourceCache.destructorLocked(mShaders.itemAt(i));
}
- mShaders.clear();
+
+ for (size_t i = 0; i < mSourcePaths.size(); i++) {
+ caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
+ }
+
+ caches.resourceCache.unlock();
for (size_t i = 0; i < mPaints.size(); i++) {
delete mPaints.itemAt(i);
}
- mPaints.clear();
for (size_t i = 0; i < mPaths.size(); i++) {
SkPath* path = mPaths.itemAt(i);
caches.pathCache.remove(path);
delete path;
}
- mPaths.clear();
-
- for (size_t i = 0; i < mSourcePaths.size(); i++) {
- caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
- }
- mSourcePaths.clear();
for (size_t i = 0; i < mMatrices.size(); i++) {
delete mMatrices.itemAt(i);
}
+
+ mBitmapResources.clear();
+ mOwnedBitmapResources.clear();
+ mFilterResources.clear();
+ mShaders.clear();
+ mSourcePaths.clear();
+ mPaints.clear();
+ mPaths.clear();
mMatrices.clear();
}
@@ -223,35 +228,44 @@
mReader.setMemory(buffer, mSize);
Caches& caches = Caches::getInstance();
+ caches.resourceCache.lock();
const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
for (size_t i = 0; i < bitmapResources.size(); i++) {
SkBitmap* resource = bitmapResources.itemAt(i);
mBitmapResources.add(resource);
- caches.resourceCache.incrementRefcount(resource);
+ caches.resourceCache.incrementRefcountLocked(resource);
}
const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
SkBitmap* resource = ownedBitmapResources.itemAt(i);
mOwnedBitmapResources.add(resource);
- caches.resourceCache.incrementRefcount(resource);
+ caches.resourceCache.incrementRefcountLocked(resource);
}
const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
for (size_t i = 0; i < filterResources.size(); i++) {
SkiaColorFilter* resource = filterResources.itemAt(i);
mFilterResources.add(resource);
- caches.resourceCache.incrementRefcount(resource);
+ caches.resourceCache.incrementRefcountLocked(resource);
}
const Vector<SkiaShader*>& shaders = recorder.getShaders();
for (size_t i = 0; i < shaders.size(); i++) {
SkiaShader* resource = shaders.itemAt(i);
mShaders.add(resource);
- caches.resourceCache.incrementRefcount(resource);
+ caches.resourceCache.incrementRefcountLocked(resource);
}
+ const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
+ for (size_t i = 0; i < sourcePaths.size(); i++) {
+ mSourcePaths.add(sourcePaths.itemAt(i));
+ caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i));
+ }
+
+ caches.resourceCache.unlock();
+
const Vector<SkPaint*>& paints = recorder.getPaints();
for (size_t i = 0; i < paints.size(); i++) {
mPaints.add(paints.itemAt(i));
@@ -262,12 +276,6 @@
mPaths.add(paths.itemAt(i));
}
- const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
- for (size_t i = 0; i < sourcePaths.size(); i++) {
- mSourcePaths.add(sourcePaths.itemAt(i));
- caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i));
- }
-
const Vector<SkMatrix*>& matrices = recorder.getMatrices();
for (size_t i = 0; i < matrices.size(); i++) {
mMatrices.add(matrices.itemAt(i));
@@ -1004,29 +1012,39 @@
}
break;
case DrawLayer: {
+ int oldAlpha = -1;
Layer* layer = (Layer*) getInt();
float x = getFloat();
float y = getFloat();
SkPaint* paint = getPaint(renderer);
- if (mCaching) {
- paint->setAlpha(mMultipliedAlpha);
+ if (mCaching && mMultipliedAlpha < 255) {
+ oldAlpha = layer->getAlpha();
+ layer->setAlpha(mMultipliedAlpha);
}
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
layer, x, y, paint);
drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
+ if (oldAlpha >= 0) {
+ layer->setAlpha(oldAlpha);
+ }
}
break;
case DrawBitmap: {
+ int oldAlpha = -1;
SkBitmap* bitmap = getBitmap();
float x = getFloat();
float y = getFloat();
SkPaint* paint = getPaint(renderer);
- if (mCaching) {
+ if (mCaching && mMultipliedAlpha < 255) {
+ oldAlpha = paint->getAlpha();
paint->setAlpha(mMultipliedAlpha);
}
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
bitmap, x, y, paint);
drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
+ if (oldAlpha >= 0) {
+ paint->setAlpha(oldAlpha);
+ }
}
break;
case DrawBitmapMatrix: {
@@ -1309,7 +1327,8 @@
// Base structure
///////////////////////////////////////////////////////////////////////////////
-DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE),
+DisplayListRenderer::DisplayListRenderer():
+ mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE),
mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
}
@@ -1320,34 +1339,38 @@
void DisplayListRenderer::reset() {
mWriter.reset();
- Caches& caches = Caches::getInstance();
+ mCaches.resourceCache.lock();
+
for (size_t i = 0; i < mBitmapResources.size(); i++) {
- caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
+ mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
}
- mBitmapResources.clear();
for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
- SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
- caches.resourceCache.decrementRefcount(bitmap);
+ mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i));
}
- mOwnedBitmapResources.clear();
for (size_t i = 0; i < mFilterResources.size(); i++) {
- caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
+ mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
}
- mFilterResources.clear();
for (size_t i = 0; i < mShaders.size(); i++) {
- caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
+ mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
}
- mShaders.clear();
- mShaderMap.clear();
for (size_t i = 0; i < mSourcePaths.size(); i++) {
- caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
+ mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
}
+
+ mCaches.resourceCache.unlock();
+
+ mBitmapResources.clear();
+ mOwnedBitmapResources.clear();
+ mFilterResources.clear();
mSourcePaths.clear();
+ mShaders.clear();
+ mShaderMap.clear();
+
mPaints.clear();
mPaintMap.clear();
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index c8b3e47..8e4f2d3 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -763,7 +763,7 @@
mPaths.add(pathCopy);
}
if (mSourcePaths.indexOf(path) < 0) {
- Caches::getInstance().resourceCache.incrementRefcount(path);
+ mCaches.resourceCache.incrementRefcount(path);
mSourcePaths.add(path);
}
@@ -811,13 +811,13 @@
// which doesn't seem worth the extra cycles for this unlikely case.
addInt((int) bitmap);
mBitmapResources.add(bitmap);
- Caches::getInstance().resourceCache.incrementRefcount(bitmap);
+ mCaches.resourceCache.incrementRefcount(bitmap);
}
void addBitmapData(SkBitmap* bitmap) {
addInt((int) bitmap);
mOwnedBitmapResources.add(bitmap);
- Caches::getInstance().resourceCache.incrementRefcount(bitmap);
+ mCaches.resourceCache.incrementRefcount(bitmap);
}
inline void addShader(SkiaShader* shader) {
@@ -833,7 +833,7 @@
// replaceValueFor() performs an add if the entry doesn't exist
mShaderMap.replaceValueFor(shader, shaderCopy);
mShaders.add(shaderCopy);
- Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
+ mCaches.resourceCache.incrementRefcount(shaderCopy);
}
addInt((int) shaderCopy);
@@ -842,7 +842,7 @@
inline void addColorFilter(SkiaColorFilter* colorFilter) {
addInt((int) colorFilter);
mFilterResources.add(colorFilter);
- Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
+ mCaches.resourceCache.incrementRefcount(colorFilter);
}
Vector<SkBitmap*> mBitmapResources;
@@ -862,15 +862,16 @@
Vector<SkMatrix*> mMatrices;
- SkWriter32 mWriter;
uint32_t mBufferSize;
int mRestoreSaveCount;
+ Caches& mCaches;
+ SkWriter32 mWriter;
+
float mTranslateX;
float mTranslateY;
bool mHasTranslate;
-
bool mHasDrawOps;
friend class DisplayList;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
new file mode 100644
index 0000000..31e169b
--- /dev/null
+++ b/libs/hwui/Layer.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <utils/Log.h>
+
+#include "Layer.h"
+#include "OpenGLRenderer.h"
+#include "Caches.h"
+
+namespace android {
+namespace uirenderer {
+
+Layer::~Layer() {
+ if (mesh) delete mesh;
+ if (meshIndices) delete meshIndices;
+ if (colorFilter) Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
+}
+
+void Layer::setPaint(SkPaint* paint) {
+ OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
+}
+
+void Layer::setColorFilter(SkiaColorFilter* filter) {
+ if (colorFilter) {
+ Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
+ }
+ colorFilter = filter;
+ if (colorFilter) {
+ Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
+ }
+}
+
+
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index f243177..76da671 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -45,6 +45,7 @@
* A layer has dimensions and is backed by an OpenGL texture or FBO.
*/
struct Layer {
+
Layer(const uint32_t layerWidth, const uint32_t layerHeight) {
mesh = NULL;
meshIndices = NULL;
@@ -60,10 +61,7 @@
displayList = NULL;
}
- ~Layer() {
- if (mesh) delete mesh;
- if (meshIndices) delete meshIndices;
- }
+ ~Layer();
/**
* Sets this layer's region to a rectangle. Computes the appropriate
@@ -106,6 +104,8 @@
texture.height = height;
}
+ ANDROID_API void setPaint(SkPaint* paint);
+
inline void setBlend(bool blend) {
texture.blend = blend;
}
@@ -191,9 +191,7 @@
return colorFilter;
}
- inline void setColorFilter(SkiaColorFilter* filter) {
- colorFilter = filter;
- }
+ ANDROID_API void setColorFilter(SkiaColorFilter* filter);
inline void bindTexture() {
glBindTexture(renderTarget, texture.id);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index b66c898..9f8b87c 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1978,6 +1978,10 @@
// Find the normal to the line
vec2 n = (b - a).copyNormalized() * halfStrokeWidth;
+ float x = n.x;
+ n.x = -n.y;
+ n.y = x;
+
if (isHairLine) {
if (isAA) {
float wideningFactor;
@@ -2002,14 +2006,10 @@
float extendedNLength = extendedN.length();
// We need to set this value on the shader prior to drawing
- boundaryWidthProportion = extendedNLength / (halfStrokeWidth + extendedNLength);
+ boundaryWidthProportion = .5 - extendedNLength / (halfStrokeWidth + extendedNLength);
n += extendedN;
}
- float x = n.x;
- n.x = -n.y;
- n.y = x;
-
// aa lines expand the endpoint vertices to encompass the AA boundary
if (isAA) {
vec2 abVector = (b - a);
@@ -2593,17 +2593,13 @@
mCaches.activeTexture(0);
- int alpha;
- SkXfermode::Mode mode;
- getAlphaAndMode(paint, &alpha, &mode);
-
- layer->setAlpha(alpha, mode);
-
if (CC_LIKELY(!layer->region.isEmpty())) {
if (layer->region.isRect()) {
composeLayerRect(layer, layer->regionRect);
} else if (layer->mesh) {
- const float a = alpha / 255.0f;
+ const float a = layer->getAlpha() / 255.0f;
+ SkiaColorFilter *oldFilter = mColorFilter;
+ mColorFilter = layer->getColorFilter();
setupDraw();
setupDrawWithTexture();
@@ -2633,6 +2629,8 @@
finishDrawTexture();
+ mColorFilter = oldFilter;
+
#if DEBUG_LAYERS_AS_REGIONS
drawRegionRects(layer->region);
#endif
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index f2b5f0a..7f9405f 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -227,6 +227,32 @@
*/
void endMark() const;
+ /**
+ * Gets the alpha and xfermode out of a paint object. If the paint is null
+ * alpha will be 255 and the xfermode will be SRC_OVER. This method does
+ * not multiply the paint's alpha by the current snapshot's alpha.
+ *
+ * @param paint The paint to extract values from
+ * @param alpha Where to store the resulting alpha
+ * @param mode Where to store the resulting xfermode
+ */
+ static inline void getAlphaAndModeDirect(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
+ if (paint) {
+ *mode = getXfermode(paint->getXfermode());
+
+ // Skia draws using the color's alpha channel if < 255
+ // Otherwise, it uses the paint's alpha
+ int color = paint->getColor();
+ *alpha = (color >> 24) & 0xFF;
+ if (*alpha == 255) {
+ *alpha = paint->getAlpha();
+ }
+ } else {
+ *mode = SkXfermode::kSrcOver_Mode;
+ *alpha = 255;
+ }
+ }
+
protected:
/**
* Compose the layer defined in the current snapshot with the layer
@@ -291,32 +317,6 @@
inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
/**
- * Gets the alpha and xfermode out of a paint object. If the paint is null
- * alpha will be 255 and the xfermode will be SRC_OVER. This method does
- * not multiply the paint's alpha by the current snapshot's alpha.
- *
- * @param paint The paint to extract values from
- * @param alpha Where to store the resulting alpha
- * @param mode Where to store the resulting xfermode
- */
- static inline void getAlphaAndModeDirect(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
- if (paint) {
- *mode = getXfermode(paint->getXfermode());
-
- // Skia draws using the color's alpha channel if < 255
- // Otherwise, it uses the paint's alpha
- int color = paint->getColor();
- *alpha = (color >> 24) & 0xFF;
- if (*alpha == 255) {
- *alpha = paint->getAlpha();
- }
- } else {
- *mode = SkXfermode::kSrcOver_Mode;
- *alpha = 255;
- }
- }
-
- /**
* Safely retrieves the mode from the specified xfermode. If the specified
* xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
*/
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 2153a8b..b0c57d1 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -38,7 +38,7 @@
ResourceCache::ResourceCache() {
Mutex::Autolock _l(mLock);
- mCache = new KeyedVector<void *, ResourceReference *>();
+ mCache = new KeyedVector<void*, ResourceReference*>();
}
ResourceCache::~ResourceCache() {
@@ -46,15 +46,17 @@
delete mCache;
}
+void ResourceCache::lock() {
+ mLock.lock();
+}
+
+void ResourceCache::unlock() {
+ mLock.unlock();
+}
+
void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
Mutex::Autolock _l(mLock);
- ssize_t index = mCache->indexOfKey(resource);
- ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
- if (ref == NULL || mCache->size() == 0) {
- ref = new ResourceReference(resourceType);
- mCache->add(resource, ref);
- }
- ref->refCount++;
+ incrementRefcountLocked(resource, resourceType);
}
void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
@@ -77,18 +79,39 @@
incrementRefcount((void*) filterResource, kColorFilter);
}
-void ResourceCache::decrementRefcount(void* resource) {
- Mutex::Autolock _l(mLock);
+void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
ssize_t index = mCache->indexOfKey(resource);
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
- if (ref == NULL) {
- // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
- return;
+ if (ref == NULL || mCache->size() == 0) {
+ ref = new ResourceReference(resourceType);
+ mCache->add(resource, ref);
}
- ref->refCount--;
- if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
- }
+ ref->refCount++;
+}
+
+void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
+ SkSafeRef(bitmapResource->pixelRef());
+ SkSafeRef(bitmapResource->getColorTable());
+ incrementRefcountLocked((void*) bitmapResource, kBitmap);
+}
+
+void ResourceCache::incrementRefcountLocked(SkPath* pathResource) {
+ incrementRefcountLocked((void*) pathResource, kPath);
+}
+
+void ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) {
+ SkSafeRef(shaderResource->getSkShader());
+ incrementRefcountLocked((void*) shaderResource, kShader);
+}
+
+void ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) {
+ SkSafeRef(filterResource->getSkColorFilter());
+ incrementRefcountLocked((void*) filterResource, kColorFilter);
+}
+
+void ResourceCache::decrementRefcount(void* resource) {
+ Mutex::Autolock _l(mLock);
+ decrementRefcountLocked(resource);
}
void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
@@ -111,27 +134,45 @@
decrementRefcount((void*) filterResource);
}
-void ResourceCache::recycle(SkBitmap* resource) {
- Mutex::Autolock _l(mLock);
+void ResourceCache::decrementRefcountLocked(void* resource) {
ssize_t index = mCache->indexOfKey(resource);
- if (index < 0) {
- // not tracking this resource; just recycle the pixel data
- resource->setPixels(NULL, NULL);
- return;
- }
- ResourceReference* ref = mCache->valueAt(index);
+ ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
- // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
+ // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
return;
}
- ref->recycled = true;
+ ref->refCount--;
if (ref->refCount == 0) {
deleteResourceReference(resource, ref);
}
}
+void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
+ SkSafeUnref(bitmapResource->pixelRef());
+ SkSafeUnref(bitmapResource->getColorTable());
+ decrementRefcountLocked((void*) bitmapResource);
+}
+
+void ResourceCache::decrementRefcountLocked(SkPath* pathResource) {
+ decrementRefcountLocked((void*) pathResource);
+}
+
+void ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) {
+ SkSafeUnref(shaderResource->getSkShader());
+ decrementRefcountLocked((void*) shaderResource);
+}
+
+void ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) {
+ SkSafeUnref(filterResource->getSkColorFilter());
+ decrementRefcountLocked((void*) filterResource);
+}
+
void ResourceCache::destructor(SkPath* resource) {
Mutex::Autolock _l(mLock);
+ destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(SkPath* resource) {
ssize_t index = mCache->indexOfKey(resource);
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
@@ -150,6 +191,10 @@
void ResourceCache::destructor(SkBitmap* resource) {
Mutex::Autolock _l(mLock);
+ destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(SkBitmap* resource) {
ssize_t index = mCache->indexOfKey(resource);
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
@@ -168,6 +213,10 @@
void ResourceCache::destructor(SkiaShader* resource) {
Mutex::Autolock _l(mLock);
+ destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(SkiaShader* resource) {
ssize_t index = mCache->indexOfKey(resource);
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
@@ -183,6 +232,10 @@
void ResourceCache::destructor(SkiaColorFilter* resource) {
Mutex::Autolock _l(mLock);
+ destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(SkiaColorFilter* resource) {
ssize_t index = mCache->indexOfKey(resource);
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
@@ -196,6 +249,29 @@
}
}
+void ResourceCache::recycle(SkBitmap* resource) {
+ Mutex::Autolock _l(mLock);
+ recycleLocked(resource);
+}
+
+void ResourceCache::recycleLocked(SkBitmap* resource) {
+ ssize_t index = mCache->indexOfKey(resource);
+ if (index < 0) {
+ // not tracking this resource; just recycle the pixel data
+ resource->setPixels(NULL, NULL);
+ return;
+ }
+ ResourceReference* ref = mCache->valueAt(index);
+ if (ref == NULL) {
+ // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
+ return;
+ }
+ ref->recycled = true;
+ if (ref->refCount == 0) {
+ deleteResourceReference(resource, ref);
+ }
+}
+
/**
* This method should only be called while the mLock mutex is held (that mutex is grabbed
* by the various destructor() and recycle() methods which call this method).
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index 8cf466b..60ffa7d 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -52,28 +52,59 @@
};
class ANDROID_API ResourceCache {
- KeyedVector<void *, ResourceReference *>* mCache;
public:
ResourceCache();
~ResourceCache();
+
+ /**
+ * When using these two methods, make sure to only invoke the *Locked()
+ * variants of increment/decrementRefcount(), recyle() and destructor()
+ */
+ void lock();
+ void unlock();
+
void incrementRefcount(SkPath* resource);
void incrementRefcount(SkBitmap* resource);
void incrementRefcount(SkiaShader* resource);
void incrementRefcount(SkiaColorFilter* resource);
- void incrementRefcount(const void* resource, ResourceType resourceType);
- void decrementRefcount(void* resource);
+
+ void incrementRefcountLocked(SkPath* resource);
+ void incrementRefcountLocked(SkBitmap* resource);
+ void incrementRefcountLocked(SkiaShader* resource);
+ void incrementRefcountLocked(SkiaColorFilter* resource);
+
void decrementRefcount(SkBitmap* resource);
void decrementRefcount(SkPath* resource);
void decrementRefcount(SkiaShader* resource);
void decrementRefcount(SkiaColorFilter* resource);
- void recycle(SkBitmap* resource);
+
+ void decrementRefcountLocked(SkBitmap* resource);
+ void decrementRefcountLocked(SkPath* resource);
+ void decrementRefcountLocked(SkiaShader* resource);
+ void decrementRefcountLocked(SkiaColorFilter* resource);
+
void destructor(SkPath* resource);
void destructor(SkBitmap* resource);
void destructor(SkiaShader* resource);
void destructor(SkiaColorFilter* resource);
+
+ void destructorLocked(SkPath* resource);
+ void destructorLocked(SkBitmap* resource);
+ void destructorLocked(SkiaShader* resource);
+ void destructorLocked(SkiaColorFilter* resource);
+
+ void recycle(SkBitmap* resource);
+ void recycleLocked(SkBitmap* resource);
+
private:
void deleteResourceReference(void* resource, ResourceReference* ref);
+
void incrementRefcount(void* resource, ResourceType resourceType);
+ void incrementRefcountLocked(void* resource, ResourceType resourceType);
+
+ void decrementRefcount(void* resource);
+ void decrementRefcountLocked(void* resource);
+
void logCache();
/**
@@ -82,6 +113,8 @@
* or a reference queue finalization thread.
*/
mutable Mutex mLock;
+
+ KeyedVector<void*, ResourceReference*>* mCache;
};
}; // namespace uirenderer
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 1ca0df4..f3a8558 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -188,6 +188,13 @@
* AudioPolicyService methods
*/
+ //
+ // audio device definitions: must be kept in sync with values in system/core/audio.h
+ //
+
+ // reserved bits
+ public static final int DEVICE_BIT_IN = 0x80000000;
+ public static final int DEVICE_BIT_DEFAULT = 0x40000000;
// output devices, be sure to update AudioManager.java also
public static final int DEVICE_OUT_EARPIECE = 0x1;
public static final int DEVICE_OUT_SPEAKER = 0x2;
@@ -204,8 +211,9 @@
public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000;
public static final int DEVICE_OUT_USB_ACCESSORY = 0x2000;
public static final int DEVICE_OUT_USB_DEVICE = 0x4000;
+ public static final int DEVICE_OUT_REMOTE_SUBMIX = 0x8000;
- public static final int DEVICE_OUT_DEFAULT = 0x8000;
+ public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT;
public static final int DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE |
DEVICE_OUT_SPEAKER |
DEVICE_OUT_WIRED_HEADSET |
@@ -221,6 +229,7 @@
DEVICE_OUT_DGTL_DOCK_HEADSET |
DEVICE_OUT_USB_ACCESSORY |
DEVICE_OUT_USB_DEVICE |
+ DEVICE_OUT_REMOTE_SUBMIX |
DEVICE_OUT_DEFAULT);
public static final int DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP |
DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
@@ -232,15 +241,36 @@
DEVICE_OUT_USB_DEVICE);
// input devices
- public static final int DEVICE_IN_COMMUNICATION = 0x10000;
- public static final int DEVICE_IN_AMBIENT = 0x20000;
- public static final int DEVICE_IN_BUILTIN_MIC1 = 0x40000;
- public static final int DEVICE_IN_BUILTIN_MIC2 = 0x80000;
- public static final int DEVICE_IN_MIC_ARRAY = 0x100000;
- public static final int DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x200000;
- public static final int DEVICE_IN_WIRED_HEADSET = 0x400000;
- public static final int DEVICE_IN_AUX_DIGITAL = 0x800000;
- public static final int DEVICE_IN_DEFAULT = 0x80000000;
+ public static final int DEVICE_IN_COMMUNICATION = DEVICE_BIT_IN | 0x1;
+ public static final int DEVICE_IN_AMBIENT = DEVICE_BIT_IN | 0x2;
+ public static final int DEVICE_IN_BUILTIN_MIC = DEVICE_BIT_IN | 0x4;
+ public static final int DEVICE_IN_BLUETOOTH_SCO_HEADSET = DEVICE_BIT_IN | 0x8;
+ public static final int DEVICE_IN_WIRED_HEADSET = DEVICE_BIT_IN | 0x10;
+ public static final int DEVICE_IN_AUX_DIGITAL = DEVICE_BIT_IN | 0x20;
+ public static final int DEVICE_IN_VOICE_CALL = DEVICE_BIT_IN | 0x40;
+ public static final int DEVICE_IN_BACK_MIC = DEVICE_BIT_IN | 0x80;
+ public static final int DEVICE_IN_REMOTE_SUBMIX = DEVICE_BIT_IN | 0x100;
+ public static final int DEVICE_IN_ANLG_DOCK_HEADSET = DEVICE_BIT_IN | 0x200;
+ public static final int DEVICE_IN_DGTL_DOCK_HEADSET = DEVICE_BIT_IN | 0x400;
+ public static final int DEVICE_IN_USB_ACCESSORY = DEVICE_BIT_IN | 0x800;
+ public static final int DEVICE_IN_USB_DEVICE = DEVICE_BIT_IN | 0x1000;
+ public static final int DEVICE_IN_DEFAULT = DEVICE_BIT_IN | DEVICE_BIT_DEFAULT;
+
+ public static final int DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION |
+ DEVICE_IN_AMBIENT |
+ DEVICE_IN_BUILTIN_MIC |
+ DEVICE_IN_BLUETOOTH_SCO_HEADSET |
+ DEVICE_IN_WIRED_HEADSET |
+ DEVICE_IN_AUX_DIGITAL |
+ DEVICE_IN_VOICE_CALL |
+ DEVICE_IN_BACK_MIC |
+ DEVICE_IN_REMOTE_SUBMIX |
+ DEVICE_IN_ANLG_DOCK_HEADSET |
+ DEVICE_IN_DGTL_DOCK_HEADSET |
+ DEVICE_IN_USB_ACCESSORY |
+ DEVICE_IN_USB_DEVICE |
+ DEVICE_IN_DEFAULT);
+ public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET;
// device states, must match AudioSystem::device_connection_state
public static final int DEVICE_STATE_UNAVAILABLE = 0;
@@ -262,6 +292,7 @@
public static final String DEVICE_OUT_DGTL_DOCK_HEADSET_NAME = "digital_dock";
public static final String DEVICE_OUT_USB_ACCESSORY_NAME = "usb_accessory";
public static final String DEVICE_OUT_USB_DEVICE_NAME = "usb_device";
+ public static final String DEVICE_OUT_REMOTE_SUBMIX_NAME = "remote_submix";
public static String getDeviceName(int device)
{
@@ -296,7 +327,9 @@
return DEVICE_OUT_USB_ACCESSORY_NAME;
case DEVICE_OUT_USB_DEVICE:
return DEVICE_OUT_USB_DEVICE_NAME;
- case DEVICE_IN_DEFAULT:
+ case DEVICE_OUT_REMOTE_SUBMIX:
+ return DEVICE_OUT_REMOTE_SUBMIX_NAME;
+ case DEVICE_OUT_DEFAULT:
default:
return "";
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 77760b4..05673c3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -67,7 +67,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 = 86;
+ private static final int DATABASE_VERSION = 87;
private Context mContext;
private int mUserHandle;
@@ -1288,6 +1288,23 @@
upgradeVersion = 86;
}
+ if (upgradeVersion == 86) {
+ db.beginTransaction();
+ try {
+ String[] settingsToMove = {
+ Settings.Secure.PACKAGE_VERIFIER_ENABLE,
+ Settings.Secure.PACKAGE_VERIFIER_TIMEOUT,
+ Settings.Secure.PACKAGE_VERIFIER_DEFAULT_RESPONSE
+ };
+ moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
+
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ upgradeVersion = 87;
+ }
+
// *** Remember to update DATABASE_VERSION above!
if (upgradeVersion != currentVersion) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 54cf73a..db2d450 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -4181,22 +4181,22 @@
Intent dock = createHomeDockIntent();
if (dock != null) {
int result = ActivityManagerNative.getDefault()
- .startActivity(null, dock,
+ .startActivityAsUser(null, dock,
dock.resolveTypeIfNeeded(mContext.getContentResolver()),
null, null, 0,
ActivityManager.START_FLAG_ONLY_IF_NEEDED,
- null, null, null);
+ null, null, null, UserHandle.USER_CURRENT);
if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
return false;
}
}
}
int result = ActivityManagerNative.getDefault()
- .startActivity(null, mHomeIntent,
+ .startActivityAsUser(null, mHomeIntent,
mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
null, null, 0,
ActivityManager.START_FLAG_ONLY_IF_NEEDED,
- null, null, null);
+ null, null, null, UserHandle.USER_CURRENT);
if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
return false;
}
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 61517b1..fd6060a 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -1628,8 +1628,8 @@
} else {
// Make sure KEEP_SCREEN_ON is disabled, since that
// would allow bypassing of the maximum time to lock.
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0);
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
}
mLastMaximumTimeToLock = timeMs;
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 6a3010b..7144808 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -185,7 +185,7 @@
}
private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
- HashMap map = mServicesByNamePerUser.get(callingUser);
+ HashMap<ComponentName, ServiceRecord> map = mServicesByNamePerUser.get(callingUser);
if (map == null) {
map = new HashMap<ComponentName, ServiceRecord>();
mServicesByNamePerUser.put(callingUser, map);
@@ -195,7 +195,8 @@
private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
int callingUser) {
- HashMap map = mServicesByIntentPerUser.get(callingUser);
+ HashMap<Intent.FilterComparison, ServiceRecord> map
+ = mServicesByIntentPerUser.get(callingUser);
if (map == null) {
map = new HashMap<Intent.FilterComparison, ServiceRecord>();
mServicesByIntentPerUser.put(callingUser, map);
@@ -1514,10 +1515,12 @@
}
}
- boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
+ private boolean collectForceStopServicesLocked(String name, int userId,
+ boolean evenPersistent, boolean doit,
+ HashMap<ComponentName, ServiceRecord> services,
+ ArrayList<ServiceRecord> result) {
boolean didSomething = false;
- ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
- for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
+ for (ServiceRecord service : services.values()) {
if ((name == null || service.packageName.equals(name))
&& (service.app == null || evenPersistent || !service.app.persistent)) {
if (!doit) {
@@ -1530,9 +1533,27 @@
}
service.app = null;
service.isolatedProc = null;
- services.add(service);
+ result.add(service);
}
}
+ return didSomething;
+ }
+
+ boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
+ boolean didSomething = false;
+ ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
+ if (userId == UserHandle.USER_ALL) {
+ for (int i=0; i<mServiceMap.mServicesByNamePerUser.size(); i++) {
+ didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent,
+ doit, mServiceMap.mServicesByNamePerUser.valueAt(i), services);
+ if (!doit && didSomething) {
+ return true;
+ }
+ }
+ } else {
+ didSomething = collectForceStopServicesLocked(name, userId, evenPersistent,
+ doit, mServiceMap.mServicesByNamePerUser.get(userId), services);
+ }
int N = services.size();
for (int i=0; i<N; i++) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 614b93a..448044a 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -116,13 +116,11 @@
import android.provider.Settings;
import android.text.format.Time;
import android.util.EventLog;
-import android.util.LocaleUtil;
import android.util.Log;
import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -434,6 +432,11 @@
final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
/**
+ * LRU list of history of current users. Most recently current is at the end.
+ */
+ final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
+
+ /**
* Packages that the user has asked to have run in screen size
* compatibility mode instead of filling the screen.
*/
@@ -1094,11 +1097,11 @@
} break;
case KILL_APPLICATION_MSG: {
synchronized (ActivityManagerService.this) {
- int uid = msg.arg1;
+ int appid = msg.arg1;
boolean restart = (msg.arg2 == 1);
String pkg = (String) msg.obj;
- forceStopPackageLocked(pkg, uid, restart, false, true, false,
- UserHandle.getUserId(uid));
+ forceStopPackageLocked(pkg, appid, restart, false, true, false,
+ UserHandle.USER_ALL);
}
} break;
case FINALIZE_PENDING_INTENT_MSG: {
@@ -1526,6 +1529,7 @@
// User 0 is the first and only user that runs at boot.
mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
+ mUserLru.add(Integer.valueOf(0));
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
@@ -2146,8 +2150,7 @@
intent.addCategory(Intent.CATEGORY_HOME);
}
ActivityInfo aInfo =
- intent.resolveActivityInfo(mContext.getPackageManager(),
- STOCK_PM_FLAGS);
+ resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
@@ -2170,6 +2173,29 @@
return true;
}
+ private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
+ ActivityInfo ai = null;
+ ComponentName comp = intent.getComponent();
+ try {
+ if (comp != null) {
+ ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
+ } else {
+ ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
+ intent,
+ intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+ flags, userId);
+
+ if (info != null) {
+ ai = info.activityInfo;
+ }
+ }
+ } catch (RemoteException e) {
+ // ignore
+ }
+
+ return ai;
+ }
+
/**
* Starts the "new version setup screen" if appropriate.
*/
@@ -2385,8 +2411,10 @@
public final WaitResult startActivityAndWait(IApplicationThread caller,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, String profileFile,
- ParcelFileDescriptor profileFd, Bundle options) {
+ ParcelFileDescriptor profileFd, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivityAndWait");
+ userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
+ false, true, "startActivityAndWait", null);
WaitResult res = new WaitResult();
mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
@@ -3542,16 +3570,15 @@
}
/*
- * The pkg name and uid have to be specified.
- * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
+ * The pkg name and app id have to be specified.
*/
- public void killApplicationWithUid(String pkg, int uid) {
+ public void killApplicationWithAppId(String pkg, int appid) {
if (pkg == null) {
return;
}
// Make sure the uid is valid.
- if (uid < 0) {
- Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
+ if (appid < 0) {
+ Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
return;
}
int callerUid = Binder.getCallingUid();
@@ -3559,7 +3586,7 @@
if (callerUid == Process.SYSTEM_UID) {
// Post an aysnc message to kill the application
Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
- msg.arg1 = uid;
+ msg.arg1 = appid;
msg.arg2 = 0;
msg.obj = pkg;
mHandler.sendMessage(msg);
@@ -3691,7 +3718,7 @@
MY_PID, Process.SYSTEM_UID, userId);
}
- private final boolean killPackageProcessesLocked(String packageName, int uid,
+ private final boolean killPackageProcessesLocked(String packageName, int appId,
int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
boolean doit, boolean evenPersistent, String reason) {
ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
@@ -3712,32 +3739,41 @@
if (doit) {
procs.add(app);
}
+ continue;
+ }
+
+ // Skip process if it doesn't meet our oom adj requirement.
+ if (app.setAdj < minOomAdj) {
+ continue;
+ }
+
// If no package is specified, we call all processes under the
// give user id.
- } else if (packageName == null) {
- if (app.userId == userId) {
- if (app.setAdj >= minOomAdj) {
- if (!doit) {
- return true;
- }
- app.removed = true;
- procs.add(app);
- }
+ if (packageName == null) {
+ if (app.userId != userId) {
+ continue;
}
- // If uid is specified and the uid and process name match
- // Or, the uid is not specified and the process name matches
- } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
- || ((app.processName.equals(packageName)
- || app.processName.startsWith(procNamePrefix))
- && uid < 0))) {
- if (app.setAdj >= minOomAdj) {
- if (!doit) {
- return true;
- }
- app.removed = true;
- procs.add(app);
+ // Package has been specified, we want to hit all processes
+ // that match it. We need to qualify this by the processes
+ // that are running under the specified app and user ID.
+ } else {
+ if (UserHandle.getAppId(app.uid) != appId) {
+ continue;
+ }
+ if (userId != UserHandle.USER_ALL && app.userId != userId) {
+ continue;
+ }
+ if (!app.pkgList.contains(packageName)) {
+ continue;
}
}
+
+ // Process has passed all conditions, kill it!
+ if (!doit) {
+ return true;
+ }
+ app.removed = true;
+ procs.add(app);
}
}
@@ -3748,22 +3784,28 @@
return N > 0;
}
- private final boolean forceStopPackageLocked(String name, int uid,
+ private final boolean forceStopPackageLocked(String name, int appId,
boolean callerWillRestart, boolean purgeCache, boolean doit,
boolean evenPersistent, int userId) {
int i;
int N;
- if (uid < 0 && name != null) {
+ if (userId == UserHandle.USER_ALL && name == null) {
+ Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
+ }
+
+ if (appId < 0 && name != null) {
try {
- uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
+ appId = UserHandle.getAppId(
+ AppGlobals.getPackageManager().getPackageUid(name, 0));
} catch (RemoteException e) {
}
}
if (doit) {
if (name != null) {
- Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
+ Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
+ + " user=" + userId);
} else {
Slog.i(TAG, "Force stopping user " + userId);
}
@@ -3775,8 +3817,14 @@
boolean remove = false;
final int entUid = ba.keyAt(i);
if (name != null) {
- if (entUid == uid) {
- remove = true;
+ if (userId == UserHandle.USER_ALL) {
+ if (UserHandle.getAppId(entUid) == appId) {
+ remove = true;
+ }
+ } else {
+ if (entUid == UserHandle.getUid(userId, appId)) {
+ remove = true;
+ }
}
} else if (UserHandle.getUserId(entUid) == userId) {
remove = true;
@@ -3791,9 +3839,8 @@
}
}
- boolean didSomething = killPackageProcessesLocked(name, uid,
- name == null ? userId : -1 , -100, callerWillRestart, false,
- doit, evenPersistent,
+ boolean didSomething = killPackageProcessesLocked(name, appId, userId,
+ -100, callerWillRestart, false, doit, evenPersistent,
name == null ? ("force stop user " + userId) : ("force stop " + name));
TaskRecord lastTask = null;
@@ -3801,7 +3848,7 @@
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
final boolean samePackage = r.packageName.equals(name)
|| (name == null && r.userId == userId);
- if (r.userId == userId
+ if ((userId == UserHandle.USER_ALL || r.userId == userId)
&& (samePackage || r.task == lastTask)
&& (r.app == null || evenPersistent || !r.app.persistent)) {
if (!doit) {
@@ -3841,22 +3888,64 @@
}
ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
- for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
- if ((name == null || provider.info.packageName.equals(name))
- && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
+ if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
+ userId, providers)) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
+ }
+ N = providers.size();
+ for (i=0; i<N; i++) {
+ removeDyingProviderLocked(null, providers.get(i), true);
+ }
+
+ if (mIntentSenderRecords.size() > 0) {
+ Iterator<WeakReference<PendingIntentRecord>> it
+ = mIntentSenderRecords.values().iterator();
+ while (it.hasNext()) {
+ WeakReference<PendingIntentRecord> wpir = it.next();
+ if (wpir == null) {
+ it.remove();
+ continue;
+ }
+ PendingIntentRecord pir = wpir.get();
+ if (pir == null) {
+ it.remove();
+ continue;
+ }
+ if (name == null) {
+ // Stopping user, remove all objects for the user.
+ if (pir.key.userId != userId) {
+ // Not the same user, skip it.
+ continue;
+ }
+ } else {
+ if (UserHandle.getAppId(pir.uid) != appId) {
+ // Different app id, skip it.
+ continue;
+ }
+ if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
+ // Different user, skip it.
+ continue;
+ }
+ if (!pir.key.packageName.equals(name)) {
+ // Different package, skip it.
+ continue;
+ }
+ }
if (!doit) {
return true;
}
didSomething = true;
- providers.add(provider);
+ it.remove();
+ pir.canceled = true;
+ if (pir.key.activity != null) {
+ pir.key.activity.pendingResults.remove(pir.ref);
+ }
}
}
- N = providers.size();
- for (i=0; i<N; i++) {
- removeDyingProviderLocked(null, providers.get(i), true);
- }
-
if (doit) {
if (purgeCache && name != null) {
AttributeCache ac = AttributeCache.instance();
@@ -6778,10 +6867,11 @@
* Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
* src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
*/
- public String getProviderMimeType(Uri uri) {
+ public String getProviderMimeType(Uri uri, int userId) {
enforceNotIsolatedCaller("getProviderMimeType");
+ userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, false, true, "getProviderMimeType", null);
final String name = uri.getAuthority();
- final int userId = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
ContentProviderHolder holder = null;
@@ -7134,7 +7224,8 @@
mDebugTransient = !persistent;
if (packageName != null) {
final long origId = Binder.clearCallingIdentity();
- forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
+ forceStopPackageLocked(packageName, -1, false, false, true, true,
+ UserHandle.USER_ALL);
Binder.restoreCallingIdentity(origId);
}
}
@@ -9129,9 +9220,14 @@
for (int i=0; i<mStartedUsers.size(); i++) {
UserStartedState uss = mStartedUsers.valueAt(i);
pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
- pw.println(":");
- uss.dump(" ", pw);
+ pw.print(": "); uss.dump("", pw);
}
+ pw.print(" mUserLru: [");
+ for (int i=0; i<mUserLru.size(); i++) {
+ if (i > 0) pw.print(", ");
+ pw.print(mUserLru.get(i));
+ }
+ pw.println("]");
pw.println(" mHomeProcess: " + mHomeProcess);
pw.println(" mPreviousProcess: " + mPreviousProcess);
if (dumpAll) {
@@ -11815,8 +11911,10 @@
public boolean startInstrumentation(ComponentName className,
String profileFile, int flags, Bundle arguments,
- IInstrumentationWatcher watcher) {
+ IInstrumentationWatcher watcher, int userId) {
enforceNotIsolatedCaller("startInstrumentation");
+ userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, false, true, "startInstrumentation", null);
// Refuse possible leaked file descriptors
if (arguments != null && arguments.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Bundle");
@@ -11828,9 +11926,10 @@
try {
ii = mContext.getPackageManager().getInstrumentationInfo(
className, STOCK_PM_FLAGS);
- ai = mContext.getPackageManager().getApplicationInfo(
- ii.targetPackage, STOCK_PM_FLAGS);
+ ai = AppGlobals.getPackageManager().getApplicationInfo(
+ ii.targetPackage, STOCK_PM_FLAGS, userId);
} catch (PackageManager.NameNotFoundException e) {
+ } catch (RemoteException e) {
}
if (ii == null) {
reportStartInstrumentationFailure(watcher, className,
@@ -11857,7 +11956,6 @@
throw new SecurityException(msg);
}
- 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);
@@ -13780,6 +13878,9 @@
}
mCurrentUserId = userId;
+ Integer userIdInt = Integer.valueOf(userId);
+ mUserLru.remove(userIdInt);
+ mUserLru.add(userIdInt);
boolean haveActivities = mMainStack.switchUser(userId);
if (!haveActivities) {
startHomeActivityLocked(userId, mStartedUsers.get(userId));
@@ -13928,6 +14029,23 @@
}
}
+ @Override
+ public boolean isUserRunning(int userId) {
+ if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
+ != PackageManager.PERMISSION_GRANTED) {
+ String msg = "Permission Denial: isUserRunning() from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid()
+ + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
+ synchronized (this) {
+ UserStartedState state = mStartedUsers.get(userId);
+ return state != null && state.mState != UserStartedState.STATE_STOPPING;
+ }
+ }
+
private boolean userExists(int userId) {
UserInfo user = getUserManager().getUserInfo(userId);
return user != null;
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 399ea59..895b52a 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -422,11 +422,10 @@
}
final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
- // TODO: Don't look for any tasks from other users
int i = mHistory.size()-1;
while (i >= 0) {
ActivityRecord r = mHistory.get(i);
- if (!r.finishing && r != notTop) {
+ if (!r.finishing && r != notTop && r.userId == mCurrentUser) {
return r;
}
i--;
@@ -435,11 +434,10 @@
}
final ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) {
- // TODO: Don't look for any tasks from other users
int i = mHistory.size()-1;
while (i >= 0) {
ActivityRecord r = mHistory.get(i);
- if (!r.finishing && !r.delayedResume && r != notTop) {
+ if (!r.finishing && !r.delayedResume && r != notTop && r.userId == mCurrentUser) {
return r;
}
i--;
@@ -457,12 +455,12 @@
* @return Returns the HistoryRecord of the next activity on the stack.
*/
final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
- // TODO: Don't look for any tasks from other users
int i = mHistory.size()-1;
while (i >= 0) {
ActivityRecord r = mHistory.get(i);
// Note: the taskId check depends on real taskId fields being non-zero
- if (!r.finishing && (token != r.appToken) && (taskId != r.task.taskId)) {
+ if (!r.finishing && (token != r.appToken) && (taskId != r.task.taskId)
+ && r.userId == mCurrentUser) {
return r;
}
i--;
@@ -1400,7 +1398,7 @@
// Launcher...
if (mMainStack) {
ActivityOptions.abort(options);
- return mService.startHomeActivityLocked(0, null);
+ return mService.startHomeActivityLocked(mCurrentUser, null);
}
}
diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java
index c80d63a..de306b5 100644
--- a/services/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/java/com/android/server/am/ContentProviderRecord.java
@@ -85,7 +85,7 @@
public boolean canRunHere(ProcessRecord app) {
return (info.multiprocess || info.processName.equals(app.processName))
- && (uid == Process.SYSTEM_UID || uid == app.info.uid);
+ && uid == app.info.uid;
}
public void addExternalProcessHandleLocked(IBinder token) {
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 0f72409..c61f13c 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -25,7 +25,6 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.UserHandle;
import android.util.Slog;
import java.io.PrintWriter;
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index 7a4fef6..2d7167b 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -180,6 +180,49 @@
}
}
+ private boolean collectForceStopProvidersLocked(String name, int appId,
+ boolean doit, boolean evenPersistent, int userId,
+ HashMap<ComponentName, ContentProviderRecord> providers,
+ ArrayList<ContentProviderRecord> result) {
+ boolean didSomething = false;
+ for (ContentProviderRecord provider : providers.values()) {
+ if ((name == null || provider.info.packageName.equals(name))
+ && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
+ result.add(provider);
+ }
+ }
+ return didSomething;
+ }
+
+ boolean collectForceStopProviders(String name, int appId,
+ boolean doit, boolean evenPersistent, int userId,
+ ArrayList<ContentProviderRecord> result) {
+ boolean didSomething = collectForceStopProvidersLocked(name, appId, doit,
+ evenPersistent, userId, mSingletonByClass, result);
+ if (!doit && didSomething) {
+ return true;
+ }
+ if (userId == UserHandle.USER_ALL) {
+ for (int i=0; i<mProvidersByClassPerUser.size(); i++) {
+ if (collectForceStopProvidersLocked(name, appId, doit, evenPersistent,
+ userId, mProvidersByClassPerUser.valueAt(i), result)) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
+ }
+ }
+ } else {
+ didSomething |= collectForceStopProvidersLocked(name, appId, doit, evenPersistent,
+ userId, getProvidersByClass(userId), result);
+ }
+ return didSomething;
+ }
+
private void dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll,
HashMap<ComponentName, ContentProviderRecord> map) {
Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it = map.entrySet().iterator();
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 55da11f..133d926 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1193,7 +1193,7 @@
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
Slog.i(TAG, "Expecting better updatd system app for " + ps.name
+ "; removing system app");
- removePackageLI(scannedPkg, true);
+ removePackageLI(ps, true);
}
continue;
@@ -1822,7 +1822,7 @@
}
pkg = new PackageParser.Package(packageName);
pkg.applicationInfo.packageName = packageName;
- pkg.applicationInfo.flags = ps.pkgFlags;
+ pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
pkg.applicationInfo.sourceDir = ps.codePathString;
pkg.applicationInfo.dataDir =
@@ -4110,8 +4110,13 @@
NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
} else {
Slog.i(TAG, "Linking native library dir for " + path);
- mInstaller.linkNativeLibraryDirectory(dataPathString,
+ int ret = mInstaller.linkNativeLibraryDirectory(dataPathString,
pkg.applicationInfo.nativeLibraryDir);
+ if (ret < 0) {
+ Slog.w(TAG, "Failed linking native library dir for " + path);
+ mLastScanError = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+ return null;
+ }
}
} catch (IOException ioe) {
Log.e(TAG, "Unable to get canonical file " + ioe.toString());
@@ -4429,20 +4434,40 @@
return pkg;
}
- private void killApplication(String pkgName, int uid) {
+ private void killApplication(String pkgName, int appId) {
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
// version of the application while the new one gets installed.
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
try {
- am.killApplicationWithUid(pkgName, uid);
+ am.killApplicationWithAppId(pkgName, appId);
} catch (RemoteException e) {
}
}
}
- void removePackageLI(PackageParser.Package pkg, boolean chatty) {
+ void removePackageLI(PackageSetting ps, boolean chatty) {
+ if (DEBUG_INSTALL) {
+ if (chatty)
+ Log.d(TAG, "Removing package " + ps.name);
+ }
+
+ // writer
+ synchronized (mPackages) {
+ mPackages.remove(ps.name);
+ if (ps.codePathString != null) {
+ mAppDirs.remove(ps.codePathString);
+ }
+
+ final PackageParser.Package pkg = ps.pkg;
+ if (pkg != null) {
+ cleanPackageDataStructuresLILPw(pkg, chatty);
+ }
+ }
+ }
+
+ void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
if (DEBUG_INSTALL) {
if (chatty)
Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
@@ -4454,34 +4479,115 @@
if (pkg.mPath != null) {
mAppDirs.remove(pkg.mPath);
}
+ cleanPackageDataStructuresLILPw(pkg, chatty);
+ }
+ }
- int N = pkg.providers.size();
- StringBuilder r = null;
- int i;
- for (i=0; i<N; i++) {
- PackageParser.Provider p = pkg.providers.get(i);
- mProvidersByComponent.remove(new ComponentName(p.info.packageName,
- p.info.name));
- if (p.info.authority == null) {
+ void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
+ int N = pkg.providers.size();
+ StringBuilder r = null;
+ int i;
+ for (i=0; i<N; i++) {
+ PackageParser.Provider p = pkg.providers.get(i);
+ mProvidersByComponent.remove(new ComponentName(p.info.packageName,
+ p.info.name));
+ if (p.info.authority == null) {
- /* The is another ContentProvider with this authority when
- * this app was installed so this authority is null,
- * Ignore it as we don't have to unregister the provider.
- */
- continue;
- }
- String names[] = p.info.authority.split(";");
- for (int j = 0; j < names.length; j++) {
- if (mProviders.get(names[j]) == p) {
- mProviders.remove(names[j]);
- if (DEBUG_REMOVE) {
- if (chatty)
- Log.d(TAG, "Unregistered content provider: " + names[j]
- + ", className = " + p.info.name + ", isSyncable = "
- + p.info.isSyncable);
- }
+ /* There was another ContentProvider with this authority when
+ * this app was installed so this authority is null,
+ * Ignore it as we don't have to unregister the provider.
+ */
+ continue;
+ }
+ String names[] = p.info.authority.split(";");
+ for (int j = 0; j < names.length; j++) {
+ if (mProviders.get(names[j]) == p) {
+ mProviders.remove(names[j]);
+ if (DEBUG_REMOVE) {
+ if (chatty)
+ Log.d(TAG, "Unregistered content provider: " + names[j]
+ + ", className = " + p.info.name + ", isSyncable = "
+ + p.info.isSyncable);
}
}
+ }
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(p.info.name);
+ }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
+ }
+
+ N = pkg.services.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Service s = pkg.services.get(i);
+ mServices.removeService(s);
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(s.info.name);
+ }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
+ }
+
+ N = pkg.receivers.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Activity a = pkg.receivers.get(i);
+ mReceivers.removeActivity(a, "receiver");
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(a.info.name);
+ }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
+ }
+
+ N = pkg.activities.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Activity a = pkg.activities.get(i);
+ mActivities.removeActivity(a, "activity");
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(a.info.name);
+ }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
+ }
+
+ N = pkg.permissions.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Permission p = pkg.permissions.get(i);
+ BasePermission bp = mSettings.mPermissions.get(p.info.name);
+ if (bp == null) {
+ bp = mSettings.mPermissionTrees.get(p.info.name);
+ }
+ if (bp != null && bp.perm == p) {
+ bp.perm = null;
if (chatty) {
if (r == null) {
r = new StringBuilder(256);
@@ -4491,105 +4597,27 @@
r.append(p.info.name);
}
}
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
- }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
+ }
- N = pkg.services.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Service s = pkg.services.get(i);
- mServices.removeService(s);
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(s.info.name);
+ N = pkg.instrumentation.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ PackageParser.Instrumentation a = pkg.instrumentation.get(i);
+ mInstrumentation.remove(a.getComponentName());
+ if (chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
}
+ r.append(a.info.name);
}
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
- }
-
- N = pkg.receivers.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Activity a = pkg.receivers.get(i);
- mReceivers.removeActivity(a, "receiver");
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(a.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
- }
-
- N = pkg.activities.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Activity a = pkg.activities.get(i);
- mActivities.removeActivity(a, "activity");
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(a.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
- }
-
- N = pkg.permissions.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Permission p = pkg.permissions.get(i);
- BasePermission bp = mSettings.mPermissions.get(p.info.name);
- if (bp == null) {
- bp = mSettings.mPermissionTrees.get(p.info.name);
- }
- if (bp != null && bp.perm == p) {
- bp.perm = null;
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(p.info.name);
- }
- }
- }
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
- }
-
- N = pkg.instrumentation.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Instrumentation a = pkg.instrumentation.get(i);
- mInstrumentation.remove(a.getComponentName());
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(a.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
- }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
}
}
@@ -5424,10 +5452,10 @@
public void onEvent(int event, String path) {
String removedPackage = null;
- int removedUid = -1;
+ int removedAppId = -1;
int[] removedUsers = null;
String addedPackage = null;
- int addedUid = -1;
+ int addedAppId = -1;
int[] addedUsers = null;
// TODO post a message to the handler to obtain serial ordering
@@ -5454,11 +5482,12 @@
return;
}
PackageParser.Package p = null;
+ PackageSetting ps = null;
// reader
synchronized (mPackages) {
p = mAppDirs.get(fullPathStr);
if (p != null) {
- PackageSetting ps = mSettings.mPackages.get(p.applicationInfo.packageName);
+ ps = mSettings.mPackages.get(p.applicationInfo.packageName);
if (ps != null) {
removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
} else {
@@ -5468,10 +5497,10 @@
addedUsers = sUserManager.getUserIds();
}
if ((event&REMOVE_EVENTS) != 0) {
- if (p != null) {
- removePackageLI(p, true);
- removedPackage = p.applicationInfo.packageName;
- removedUid = p.applicationInfo.uid;
+ if (ps != null) {
+ removePackageLI(ps, true);
+ removedPackage = ps.name;
+ removedAppId = ps.appId;
}
}
@@ -5496,7 +5525,7 @@
p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0);
}
addedPackage = p.applicationInfo.packageName;
- addedUid = p.applicationInfo.uid;
+ addedAppId = UserHandle.getAppId(p.applicationInfo.uid);
}
}
}
@@ -5509,14 +5538,14 @@
if (removedPackage != null) {
Bundle extras = new Bundle(1);
- extras.putInt(Intent.EXTRA_UID, removedUid);
+ extras.putInt(Intent.EXTRA_UID, removedAppId);
extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
extras, null, null, removedUsers);
}
if (addedPackage != null) {
Bundle extras = new Bundle(1);
- extras.putInt(Intent.EXTRA_UID, addedUid);
+ extras.putInt(Intent.EXTRA_UID, addedAppId);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
extras, null, null, addedUsers);
}
@@ -5791,8 +5820,8 @@
* @return verification timeout in milliseconds
*/
private long getVerificationTimeout() {
- return android.provider.Settings.Secure.getLong(mContext.getContentResolver(),
- android.provider.Settings.Secure.PACKAGE_VERIFIER_TIMEOUT,
+ return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
+ android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
DEFAULT_VERIFICATION_TIMEOUT);
}
@@ -5802,8 +5831,8 @@
* @return default verification response code
*/
private int getDefaultVerificationResponse() {
- return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
- android.provider.Settings.Secure.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
+ return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
+ android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
DEFAULT_VERIFICATION_RESPONSE);
}
@@ -5813,8 +5842,8 @@
* @return true if verification should be performed
*/
private boolean isVerificationEnabled() {
- return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
- android.provider.Settings.Secure.PACKAGE_VERIFIER_ENABLE,
+ return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
+ android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE,
DEFAULT_VERIFY_ENABLE ? 1 : 0) == 1 ? true : false;
}
@@ -7527,7 +7556,7 @@
res.removedInfo.uid = oldPkg.applicationInfo.uid;
res.removedInfo.removedPackage = packageName;
// Remove existing system package
- removePackageLI(oldPkg, true);
+ removePackageLI(oldPkgSetting, true);
// writer
synchronized (mPackages) {
if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) {
@@ -7566,7 +7595,7 @@
// Re installation failed. Restore old information
// Remove new pkg information
if (newPackage != null) {
- removePackageLI(newPackage, true);
+ removeInstalledPackageLI(newPackage, true);
}
// Add back the old system package
scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user);
@@ -7967,10 +7996,10 @@
* make sure this flag is set for partially installed apps. If not its meaningless to
* delete a partially installed application.
*/
- private void removePackageDataLI(PackageParser.Package p, PackageRemovedInfo outInfo,
+ private void removePackageDataLI(PackageSetting ps, PackageRemovedInfo outInfo,
int flags, boolean writeSettings) {
- String packageName = p.packageName;
- removePackageLI(p, (flags&REMOVE_CHATTY) != 0);
+ String packageName = ps.name;
+ removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
// Retrieve object to delete permissions for shared user later on
final PackageSetting deletedPs;
// reader
@@ -8015,38 +8044,32 @@
/*
* Tries to delete system package.
*/
- private boolean deleteSystemPackageLI(PackageParser.Package p,
+ private boolean deleteSystemPackageLI(PackageSetting newPs,
int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
- ApplicationInfo applicationInfo = p.applicationInfo;
- //applicable for non-partially installed applications only
- if (applicationInfo == null) {
- Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
- return false;
- }
- PackageSetting ps = null;
+ PackageSetting disabledPs = null;
// Confirm if the system package has been updated
// An updated system app can be deleted. This will also have to restore
// the system pkg from system partition
// reader
synchronized (mPackages) {
- ps = mSettings.getDisabledSystemPkgLPr(p.packageName);
+ disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
}
- if (ps == null) {
- Slog.w(TAG, "Attempt to delete unknown system package "+ p.packageName);
+ if (disabledPs == null) {
+ Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
return false;
} else {
Log.i(TAG, "Deleting system pkg from data partition");
}
// Delete the updated package
outInfo.isRemovedPackageSystemUpdate = true;
- if (ps.versionCode < p.mVersionCode) {
+ if (disabledPs.versionCode < newPs.versionCode) {
// Delete data for downgrades
flags &= ~PackageManager.DELETE_KEEP_DATA;
} else {
// Preserve data by setting flag
flags |= PackageManager.DELETE_KEEP_DATA;
}
- boolean ret = deleteInstalledPackageLI(p, true, flags, outInfo,
+ boolean ret = deleteInstalledPackageLI(newPs, true, flags, outInfo,
writeSettings);
if (!ret) {
return false;
@@ -8054,17 +8077,18 @@
// writer
synchronized (mPackages) {
// Reinstate the old system package
- mSettings.enableSystemPackageLPw(p.packageName);
+ mSettings.enableSystemPackageLPw(newPs.name);
// Remove any native libraries from the upgraded package.
- NativeLibraryHelper.removeNativeBinariesLI(p.applicationInfo.nativeLibraryDir);
+ NativeLibraryHelper.removeNativeBinariesLI(newPs.nativeLibraryPathString);
}
// Install the system package
- PackageParser.Package newPkg = scanPackageLI(ps.codePath,
+ PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath,
PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM,
SCAN_MONITOR | SCAN_NO_PATHS, 0, null);
if (newPkg == null) {
- Slog.w(TAG, "Failed to restore system package:"+p.packageName+" with error:" + mLastScanError);
+ Slog.w(TAG, "Failed to restore system package:" + newPs.name
+ + " with error:" + mLastScanError);
return false;
}
// writer
@@ -8079,28 +8103,23 @@
return true;
}
- private boolean deleteInstalledPackageLI(PackageParser.Package p,
+ private boolean deleteInstalledPackageLI(PackageSetting ps,
boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo,
boolean writeSettings) {
- ApplicationInfo applicationInfo = p.applicationInfo;
- if (applicationInfo == null) {
- Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
- return false;
- }
if (outInfo != null) {
- outInfo.uid = applicationInfo.uid;
+ outInfo.uid = ps.appId;
}
// Delete package data from internal structures and also remove data if flag is set
- removePackageDataLI(p, outInfo, flags, writeSettings);
+ removePackageDataLI(ps, outInfo, flags, writeSettings);
// Delete application code and resources
if (deleteCodeAndResources) {
// TODO can pick up from PackageSettings as well
- int installFlags = isExternal(p) ? PackageManager.INSTALL_EXTERNAL : 0;
- installFlags |= isForwardLocked(p) ? PackageManager.INSTALL_FORWARD_LOCK : 0;
- outInfo.args = createInstallArgs(installFlags, applicationInfo.sourceDir,
- applicationInfo.publicSourceDir, applicationInfo.nativeLibraryDir);
+ int installFlags = isExternal(ps) ? PackageManager.INSTALL_EXTERNAL : 0;
+ installFlags |= isForwardLocked(ps) ? PackageManager.INSTALL_FORWARD_LOCK : 0;
+ outInfo.args = createInstallArgs(installFlags, ps.codePathString,
+ ps.resourcePathString, ps.nativeLibraryPathString);
}
return true;
}
@@ -8115,28 +8134,17 @@
Slog.w(TAG, "Attempt to delete null packageName.");
return false;
}
- PackageParser.Package p;
+ PackageSetting ps;
boolean dataOnly = false;
int removeUser = -1;
int appId = -1;
synchronized (mPackages) {
- p = mPackages.get(packageName);
- if (p == null) {
- //this retrieves partially installed apps
- dataOnly = true;
- PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps == null) {
- Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
- return false;
- }
- p = ps.pkg;
- }
- if (p == null) {
+ ps = mSettings.mPackages.get(packageName);
+ if (ps == null) {
Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
return false;
}
- final PackageSetting ps = (PackageSetting)p.mExtras;
- if (!isSystemApp(p) && ps != null && user != null
+ if (!isSystemApp(ps) && user != null
&& user.getIdentifier() != UserHandle.USER_ALL) {
// The caller is asking that the package only be deleted for a single
// user. To do this, we just mark its uninstalled state and delete
@@ -8177,25 +8185,20 @@
if (dataOnly) {
// Delete application data first
- removePackageDataLI(p, outInfo, flags, writeSettings);
+ removePackageDataLI(ps, outInfo, flags, writeSettings);
return true;
}
- // At this point the package should have ApplicationInfo associated with it
- if (p.applicationInfo == null) {
- Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
- return false;
- }
boolean ret = false;
- if (isSystemApp(p)) {
- Log.i(TAG, "Removing system package:"+p.packageName);
+ if (isSystemApp(ps)) {
+ Log.i(TAG, "Removing system package:" + ps.name);
// When an updated system application is deleted we delete the existing resources as well and
// fall back to existing code in system partition
- ret = deleteSystemPackageLI(p, flags, outInfo, writeSettings);
+ ret = deleteSystemPackageLI(ps, flags, outInfo, writeSettings);
} else {
- Log.i(TAG, "Removing non-system package:"+p.packageName);
+ Log.i(TAG, "Removing non-system package:" + ps.name);
// Kill application pre-emptively especially for apps on sd.
- killApplication(packageName, p.applicationInfo.uid);
- ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo,
+ killApplication(packageName, ps.appId);
+ ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, outInfo,
writeSettings);
}
return ret;
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 5f10d44..b85353c 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -32,7 +32,6 @@
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
-import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -50,7 +49,6 @@
import android.os.Environment;
import android.os.FileUtils;
import android.os.Process;
-import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
@@ -1261,7 +1259,7 @@
final ArrayList<PackageCleanItem> pkgs = mPackagesToBeCleaned.valueAt(i);
for (int j=0; j<pkgs.size(); j++) {
serializer.startTag(null, "cleaning-package");
- PackageCleanItem item = pkgs.get(i);
+ PackageCleanItem item = pkgs.get(j);
serializer.attribute(null, ATTR_NAME, item.packageName);
serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");
serializer.attribute(null, ATTR_USER, userStr);
@@ -2603,8 +2601,8 @@
first = false;
pw.print("anyDensity");
}
+ pw.println("]");
}
- pw.println("]");
pw.print(" timeStamp=");
date.setTime(ps.timeStamp);
pw.println(sdf.format(date));
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 59d0954..fda619c 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -372,8 +372,8 @@
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP), false, mSettingsObserver);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT), false, mSettingsObserver);
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.STAY_ON_WHILE_PLUGGED_IN), false, mSettingsObserver);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN), false, mSettingsObserver);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS), false, mSettingsObserver);
resolver.registerContentObserver(Settings.System.getUriFor(
@@ -405,8 +405,8 @@
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 0) != 0);
mScreenOffTimeoutSetting = Settings.System.getInt(resolver,
Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
- mStayOnWhilePluggedInSetting = Settings.System.getInt(resolver,
- Settings.System.STAY_ON_WHILE_PLUGGED_IN,
+ mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
BatteryManager.BATTERY_PLUGGED_AC);
final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
@@ -1585,8 +1585,8 @@
}
private void setStayOnSettingInternal(int val) {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.STAY_ON_WHILE_PLUGGED_IN, val);
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
}
/**
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 4539674..18e793d 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -893,6 +893,12 @@
return -1;
}
+ /**
+ * Return the list of Windows from the passed token on the given Display.
+ * @param token The token with all the windows.
+ * @param displayContent The display we are interested in.
+ * @return List of windows from token that are on displayContent.
+ */
WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
final WindowList windowList = new WindowList();
final int count = token.windows.size();
@@ -934,7 +940,7 @@
WindowState lastWindow = tokenWindowList.get(index);
if (atoken != null && lastWindow == atoken.startingWindow) {
placeWindowBefore(lastWindow, win);
- tokenWindowsPos = token.windows.indexOf(lastWindow) - 1;
+ tokenWindowsPos = token.windows.indexOf(lastWindow);
} else {
int newIdx = findIdxBasedOnAppTokens(win);
//there is a window above this one associated with the same
@@ -943,10 +949,15 @@
//windows associated with this token.
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
Slog.v(TAG, "Adding window " + win + " at "
- + (newIdx+1) + " of " + N);
+ + (newIdx + 1) + " of " + N);
}
- windows.add(newIdx+1, win);
- tokenWindowsPos = token.windows.indexOf(windows.get(newIdx)) + 1;
+ windows.add(newIdx + 1, win);
+ if (newIdx < 0) {
+ // No window from token found on win's display.
+ tokenWindowsPos = 0;
+ } else {
+ tokenWindowsPos = token.windows.indexOf(windows.get(newIdx)) + 1;
+ }
mWindowsChanged = true;
}
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
index f0abb50..eed0ec8 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
@@ -153,6 +153,14 @@
canvas.drawLine(10.0f, 45.0f, 20.0f, 55.0f, mSmallPaint);
canvas.drawLine(10.0f, 60.0f, 50.0f, 60.0f, mHairLinePaint);
canvas.restore();
+
+ canvas.save();
+ canvas.scale(10.0f, 50.0f);
+ mSmallPaint.setStrokeWidth(0.0f);
+ canvas.drawLine(20.0f, 9.0f, 30.0f, 11.0f, mSmallPaint);
+ mSmallPaint.setStrokeWidth(1.0f);
+ canvas.drawLine(30.0f, 9.0f, 40.0f, 11.0f, mSmallPaint);
+ canvas.restore();
}
}
}
diff --git a/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/city.png b/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/city.png
deleted file mode 100644
index 856eeff..0000000
--- a/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/city.png
+++ /dev/null
Binary files differ
diff --git a/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img1600x1067.jpg b/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img1600x1067.jpg
new file mode 100644
index 0000000..05d3ee2
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img1600x1067.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img640x427.jpg b/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img640x427.jpg
new file mode 100644
index 0000000..5bce392
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/res/drawable-nodpi/img640x427.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ColorMatrix.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ColorMatrix.java
index 87a2de1..2ac40a1 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ColorMatrix.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ColorMatrix.java
@@ -33,9 +33,11 @@
private ScriptC_colormatrix mScript;
private ScriptIntrinsicColorMatrix mIntrinsic;
private boolean mUseIntrinsic;
+ private boolean mUseGrey;
- public ColorMatrix(boolean useIntrinsic) {
+ public ColorMatrix(boolean useIntrinsic, boolean useGrey) {
mUseIntrinsic = useIntrinsic;
+ mUseGrey = useGrey;
}
public void createTest(android.content.res.Resources res) {
@@ -46,7 +48,11 @@
if (mUseIntrinsic) {
mIntrinsic = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
- mIntrinsic.setColorMatrix(m);
+ if (mUseGrey) {
+ mIntrinsic.setGreyscale();
+ } else {
+ mIntrinsic.setColorMatrix(m);
+ }
} else {
mScript = new ScriptC_colormatrix(mRS, res, R.raw.colormatrix);
mScript.invoke_setMatrix(m);
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 001dea8..37577eb 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -180,12 +180,15 @@
mTest = new Convolve3x3(true);
break;
case 19:
- mTest = new ColorMatrix(false);
+ mTest = new ColorMatrix(false, false);
break;
case 20:
- mTest = new ColorMatrix(true);
+ mTest = new ColorMatrix(true, false);
break;
case 21:
+ mTest = new ColorMatrix(true, true);
+ break;
+ case 22:
mTest = new Copy();
break;
}
@@ -200,7 +203,7 @@
}
void setupTests() {
- mTestNames = new String[22];
+ mTestNames = new String[23];
mTestNames[0] = "Levels Vec3 Relaxed";
mTestNames[1] = "Levels Vec4 Relaxed";
mTestNames[2] = "Levels Vec3 Full";
@@ -222,7 +225,8 @@
mTestNames[18] = "Intrinsics Convolve 3x3";
mTestNames[19] = "ColorMatrix";
mTestNames[20] = "Intrinsics ColorMatrix";
- mTestNames[21] = "Copy";
+ mTestNames[21] = "Intrinsics ColorMatrix Grey";
+ mTestNames[22] = "Copy";
mTestSpinner.setAdapter(new ArrayAdapter<String>(
this, R.layout.spinner_layout, mTestNames));
}
@@ -243,8 +247,8 @@
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
- mBitmapIn = loadBitmap(R.drawable.city);
- mBitmapOut = loadBitmap(R.drawable.city);
+ mBitmapIn = loadBitmap(R.drawable.img1600x1067);
+ mBitmapOut = loadBitmap(R.drawable.img1600x1067);
mSurfaceView = (SurfaceView) findViewById(R.id.surface);