Merge "Import translations. DO NOT MERGE"
diff --git a/api/current.txt b/api/current.txt
index 3230bd8..15351de 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1132,6 +1132,7 @@
field public static final int textAppearanceLargeInverse = 16842819; // 0x1010043
field public static final int textAppearanceLargePopupMenu = 16843521; // 0x1010301
field public static final int textAppearanceListItem = 16843678; // 0x101039e
+ field public static final int textAppearanceListItemSecondary = 16843838; // 0x101043e
field public static final int textAppearanceListItemSmall = 16843679; // 0x101039f
field public static final int textAppearanceMedium = 16842817; // 0x1010041
field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044
@@ -10632,6 +10633,7 @@
method public void setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
method public final void setTileModeY(android.graphics.Shader.TileMode);
method public void setTint(android.content.res.ColorStateList);
+ method public void setTintMode(android.graphics.PorterDuff.Mode);
}
public class ClipDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
@@ -10909,6 +10911,7 @@
method public void setTargetDensity(android.util.DisplayMetrics);
method public void setTargetDensity(int);
method public void setTint(android.content.res.ColorStateList);
+ method public void setTintMode(android.graphics.PorterDuff.Mode);
}
public class PaintDrawable extends android.graphics.drawable.ShapeDrawable {
@@ -10999,6 +11002,9 @@
public class TouchFeedbackDrawable extends android.graphics.drawable.LayerDrawable {
method public android.graphics.Rect getDirtyBounds();
+ method public android.content.res.ColorStateList getTint();
+ method public void setTint(android.content.res.ColorStateList);
+ method public void setTintMode(android.graphics.PorterDuff.Mode);
}
public class TransitionDrawable extends android.graphics.drawable.LayerDrawable implements android.graphics.drawable.Drawable.Callback {
@@ -11721,6 +11727,7 @@
field public static final int CONTROL_AWB_STATE_LOCKED = 3; // 0x3
field public static final int CONTROL_AWB_STATE_SEARCHING = 1; // 0x1
field public static final int CONTROL_CAPTURE_INTENT_CUSTOM = 0; // 0x0
+ field public static final int CONTROL_CAPTURE_INTENT_MANUAL = 6; // 0x6
field public static final int CONTROL_CAPTURE_INTENT_PREVIEW = 1; // 0x1
field public static final int CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2; // 0x2
field public static final int CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3; // 0x3
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 30c84f6..d8be439 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1534,10 +1534,10 @@
/**
* @hide
*/
- public void setActiveAdmin(ComponentName policyReceiver, boolean refreshing) {
+ public void setActiveAdmin(ComponentName policyReceiver, boolean refreshing, int userHandle) {
if (mService != null) {
try {
- mService.setActiveAdmin(policyReceiver, refreshing, UserHandle.myUserId());
+ mService.setActiveAdmin(policyReceiver, refreshing, userHandle);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -1545,6 +1545,13 @@
}
/**
+ * @hide
+ */
+ public void setActiveAdmin(ComponentName policyReceiver, boolean refreshing) {
+ setActiveAdmin(policyReceiver, refreshing, UserHandle.myUserId());
+ }
+
+ /**
* Returns the DeviceAdminInfo as defined by the administrator's package info & meta-data
* @hide
*/
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 101b721..ff3af7c 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -50,6 +50,7 @@
private boolean mAutoConnect;
private int mConnState;
private final Object mStateLock = new Object();
+ private Boolean mDeviceBusy = false;
private static final int CONN_STATE_IDLE = 0;
private static final int CONN_STATE_CONNECTING = 1;
@@ -166,6 +167,10 @@
mConnState = CONN_STATE_IDLE;
}
}
+
+ synchronized(mDeviceBusy) {
+ mDeviceBusy = false;
+ }
}
/**
@@ -301,6 +306,11 @@
if (!address.equals(mDevice.getAddress())) {
return;
}
+
+ synchronized(mDeviceBusy) {
+ mDeviceBusy = false;
+ }
+
if ((status == GATT_INSUFFICIENT_AUTHENTICATION
|| status == GATT_INSUFFICIENT_ENCRYPTION)
&& mAuthRetry == false) {
@@ -348,6 +358,11 @@
if (!address.equals(mDevice.getAddress())) {
return;
}
+
+ synchronized(mDeviceBusy) {
+ mDeviceBusy = false;
+ }
+
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
srvcInstId, srvcType);
if (service == null) return;
@@ -425,6 +440,11 @@
if (!address.equals(mDevice.getAddress())) {
return;
}
+
+ synchronized(mDeviceBusy) {
+ mDeviceBusy = false;
+ }
+
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
srvcInstId, srvcType);
if (service == null) return;
@@ -474,6 +494,11 @@
if (!address.equals(mDevice.getAddress())) {
return;
}
+
+ synchronized(mDeviceBusy) {
+ mDeviceBusy = false;
+ }
+
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
srvcInstId, srvcType);
if (service == null) return;
@@ -519,6 +544,11 @@
if (!address.equals(mDevice.getAddress())) {
return;
}
+
+ synchronized(mDeviceBusy) {
+ mDeviceBusy = false;
+ }
+
try {
mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
} catch (Exception ex) {
@@ -851,6 +881,11 @@
BluetoothDevice device = service.getDevice();
if (device == null) return false;
+ synchronized(mDeviceBusy) {
+ if (mDeviceBusy) return false;
+ mDeviceBusy = true;
+ }
+
try {
mService.readCharacteristic(mClientIf, device.getAddress(),
service.getType(), service.getInstanceId(),
@@ -858,6 +893,7 @@
new ParcelUuid(characteristic.getUuid()), AUTHENTICATION_NONE);
} catch (RemoteException e) {
Log.e(TAG,"",e);
+ mDeviceBusy = false;
return false;
}
@@ -890,6 +926,11 @@
BluetoothDevice device = service.getDevice();
if (device == null) return false;
+ synchronized(mDeviceBusy) {
+ if (mDeviceBusy) return false;
+ mDeviceBusy = true;
+ }
+
try {
mService.writeCharacteristic(mClientIf, device.getAddress(),
service.getType(), service.getInstanceId(),
@@ -899,6 +940,7 @@
characteristic.getValue());
} catch (RemoteException e) {
Log.e(TAG,"",e);
+ mDeviceBusy = false;
return false;
}
@@ -930,6 +972,11 @@
BluetoothDevice device = service.getDevice();
if (device == null) return false;
+ synchronized(mDeviceBusy) {
+ if (mDeviceBusy) return false;
+ mDeviceBusy = true;
+ }
+
try {
mService.readDescriptor(mClientIf, device.getAddress(), service.getType(),
service.getInstanceId(), new ParcelUuid(service.getUuid()),
@@ -938,6 +985,7 @@
AUTHENTICATION_NONE);
} catch (RemoteException e) {
Log.e(TAG,"",e);
+ mDeviceBusy = false;
return false;
}
@@ -968,6 +1016,11 @@
BluetoothDevice device = service.getDevice();
if (device == null) return false;
+ synchronized(mDeviceBusy) {
+ if (mDeviceBusy) return false;
+ mDeviceBusy = true;
+ }
+
try {
mService.writeDescriptor(mClientIf, device.getAddress(), service.getType(),
service.getInstanceId(), new ParcelUuid(service.getUuid()),
@@ -977,6 +1030,7 @@
descriptor.getValue());
} catch (RemoteException e) {
Log.e(TAG,"",e);
+ mDeviceBusy = false;
return false;
}
@@ -1034,10 +1088,16 @@
if (DBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return false;
+ synchronized(mDeviceBusy) {
+ if (mDeviceBusy) return false;
+ mDeviceBusy = true;
+ }
+
try {
mService.endReliableWrite(mClientIf, mDevice.getAddress(), true);
} catch (RemoteException e) {
Log.e(TAG,"",e);
+ mDeviceBusy = false;
return false;
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 5d02ae9..0d1b262 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -447,6 +447,15 @@
public String nativeLibraryDir;
/**
+ * The ABI that this application requires, This is inferred from the ABIs
+ * of the native JNI libraries the application bundles. Will be {@code null}
+ * if this application does not require any particular ABI.
+ *
+ * {@hide}
+ */
+ public String requiredCpuAbi;
+
+ /**
* The kernel user-ID that has been assigned to this application;
* currently this is not a unique ID (multiple applications can have
* the same uid).
@@ -583,6 +592,7 @@
sourceDir = orig.sourceDir;
publicSourceDir = orig.publicSourceDir;
nativeLibraryDir = orig.nativeLibraryDir;
+ requiredCpuAbi = orig.requiredCpuAbi;
resourceDirs = orig.resourceDirs;
seinfo = orig.seinfo;
sharedLibraryFiles = orig.sharedLibraryFiles;
@@ -624,6 +634,7 @@
dest.writeString(sourceDir);
dest.writeString(publicSourceDir);
dest.writeString(nativeLibraryDir);
+ dest.writeString(requiredCpuAbi);
dest.writeStringArray(resourceDirs);
dest.writeString(seinfo);
dest.writeStringArray(sharedLibraryFiles);
@@ -664,6 +675,7 @@
sourceDir = source.readString();
publicSourceDir = source.readString();
nativeLibraryDir = source.readString();
+ requiredCpuAbi = source.readString();
resourceDirs = source.readStringArray();
seinfo = source.readString();
sharedLibraryFiles = source.readStringArray();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 3300e9d..d24a472 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -698,6 +698,25 @@
public static final int INSTALL_FAILED_DUPLICATE_PERMISSION = -112;
/**
+ * Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the system failed to install the package because its packaged native code did not
+ * match any of the ABIs supported by the system.
+ *
+ * @hide
+ */
+ public static final int INSTALL_FAILED_NO_MATCHING_ABIS = -113;
+
+ /**
+ * Internal return code for NativeLibraryHelper methods to indicate that the package
+ * being processed did not contain any native code. This is placed here only so that
+ * it can belong to the same value space as the other install failure codes.
+ *
+ * @hide
+ */
+ public static final int NO_NATIVE_LIBRARIES = -114;
+
+ /**
* Flag parameter for {@link #deletePackage} to indicate that you don't want to delete the
* package's data directory.
*
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 1e34498..9b1bc53 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -940,6 +940,17 @@
*/
public static final int CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5;
+ /**
+ * <p>This request is for manual capture use case where
+ * the applications want to directly control the capture parameters
+ * (e.g. {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}, {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} etc.).</p>
+ *
+ * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+ * @see CaptureRequest#SENSOR_SENSITIVITY
+ * @see CaptureRequest#CONTROL_CAPTURE_INTENT
+ */
+ public static final int CONTROL_CAPTURE_INTENT_MANUAL = 6;
+
//
// Enumeration values for CaptureRequest#CONTROL_EFFECT_MODE
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 7656505..c4e342c 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -714,16 +714,21 @@
* auto-focus, auto-white balance) routines about the purpose
* of this capture, to help the camera device to decide optimal 3A
* strategy.</p>
- * <p>This control is only effective if <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code>
- * and any 3A routine is active.</p>
+ * <p>This control (except for MANUAL) is only effective if
+ * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
+ * <p>ZERO_SHUTTER_LAG must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+ * contains ZSL. MANUAL must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+ * contains MANUAL_SENSOR.</p>
*
* @see CaptureRequest#CONTROL_MODE
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
* @see #CONTROL_CAPTURE_INTENT_CUSTOM
* @see #CONTROL_CAPTURE_INTENT_PREVIEW
* @see #CONTROL_CAPTURE_INTENT_STILL_CAPTURE
* @see #CONTROL_CAPTURE_INTENT_VIDEO_RECORD
* @see #CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT
* @see #CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG
+ * @see #CONTROL_CAPTURE_INTENT_MANUAL
*/
public static final Key<Integer> CONTROL_CAPTURE_INTENT =
new Key<Integer>("android.control.captureIntent", int.class);
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 0d4a4cb..c5e5753 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -461,6 +461,10 @@
return (T) getFaces();
} else if (key.equals(CaptureResult.STATISTICS_FACE_RECTANGLES)) {
return (T) getFaceRectangles();
+ } else if (key.equals(CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS)) {
+ return (T) getAvailableStreamConfigurations();
+ } else if (key.equals(CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS)) {
+ return (T) getAvailableMinFrameDurations();
}
// For other keys, get() falls back to getBase()
@@ -481,6 +485,50 @@
return availableFormats;
}
+ private int[] getAvailableStreamConfigurations() {
+ final int NUM_ELEMENTS_IN_CONFIG = 4;
+ int[] availableConfigs =
+ getBase(CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
+ if (availableConfigs != null) {
+ if (availableConfigs.length % NUM_ELEMENTS_IN_CONFIG != 0) {
+ Log.w(TAG, "availableStreamConfigurations is malformed, length must be multiple"
+ + " of " + NUM_ELEMENTS_IN_CONFIG);
+ return availableConfigs;
+ }
+
+ for (int i = 0; i < availableConfigs.length; i += NUM_ELEMENTS_IN_CONFIG) {
+ // JPEG has different value between native and managed side, need override.
+ if (availableConfigs[i] == NATIVE_JPEG_FORMAT) {
+ availableConfigs[i] = ImageFormat.JPEG;
+ }
+ }
+ }
+
+ return availableConfigs;
+ }
+
+ private long[] getAvailableMinFrameDurations() {
+ final int NUM_ELEMENTS_IN_DURATION = 4;
+ long[] availableMinDurations =
+ getBase(CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
+ if (availableMinDurations != null) {
+ if (availableMinDurations.length % NUM_ELEMENTS_IN_DURATION != 0) {
+ Log.w(TAG, "availableStreamConfigurations is malformed, length must be multiple"
+ + " of " + NUM_ELEMENTS_IN_DURATION);
+ return availableMinDurations;
+ }
+
+ for (int i = 0; i < availableMinDurations.length; i += NUM_ELEMENTS_IN_DURATION) {
+ // JPEG has different value between native and managed side, need override.
+ if (availableMinDurations[i] == NATIVE_JPEG_FORMAT) {
+ availableMinDurations[i] = ImageFormat.JPEG;
+ }
+ }
+ }
+
+ return availableMinDurations;
+ }
+
private Face[] getFaces() {
final int FACE_LANDMARK_SIZE = 6;
@@ -607,12 +655,56 @@
return setAvailableFormats((int[]) value);
} else if (key.equals(CaptureResult.STATISTICS_FACE_RECTANGLES)) {
return setFaceRectangles((Rect[]) value);
+ } else if (key.equals(CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS)) {
+ return setAvailableStreamConfigurations((int[])value);
+ } else if (key.equals(CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS)) {
+ return setAvailableMinFrameDurations((long[])value);
}
// For other keys, set() falls back to setBase().
return false;
}
+ private boolean setAvailableStreamConfigurations(int[] value) {
+ final int NUM_ELEMENTS_IN_CONFIG = 4;
+ int[] availableConfigs = value;
+ if (value == null) {
+ // Let setBase() to handle the null value case.
+ return false;
+ }
+
+ int[] newValues = new int[availableConfigs.length];
+ for (int i = 0; i < availableConfigs.length; i++) {
+ newValues[i] = availableConfigs[i];
+ if (i % NUM_ELEMENTS_IN_CONFIG == 0 && availableConfigs[i] == ImageFormat.JPEG) {
+ newValues[i] = NATIVE_JPEG_FORMAT;
+ }
+ }
+
+ setBase(CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS, newValues);
+ return true;
+ }
+
+ private boolean setAvailableMinFrameDurations(long[] value) {
+ final int NUM_ELEMENTS_IN_DURATION = 4;
+ long[] availableDurations = value;
+ if (value == null) {
+ // Let setBase() to handle the null value case.
+ return false;
+ }
+
+ long[] newValues = new long[availableDurations.length];
+ for (int i = 0; i < availableDurations.length; i++) {
+ newValues[i] = availableDurations[i];
+ if (i % NUM_ELEMENTS_IN_DURATION == 0 && availableDurations[i] == ImageFormat.JPEG) {
+ newValues[i] = NATIVE_JPEG_FORMAT;
+ }
+ }
+
+ setBase(CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS, newValues);
+ return true;
+ }
+
private boolean setAvailableFormats(int[] value) {
int[] availableFormat = value;
if (value == null) {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index c8051aa..7f1a2e4 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -74,7 +74,14 @@
/** A hardware serial number, if available. Alphanumeric only, case-insensitive. */
public static final String SERIAL = getString("ro.serialno");
-
+
+ /**
+ * A list of ABIs (in priority) order supported by this device.
+ *
+ * @hide
+ */
+ public static final String[] SUPPORTED_ABIS = getString("ro.product.cpu.abilist").split(",");
+
/** Various version strings. */
public static class VERSION {
/**
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 79ff49c..c947eda 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -466,6 +466,7 @@
* @param debugFlags Additional flags.
* @param targetSdkVersion The target SDK version for the app.
* @param seInfo null-ok SELinux information for the new process.
+ * @param abi non-null the ABI this app should be started with.
* @param zygoteArgs Additional arguments to supply to the zygote process.
*
* @return An object that describes the result of the attempt to start the process.
@@ -479,12 +480,12 @@
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
+ String abi,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
- null, /* zygoteAbi TODO: Replace this with the real ABI */
- zygoteArgs);
+ abi, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -702,13 +703,6 @@
primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET, getNumTries(primaryZygoteState));
}
- // TODO: Revert this temporary change. This is required to test
- // and submit this change ahead of the package manager changes
- // that supply this abi.
- if (abi == null) {
- return primaryZygoteState;
- }
-
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 2ef5b66..939cda9 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -625,12 +625,13 @@
return _result;
}
- public int encryptStorage(String password) throws RemoteException {
+ public int encryptStorage(int type, String password) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(type);
_data.writeString(password);
mRemote.transact(Stub.TRANSACTION_encryptStorage, _data, _reply, 0);
_reply.readException();
@@ -1210,8 +1211,9 @@
}
case TRANSACTION_encryptStorage: {
data.enforceInterface(DESCRIPTOR);
+ int type = data.readInt();
String password = data.readString();
- int result = encryptStorage(password);
+ int result = encryptStorage(type, password);
reply.writeNoException();
reply.writeInt(result);
return true;
@@ -1495,7 +1497,7 @@
/**
* Encrypts storage.
*/
- public int encryptStorage(String password) throws RemoteException;
+ public int encryptStorage(int type, String password) throws RemoteException;
/**
* Changes the encryption password.
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 144c909..56d5617 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -533,8 +533,7 @@
* @see #onCreateView(ViewGroup)
*/
protected void onBindView(View view) {
- final TextView titleView = (TextView) view.findViewById(
- com.android.internal.R.id.title);
+ final TextView titleView = (TextView) view.findViewById(com.android.internal.R.id.title);
if (titleView != null) {
final CharSequence title = getTitle();
if (!TextUtils.isEmpty(title)) {
@@ -557,7 +556,7 @@
}
}
- ImageView imageView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
+ final ImageView imageView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
if (imageView != null) {
if (mIconResId != 0 || mIcon != null) {
if (mIcon == null) {
@@ -570,6 +569,11 @@
imageView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
}
+ final View imageFrame = view.findViewById(com.android.internal.R.id.icon_frame);
+ if (imageFrame != null) {
+ imageFrame.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
+ }
+
if (mShouldDisableView) {
setEnabledStateOnViews(view, isEnabled());
}
diff --git a/core/java/android/provider/SearchIndexablesContract.java b/core/java/android/provider/SearchIndexablesContract.java
index 05f3a1c..1754dce 100644
--- a/core/java/android/provider/SearchIndexablesContract.java
+++ b/core/java/android/provider/SearchIndexablesContract.java
@@ -58,33 +58,64 @@
* Indexable xml resources colums.
*/
public static final String[] INDEXABLES_XML_RES_COLUMNS = new String[] {
- XmlResource.COLUMN_RANK,
- XmlResource.COLUMN_XML_RESID,
- XmlResource.COLUMN_CLASS_NAME,
- XmlResource.COLUMN_ICON_RESID,
- XmlResource.COLUMN_INTENT_ACTION,
- XmlResource.COLUMN_INTENT_TARGET_PACKAGE,
- XmlResource.COLUMN_INTENT_TARGET_CLASS
+ XmlResource.COLUMN_RANK, // 0
+ XmlResource.COLUMN_XML_RESID, // 1
+ XmlResource.COLUMN_CLASS_NAME, // 2
+ XmlResource.COLUMN_ICON_RESID, // 3
+ XmlResource.COLUMN_INTENT_ACTION, // 4
+ XmlResource.COLUMN_INTENT_TARGET_PACKAGE, // 5
+ XmlResource.COLUMN_INTENT_TARGET_CLASS // 6
};
/**
+ * Indexable xml resources colums indices.
+ */
+ public static final int COLUMN_INDEX_XML_RES_RANK = 0;
+ public static final int COLUMN_INDEX_XML_RES_RESID = 1;
+ public static final int COLUMN_INDEX_XML_RES_CLASS_NAME = 2;
+ public static final int COLUMN_INDEX_XML_RES_ICON_RESID = 3;
+ public static final int COLUMN_INDEX_XML_RES_INTENT_ACTION = 4;
+ public static final int COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE = 5;
+ public static final int COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS = 6;
+
+ /**
* Indexable raw data colums.
*/
public static final String[] INDEXABLES_RAW_COLUMNS = new String[] {
- RawData.COLUMN_RANK,
- RawData.COLUMN_TITLE,
- RawData.COLUMN_SUMMARY_ON,
- RawData.COLUMN_SUMMARY_OFF,
- RawData.COLUMN_KEYWORDS,
- RawData.COLUMN_SCREEN_TITLE,
- RawData.COLUMN_CLASS_NAME,
- RawData.COLUMN_ICON_RESID,
- RawData.COLUMN_INTENT_ACTION,
- RawData.COLUMN_INTENT_TARGET_PACKAGE,
- RawData.COLUMN_INTENT_TARGET_CLASS,
+ RawData.COLUMN_RANK, // 0
+ RawData.COLUMN_TITLE, // 1
+ RawData.COLUMN_SUMMARY_ON, // 2
+ RawData.COLUMN_SUMMARY_OFF, // 3
+ RawData.COLUMN_ENTRIES, // 4
+ RawData.COLUMN_KEYWORDS, // 5
+ RawData.COLUMN_SCREEN_TITLE, // 6
+ RawData.COLUMN_CLASS_NAME, // 7
+ RawData.COLUMN_ICON_RESID, // 8
+ RawData.COLUMN_INTENT_ACTION, // 9
+ RawData.COLUMN_INTENT_TARGET_PACKAGE, // 10
+ RawData.COLUMN_INTENT_TARGET_CLASS, // 11
+ RawData.COLUMN_KEY, // 12
};
/**
+ * Indexable raw data colums indices.
+ */
+ public static final int COLUMN_INDEX_RAW_RANK = 0;
+ public static final int COLUMN_INDEX_RAW_TITLE = 1;
+ public static final int COLUMN_INDEX_RAW_SUMMARY_ON = 2;
+ public static final int COLUMN_INDEX_RAW_SUMMARY_OFF = 3;
+ public static final int COLUMN_INDEX_RAW_ENTRIES = 4;
+ public static final int COLUMN_INDEX_RAW_KEYWORDS = 5;
+ public static final int COLUMN_INDEX_RAW_SCREEN_TITLE = 6;
+ public static final int COLUMN_INDEX_RAW_CLASS_NAME = 7;
+ public static final int COLUMN_INDEX_RAW_ICON_RESID = 8;
+ public static final int COLUMN_INDEX_RAW_INTENT_ACTION = 9;
+ public static final int COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE = 10;
+ public static final int COLUMN_INDEX_RAW_INTENT_TARGET_CLASS = 11;
+ public static final int COLUMN_INDEX_RAW_KEY = 12;
+
+
+ /**
* Constants related to a {@link SearchIndexableResource}.
*
* This is a description of
@@ -134,6 +165,11 @@
public static final String COLUMN_SUMMARY_OFF = "summaryOff";
/**
+ * Entries associated with the raw data (when the data can can several values).
+ */
+ public static final String COLUMN_ENTRIES = "entries";
+
+ /**
* Keywords' raw data.
*/
public static final String COLUMN_KEYWORDS = "keywords";
@@ -142,6 +178,11 @@
* Fragment's title associated with the raw data.
*/
public static final String COLUMN_SCREEN_TITLE = "screenTitle";
+
+ /**
+ * Key associated with the raw data. The key needs to be unique.
+ */
+ public static final String COLUMN_KEY = "key";
}
/**
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index ad33b6f..eba4f7f 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -838,6 +838,11 @@
}
}
+ @Override
+ void pauseSurface(Surface surface) {
+ // No-op
+ }
+
boolean initializeEgl() {
synchronized (sEglLock) {
if (sEgl == null && sEglConfig == null) {
@@ -1221,11 +1226,6 @@
}
}
- void setDisplayListData(long displayList, long newData) {
- nSetDisplayListData(displayList, newData);
- }
- private static native void nSetDisplayListData(long displayList, long newData);
-
@Override
void fence() {
// Everything is immediate, so this is a no-op
@@ -1317,7 +1317,7 @@
}
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
- nUpdateRenderNodeProperties(displayList.getNativeDisplayList());
+ nPrepareTree(displayList.getNativeDisplayList());
try {
status |= canvas.drawDisplayList(displayList, mRedrawClip,
RenderNode.FLAG_CLIP_CHILDREN);
@@ -1476,7 +1476,7 @@
static native void nDestroyLayer(long layerPtr);
- private static native void nUpdateRenderNodeProperties(long displayListPtr);
+ private static native void nPrepareTree(long displayListPtr);
class DrawPerformanceDataProvider extends GraphDataProvider {
private final int mGraphType;
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 92d85d1..56d96e1 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -234,6 +234,13 @@
abstract void updateSurface(Surface surface) throws OutOfResourcesException;
/**
+ * Stops any rendering into the surface. Use this if it is unclear whether
+ * or not the surface used by the HardwareRenderer will be changing. It
+ * Suspends any rendering into the surface, but will not do any destruction
+ */
+ abstract void pauseSurface(Surface surface);
+
+ /**
* Destroys all hardware rendering resources associated with the specified
* view hierarchy.
*
@@ -573,8 +580,6 @@
mRequested = requested;
}
- abstract void setDisplayListData(long displayList, long newData);
-
/**
* Blocks until all previously queued work has completed.
*/
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 78ddf5b..30e4281 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -174,12 +174,10 @@
public static final int STATUS_DREW = 0x4;
private boolean mValid;
- private final long mNativeDisplayList;
- private HardwareRenderer mRenderer;
+ private final long mNativeRenderNode;
private RenderNode(String name) {
- mNativeDisplayList = nCreate();
- nSetDisplayListName(mNativeDisplayList, name);
+ mNativeRenderNode = nCreate(name);
}
/**
@@ -202,7 +200,7 @@
* stored in this display list.
*
* Calling this method will mark the render node invalid until
- * {@link #end(HardwareRenderer, HardwareCanvas)} is called.
+ * {@link #end(HardwareCanvas)} is called.
* Only valid render nodes can be replayed.
*
* @param width The width of the recording viewport
@@ -210,7 +208,7 @@
*
* @return A canvas to record drawing operations.
*
- * @see #end(HardwareRenderer, HardwareCanvas)
+ * @see #end(HardwareCanvas)
* @see #isValid()
*/
public HardwareCanvas start(int width, int height) {
@@ -229,21 +227,15 @@
* @see #start(int, int)
* @see #isValid()
*/
- public void end(HardwareRenderer renderer, HardwareCanvas endCanvas) {
+ public void end(HardwareCanvas endCanvas) {
if (!(endCanvas instanceof GLES20RecordingCanvas)) {
throw new IllegalArgumentException("Passed an invalid canvas to end!");
}
GLES20RecordingCanvas canvas = (GLES20RecordingCanvas) endCanvas;
canvas.onPostDraw();
- long displayListData = canvas.finishRecording();
- if (renderer != mRenderer) {
- // If we are changing renderers first destroy with the old
- // renderer, then set with the new one
- destroyDisplayListData();
- }
- mRenderer = renderer;
- setDisplayListData(displayListData);
+ long renderNodeData = canvas.finishRecording();
+ nSetDisplayListData(mNativeRenderNode, renderNodeData);
canvas.recycle();
mValid = true;
}
@@ -258,19 +250,10 @@
public void destroyDisplayListData() {
if (!mValid) return;
- setDisplayListData(0);
- mRenderer = null;
+ nSetDisplayListData(mNativeRenderNode, 0);
mValid = false;
}
- private void setDisplayListData(long newData) {
- if (mRenderer != null) {
- mRenderer.setDisplayListData(mNativeDisplayList, newData);
- } else {
- throw new IllegalStateException("Trying to set data without a renderer! data=" + newData);
- }
- }
-
/**
* Returns whether the RenderNode's display list content is currently usable.
* If this returns false, the display list should be re-recorded prior to replaying it.
@@ -283,7 +266,7 @@
if (!mValid) {
throw new IllegalStateException("The display list is not valid.");
}
- return mNativeDisplayList;
+ return mNativeRenderNode;
}
///////////////////////////////////////////////////////////////////////////
@@ -291,15 +274,15 @@
///////////////////////////////////////////////////////////////////////////
public boolean hasIdentityMatrix() {
- return nHasIdentityMatrix(mNativeDisplayList);
+ return nHasIdentityMatrix(mNativeRenderNode);
}
public void getMatrix(@NonNull Matrix outMatrix) {
- nGetTransformMatrix(mNativeDisplayList, outMatrix.native_instance);
+ nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
}
public void getInverseMatrix(@NonNull Matrix outMatrix) {
- nGetInverseTransformMatrix(mNativeDisplayList, outMatrix.native_instance);
+ nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
}
///////////////////////////////////////////////////////////////////////////
@@ -316,7 +299,7 @@
* @hide
*/
public void setCaching(boolean caching) {
- nSetCaching(mNativeDisplayList, caching);
+ nSetCaching(mNativeRenderNode, caching);
}
/**
@@ -326,7 +309,7 @@
* @param clipToBounds true if the display list should clip to its bounds
*/
public void setClipToBounds(boolean clipToBounds) {
- nSetClipToBounds(mNativeDisplayList, clipToBounds);
+ nSetClipToBounds(mNativeRenderNode, clipToBounds);
}
/**
@@ -337,7 +320,7 @@
* containing volume.
*/
public void setProjectBackwards(boolean shouldProject) {
- nSetProjectBackwards(mNativeDisplayList, shouldProject);
+ nSetProjectBackwards(mNativeRenderNode, shouldProject);
}
/**
@@ -346,7 +329,7 @@
* ProjectBackwards=true directly on top of it. Default value is false.
*/
public void setProjectionReceiver(boolean shouldRecieve) {
- nSetProjectionReceiver(mNativeDisplayList, shouldRecieve);
+ nSetProjectionReceiver(mNativeRenderNode, shouldRecieve);
}
/**
@@ -357,14 +340,14 @@
*/
public void setOutline(Outline outline) {
if (outline == null) {
- nSetOutlineEmpty(mNativeDisplayList);
+ nSetOutlineEmpty(mNativeRenderNode);
} else if (!outline.isValid()) {
throw new IllegalArgumentException("Outline must be valid");
} else if (outline.mRect != null) {
- nSetOutlineRoundRect(mNativeDisplayList, outline.mRect.left, outline.mRect.top,
+ nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top,
outline.mRect.right, outline.mRect.bottom, outline.mRadius);
} else if (outline.mPath != null) {
- nSetOutlineConvexPath(mNativeDisplayList, outline.mPath.mNativePath);
+ nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath);
}
}
@@ -374,7 +357,7 @@
* @param clipToOutline true if clipping to the outline.
*/
public void setClipToOutline(boolean clipToOutline) {
- nSetClipToOutline(mNativeDisplayList, clipToOutline);
+ nSetClipToOutline(mNativeRenderNode, clipToOutline);
}
/**
@@ -382,7 +365,7 @@
*/
public void setRevealClip(boolean shouldClip, boolean inverseClip,
float x, float y, float radius) {
- nSetRevealClip(mNativeDisplayList, shouldClip, inverseClip, x, y, radius);
+ nSetRevealClip(mNativeRenderNode, shouldClip, inverseClip, x, y, radius);
}
/**
@@ -392,7 +375,7 @@
* @param matrix A transform matrix to apply to this display list
*/
public void setStaticMatrix(Matrix matrix) {
- nSetStaticMatrix(mNativeDisplayList, matrix.native_instance);
+ nSetStaticMatrix(mNativeRenderNode, matrix.native_instance);
}
/**
@@ -406,7 +389,7 @@
* @hide
*/
public void setAnimationMatrix(Matrix matrix) {
- nSetAnimationMatrix(mNativeDisplayList,
+ nSetAnimationMatrix(mNativeRenderNode,
(matrix != null) ? matrix.native_instance : 0);
}
@@ -419,7 +402,7 @@
* @see #getAlpha()
*/
public void setAlpha(float alpha) {
- nSetAlpha(mNativeDisplayList, alpha);
+ nSetAlpha(mNativeRenderNode, alpha);
}
/**
@@ -430,7 +413,7 @@
* @see #setAlpha(float)
*/
public float getAlpha() {
- return nGetAlpha(mNativeDisplayList);
+ return nGetAlpha(mNativeRenderNode);
}
/**
@@ -445,7 +428,7 @@
* @see #hasOverlappingRendering()
*/
public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
- nSetHasOverlappingRendering(mNativeDisplayList, hasOverlappingRendering);
+ nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering);
}
/**
@@ -457,7 +440,7 @@
*/
public boolean hasOverlappingRendering() {
//noinspection SimplifiableIfStatement
- return nHasOverlappingRendering(mNativeDisplayList);
+ return nHasOverlappingRendering(mNativeRenderNode);
}
/**
@@ -469,7 +452,7 @@
* @see #getTranslationX()
*/
public void setTranslationX(float translationX) {
- nSetTranslationX(mNativeDisplayList, translationX);
+ nSetTranslationX(mNativeRenderNode, translationX);
}
/**
@@ -478,7 +461,7 @@
* @see #setTranslationX(float)
*/
public float getTranslationX() {
- return nGetTranslationX(mNativeDisplayList);
+ return nGetTranslationX(mNativeRenderNode);
}
/**
@@ -490,7 +473,7 @@
* @see #getTranslationY()
*/
public void setTranslationY(float translationY) {
- nSetTranslationY(mNativeDisplayList, translationY);
+ nSetTranslationY(mNativeRenderNode, translationY);
}
/**
@@ -499,7 +482,7 @@
* @see #setTranslationY(float)
*/
public float getTranslationY() {
- return nGetTranslationY(mNativeDisplayList);
+ return nGetTranslationY(mNativeRenderNode);
}
/**
@@ -509,7 +492,7 @@
* @see #getTranslationZ()
*/
public void setTranslationZ(float translationZ) {
- nSetTranslationZ(mNativeDisplayList, translationZ);
+ nSetTranslationZ(mNativeRenderNode, translationZ);
}
/**
@@ -518,7 +501,7 @@
* @see #setTranslationZ(float)
*/
public float getTranslationZ() {
- return nGetTranslationZ(mNativeDisplayList);
+ return nGetTranslationZ(mNativeRenderNode);
}
/**
@@ -530,7 +513,7 @@
* @see #getRotation()
*/
public void setRotation(float rotation) {
- nSetRotation(mNativeDisplayList, rotation);
+ nSetRotation(mNativeRenderNode, rotation);
}
/**
@@ -539,7 +522,7 @@
* @see #setRotation(float)
*/
public float getRotation() {
- return nGetRotation(mNativeDisplayList);
+ return nGetRotation(mNativeRenderNode);
}
/**
@@ -551,7 +534,7 @@
* @see #getRotationX()
*/
public void setRotationX(float rotationX) {
- nSetRotationX(mNativeDisplayList, rotationX);
+ nSetRotationX(mNativeRenderNode, rotationX);
}
/**
@@ -560,7 +543,7 @@
* @see #setRotationX(float)
*/
public float getRotationX() {
- return nGetRotationX(mNativeDisplayList);
+ return nGetRotationX(mNativeRenderNode);
}
/**
@@ -572,7 +555,7 @@
* @see #getRotationY()
*/
public void setRotationY(float rotationY) {
- nSetRotationY(mNativeDisplayList, rotationY);
+ nSetRotationY(mNativeRenderNode, rotationY);
}
/**
@@ -581,7 +564,7 @@
* @see #setRotationY(float)
*/
public float getRotationY() {
- return nGetRotationY(mNativeDisplayList);
+ return nGetRotationY(mNativeRenderNode);
}
/**
@@ -593,7 +576,7 @@
* @see #getScaleX()
*/
public void setScaleX(float scaleX) {
- nSetScaleX(mNativeDisplayList, scaleX);
+ nSetScaleX(mNativeRenderNode, scaleX);
}
/**
@@ -602,7 +585,7 @@
* @see #setScaleX(float)
*/
public float getScaleX() {
- return nGetScaleX(mNativeDisplayList);
+ return nGetScaleX(mNativeRenderNode);
}
/**
@@ -614,7 +597,7 @@
* @see #getScaleY()
*/
public void setScaleY(float scaleY) {
- nSetScaleY(mNativeDisplayList, scaleY);
+ nSetScaleY(mNativeRenderNode, scaleY);
}
/**
@@ -623,7 +606,7 @@
* @see #setScaleY(float)
*/
public float getScaleY() {
- return nGetScaleY(mNativeDisplayList);
+ return nGetScaleY(mNativeRenderNode);
}
/**
@@ -635,7 +618,7 @@
* @see #getPivotX()
*/
public void setPivotX(float pivotX) {
- nSetPivotX(mNativeDisplayList, pivotX);
+ nSetPivotX(mNativeRenderNode, pivotX);
}
/**
@@ -644,7 +627,7 @@
* @see #setPivotX(float)
*/
public float getPivotX() {
- return nGetPivotX(mNativeDisplayList);
+ return nGetPivotX(mNativeRenderNode);
}
/**
@@ -656,7 +639,7 @@
* @see #getPivotY()
*/
public void setPivotY(float pivotY) {
- nSetPivotY(mNativeDisplayList, pivotY);
+ nSetPivotY(mNativeRenderNode, pivotY);
}
/**
@@ -665,11 +648,11 @@
* @see #setPivotY(float)
*/
public float getPivotY() {
- return nGetPivotY(mNativeDisplayList);
+ return nGetPivotY(mNativeRenderNode);
}
public boolean isPivotExplicitlySet() {
- return nIsPivotExplicitlySet(mNativeDisplayList);
+ return nIsPivotExplicitlySet(mNativeRenderNode);
}
/**
@@ -683,7 +666,7 @@
* @see #getCameraDistance()
*/
public void setCameraDistance(float distance) {
- nSetCameraDistance(mNativeDisplayList, distance);
+ nSetCameraDistance(mNativeRenderNode, distance);
}
/**
@@ -692,7 +675,7 @@
* @see #setCameraDistance(float)
*/
public float getCameraDistance() {
- return nGetCameraDistance(mNativeDisplayList);
+ return nGetCameraDistance(mNativeRenderNode);
}
/**
@@ -704,7 +687,7 @@
* @see #getLeft()
*/
public void setLeft(int left) {
- nSetLeft(mNativeDisplayList, left);
+ nSetLeft(mNativeRenderNode, left);
}
/**
@@ -713,7 +696,7 @@
* @see #setLeft(int)
*/
public float getLeft() {
- return nGetLeft(mNativeDisplayList);
+ return nGetLeft(mNativeRenderNode);
}
/**
@@ -725,7 +708,7 @@
* @see #getTop()
*/
public void setTop(int top) {
- nSetTop(mNativeDisplayList, top);
+ nSetTop(mNativeRenderNode, top);
}
/**
@@ -734,7 +717,7 @@
* @see #setTop(int)
*/
public float getTop() {
- return nGetTop(mNativeDisplayList);
+ return nGetTop(mNativeRenderNode);
}
/**
@@ -746,7 +729,7 @@
* @see #getRight()
*/
public void setRight(int right) {
- nSetRight(mNativeDisplayList, right);
+ nSetRight(mNativeRenderNode, right);
}
/**
@@ -755,7 +738,7 @@
* @see #setRight(int)
*/
public float getRight() {
- return nGetRight(mNativeDisplayList);
+ return nGetRight(mNativeRenderNode);
}
/**
@@ -767,7 +750,7 @@
* @see #getBottom()
*/
public void setBottom(int bottom) {
- nSetBottom(mNativeDisplayList, bottom);
+ nSetBottom(mNativeRenderNode, bottom);
}
/**
@@ -776,7 +759,7 @@
* @see #setBottom(int)
*/
public float getBottom() {
- return nGetBottom(mNativeDisplayList);
+ return nGetBottom(mNativeRenderNode);
}
/**
@@ -793,7 +776,7 @@
* @see View#setBottom(int)
*/
public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
- nSetLeftTopRightBottom(mNativeDisplayList, left, top, right, bottom);
+ nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
}
/**
@@ -805,7 +788,7 @@
* @see View#offsetLeftAndRight(int)
*/
public void offsetLeftAndRight(float offset) {
- nOffsetLeftAndRight(mNativeDisplayList, offset);
+ nOffsetLeftAndRight(mNativeRenderNode, offset);
}
/**
@@ -817,7 +800,7 @@
* @see View#offsetTopAndBottom(int)
*/
public void offsetTopAndBottom(float offset) {
- nOffsetTopAndBottom(mNativeDisplayList, offset);
+ nOffsetTopAndBottom(mNativeRenderNode, offset);
}
/**
@@ -827,80 +810,80 @@
* @hide
*/
public void output() {
- nOutput(mNativeDisplayList);
+ nOutput(mNativeRenderNode);
}
///////////////////////////////////////////////////////////////////////////
// Native methods
///////////////////////////////////////////////////////////////////////////
- private static native long nCreate();
- private static native void nDestroyDisplayList(long displayList);
- private static native void nSetDisplayListName(long displayList, String name);
+ private static native long nCreate(String name);
+ private static native void nDestroyRenderNode(long renderNode);
+ private static native void nSetDisplayListData(long renderNode, long newData);
// Matrix
- private static native void nGetTransformMatrix(long displayList, long nativeMatrix);
- private static native void nGetInverseTransformMatrix(long displayList, long nativeMatrix);
- private static native boolean nHasIdentityMatrix(long displayList);
+ private static native void nGetTransformMatrix(long renderNode, long nativeMatrix);
+ private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix);
+ private static native boolean nHasIdentityMatrix(long renderNode);
// Properties
- private static native void nOffsetTopAndBottom(long displayList, float offset);
- private static native void nOffsetLeftAndRight(long displayList, float offset);
- private static native void nSetLeftTopRightBottom(long displayList, int left, int top,
+ private static native void nOffsetTopAndBottom(long renderNode, float offset);
+ private static native void nOffsetLeftAndRight(long renderNode, float offset);
+ private static native void nSetLeftTopRightBottom(long renderNode, int left, int top,
int right, int bottom);
- private static native void nSetBottom(long displayList, int bottom);
- private static native void nSetRight(long displayList, int right);
- private static native void nSetTop(long displayList, int top);
- private static native void nSetLeft(long displayList, int left);
- private static native void nSetCameraDistance(long displayList, float distance);
- private static native void nSetPivotY(long displayList, float pivotY);
- private static native void nSetPivotX(long displayList, float pivotX);
- private static native void nSetCaching(long displayList, boolean caching);
- private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
- private static native void nSetProjectBackwards(long displayList, boolean shouldProject);
- private static native void nSetProjectionReceiver(long displayList, boolean shouldRecieve);
- private static native void nSetOutlineRoundRect(long displayList, int left, int top,
+ private static native void nSetBottom(long renderNode, int bottom);
+ private static native void nSetRight(long renderNode, int right);
+ private static native void nSetTop(long renderNode, int top);
+ private static native void nSetLeft(long renderNode, int left);
+ private static native void nSetCameraDistance(long renderNode, float distance);
+ private static native void nSetPivotY(long renderNode, float pivotY);
+ private static native void nSetPivotX(long renderNode, float pivotX);
+ private static native void nSetCaching(long renderNode, boolean caching);
+ private static native void nSetClipToBounds(long renderNode, boolean clipToBounds);
+ private static native void nSetProjectBackwards(long renderNode, boolean shouldProject);
+ private static native void nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
+ private static native void nSetOutlineRoundRect(long renderNode, int left, int top,
int right, int bottom, float radius);
- private static native void nSetOutlineConvexPath(long displayList, long nativePath);
- private static native void nSetOutlineEmpty(long displayList);
- private static native void nSetClipToOutline(long displayList, boolean clipToOutline);
- private static native void nSetRevealClip(long displayList,
+ private static native void nSetOutlineConvexPath(long renderNode, long nativePath);
+ private static native void nSetOutlineEmpty(long renderNode);
+ private static native void nSetClipToOutline(long renderNode, boolean clipToOutline);
+ private static native void nSetRevealClip(long renderNode,
boolean shouldClip, boolean inverseClip, float x, float y, float radius);
- private static native void nSetAlpha(long displayList, float alpha);
- private static native void nSetHasOverlappingRendering(long displayList,
+ private static native void nSetAlpha(long renderNode, float alpha);
+ private static native void nSetHasOverlappingRendering(long renderNode,
boolean hasOverlappingRendering);
- private static native void nSetTranslationX(long displayList, float translationX);
- private static native void nSetTranslationY(long displayList, float translationY);
- private static native void nSetTranslationZ(long displayList, float translationZ);
- private static native void nSetRotation(long displayList, float rotation);
- private static native void nSetRotationX(long displayList, float rotationX);
- private static native void nSetRotationY(long displayList, float rotationY);
- private static native void nSetScaleX(long displayList, float scaleX);
- private static native void nSetScaleY(long displayList, float scaleY);
- private static native void nSetStaticMatrix(long displayList, long nativeMatrix);
- private static native void nSetAnimationMatrix(long displayList, long animationMatrix);
+ private static native void nSetTranslationX(long renderNode, float translationX);
+ private static native void nSetTranslationY(long renderNode, float translationY);
+ private static native void nSetTranslationZ(long renderNode, float translationZ);
+ private static native void nSetRotation(long renderNode, float rotation);
+ private static native void nSetRotationX(long renderNode, float rotationX);
+ private static native void nSetRotationY(long renderNode, float rotationY);
+ private static native void nSetScaleX(long renderNode, float scaleX);
+ private static native void nSetScaleY(long renderNode, float scaleY);
+ private static native void nSetStaticMatrix(long renderNode, long nativeMatrix);
+ private static native void nSetAnimationMatrix(long renderNode, long animationMatrix);
- private static native boolean nHasOverlappingRendering(long displayList);
- private static native float nGetAlpha(long displayList);
- private static native float nGetLeft(long displayList);
- private static native float nGetTop(long displayList);
- private static native float nGetRight(long displayList);
- private static native float nGetBottom(long displayList);
- private static native float nGetCameraDistance(long displayList);
- private static native float nGetScaleX(long displayList);
- private static native float nGetScaleY(long displayList);
- private static native float nGetTranslationX(long displayList);
- private static native float nGetTranslationY(long displayList);
- private static native float nGetTranslationZ(long displayList);
- private static native float nGetRotation(long displayList);
- private static native float nGetRotationX(long displayList);
- private static native float nGetRotationY(long displayList);
- private static native boolean nIsPivotExplicitlySet(long displayList);
- private static native float nGetPivotX(long displayList);
- private static native float nGetPivotY(long displayList);
- private static native void nOutput(long displayList);
+ private static native boolean nHasOverlappingRendering(long renderNode);
+ private static native float nGetAlpha(long renderNode);
+ private static native float nGetLeft(long renderNode);
+ private static native float nGetTop(long renderNode);
+ private static native float nGetRight(long renderNode);
+ private static native float nGetBottom(long renderNode);
+ private static native float nGetCameraDistance(long renderNode);
+ private static native float nGetScaleX(long renderNode);
+ private static native float nGetScaleY(long renderNode);
+ private static native float nGetTranslationX(long renderNode);
+ private static native float nGetTranslationY(long renderNode);
+ private static native float nGetTranslationZ(long renderNode);
+ private static native float nGetRotation(long renderNode);
+ private static native float nGetRotationX(long renderNode);
+ private static native float nGetRotationY(long renderNode);
+ private static native boolean nIsPivotExplicitlySet(long renderNode);
+ private static native float nGetPivotX(long renderNode);
+ private static native float nGetPivotY(long renderNode);
+ private static native void nOutput(long renderNode);
///////////////////////////////////////////////////////////////////////////
// Finalization
@@ -909,7 +892,7 @@
@Override
protected void finalize() throws Throwable {
try {
- nDestroyDisplayList(mNativeDisplayList);
+ nDestroyRenderNode(mNativeRenderNode);
} finally {
super.finalize();
}
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index a747ab6..1ecc3c6 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -54,28 +54,46 @@
private int mWidth, mHeight;
private long mNativeProxy;
+ private boolean mInitialized = false;
ThreadedRenderer(boolean translucent) {
mNativeProxy = nCreateProxy(translucent);
- setEnabled(mNativeProxy != 0);
}
@Override
void destroy(boolean full) {
+ mInitialized = false;
+ updateEnabledState(null);
nDestroyCanvas(mNativeProxy);
}
+ private void updateEnabledState(Surface surface) {
+ if (surface == null || !surface.isValid()) {
+ setEnabled(false);
+ } else {
+ setEnabled(mInitialized);
+ }
+ }
+
@Override
boolean initialize(Surface surface) throws OutOfResourcesException {
+ mInitialized = true;
+ updateEnabledState(surface);
return nInitialize(mNativeProxy, surface);
}
@Override
void updateSurface(Surface surface) throws OutOfResourcesException {
+ updateEnabledState(surface);
nUpdateSurface(mNativeProxy, surface);
}
@Override
+ void pauseSurface(Surface surface) {
+ nPauseSurface(mNativeProxy, surface);
+ }
+
+ @Override
void destroyHardwareResources(View view) {
destroyResources(view);
// TODO: GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
@@ -148,11 +166,6 @@
}
@Override
- void setDisplayListData(long displayList, long newData) {
- nSetDisplayListData(mNativeProxy, displayList, newData);
- }
-
- @Override
void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) {
attachInfo.mIgnoreDirtyState = true;
attachInfo.mDrawingTime = SystemClock.uptimeMillis();
@@ -267,6 +280,7 @@
private static native boolean nInitialize(long nativeProxy, Surface window);
private static native void nUpdateSurface(long nativeProxy, Surface window);
+ private static native void nPauseSurface(long nativeProxy, Surface window);
private static native void nSetup(long nativeProxy, int width, int height);
private static native void nSetDisplayListData(long nativeProxy, long displayList,
long newData);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6c414f6..9761f1a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13549,11 +13549,10 @@
* @return A new or reused DisplayList object.
*/
private void updateDisplayListIfDirty(@NonNull RenderNode renderNode, boolean isLayer) {
- final HardwareRenderer renderer = getHardwareRenderer();
if (renderNode == null) {
throw new IllegalArgumentException("RenderNode must not be null");
}
- if (renderer == null || !canHaveDisplayList()) {
+ if (!canHaveDisplayList()) {
// can't populate RenderNode, don't try
return;
}
@@ -13627,21 +13626,13 @@
}
}
} finally {
- renderNode.end(renderer, canvas);
+ renderNode.end(canvas);
renderNode.setCaching(caching);
if (isLayer) {
renderNode.setLeftTopRightBottom(0, 0, width, height);
} else {
setDisplayListProperties(renderNode);
}
-
- if (renderer != getHardwareRenderer()) {
- Log.w(VIEW_LOG_TAG, "View was detached during a draw() call!");
- // TODO: Should this be elevated to a crash?
- // For now have it behaves the same as it previously did, it
- // will result in the DisplayListData being destroyed later
- // than it could be but oh well...
- }
}
} else if (!isLayer) {
mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
@@ -14913,7 +14904,7 @@
final int height = bounds.height();
final HardwareCanvas canvas = displayList.start(width, height);
drawable.draw(canvas);
- displayList.end(getHardwareRenderer(), canvas);
+ displayList.end(canvas);
// Set up drawable properties that are view-independent.
displayList.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 94f0683..65ac50d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1421,6 +1421,12 @@
host.getMeasuredHeight() + ", params=" + params);
}
+ if (mAttachInfo.mHardwareRenderer != null) {
+ // relayoutWindow may decide to destroy mSurface. As that decision
+ // happens in WindowManager service, we need to be defensive here
+ // and stop using the surface in case it gets destroyed.
+ mAttachInfo.mHardwareRenderer.pauseSurface(mSurface);
+ }
final int surfaceGenerationId = mSurface.getGenerationId();
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
if (!mDrawDuringWindowsAnimating &&
@@ -1499,7 +1505,7 @@
com.android.internal.R.integer.config_mediumAnimTime);
layerCanvas.restoreToCount(restoreCount);
- layerRenderNode.end(mAttachInfo.mHardwareRenderer, layerCanvas);
+ layerRenderNode.end(layerCanvas);
layerRenderNode.setCaching(true);
layerRenderNode.setLeftTopRightBottom(0, 0, mWidth, mHeight);
mTempRect.set(0, 0, mWidth, mHeight);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 14e7951c..b0a4e24 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1338,7 +1338,6 @@
layout.drawBackground(canvas, highlight, highlightPaint, cursorOffsetVertical,
firstLine, lastLine);
- final HardwareRenderer renderer = mTextView.getHardwareRenderer();
if (layout instanceof DynamicLayout) {
if (mTextDisplayLists == null) {
@@ -1402,7 +1401,7 @@
// No need to untranslate, previous context is popped after
// drawDisplayList
} finally {
- blockDisplayList.end(renderer, hardwareCanvas);
+ blockDisplayList.end(hardwareCanvas);
// Same as drawDisplayList below, handled by our TextView's parent
blockDisplayList.setClipToBounds(false);
}
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index 6d65782..ba419f9 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -16,7 +16,7 @@
package com.android.internal.content;
-import android.os.Build;
+import android.content.pm.PackageManager;
import android.util.Slog;
import java.io.File;
@@ -31,38 +31,76 @@
private static final boolean DEBUG_NATIVE = false;
- private static native long nativeSumNativeBinaries(String file, String cpuAbi, String cpuAbi2);
-
/**
- * Sums the size of native binaries in an APK.
+ * A handle to an opened APK. Used as input to the various NativeLibraryHelper
+ * methods. Allows us to scan and parse the APK exactly once instead of doing
+ * it multiple times.
*
- * @param apkFile APK file to scan for native libraries
- * @return size of all native binary files in bytes
+ * @hide
*/
- public static long sumNativeBinariesLI(File apkFile) {
- final String cpuAbi = Build.CPU_ABI;
- final String cpuAbi2 = Build.CPU_ABI2;
- return nativeSumNativeBinaries(apkFile.getPath(), cpuAbi, cpuAbi2);
+ public static class ApkHandle {
+ final String apkPath;
+ final long apkHandle;
+
+ public ApkHandle(String path) {
+ apkPath = path;
+ apkHandle = nativeOpenApk(apkPath);
+ }
+
+ public ApkHandle(File apkFile) {
+ apkPath = apkFile.getPath();
+ apkHandle = nativeOpenApk(apkPath);
+ }
+
+ public void close() {
+ nativeClose(apkHandle);
+ }
}
- private native static int nativeCopyNativeBinaries(String filePath, String sharedLibraryPath,
- String cpuAbi, String cpuAbi2);
+
+ private static native long nativeOpenApk(String path);
+ private static native void nativeClose(long handle);
+
+ private static native long nativeSumNativeBinaries(long handle, String cpuAbi);
+
+ /**
+ * Sums the size of native binaries in an APK for a given ABI.
+ *
+ * @return size of all native binary files in bytes
+ */
+ public static long sumNativeBinariesLI(ApkHandle handle, String abi) {
+ return nativeSumNativeBinaries(handle.apkHandle, abi);
+ }
+
+ private native static int nativeCopyNativeBinaries(long handle,
+ String sharedLibraryPath, String abiToCopy);
/**
* Copies native binaries to a shared library directory.
*
- * @param apkFile APK file to scan for native libraries
+ * @param handle APK file to scan for native libraries
* @param sharedLibraryDir directory for libraries to be copied to
* @return {@link PackageManager#INSTALL_SUCCEEDED} if successful or another
* error code from that class if not
*/
- public static int copyNativeBinariesIfNeededLI(File apkFile, File sharedLibraryDir) {
- final String cpuAbi = Build.CPU_ABI;
- final String cpuAbi2 = Build.CPU_ABI2;
- return nativeCopyNativeBinaries(apkFile.getPath(), sharedLibraryDir.getPath(), cpuAbi,
- cpuAbi2);
+ public static int copyNativeBinariesIfNeededLI(ApkHandle handle, File sharedLibraryDir,
+ String abi) {
+ return nativeCopyNativeBinaries(handle.apkHandle, sharedLibraryDir.getPath(), abi);
}
+ /**
+ * Checks if a given APK contains native code for any of the provided
+ * {@code supportedAbis}. Returns an index into {@code supportedAbis} if a matching
+ * ABI is found, {@link PackageManager#NO_NATIVE_LIBRARIES} if the
+ * APK doesn't contain any native code, and
+ * {@link PackageManager#INSTALL_FAILED_NO_MATCHING_ABIS} if none of the ABIs match.
+ */
+ public static int findSupportedAbi(ApkHandle handle, String[] supportedAbis) {
+ return nativeFindSupportedAbi(handle.apkHandle, supportedAbis);
+ }
+
+ private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis);
+
// Convenience method to call removeNativeBinariesFromDirLI(File)
public static boolean removeNativeBinariesLI(String nativeLibraryPath) {
return removeNativeBinariesFromDirLI(new File(nativeLibraryPath));
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 2593420..8a0eaa2 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -177,13 +177,13 @@
break;
}
if (ret < 0) {
- if (errno == EINTR) {
+ if (ret == -EINTR) {
continue;
}
- if (errno == EINVAL) {
+ if (ret == -EINVAL) {
jniThrowException(env, "java/io/IOException", "Event too short");
- } else if (errno != EAGAIN) {
- jniThrowIOException(env, errno); // Will throw on return
+ } else if (ret != -EAGAIN) {
+ jniThrowIOException(env, -ret); // Will throw on return
}
break;
}
diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp
index 180c625..6ae6c8f 100644
--- a/core/jni/android_view_GLRenderer.cpp
+++ b/core/jni/android_view_GLRenderer.cpp
@@ -142,19 +142,12 @@
LayerRenderer::destroyLayer(layer);
}
-static void android_view_GLRenderer_setDisplayListData(JNIEnv* env, jobject clazz,
- jlong displayListPtr, jlong newDataPtr) {
- using namespace android::uirenderer;
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
- displayList->setData(newData);
-}
-
-static void android_view_GLRenderer_updateRenderNodeProperties(JNIEnv* env, jobject clazz,
+static void android_view_GLRenderer_prepareTree(JNIEnv* env, jobject clazz,
jlong renderNodePtr) {
using namespace android::uirenderer;
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
- renderNode->updateProperties();
+ TreeInfo info = {0};
+ renderNode->prepareTree(info);
}
static void android_view_GLRenderer_invokeFunctor(JNIEnv* env, jobject clazz,
@@ -195,8 +188,7 @@
{ "getSystemTime", "()J", (void*) android_view_GLRenderer_getSystemTime },
{ "nDestroyLayer", "(J)V", (void*) android_view_GLRenderer_destroyLayer },
- { "nSetDisplayListData", "(JJ)V", (void*) android_view_GLRenderer_setDisplayListData },
- { "nUpdateRenderNodeProperties", "(J)V", (void*) android_view_GLRenderer_updateRenderNodeProperties },
+ { "nPrepareTree", "(J)V", (void*) android_view_GLRenderer_prepareTree },
{ "nInvokeFunctor", "(JZ)V", (void*) android_view_GLRenderer_invokeFunctor },
#endif
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index 4bf5f78..2eb0d78 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -127,7 +127,8 @@
static jboolean android_view_HardwareLayer_flushChanges(JNIEnv* env, jobject clazz,
jlong layerUpdaterPtr) {
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
- return layer->apply();
+ bool ignoredHasFunctors;
+ return layer->apply(&ignoredHasFunctors);
}
static jlong android_view_HardwareLayer_getLayer(JNIEnv* env, jobject clazz,
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index cf95657..31a1de6 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -41,32 +41,34 @@
// DisplayList view properties
// ----------------------------------------------------------------------------
-static void android_view_RenderNode_setDisplayListName(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jstring name) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+static void android_view_RenderNode_output(JNIEnv* env,
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->output();
+}
+
+static jlong android_view_RenderNode_create(JNIEnv* env, jobject clazz, jstring name) {
+ RenderNode* renderNode = new RenderNode();
+ renderNode->incStrong(0);
if (name != NULL) {
const char* textArray = env->GetStringUTFChars(name, NULL);
- displayList->setName(textArray);
+ renderNode->setName(textArray);
env->ReleaseStringUTFChars(name, textArray);
}
+ return reinterpret_cast<jlong>(renderNode);
}
-static void android_view_RenderNode_output(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->output();
+static void android_view_RenderNode_destroyRenderNode(JNIEnv* env,
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->decStrong(0);
}
-static jlong android_view_RenderNode_create(JNIEnv* env, jobject clazz) {
- RenderNode* displayList = new RenderNode();
- displayList->incStrong(0);
- return reinterpret_cast<jlong>(displayList);
-}
-
-static void android_view_RenderNode_destroyDisplayList(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->decStrong(0);
+static void android_view_RenderNode_setDisplayListData(JNIEnv* env,
+ jobject clazz, jlong renderNodePtr, jlong newDataPtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
+ renderNode->setStagingDisplayList(newData);
}
// ----------------------------------------------------------------------------
@@ -74,201 +76,201 @@
// ----------------------------------------------------------------------------
static void android_view_RenderNode_setCaching(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jboolean caching) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setCaching(caching);
+ jobject clazz, jlong renderNodePtr, jboolean caching) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setCaching(caching);
}
static void android_view_RenderNode_setStaticMatrix(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jlong matrixPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+ jobject clazz, jlong renderNodePtr, jlong matrixPtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
- displayList->mutateStagingProperties().setStaticMatrix(matrix);
+ renderNode->mutateStagingProperties().setStaticMatrix(matrix);
}
static void android_view_RenderNode_setAnimationMatrix(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jlong matrixPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+ jobject clazz, jlong renderNodePtr, jlong matrixPtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
- displayList->mutateStagingProperties().setAnimationMatrix(matrix);
+ renderNode->mutateStagingProperties().setAnimationMatrix(matrix);
}
static void android_view_RenderNode_setClipToBounds(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jboolean clipToBounds) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setClipToBounds(clipToBounds);
+ jobject clazz, jlong renderNodePtr, jboolean clipToBounds) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setClipToBounds(clipToBounds);
}
static void android_view_RenderNode_setProjectBackwards(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jboolean shouldProject) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setProjectBackwards(shouldProject);
+ jobject clazz, jlong renderNodePtr, jboolean shouldProject) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setProjectBackwards(shouldProject);
}
static void android_view_RenderNode_setProjectionReceiver(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jboolean shouldRecieve) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setProjectionReceiver(shouldRecieve);
+ jobject clazz, jlong renderNodePtr, jboolean shouldRecieve) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setProjectionReceiver(shouldRecieve);
}
static void android_view_RenderNode_setOutlineRoundRect(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jint left, jint top,
+ jobject clazz, jlong renderNodePtr, jint left, jint top,
jint right, jint bottom, jfloat radius) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom, radius);
- displayList->mutateStagingProperties().updateClipPath();
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom, radius);
+ renderNode->mutateStagingProperties().updateClipPath();
}
static void android_view_RenderNode_setOutlineConvexPath(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+ jobject clazz, jlong renderNodePtr, jlong outlinePathPtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
- displayList->mutateStagingProperties().mutableOutline().setConvexPath(outlinePath);
- displayList->mutateStagingProperties().updateClipPath();
+ renderNode->mutateStagingProperties().mutableOutline().setConvexPath(outlinePath);
+ renderNode->mutateStagingProperties().updateClipPath();
}
static void android_view_RenderNode_setOutlineEmpty(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().mutableOutline().setEmpty();
- displayList->mutateStagingProperties().updateClipPath();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().mutableOutline().setEmpty();
+ renderNode->mutateStagingProperties().updateClipPath();
}
static void android_view_RenderNode_setClipToOutline(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline);
- displayList->mutateStagingProperties().updateClipPath();
+ jobject clazz, jlong renderNodePtr, jboolean clipToOutline) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline);
+ renderNode->mutateStagingProperties().updateClipPath();
}
static void android_view_RenderNode_setRevealClip(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jboolean shouldClip, jboolean inverseClip,
+ jobject clazz, jlong renderNodePtr, jboolean shouldClip, jboolean inverseClip,
jfloat x, jfloat y, jfloat radius) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().mutableRevealClip().set(
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().mutableRevealClip().set(
shouldClip, inverseClip, x, y, radius);
- displayList->mutateStagingProperties().updateClipPath();
+ renderNode->mutateStagingProperties().updateClipPath();
}
static void android_view_RenderNode_setAlpha(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float alpha) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setAlpha(alpha);
+ jobject clazz, jlong renderNodePtr, float alpha) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setAlpha(alpha);
}
static void android_view_RenderNode_setHasOverlappingRendering(JNIEnv* env,
- jobject clazz, jlong displayListPtr, bool hasOverlappingRendering) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setHasOverlappingRendering(hasOverlappingRendering);
+ jobject clazz, jlong renderNodePtr, bool hasOverlappingRendering) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setHasOverlappingRendering(hasOverlappingRendering);
}
static void android_view_RenderNode_setTranslationX(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float tx) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setTranslationX(tx);
+ jobject clazz, jlong renderNodePtr, float tx) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setTranslationX(tx);
}
static void android_view_RenderNode_setTranslationY(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float ty) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setTranslationY(ty);
+ jobject clazz, jlong renderNodePtr, float ty) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setTranslationY(ty);
}
static void android_view_RenderNode_setTranslationZ(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float tz) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setTranslationZ(tz);
+ jobject clazz, jlong renderNodePtr, float tz) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setTranslationZ(tz);
}
static void android_view_RenderNode_setRotation(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float rotation) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setRotation(rotation);
+ jobject clazz, jlong renderNodePtr, float rotation) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setRotation(rotation);
}
static void android_view_RenderNode_setRotationX(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float rx) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setRotationX(rx);
+ jobject clazz, jlong renderNodePtr, float rx) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setRotationX(rx);
}
static void android_view_RenderNode_setRotationY(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float ry) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setRotationY(ry);
+ jobject clazz, jlong renderNodePtr, float ry) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setRotationY(ry);
}
static void android_view_RenderNode_setScaleX(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float sx) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setScaleX(sx);
+ jobject clazz, jlong renderNodePtr, float sx) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setScaleX(sx);
}
static void android_view_RenderNode_setScaleY(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float sy) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setScaleY(sy);
+ jobject clazz, jlong renderNodePtr, float sy) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setScaleY(sy);
}
static void android_view_RenderNode_setPivotX(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float px) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setPivotX(px);
+ jobject clazz, jlong renderNodePtr, float px) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setPivotX(px);
}
static void android_view_RenderNode_setPivotY(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float py) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setPivotY(py);
+ jobject clazz, jlong renderNodePtr, float py) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setPivotY(py);
}
static void android_view_RenderNode_setCameraDistance(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float distance) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setCameraDistance(distance);
+ jobject clazz, jlong renderNodePtr, float distance) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setCameraDistance(distance);
}
static void android_view_RenderNode_setLeft(JNIEnv* env,
- jobject clazz, jlong displayListPtr, int left) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setLeft(left);
+ jobject clazz, jlong renderNodePtr, int left) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setLeft(left);
}
static void android_view_RenderNode_setTop(JNIEnv* env,
- jobject clazz, jlong displayListPtr, int top) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setTop(top);
+ jobject clazz, jlong renderNodePtr, int top) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setTop(top);
}
static void android_view_RenderNode_setRight(JNIEnv* env,
- jobject clazz, jlong displayListPtr, int right) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setRight(right);
+ jobject clazz, jlong renderNodePtr, int right) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setRight(right);
}
static void android_view_RenderNode_setBottom(JNIEnv* env,
- jobject clazz, jlong displayListPtr, int bottom) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setBottom(bottom);
+ jobject clazz, jlong renderNodePtr, int bottom) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setBottom(bottom);
}
static void android_view_RenderNode_setLeftTopRightBottom(JNIEnv* env,
- jobject clazz, jlong displayListPtr, int left, int top,
+ jobject clazz, jlong renderNodePtr, int left, int top,
int right, int bottom) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom);
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom);
}
static void android_view_RenderNode_offsetLeftAndRight(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float offset) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().offsetLeftRight(offset);
+ jobject clazz, jlong renderNodePtr, float offset) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().offsetLeftRight(offset);
}
static void android_view_RenderNode_offsetTopAndBottom(JNIEnv* env,
- jobject clazz, jlong displayListPtr, float offset) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().offsetTopBottom(offset);
+ jobject clazz, jlong renderNodePtr, float offset) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().offsetTopBottom(offset);
}
// ----------------------------------------------------------------------------
@@ -276,105 +278,105 @@
// ----------------------------------------------------------------------------
static jboolean android_view_RenderNode_hasOverlappingRendering(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().hasOverlappingRendering();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().hasOverlappingRendering();
}
static jfloat android_view_RenderNode_getAlpha(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getAlpha();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getAlpha();
}
static jfloat android_view_RenderNode_getLeft(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getLeft();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getLeft();
}
static jfloat android_view_RenderNode_getTop(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getTop();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getTop();
}
static jfloat android_view_RenderNode_getRight(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getRight();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getRight();
}
static jfloat android_view_RenderNode_getBottom(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getBottom();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getBottom();
}
static jfloat android_view_RenderNode_getCameraDistance(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getCameraDistance();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getCameraDistance();
}
static jfloat android_view_RenderNode_getScaleX(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getScaleX();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getScaleX();
}
static jfloat android_view_RenderNode_getScaleY(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getScaleY();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getScaleY();
}
static jfloat android_view_RenderNode_getTranslationX(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getTranslationX();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getTranslationX();
}
static jfloat android_view_RenderNode_getTranslationY(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getTranslationY();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getTranslationY();
}
static jfloat android_view_RenderNode_getTranslationZ(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getTranslationZ();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getTranslationZ();
}
static jfloat android_view_RenderNode_getRotation(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getRotation();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getRotation();
}
static jfloat android_view_RenderNode_getRotationX(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getRotationX();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getRotationX();
}
static jfloat android_view_RenderNode_getRotationY(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getRotationY();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getRotationY();
}
static jboolean android_view_RenderNode_isPivotExplicitlySet(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().isPivotExplicitlySet();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().isPivotExplicitlySet();
}
static jboolean android_view_RenderNode_hasIdentityMatrix(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- return displayList->stagingProperties().getMatrixFlags() == 0;
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ return renderNode->stagingProperties().getMatrixFlags() == 0;
}
// ----------------------------------------------------------------------------
@@ -382,16 +384,16 @@
// ----------------------------------------------------------------------------
static void android_view_RenderNode_getTransformMatrix(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jlong outMatrixPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+ jobject clazz, jlong renderNodePtr, jlong outMatrixPtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
- displayList->mutateStagingProperties().updateMatrix();
- const SkMatrix* transformMatrix = displayList->stagingProperties().getTransformMatrix();
+ renderNode->mutateStagingProperties().updateMatrix();
+ const SkMatrix* transformMatrix = renderNode->stagingProperties().getTransformMatrix();
- if (displayList->stagingProperties().getMatrixFlags() == TRANSLATION) {
- outMatrix->setTranslate(displayList->stagingProperties().getTranslationX(),
- displayList->stagingProperties().getTranslationY());
+ if (renderNode->stagingProperties().getMatrixFlags() == TRANSLATION) {
+ outMatrix->setTranslate(renderNode->stagingProperties().getTranslationX(),
+ renderNode->stagingProperties().getTranslationY());
} else if (transformMatrix) {
*outMatrix = *transformMatrix;
} else {
@@ -400,9 +402,9 @@
}
static void android_view_RenderNode_getInverseTransformMatrix(JNIEnv* env,
- jobject clazz, jlong displayListPtr, jlong outMatrixPtr) {
+ jobject clazz, jlong renderNodePtr, jlong outMatrixPtr) {
// load transform matrix
- android_view_RenderNode_getTransformMatrix(env, clazz, displayListPtr, outMatrixPtr);
+ android_view_RenderNode_getTransformMatrix(env, clazz, renderNodePtr, outMatrixPtr);
SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
// return it inverted
@@ -413,17 +415,17 @@
}
static jfloat android_view_RenderNode_getPivotX(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().updateMatrix();
- return displayList->stagingProperties().getPivotX();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().updateMatrix();
+ return renderNode->stagingProperties().getPivotX();
}
static jfloat android_view_RenderNode_getPivotY(JNIEnv* env,
- jobject clazz, jlong displayListPtr) {
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- displayList->mutateStagingProperties().updateMatrix();
- return displayList->stagingProperties().getPivotY();
+ jobject clazz, jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().updateMatrix();
+ return renderNode->stagingProperties().getPivotY();
}
#endif // USE_OPENGL_RENDERER
@@ -436,10 +438,9 @@
static JNINativeMethod gMethods[] = {
#ifdef USE_OPENGL_RENDERER
- { "nCreate", "()J", (void*) android_view_RenderNode_create },
- { "nDestroyDisplayList", "(J)V", (void*) android_view_RenderNode_destroyDisplayList },
- { "nSetDisplayListName", "(JLjava/lang/String;)V",
- (void*) android_view_RenderNode_setDisplayListName },
+ { "nCreate", "(Ljava/lang/String;)J", (void*) android_view_RenderNode_create },
+ { "nDestroyRenderNode", "(J)V", (void*) android_view_RenderNode_destroyRenderNode },
+ { "nSetDisplayListData", "(JJ)V", (void*) android_view_RenderNode_setDisplayListData },
{ "nOutput", "(J)V", (void*) android_view_RenderNode_output },
{ "nSetCaching", "(JZ)V", (void*) android_view_RenderNode_setCaching },
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 32890cf..36c8357 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -84,7 +84,7 @@
jlong proxyPtr, jobject jsurface) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface);
- return proxy->initialize(window.get());
+ return proxy->initialize(window);
}
static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
@@ -94,7 +94,17 @@
if (jsurface) {
window = android_view_Surface_getNativeWindow(env, jsurface);
}
- proxy->updateSurface(window.get());
+ proxy->updateSurface(window);
+}
+
+static void android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jobject jsurface) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ sp<ANativeWindow> window;
+ if (jsurface) {
+ window = android_view_Surface_getNativeWindow(env, jsurface);
+ }
+ proxy->pauseSurface(window);
}
static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz,
@@ -103,14 +113,6 @@
proxy->setup(width, height);
}
-static void android_view_ThreadedRenderer_setDisplayListData(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jlong displayListPtr, jlong newDataPtr) {
- RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
- proxy->setDisplayListData(displayList, newData);
-}
-
static void android_view_ThreadedRenderer_drawDisplayList(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong displayListPtr, jint dirtyLeft, jint dirtyTop,
jint dirtyRight, jint dirtyBottom) {
@@ -203,8 +205,8 @@
{ "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
{ "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize },
{ "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
+ { "nPauseSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_pauseSurface },
{ "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup },
- { "nSetDisplayListData", "(JJJ)V", (void*) android_view_ThreadedRenderer_setDisplayListData },
{ "nDrawDisplayList", "(JJIIII)V", (void*) android_view_ThreadedRenderer_drawDisplayList },
{ "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas },
{ "nAttachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_attachFunctor },
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index a860918..230658f 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -19,11 +19,12 @@
#include <android_runtime/AndroidRuntime.h>
-#include <utils/Log.h>
-#include <androidfw/ZipFileRO.h>
-#include <androidfw/ZipUtils.h>
#include <ScopedUtfChars.h>
#include <UniquePtr.h>
+#include <androidfw/ZipFileRO.h>
+#include <androidfw/ZipUtils.h>
+#include <utils/Log.h>
+#include <utils/Vector.h>
#include <zlib.h>
@@ -54,17 +55,19 @@
namespace android {
// These match PackageManager.java install codes
-typedef enum {
+enum install_status_t {
INSTALL_SUCCEEDED = 1,
INSTALL_FAILED_INVALID_APK = -2,
INSTALL_FAILED_INSUFFICIENT_STORAGE = -4,
INSTALL_FAILED_CONTAINER_ERROR = -18,
INSTALL_FAILED_INTERNAL_ERROR = -110,
-} install_status_t;
+ INSTALL_FAILED_NO_MATCHING_ABIS = -113,
+ NO_NATIVE_LIBRARIES = -114
+};
typedef install_status_t (*iterFunc)(JNIEnv*, void*, ZipFileRO*, ZipEntryRO, const char*);
-// Equivalent to isFilenameSafe
+// Equivalent to android.os.FileUtils.isFilenameSafe
static bool
isFilenameSafe(const char* filename)
{
@@ -268,126 +271,252 @@
return INSTALL_SUCCEEDED;
}
-static install_status_t
-iterateOverNativeFiles(JNIEnv *env, jstring javaFilePath, jstring javaCpuAbi, jstring javaCpuAbi2,
- iterFunc callFunc, void* callArg) {
- ScopedUtfChars filePath(env, javaFilePath);
- ScopedUtfChars cpuAbi(env, javaCpuAbi);
- ScopedUtfChars cpuAbi2(env, javaCpuAbi2);
-
- UniquePtr<ZipFileRO> zipFile(ZipFileRO::open(filePath.c_str()));
- if (zipFile.get() == NULL) {
- ALOGI("Couldn't open APK %s\n", filePath.c_str());
- return INSTALL_FAILED_INVALID_APK;
+/*
+ * An iterator over all shared libraries in a zip file. An entry is
+ * considered to be a shared library if all of the conditions below are
+ * satisfied :
+ *
+ * - The entry is under the lib/ directory.
+ * - The entry name ends with ".so" and the entry name starts with "lib",
+ * an exception is made for entries whose name is "gdbserver".
+ * - The entry filename is "safe" (as determined by isFilenameSafe).
+ *
+ */
+class NativeLibrariesIterator {
+private:
+ NativeLibrariesIterator(ZipFileRO* zipFile, void* cookie)
+ : mZipFile(zipFile), mCookie(cookie), mLastSlash(NULL) {
+ fileName[0] = '\0';
}
+public:
+ static NativeLibrariesIterator* create(ZipFileRO* zipFile) {
+ void* cookie = NULL;
+ if (!zipFile->startIteration(&cookie)) {
+ return NULL;
+ }
+
+ return new NativeLibrariesIterator(zipFile, cookie);
+ }
+
+ ZipEntryRO next() {
+ ZipEntryRO next = NULL;
+ while ((next = mZipFile->nextEntry(mCookie)) != NULL) {
+ // Make sure this entry has a filename.
+ if (mZipFile->getEntryFileName(next, fileName, sizeof(fileName))) {
+ continue;
+ }
+
+ // Make sure we're in the lib directory of the ZIP.
+ if (strncmp(fileName, APK_LIB, APK_LIB_LEN)) {
+ continue;
+ }
+
+ // Make sure the filename is at least to the minimum library name size.
+ const size_t fileNameLen = strlen(fileName);
+ static const size_t minLength = APK_LIB_LEN + 2 + LIB_PREFIX_LEN + 1 + LIB_SUFFIX_LEN;
+ if (fileNameLen < minLength) {
+ continue;
+ }
+
+ const char* lastSlash = strrchr(fileName, '/');
+ ALOG_ASSERT(lastSlash != NULL, "last slash was null somehow for %s\n", fileName);
+
+ // Exception: If we find the gdbserver binary, return it.
+ if (!strncmp(lastSlash + 1, GDBSERVER, GDBSERVER_LEN)) {
+ break;
+ }
+
+ // Make sure the filename starts with lib and ends with ".so".
+ if (strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX, LIB_SUFFIX_LEN)
+ || strncmp(lastSlash, LIB_PREFIX, LIB_PREFIX_LEN)) {
+ continue;
+ }
+
+ // Make sure the filename is safe.
+ if (!isFilenameSafe(lastSlash + 1)) {
+ continue;
+ }
+
+ mLastSlash = lastSlash;
+ break;
+ }
+
+ return next;
+ }
+
+ inline const char* currentEntry() const {
+ return fileName;
+ }
+
+ inline const char* lastSlash() const {
+ return mLastSlash;
+ }
+
+ virtual ~NativeLibrariesIterator() {
+ mZipFile->endIteration(mCookie);
+ }
+private:
+
char fileName[PATH_MAX];
- bool hasPrimaryAbi = false;
+ ZipFileRO* const mZipFile;
+ void* mCookie;
+ const char* mLastSlash;
+};
- void* cookie = NULL;
- if (!zipFile->startIteration(&cookie)) {
- ALOGI("Couldn't iterate over APK%s\n", filePath.c_str());
+static install_status_t
+iterateOverNativeFiles(JNIEnv *env, jlong apkHandle, jstring javaCpuAbi,
+ iterFunc callFunc, void* callArg) {
+ ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
+ if (zipFile == NULL) {
return INSTALL_FAILED_INVALID_APK;
}
+ UniquePtr<NativeLibrariesIterator> it(NativeLibrariesIterator::create(zipFile));
+ if (it.get() == NULL) {
+ return INSTALL_FAILED_INVALID_APK;
+ }
+
+ const ScopedUtfChars cpuAbi(env, javaCpuAbi);
+ if (cpuAbi.c_str() == NULL) {
+ // This would've thrown, so this return code isn't observable by
+ // Java.
+ return INSTALL_FAILED_INVALID_APK;
+ }
ZipEntryRO entry = NULL;
- while ((entry = zipFile->nextEntry(cookie)) != NULL) {
- // Make sure this entry has a filename.
- if (zipFile->getEntryFileName(entry, fileName, sizeof(fileName))) {
- continue;
- }
-
- // Make sure we're in the lib directory of the ZIP.
- if (strncmp(fileName, APK_LIB, APK_LIB_LEN)) {
- continue;
- }
-
- // Make sure the filename is at least to the minimum library name size.
- const size_t fileNameLen = strlen(fileName);
- static const size_t minLength = APK_LIB_LEN + 2 + LIB_PREFIX_LEN + 1 + LIB_SUFFIX_LEN;
- if (fileNameLen < minLength) {
- continue;
- }
-
- const char* lastSlash = strrchr(fileName, '/');
- ALOG_ASSERT(lastSlash != NULL, "last slash was null somehow for %s\n", fileName);
+ while ((entry = it->next()) != NULL) {
+ const char* fileName = it->currentEntry();
+ const char* lastSlash = it->lastSlash();
// Check to make sure the CPU ABI of this file is one we support.
const char* cpuAbiOffset = fileName + APK_LIB_LEN;
const size_t cpuAbiRegionSize = lastSlash - cpuAbiOffset;
- ALOGV("Comparing ABIs %s and %s versus %s\n", cpuAbi.c_str(), cpuAbi2.c_str(), cpuAbiOffset);
- if (cpuAbi.size() == cpuAbiRegionSize
- && *(cpuAbiOffset + cpuAbi.size()) == '/'
- && !strncmp(cpuAbiOffset, cpuAbi.c_str(), cpuAbiRegionSize)) {
- ALOGV("Using primary ABI %s\n", cpuAbi.c_str());
- hasPrimaryAbi = true;
- } else if (cpuAbi2.size() == cpuAbiRegionSize
- && *(cpuAbiOffset + cpuAbi2.size()) == '/'
- && !strncmp(cpuAbiOffset, cpuAbi2.c_str(), cpuAbiRegionSize)) {
-
- /*
- * If this library matches both the primary and secondary ABIs,
- * only use the primary ABI.
- */
- if (hasPrimaryAbi) {
- ALOGV("Already saw primary ABI, skipping secondary ABI %s\n", cpuAbi2.c_str());
- continue;
- } else {
- ALOGV("Using secondary ABI %s\n", cpuAbi2.c_str());
- }
- } else {
- ALOGV("abi didn't match anything: %s (end at %zd)\n", cpuAbiOffset, cpuAbiRegionSize);
- continue;
- }
-
- // If this is a .so file, check to see if we need to copy it.
- if ((!strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX, LIB_SUFFIX_LEN)
- && !strncmp(lastSlash, LIB_PREFIX, LIB_PREFIX_LEN)
- && isFilenameSafe(lastSlash + 1))
- || !strncmp(lastSlash + 1, GDBSERVER, GDBSERVER_LEN)) {
-
- install_status_t ret = callFunc(env, callArg, zipFile.get(), entry, lastSlash + 1);
+ if (cpuAbi.size() == cpuAbiRegionSize && !strncmp(cpuAbiOffset, cpuAbi.c_str(), cpuAbiRegionSize)) {
+ install_status_t ret = callFunc(env, callArg, zipFile, entry, lastSlash + 1);
if (ret != INSTALL_SUCCEEDED) {
ALOGV("Failure for entry %s", lastSlash + 1);
- zipFile->endIteration(cookie);
return ret;
}
}
}
- zipFile->endIteration(cookie);
-
return INSTALL_SUCCEEDED;
}
+
+static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supportedAbisArray) {
+ const int numAbis = env->GetArrayLength(supportedAbisArray);
+ Vector<ScopedUtfChars*> supportedAbis;
+
+ for (int i = 0; i < numAbis; ++i) {
+ supportedAbis.add(new ScopedUtfChars(env,
+ (jstring) env->GetObjectArrayElement(supportedAbisArray, i)));
+ }
+
+ ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
+ if (zipFile == NULL) {
+ return INSTALL_FAILED_INVALID_APK;
+ }
+
+ UniquePtr<NativeLibrariesIterator> it(NativeLibrariesIterator::create(zipFile));
+ if (it.get() == NULL) {
+ return INSTALL_FAILED_INVALID_APK;
+ }
+
+ ZipEntryRO entry = NULL;
+ char fileName[PATH_MAX];
+ int status = NO_NATIVE_LIBRARIES;
+ while ((entry = it->next()) != NULL) {
+ // We're currently in the lib/ directory of the APK, so it does have some native
+ // code. We should return INSTALL_FAILED_NO_MATCHING_ABIS if none of the
+ // libraries match.
+ if (status == NO_NATIVE_LIBRARIES) {
+ status = INSTALL_FAILED_NO_MATCHING_ABIS;
+ }
+
+ const char* fileName = it->currentEntry();
+ const char* lastSlash = it->lastSlash();
+
+ // Check to see if this CPU ABI matches what we are looking for.
+ const char* abiOffset = fileName + APK_LIB_LEN;
+ const size_t abiSize = lastSlash - abiOffset;
+ for (int i = 0; i < numAbis; i++) {
+ const ScopedUtfChars* abi = supportedAbis[i];
+ if (abi->size() == abiSize && !strncmp(abiOffset, abi->c_str(), abiSize)) {
+ // The entry that comes in first (i.e. with a lower index) has the higher priority.
+ if (((i < status) && (status >= 0)) || (status < 0) ) {
+ status = i;
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < numAbis; ++i) {
+ delete supportedAbis[i];
+ }
+
+ return status;
+}
+
static jint
com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
- jstring javaFilePath, jstring javaNativeLibPath, jstring javaCpuAbi, jstring javaCpuAbi2)
+ jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi)
{
- return (jint) iterateOverNativeFiles(env, javaFilePath, javaCpuAbi, javaCpuAbi2,
+ return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi,
copyFileIfChanged, &javaNativeLibPath);
}
static jlong
com_android_internal_content_NativeLibraryHelper_sumNativeBinaries(JNIEnv *env, jclass clazz,
- jstring javaFilePath, jstring javaCpuAbi, jstring javaCpuAbi2)
+ jlong apkHandle, jstring javaCpuAbi)
{
size_t totalSize = 0;
- iterateOverNativeFiles(env, javaFilePath, javaCpuAbi, javaCpuAbi2, sumFiles, &totalSize);
+ iterateOverNativeFiles(env, apkHandle, javaCpuAbi, sumFiles, &totalSize);
return totalSize;
}
+static jint
+com_android_internal_content_NativeLibraryHelper_findSupportedAbi(JNIEnv *env, jclass clazz,
+ jlong apkHandle, jobjectArray javaCpuAbisToSearch)
+{
+ return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch);
+}
+
+static jlong
+com_android_internal_content_NativeLibraryHelper_openApk(JNIEnv *env, jclass, jstring apkPath)
+{
+ ScopedUtfChars filePath(env, apkPath);
+ ZipFileRO* zipFile = ZipFileRO::open(filePath.c_str());
+
+ return reinterpret_cast<jlong>(zipFile);
+}
+
+static void
+com_android_internal_content_NativeLibraryHelper_close(JNIEnv *env, jclass, jlong apkHandle)
+{
+ delete reinterpret_cast<ZipFileRO*>(apkHandle);
+}
+
static JNINativeMethod gMethods[] = {
+ {"nativeOpenApk",
+ "(Ljava/lang/String;)J",
+ (void *)com_android_internal_content_NativeLibraryHelper_openApk},
+ {"nativeClose",
+ "(J)V",
+ (void *)com_android_internal_content_NativeLibraryHelper_close},
{"nativeCopyNativeBinaries",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
+ "(JLjava/lang/String;Ljava/lang/String;)I",
(void *)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries},
{"nativeSumNativeBinaries",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J",
+ "(JLjava/lang/String;)J",
(void *)com_android_internal_content_NativeLibraryHelper_sumNativeBinaries},
+ {"nativeFindSupportedAbi",
+ "(J[Ljava/lang/String;)I",
+ (void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi},
};
diff --git a/core/res/res/layout/preference_category_quantum.xml b/core/res/res/layout/preference_category_quantum.xml
new file mode 100644
index 0000000..032e09d
--- /dev/null
+++ b/core/res/res/layout/preference_category_quantum.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- Layout used for PreferenceCategory in a PreferenceActivity. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+android:id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dip"
+ android:textAppearance="@style/TextAppearance.Quantum.Body2"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textStyle="bold"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd"
+ android:paddingTop="16dip" />
diff --git a/core/res/res/layout/preference_child_quantum.xml b/core/res/res/layout/preference_child_quantum.xml
new file mode 100644
index 0000000..690d64a
--- /dev/null
+++ b/core/res/res/layout/preference_child_quantum.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- Layout for a visually child-like Preference in a PreferenceActivity. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="?attr/listPreferredItemPaddingStart"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd">
+
+ <LinearLayout
+ android:id="@+android:id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="58dip"
+ android:gravity="left|center_vertical"
+ android:orientation="horizontal">
+ <ImageView
+ android:id="@+android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dip" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="16dip"
+ android:paddingBottom="16dip">
+
+ <TextView android:id="@+android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+
+ <TextView android:id="@+android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10" />
+
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout android:id="@+android:id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="58dip"
+ android:gravity="right|center_vertical"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/preference_information_quantum.xml b/core/res/res/layout/preference_information_quantum.xml
new file mode 100644
index 0000000..f21640fc
--- /dev/null
+++ b/core/res/res/layout/preference_information_quantum.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- Layout for a Preference in a PreferenceActivity. The
+ Preference is able to place a specific widget for its particular
+ type in the "widget_frame" layout. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd">
+
+ <LinearLayout
+ android:id="@+android:id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="58dip"
+ android:gravity="left|center_vertical"
+ android:orientation="horizontal">
+ <ImageView
+ android:id="@+android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dip" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="16dip"
+ android:paddingBottom="16dip">
+
+ <TextView android:id="@+android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+
+ <TextView android:id="@+android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10" />
+
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout android:id="@+android:id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="58dip"
+ android:gravity="right|center_vertical"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/preference_quantum.xml b/core/res/res/layout/preference_quantum.xml
new file mode 100644
index 0000000..a4fe73d
--- /dev/null
+++ b/core/res/res/layout/preference_quantum.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- Layout for a Preference in a PreferenceActivity. The
+ Preference is able to place a specific widget for its particular
+ type in the "widget_frame" layout. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/activatedBackgroundIndicator">
+
+ <LinearLayout
+ android:id="@+android:id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="58dip"
+ android:gravity="left|center_vertical"
+ android:orientation="horizontal">
+ <ImageView
+ android:id="@+android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="centerInside"
+ android:layout_marginEnd="8dip" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="16dip"
+ android:paddingBottom="16dip">
+
+ <TextView android:id="@+android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee" />
+
+ <TextView android:id="@+android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10" />
+
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout android:id="@+android:id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="58dip"
+ android:gravity="right|center_vertical"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/preference_widget_checkbox.xml b/core/res/res/layout/preference_widget_checkbox.xml
index 33a43f4..bfd7f0a 100644
--- a/core/res/res/layout/preference_widget_checkbox.xml
+++ b/core/res/res/layout/preference_widget_checkbox.xml
@@ -20,6 +20,5 @@
android:id="@+android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"
android:focusable="false"
android:clickable="false" />
diff --git a/core/res/res/layout/preference_widget_switch.xml b/core/res/res/layout/preference_widget_switch.xml
index 83ef097..534c7ec 100644
--- a/core/res/res/layout/preference_widget_switch.xml
+++ b/core/res/res/layout/preference_widget_switch.xml
@@ -20,6 +20,5 @@
android:id="@+android:id/switchWidget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"
android:padding="16dip"
android:focusable="false" />
diff --git a/core/res/res/layout/simple_list_item_1.xml b/core/res/res/layout/simple_list_item_1.xml
index 4249d10..43a5635 100644
--- a/core/res/res/layout/simple_list_item_1.xml
+++ b/core/res/res/layout/simple_list_item_1.xml
@@ -22,5 +22,4 @@
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
-/>
+ android:minHeight="?android:attr/listPreferredItemHeightSmall" />
diff --git a/core/res/res/layout/simple_list_item_2.xml b/core/res/res/layout/simple_list_item_2.xml
index 63c542b..b47a3465 100644
--- a/core/res/res/layout/simple_list_item_2.xml
+++ b/core/res/res/layout/simple_list_item_2.xml
@@ -20,22 +20,19 @@
android:minHeight="?android:attr/listPreferredItemHeight"
android:mode="twoLine"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
->
-
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
<TextView android:id="@android:id/text1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dip"
- android:textAppearance="?android:attr/textAppearanceListItem"
- />
-
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dip"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+
<TextView android:id="@android:id/text2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@android:id/text1"
- android:layout_alignStart="@android:id/text1"
- android:textAppearance="?android:attr/textAppearanceSmall"
- />
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/text1"
+ android:layout_alignStart="@android:id/text1"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary" />
</TwoLineListItem>
diff --git a/core/res/res/layout/simple_list_item_2_single_choice.xml b/core/res/res/layout/simple_list_item_2_single_choice.xml
index 5629567..65c5856 100644
--- a/core/res/res/layout/simple_list_item_2_single_choice.xml
+++ b/core/res/res/layout/simple_list_item_2_single_choice.xml
@@ -22,31 +22,34 @@
android:paddingStart="16dip"
android:paddingEnd="12dip"
android:minHeight="?android:attr/listPreferredItemHeightSmall">
+
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center_vertical">
+
<TextView android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?android:attr/textColorAlertDialogListItem"
android:gravity="center_vertical|start"
android:singleLine="true"
- android:ellipsize="marquee"
- />
+ android:ellipsize="marquee" />
+
<TextView android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorAlertDialogListItem"
android:gravity="center_vertical|start"
android:singleLine="true"
- android:ellipsize="marquee"
- />
+ android:ellipsize="marquee" />
+
</LinearLayout>
+
<RadioButton
android:id="@+id/radio"
android:layout_width="35dip"
@@ -54,6 +57,6 @@
android:paddingEnd="12dip"
android:gravity="center_vertical"
android:focusable="false"
- android:clickable="false"
- />
+ android:clickable="false" />
+
</LinearLayout>
diff --git a/core/res/res/layout/simple_list_item_activated_1.xml b/core/res/res/layout/simple_list_item_activated_1.xml
index 41155e4..9b778d7 100644
--- a/core/res/res/layout/simple_list_item_activated_1.xml
+++ b/core/res/res/layout/simple_list_item_activated_1.xml
@@ -23,5 +23,4 @@
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/activatedBackgroundIndicator"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
-/>
+ android:minHeight="?android:attr/listPreferredItemHeightSmall" />
diff --git a/core/res/res/layout/simple_list_item_activated_2.xml b/core/res/res/layout/simple_list_item_activated_2.xml
index 725697d..5036813 100644
--- a/core/res/res/layout/simple_list_item_activated_2.xml
+++ b/core/res/res/layout/simple_list_item_activated_2.xml
@@ -21,23 +21,20 @@
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeight"
- android:mode="twoLine"
->
+ android:mode="twoLine">
<TextView android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
android:layout_marginTop="6dip"
- android:textAppearance="?android:attr/textAppearanceListItem"
- />
+ android:textAppearance="?android:attr/textAppearanceListItem" />
<TextView android:id="@android:id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@android:id/text1"
android:layout_alignStart="@android:id/text1"
- android:textAppearance="?android:attr/textAppearanceSmall"
- />
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary" />
</TwoLineListItem>
diff --git a/core/res/res/layout/simple_list_item_checked.xml b/core/res/res/layout/simple_list_item_checked.xml
index 0c497d6..4673e27 100644
--- a/core/res/res/layout/simple_list_item_checked.xml
+++ b/core/res/res/layout/simple_list_item_checked.xml
@@ -22,5 +22,4 @@
android:gravity="center_vertical"
android:checkMark="?android:attr/textCheckMark"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-/>
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />
diff --git a/core/res/res/layout/simple_list_item_multiple_choice.xml b/core/res/res/layout/simple_list_item_multiple_choice.xml
index 076d8c6..440b6fd 100644
--- a/core/res/res/layout/simple_list_item_multiple_choice.xml
+++ b/core/res/res/layout/simple_list_item_multiple_choice.xml
@@ -22,5 +22,4 @@
android:gravity="center_vertical"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-/>
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />
diff --git a/core/res/res/layout/simple_list_item_single_choice.xml b/core/res/res/layout/simple_list_item_single_choice.xml
index 4c1af09..02cb7f7 100644
--- a/core/res/res/layout/simple_list_item_single_choice.xml
+++ b/core/res/res/layout/simple_list_item_single_choice.xml
@@ -22,5 +22,4 @@
android:gravity="center_vertical"
android:checkMark="?android:attr/listChoiceIndicatorSingle"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-/>
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 46cb9b22..f364bd0 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -245,6 +245,8 @@
<!-- The preferred TextAppearance for the primary text of list items. -->
<attr name="textAppearanceListItem" format="reference" />
+ <!-- The preferred TextAppearance for the secondary text of list items. -->
+ <attr name="textAppearanceListItemSecondary" format="reference" />
<!-- The preferred TextAppearance for the primary text of small list items. -->
<attr name="textAppearanceListItemSmall" format="reference" />
@@ -4409,14 +4411,23 @@
<!-- When a tint color is set, specifies its Porter-Duff blending mode. The
default value is src_in, which treats the drawable as an alpha mask. -->
<attr name="tintMode">
- <!-- [Sa * Da, Sc * Da] -->
- <enum name="src_in" value="0" />
- <!-- [Da, Sc * Da + (1 - Sa) * Dc] -->
- <enum name="src_atop" value="1" />
- <!-- [Sa * Da, Sc * Dc] -->
- <enum name="multiply" value="2" />
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
<!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
- <enum name="screen" value="3" />
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
</attr>
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index acdf926..d3bee28 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2148,6 +2148,7 @@
<public type="attr" name="subtitleTextAppearance" />
<public type="attr" name="slideEdge" />
<public type="attr" name="actionBarTheme" />
+ <public type="attr" name="textAppearanceListItemSecondary" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
index dd148c4..2720d61 100644
--- a/core/res/res/values/styles_quantum.xml
+++ b/core/res/res/values/styles_quantum.xml
@@ -33,7 +33,7 @@
<eat-comment/>
<style name="Preference.Quantum">
- <item name="layout">@layout/preference_holo</item>
+ <item name="layout">@layout/preference_quantum</item>
</style>
<style name="PreferenceFragment.Quantum">
@@ -42,13 +42,13 @@
</style>
<style name="Preference.Quantum.Information">
- <item name="layout">@layout/preference_information_holo</item>
+ <item name="layout">@layout/preference_information_quantum</item>
<item name="enabled">false</item>
<item name="shouldDisableView">false</item>
</style>
<style name="Preference.Quantum.Category">
- <item name="layout">@layout/preference_category_holo</item>
+ <item name="layout">@layout/preference_category_quantum</item>
<!-- The title should not dim if the category is disabled, instead only the preference children should dim. -->
<item name="shouldDisableView">false</item>
<item name="selectable">false</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b011483..ac6c15d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1835,5 +1835,6 @@
<java-symbol type="attr" name="titleTextAppearance" />
<java-symbol type="attr" name="subtitleTextAppearance" />
<java-symbol type="drawable" name="ic_lock_bugreport" />
+ <java-symbol type="id" name="icon_frame" />
</resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 7aea814..6f9e55b 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -126,6 +126,7 @@
<item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeight</item>
<item name="textAppearanceListItem">?android:attr/textAppearanceLarge</item>
<item name="textAppearanceListItemSmall">?android:attr/textAppearanceLarge</item>
+ <item name="textAppearanceListItemSecondary">?android:attr/textAppearanceSmall</item>
<item name="listPreferredItemPaddingLeft">6dip</item>
<item name="listPreferredItemPaddingRight">6dip</item>
<item name="listPreferredItemPaddingStart">6dip</item>
@@ -349,6 +350,7 @@
<item name="actionMenuTextAppearance">@android:style/TextAppearance.Holo.Widget.ActionBar.Menu</item>
<item name="actionMenuTextColor">?android:attr/textColorPrimary</item>
<item name="actionBarWidgetTheme">@null</item>
+ <item name="actionBarTheme">@null</item>
<item name="actionBarDivider">?android:attr/dividerVertical</item>
<item name="actionBarItemBackground">?android:attr/selectableItemBackground</item>
@@ -701,6 +703,7 @@
<item name="itemTextAppearance">@android:style/TextAppearance.Large.Inverse</item>
<item name="textAppearanceListItem">@android:style/TextAppearance.Large.Inverse</item>
<item name="textAppearanceListItemSmall">@android:style/TextAppearance.Large.Inverse</item>
+ <item name="textAppearanceListItemSecondary">@android:style/TextAppearance.Small.Inverse</item>
</style>
<!-- Default heme for the TimePicker dialog windows, which is used by the
@@ -1006,6 +1009,7 @@
<item name="listPreferredItemHeightLarge">80dip</item>
<item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item>
<item name="textAppearanceListItemSmall">?android:attr/textAppearanceMedium</item>
+ <item name="textAppearanceListItemSecondary">?android:attr/textAppearanceSmall</item>
<item name="listPreferredItemPaddingLeft">8dip</item>
<item name="listPreferredItemPaddingRight">8dip</item>
<item name="listPreferredItemPaddingStart">8dip</item>
@@ -1194,6 +1198,7 @@
<item name="actionBarSize">@dimen/action_bar_default_height</item>
<item name="actionModePopupWindowStyle">@android:style/Widget.Holo.PopupWindow.ActionMode</item>
<item name="actionBarWidgetTheme">@null</item>
+ <item name="actionBarTheme">@null</item>
<item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_dark</item>
<item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_dark</item>
@@ -1335,6 +1340,7 @@
<item name="listPreferredItemHeightLarge">80dip</item>
<item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item>
<item name="textAppearanceListItemSmall">?android:attr/textAppearanceMedium</item>
+ <item name="textAppearanceListItemSecondary">?android:attr/textAppearanceSmall</item>
<item name="listPreferredItemPaddingLeft">8dip</item>
<item name="listPreferredItemPaddingRight">8dip</item>
<item name="listPreferredItemPaddingStart">8dip</item>
@@ -1526,6 +1532,7 @@
<item name="actionBarSize">@dimen/action_bar_default_height</item>
<item name="actionModePopupWindowStyle">@android:style/Widget.Holo.Light.PopupWindow.ActionMode</item>
<item name="actionBarWidgetTheme">@null</item>
+ <item name="actionBarTheme">@null</item>
<item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_light</item>
<item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_light</item>
@@ -1585,6 +1592,7 @@
<item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
<item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse</item>
<item name="actionBarWidgetTheme">@android:style/Theme.Holo</item>
+ <item name="actionBarTheme">@null</item>
<item name="actionDropDownStyle">@android:style/Widget.Holo.Spinner.DropDown.ActionBar</item>
<item name="actionButtonStyle">@android:style/Widget.Holo.ActionButton</item>
diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml
index b5ac8fa..9e235d6 100644
--- a/core/res/res/values/themes_quantum.xml
+++ b/core/res/res/values/themes_quantum.xml
@@ -109,11 +109,13 @@
<item name="listPreferredItemHeightSmall">48dip</item>
<item name="listPreferredItemHeightLarge">80dip</item>
<item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
- <item name="textAppearanceListItemSmall">?attr/textAppearanceMedium</item>
- <item name="listPreferredItemPaddingLeft">8dip</item>
- <item name="listPreferredItemPaddingRight">8dip</item>
- <item name="listPreferredItemPaddingStart">8dip</item>
- <item name="listPreferredItemPaddingEnd">8dip</item>
+ <item name="textAppearanceListItem">@style/TextAppearance.Quantum.Subhead</item>
+ <item name="textAppearanceListItemSmall">@style/TextAppearance.Quantum.Subhead</item>
+ <item name="textAppearanceListItemSecondary">@style/TextAppearance.Quantum.Body1</item>
+ <item name="listPreferredItemPaddingLeft">16dip</item>
+ <item name="listPreferredItemPaddingRight">16dip</item>
+ <item name="listPreferredItemPaddingStart">16dip</item>
+ <item name="listPreferredItemPaddingEnd">16dip</item>
<!-- @hide -->
<item name="searchResultListItemHeight">58dip</item>
@@ -269,6 +271,7 @@
<!-- Preference styles -->
<item name="preferenceScreenStyle">@style/Preference.Quantum.PreferenceScreen</item>
<item name="preferenceFragmentStyle">@style/PreferenceFragment.Quantum</item>
+ <item name="preferenceFragmentPaddingSide">0dip</item>
<item name="preferenceCategoryStyle">@style/Preference.Quantum.Category</item>
<item name="preferenceStyle">@style/Preference.Quantum</item>
<item name="preferenceInformationStyle">@style/Preference.Quantum.Information</item>
@@ -278,7 +281,7 @@
<item name="dialogPreferenceStyle">@style/Preference.Quantum.DialogPreference</item>
<item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
<item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
- <item name="preferenceLayoutChild">@layout/preference_child_holo</item>
+ <item name="preferenceLayoutChild">@layout/preference_child_quantum</item>
<item name="detailsElementBackground">?attr/colorBackground</item>
<!-- Search widget styles -->
@@ -442,11 +445,13 @@
<item name="listPreferredItemHeightSmall">48dip</item>
<item name="listPreferredItemHeightLarge">80dip</item>
<item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
- <item name="textAppearanceListItemSmall">?attr/textAppearanceMedium</item>
- <item name="listPreferredItemPaddingLeft">8dip</item>
- <item name="listPreferredItemPaddingRight">8dip</item>
- <item name="listPreferredItemPaddingStart">8dip</item>
- <item name="listPreferredItemPaddingEnd">8dip</item>
+ <item name="textAppearanceListItem">@style/TextAppearance.Quantum.Subhead</item>
+ <item name="textAppearanceListItemSmall">@style/TextAppearance.Quantum.Subhead</item>
+ <item name="textAppearanceListItemSecondary">@style/TextAppearance.Quantum.Body1</item>
+ <item name="listPreferredItemPaddingLeft">16dip</item>
+ <item name="listPreferredItemPaddingRight">16dip</item>
+ <item name="listPreferredItemPaddingStart">16dip</item>
+ <item name="listPreferredItemPaddingEnd">16dip</item>
<!-- @hide -->
<item name="searchResultListItemHeight">58dip</item>
@@ -601,6 +606,7 @@
<!-- Preference styles -->
<item name="preferenceScreenStyle">@style/Preference.Quantum.PreferenceScreen</item>
<item name="preferenceFragmentStyle">@style/PreferenceFragment.Quantum</item>
+ <item name="preferenceFragmentPaddingSide">0dip</item>
<item name="preferenceCategoryStyle">@style/Preference.Quantum.Category</item>
<item name="preferenceStyle">@style/Preference.Quantum</item>
<item name="preferenceInformationStyle">@style/Preference.Quantum.Information</item>
@@ -610,7 +616,7 @@
<item name="dialogPreferenceStyle">@style/Preference.Quantum.DialogPreference</item>
<item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
<item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
- <item name="preferenceLayoutChild">@layout/preference_child_holo</item>
+ <item name="preferenceLayoutChild">@layout/preference_child_quantum</item>
<item name="detailsElementBackground">?attr/colorBackground</item>
<!-- PreferenceFrameLayout attributes -->
@@ -706,6 +712,7 @@
with an inverse color profile. The dark action bar sharply stands out against
the light content. -->
<style name="Theme.Quantum.Light.DarkActionBar">
+ <item name="actionBarWidgetTheme">@null</item>
<item name="actionBarTheme">@style/Theme.Quantum</item>
</style>
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 19131f2..66a88a2 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -595,7 +595,6 @@
* Specifies the blending mode used to apply tint.
*
* @param tintMode A Porter-Duff blending mode
- * @hide Pending finalization of supported Modes
*/
public void setTintMode(Mode tintMode) {
if (mBitmapState.mTintMode != tintMode) {
@@ -606,10 +605,7 @@
}
/**
- * Returns the tint mode for this drawable, or {@code null} if none set.
- *
- * @return the tint mode for this drawable, or {@code null} if none set
- * @hide
+ * @hide only needed by a hack within ProgressBar
*/
public Mode getTintMode() {
return mBitmapState.mTintMode;
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 077db7a..21cd5db 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -1248,16 +1248,14 @@
*/
static PorterDuff.Mode parseTintMode(int value, Mode defaultMode) {
switch (value) {
- case 0:
- return Mode.SRC_IN;
- case 1:
- return Mode.SRC_ATOP;
- case 2:
- return Mode.MULTIPLY;
- case 3:
- return Mode.SCREEN;
+ case 3: return Mode.SRC_OVER;
+ case 5: return Mode.SRC_IN;
+ case 9: return Mode.SRC_ATOP;
+ case 14: return Mode.MULTIPLY;
+ case 15: return Mode.SCREEN;
+ case 16: return Mode.ADD;
+ default: return defaultMode;
}
- return defaultMode;
}
}
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 66193a5..3e9ca0a 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -345,7 +345,6 @@
* Specifies the blending mode used to apply tint.
*
* @param tintMode A Porter-Duff blending mode
- * @hide Pending finalization of supported Modes
*/
public void setTintMode(Mode tintMode) {
if (mNinePatchState.mTintMode != tintMode) {
diff --git a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
index 3323a25..2810c43 100644
--- a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
+++ b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
@@ -124,6 +124,41 @@
return super.isStateful() || mState.mTint != null && mState.mTint.isStateful();
}
+ /**
+ * Specifies a tint for drawing touch feedback ripples.
+ *
+ * @param tint Color state list to use for tinting touch feedback ripples,
+ * or null to clear the tint
+ */
+ public void setTint(ColorStateList tint) {
+ if (mState.mTint != tint) {
+ mState.mTint = tint;
+ invalidateSelf();
+ }
+ }
+
+ /**
+ * Returns the tint color for touch feedback ripples.
+ *
+ * @return Color state list to use for tinting touch feedback ripples, or
+ * null if none set
+ */
+ public ColorStateList getTint() {
+ return mState.mTint;
+ }
+
+ /**
+ * Specifies the blending mode used to draw touch feedback ripples.
+ *
+ * @param tintMode A Porter-Duff blending mode
+ */
+ public void setTintMode(Mode tintMode) {
+ if (mState.mTintMode != tintMode) {
+ mState.mTintMode = tintMode;
+ invalidateSelf();
+ }
+ }
+
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index ce711b6..c64c169 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -62,7 +62,7 @@
}
}
-bool DeferredLayerUpdater::apply() {
+bool DeferredLayerUpdater::apply(bool* hasFunctors) {
bool success = true;
// These properties are applied the same to both layer types
mLayer->setColorFilter(mColorFilter);
@@ -73,7 +73,11 @@
success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight);
}
mLayer->setBlend(mBlend);
- mDisplayList->updateProperties();
+ TreeInfo info = {0};
+ mDisplayList->prepareTree(info);
+ if (info.hasFunctors) {
+ *hasFunctors = true;
+ }
mLayer->updateDeferred(mDisplayList.get(),
mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
mDirtyRect.setEmpty();
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index ce08c2d..2cc9229 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -77,7 +77,7 @@
ANDROID_API void setPaint(const SkPaint* paint);
- ANDROID_API bool apply();
+ ANDROID_API bool apply(bool* hasFunctors);
ANDROID_API Layer* backingLayer() {
return mLayer;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index a84aa6b..140a07a 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -192,7 +192,9 @@
flags, *currentTransform());
addDrawOp(op);
mDisplayListData->addChild(op);
- if (displayList->isProjectionReceiver()) {
+
+ if (displayList->stagingProperties().isProjectionReceiver()) {
+ // use staging property, since recording on UI thread
mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size() - 1;
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 9dbcd36..f37487f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1901,7 +1901,6 @@
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
// compute 3d ordering
- displayList->updateProperties();
displayList->computeOrdering();
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
status = startFrame();
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 5010076..823ae7b 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -49,7 +49,12 @@
fflush(file);
}
-RenderNode::RenderNode() : mDestroyed(false), mNeedsPropertiesSync(false), mDisplayListData(0) {
+RenderNode::RenderNode()
+ : mDestroyed(false)
+ , mNeedsPropertiesSync(false)
+ , mNeedsDisplayListDataSync(false)
+ , mDisplayListData(0)
+ , mStagingDisplayListData(0) {
}
RenderNode::~RenderNode() {
@@ -57,13 +62,15 @@
mDestroyed = true;
delete mDisplayListData;
+ delete mStagingDisplayListData;
}
-void RenderNode::setData(DisplayListData* data) {
- delete mDisplayListData;
- mDisplayListData = data;
- if (mDisplayListData) {
- Caches::getInstance().registerFunctors(mDisplayListData->functorCount);
+void RenderNode::setStagingDisplayList(DisplayListData* data) {
+ mNeedsDisplayListDataSync = true;
+ delete mStagingDisplayListData;
+ mStagingDisplayListData = data;
+ if (mStagingDisplayListData) {
+ Caches::getInstance().registerFunctors(mStagingDisplayListData->functorCount);
}
}
@@ -86,35 +93,45 @@
ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string());
}
-void RenderNode::updateProperties() {
+void RenderNode::prepareTree(TreeInfo& info) {
+ ATRACE_CALL();
+
+ prepareTreeImpl(info);
+}
+
+void RenderNode::prepareTreeImpl(TreeInfo& info) {
+ pushStagingChanges(info);
+ prepareSubTree(info, mDisplayListData);
+}
+
+void RenderNode::pushStagingChanges(TreeInfo& info) {
if (mNeedsPropertiesSync) {
mNeedsPropertiesSync = false;
mProperties = mStagingProperties;
}
-
- if (mDisplayListData) {
- for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
- RenderNode* childNode = mDisplayListData->children()[i]->mDisplayList;
- childNode->updateProperties();
- }
+ if (mNeedsDisplayListDataSync) {
+ mNeedsDisplayListDataSync = false;
+ // Do a push pass on the old tree to handle freeing DisplayListData
+ // that are no longer used
+ TreeInfo oldTreeInfo = {0};
+ prepareSubTree(oldTreeInfo, mDisplayListData);
+ // TODO: The damage for the old tree should be accounted for
+ delete mDisplayListData;
+ mDisplayListData = mStagingDisplayListData;
+ mStagingDisplayListData = 0;
}
}
-bool RenderNode::hasFunctors() {
- if (!mDisplayListData) return false;
-
- if (mDisplayListData->functorCount) {
- return true;
- }
-
- for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
- RenderNode* childNode = mDisplayListData->children()[i]->mDisplayList;
- if (childNode->hasFunctors()) {
- return true;
+void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
+ if (subtree) {
+ if (!info.hasFunctors) {
+ info.hasFunctors = subtree->functorCount;
+ }
+ for (size_t i = 0; i < subtree->children().size(); i++) {
+ RenderNode* childNode = subtree->children()[i]->mDisplayList;
+ childNode->prepareTreeImpl(info);
}
}
-
- return false;
}
/*
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index fd0fabc..7853701 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -65,6 +65,11 @@
class RestoreToCountOp;
class DrawDisplayListOp;
+struct TreeInfo {
+ bool hasFunctors;
+ // TODO: Damage calculations? Flag to skip staging pushes for RT animations?
+};
+
/**
* Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties.
*
@@ -89,7 +94,7 @@
ANDROID_API static void outputLogBuffer(int fd);
- ANDROID_API void setData(DisplayListData* newData);
+ ANDROID_API void setStagingDisplayList(DisplayListData* newData);
void computeOrdering();
@@ -105,6 +110,10 @@
return mDisplayListData && mDisplayListData->hasDrawOps;
}
+ const char* getName() const {
+ return mName.string();
+ }
+
void setName(const char* name) {
if (name) {
char* lastPeriod = strrchr(name, '.');
@@ -129,10 +138,6 @@
return mStagingProperties;
}
- bool isProjectionReceiver() {
- return properties().isProjectionReceiver();
- }
-
int getWidth() {
return properties().getWidth();
}
@@ -141,10 +146,7 @@
return properties().getHeight();
}
- ANDROID_API void updateProperties();
-
- // Returns true if this RenderNode or any of its children have functors
- bool hasFunctors();
+ ANDROID_API void prepareTree(TreeInfo& info);
private:
typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair;
@@ -203,6 +205,10 @@
const char* mText;
};
+ void prepareTreeImpl(TreeInfo& info);
+ void pushStagingChanges(TreeInfo& info);
+ void prepareSubTree(TreeInfo& info, DisplayListData* subtree);
+
String8 mName;
bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
@@ -210,7 +216,9 @@
RenderProperties mProperties;
RenderProperties mStagingProperties;
+ bool mNeedsDisplayListDataSync;
DisplayListData* mDisplayListData;
+ DisplayListData* mStagingDisplayListData;
/**
* Draw time state - these properties are only set and used during rendering
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index c231f6f..c5122e2 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -347,6 +347,7 @@
if (mEglSurface != EGL_NO_SURFACE) {
mDirtyRegionsEnabled = mGlobalContext->enableDirtyRegions(mEglSurface);
+ mGlobalContext->makeCurrent(mEglSurface);
mHaveNewSurface = true;
}
}
@@ -356,14 +357,15 @@
mHaveNewSurface = false;
}
-void CanvasContext::makeCurrent() {
+void CanvasContext::requireSurface() {
+ LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
+ "requireSurface() called but no surface set!");
mGlobalContext->makeCurrent(mEglSurface);
}
bool CanvasContext::initialize(EGLNativeWindowType window) {
if (mCanvas) return false;
setSurface(window);
- makeCurrent();
mCanvas = new OpenGLRenderer();
mCanvas->initProperties();
return true;
@@ -371,7 +373,11 @@
void CanvasContext::updateSurface(EGLNativeWindowType window) {
setSurface(window);
- makeCurrent();
+}
+
+void CanvasContext::pauseSurface(EGLNativeWindowType window) {
+ // TODO: For now we just need a fence, in the future suspend any animations
+ // and such to prevent from trying to render into this surface
}
void CanvasContext::setup(int width, int height) {
@@ -379,15 +385,12 @@
mCanvas->setViewport(width, height);
}
-void CanvasContext::setDisplayListData(RenderNode* displayList, DisplayListData* newData) {
- displayList->setData(newData);
-}
-
-void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters) {
+void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters,
+ bool* hasFunctors) {
mGlobalContext->makeCurrent(mEglSurface);
for (size_t i = 0; i < layerUpdaters->size(); i++) {
DeferredLayerUpdater* update = layerUpdaters->itemAt(i);
- LOG_ALWAYS_FATAL_IF(!update->apply(), "Failed to update layer!");
+ LOG_ALWAYS_FATAL_IF(!update->apply(hasFunctors), "Failed to update layer!");
if (update->backingLayer()->deferredUpdateScheduled) {
mCanvas->pushLayerUpdate(update->backingLayer());
}
@@ -460,7 +463,7 @@
if (!mCanvas) return;
- makeCurrent();
+ requireSurface();
Rect dirty;
mCanvas->invokeFunctors(dirty);
}
@@ -481,7 +484,8 @@
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
requireGlContext();
- layer->apply();
+ bool hasFunctors;
+ layer->apply(&hasFunctors);
return LayerRenderer::copyLayer(layer->backingLayer(), bitmap);
}
@@ -491,12 +495,12 @@
}
Layer* CanvasContext::createRenderLayer(int width, int height) {
- requireGlContext();
+ requireSurface();
return LayerRenderer::createRenderLayer(width, height);
}
Layer* CanvasContext::createTextureLayer() {
- requireGlContext();
+ requireSurface();
return LayerRenderer::createTextureLayer();
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 6f1c37f..a24162e 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -63,9 +63,9 @@
bool initialize(EGLNativeWindowType window);
void updateSurface(EGLNativeWindowType window);
+ void pauseSurface(EGLNativeWindowType window);
void setup(int width, int height);
- void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
- void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters);
+ void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, bool* hasFunctors);
void drawDisplayList(RenderNode* displayList, Rect* dirty);
void destroyCanvas();
@@ -83,7 +83,7 @@
private:
void setSurface(EGLNativeWindowType window);
void swapBuffers();
- void makeCurrent();
+ void requireSurface();
friend class InvokeFunctorsTask;
void invokeFunctors();
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 7b509a2..372d0d0 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -30,18 +30,6 @@
namespace uirenderer {
namespace renderthread {
-SetDisplayListData::SetDisplayListData() : mNewData(0) {}
-
-SetDisplayListData::SetDisplayListData(RenderNode* node, DisplayListData* newData)
- : mTargetNode(node), mNewData(newData) {
-}
-
-SetDisplayListData::~SetDisplayListData() {}
-
-void SetDisplayListData::apply() const {
- mTargetNode->setData(mNewData);
-}
-
DrawFrameTask::DrawFrameTask() : mContext(0), mTaskMode(MODE_INVALID), mRenderNode(0) {
}
@@ -52,13 +40,6 @@
mContext = context;
}
-void DrawFrameTask::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) {
- LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to setDisplayListData with!");
-
- SetDisplayListData setter(renderNode, newData);
- mDisplayListDataUpdates.push(setter);
-}
-
void DrawFrameTask::addLayer(DeferredLayerUpdater* layer) {
LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to addLayer with!");
@@ -113,7 +94,8 @@
void DrawFrameTask::run() {
ATRACE_NAME("DrawFrame");
- syncFrameState();
+ // canUnblockUiThread is temporary until WebView has a solution for syncing frame state
+ bool canUnblockUiThread = syncFrameState();
if (mTaskMode == MODE_STATE_ONLY) {
unblockUiThread();
@@ -125,9 +107,6 @@
sp<RenderNode> renderNode = mRenderNode;
CanvasContext* context = mContext;
- // This is temporary until WebView has a solution for syncing frame state
- bool canUnblockUiThread = !requiresSynchronousDraw(renderNode.get());
-
// From this point on anything in "this" is *UNSAFE TO ACCESS*
if (canUnblockUiThread) {
unblockUiThread();
@@ -140,21 +119,20 @@
}
}
-void DrawFrameTask::syncFrameState() {
+bool DrawFrameTask::syncFrameState() {
ATRACE_CALL();
- for (size_t i = 0; i < mDisplayListDataUpdates.size(); i++) {
- const SetDisplayListData& setter = mDisplayListDataUpdates[i];
- setter.apply();
- }
- mDisplayListDataUpdates.clear();
-
- mContext->processLayerUpdates(&mLayers);
+ bool hasFunctors = false;
+ mContext->processLayerUpdates(&mLayers, &hasFunctors);
// If we don't have an mRenderNode this is a state flush only
if (mRenderNode.get()) {
- mRenderNode->updateProperties();
+ TreeInfo info = {0};
+ mRenderNode->prepareTree(info);
+ hasFunctors |= info.hasFunctors;
}
+
+ return !hasFunctors;
}
void DrawFrameTask::unblockUiThread() {
@@ -172,10 +150,6 @@
context->drawDisplayList(renderNode, dirty);
}
-bool DrawFrameTask::requiresSynchronousDraw(RenderNode* renderNode) {
- return renderNode->hasFunctors();
-}
-
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index 4e9b244..a512408 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -37,18 +37,6 @@
class CanvasContext;
class RenderThread;
-class SetDisplayListData {
-public:
- // This ctor exists for Vector's usage
- SetDisplayListData();
- SetDisplayListData(RenderNode* node, DisplayListData* newData);
- ~SetDisplayListData();
- void apply() const;
-private:
- sp<RenderNode> mTargetNode;
- DisplayListData* mNewData;
-};
-
/*
* This is a special Super Task. It is re-used multiple times by RenderProxy,
* and contains state (such as layer updaters & new DisplayListDatas) that is
@@ -62,7 +50,6 @@
void setContext(CanvasContext* context);
- void setDisplayListData(RenderNode* renderNode, DisplayListData* newData);
void addLayer(DeferredLayerUpdater* layer);
void removeLayer(DeferredLayerUpdater* layer);
@@ -81,14 +68,10 @@
};
void postAndWait(RenderThread* renderThread, TaskMode mode);
- void syncFrameState();
+ bool syncFrameState();
void unblockUiThread();
static void drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty);
- // This checks to see if there are any drawGlFunctors which would require
- // a synchronous drawRenderNode()
- static bool requiresSynchronousDraw(RenderNode* renderNode);
-
Mutex mLock;
Condition mSignal;
@@ -100,7 +83,6 @@
TaskMode mTaskMode;
sp<RenderNode> mRenderNode;
Rect mDirty;
- Vector<SetDisplayListData> mDisplayListDataUpdates;
/*********************************************
* Multi frame data
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index e817e61..49b9aca 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -92,10 +92,10 @@
return (void*) args->context->initialize(args->window);
}
-bool RenderProxy::initialize(EGLNativeWindowType window) {
+bool RenderProxy::initialize(const sp<ANativeWindow>& window) {
SETUP_TASK(initialize);
args->context = mContext;
- args->window = window;
+ args->window = window.get();
return (bool) postAndWait(task);
}
@@ -104,11 +104,23 @@
return NULL;
}
-void RenderProxy::updateSurface(EGLNativeWindowType window) {
+void RenderProxy::updateSurface(const sp<ANativeWindow>& window) {
SETUP_TASK(updateSurface);
args->context = mContext;
- args->window = window;
- post(task);
+ args->window = window.get();
+ postAndWait(task);
+}
+
+CREATE_BRIDGE2(pauseSurface, CanvasContext* context, EGLNativeWindowType window) {
+ args->context->pauseSurface(args->window);
+ return NULL;
+}
+
+void RenderProxy::pauseSurface(const sp<ANativeWindow>& window) {
+ SETUP_TASK(pauseSurface);
+ args->context = mContext;
+ args->window = window.get();
+ postAndWait(task);
}
CREATE_BRIDGE3(setup, CanvasContext* context, int width, int height) {
@@ -124,10 +136,6 @@
post(task);
}
-void RenderProxy::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) {
- mDrawFrameTask.setDisplayListData(renderNode, newData);
-}
-
void RenderProxy::drawDisplayList(RenderNode* displayList,
int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom) {
mDrawFrameTask.setRenderNode(displayList);
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index c50da79..1ad3c85 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -59,10 +59,10 @@
ANDROID_API RenderProxy(bool translucent);
ANDROID_API virtual ~RenderProxy();
- ANDROID_API bool initialize(EGLNativeWindowType window);
- ANDROID_API void updateSurface(EGLNativeWindowType window);
+ ANDROID_API bool initialize(const sp<ANativeWindow>& window);
+ ANDROID_API void updateSurface(const sp<ANativeWindow>& window);
+ ANDROID_API void pauseSurface(const sp<ANativeWindow>& window);
ANDROID_API void setup(int width, int height);
- ANDROID_API void setDisplayListData(RenderNode* renderNode, DisplayListData* newData);
ANDROID_API void drawDisplayList(RenderNode* displayList,
int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
ANDROID_API void destroyCanvas();
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index f688d81..664c707 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -471,10 +471,6 @@
final FocusRequester exFocusOwner = mFocusStack.pop();
exFocusOwner.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS);
exFocusOwner.release();
- // clear RCD
- synchronized(mPRStack) {
- clearRemoteControlDisplay_syncAfRcs();
- }
}
}
}
@@ -535,10 +531,6 @@
if (signal) {
// notify the new top of the stack it gained focus
notifyTopOfAudioFocusStack();
- // there's a new top of the stack, let the remote control know
- synchronized(mPRStack) {
- checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
- }
}
} else {
// focus is abandoned by a client that's not at the top of the stack,
@@ -582,10 +574,6 @@
// we removed an entry at the top of the stack:
// notify the new top of the stack it gained focus.
notifyTopOfAudioFocusStack();
- // there's a new top of the stack, let the remote control know
- synchronized(mPRStack) {
- checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
- }
}
}
@@ -694,10 +682,6 @@
mFocusStack.push(new FocusRequester(mainStreamType, focusChangeHint, fd, cb,
clientId, afdh, callingPackageName, Binder.getCallingUid()));
- // there's a new top of the stack, let the remote control know
- synchronized(mPRStack) {
- checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
- }
}//synchronized(mAudioFocusLock)
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
@@ -1237,11 +1221,11 @@
/**
* Helper function:
* Set the new remote control receiver at the top of the RC focus stack.
- * Called synchronized on mAudioFocusLock, then mPRStack
+ * Called synchronized on mPRStack
* precondition: mediaIntent != null
* @return true if mPRStack was changed, false otherwise
*/
- private boolean pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent,
+ private boolean pushMediaButtonReceiver_syncPrs(PendingIntent mediaIntent,
ComponentName target, IBinder token) {
// already at top of stack?
if (!mPRStack.empty() && mPRStack.peek().hasMatchingMediaButtonIntent(mediaIntent)) {
@@ -1285,10 +1269,10 @@
/**
* Helper function:
* Remove the remote control receiver from the RC focus stack.
- * Called synchronized on mAudioFocusLock, then mPRStack
+ * Called synchronized on mPRStack
* precondition: pi != null
*/
- private void removeMediaButtonReceiver_syncAfRcs(PendingIntent pi) {
+ private void removeMediaButtonReceiver_syncPrs(PendingIntent pi) {
try {
for (int index = mPRStack.size()-1; index >= 0; index--) {
final PlayerRecord prse = mPRStack.elementAt(index);
@@ -1470,7 +1454,7 @@
* Helper function:
* Called synchronized on mPRStack
*/
- private void clearRemoteControlDisplay_syncAfRcs() {
+ private void clearRemoteControlDisplay_syncPrs() {
synchronized(mCurrentRcLock) {
mCurrentRcClient = null;
}
@@ -1480,20 +1464,20 @@
/**
* Helper function for code readability: only to be called from
- * checkUpdateRemoteControlDisplay_syncAfRcs() which checks the preconditions for
+ * checkUpdateRemoteControlDisplay_syncPrs() which checks the preconditions for
* this method.
* Preconditions:
- * - called synchronized mAudioFocusLock then on mPRStack
+ * - called synchronized on mPRStack
* - mPRStack.isEmpty() is false
*/
- private void updateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
+ private void updateRemoteControlDisplay_syncPrs(int infoChangedFlags) {
PlayerRecord prse = mPRStack.peek();
int infoFlagsAboutToBeUsed = infoChangedFlags;
// this is where we enforce opt-in for information display on the remote controls
// with the new AudioManager.registerRemoteControlClient() API
if (prse.getRcc() == null) {
//Log.w(TAG, "Can't update remote control display with null remote control client");
- clearRemoteControlDisplay_syncAfRcs();
+ clearRemoteControlDisplay_syncPrs();
return;
}
synchronized(mCurrentRcLock) {
@@ -1511,62 +1495,25 @@
/**
* Helper function:
- * Called synchronized on mAudioFocusLock, then mPRStack
+ * Called synchronized on mPRStack
* Check whether the remote control display should be updated, triggers the update if required
* @param infoChangedFlags the flags corresponding to the remote control client information
* that has changed, if applicable (checking for the update conditions might trigger a
* clear, rather than an update event).
*/
- private void checkUpdateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
+ private void checkUpdateRemoteControlDisplay_syncPrs(int infoChangedFlags) {
// determine whether the remote control display should be refreshed
- // if either stack is empty, there is a mismatch, so clear the RC display
- if (mPRStack.isEmpty() || mFocusStack.isEmpty()) {
- clearRemoteControlDisplay_syncAfRcs();
+ // if the player record stack is empty, there is nothing to display, so clear the RC display
+ if (mPRStack.isEmpty()) {
+ clearRemoteControlDisplay_syncPrs();
return;
}
- // determine which entry in the AudioFocus stack to consider, and compare against the
- // top of the stack for the media button event receivers : simply using the top of the
- // stack would make the entry disappear from the RemoteControlDisplay in conditions such as
- // notifications playing during music playback.
- // Crawl the AudioFocus stack from the top until an entry is found with the following
- // characteristics:
- // - focus gain on STREAM_MUSIC stream
- // - non-transient focus gain on a stream other than music
- FocusRequester af = null;
- try {
- for (int index = mFocusStack.size()-1; index >= 0; index--) {
- FocusRequester fr = mFocusStack.elementAt(index);
- if ((fr.getStreamType() == AudioManager.STREAM_MUSIC)
- || (fr.getGainRequest() == AudioManager.AUDIOFOCUS_GAIN)) {
- af = fr;
- break;
- }
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- Log.e(TAG, "Wrong index accessing audio focus stack when updating RCD: " + e);
- af = null;
- }
- if (af == null) {
- clearRemoteControlDisplay_syncAfRcs();
- return;
- }
-
- // if the audio focus and RC owners belong to different packages, there is a mismatch, clear
- if (!af.hasSamePackage(mPRStack.peek().getCallingPackageName())) {
- clearRemoteControlDisplay_syncAfRcs();
- return;
- }
- // if the audio focus didn't originate from the same Uid as the one in which the remote
- // control information will be retrieved, clear
- if (!af.hasSameUid(mPRStack.peek().getCallingUid())) {
- clearRemoteControlDisplay_syncAfRcs();
- return;
- }
+ // this is where more rules for refresh go
// refresh conditions were verified: update the remote controls
- // ok to call: synchronized mAudioFocusLock then on mPRStack, mPRStack is not empty
- updateRemoteControlDisplay_syncAfRcs(infoChangedFlags);
+ // ok to call: synchronized on mPRStack, mPRStack is not empty
+ updateRemoteControlDisplay_syncPrs(infoChangedFlags);
}
/**
@@ -1582,35 +1529,33 @@
private void onPromoteRcc(int rccId) {
if (DEBUG_RC) { Log.d(TAG, "Promoting RCC " + rccId); }
- synchronized(mAudioFocusLock) {
- synchronized(mPRStack) {
- // ignore if given RCC ID is already at top of remote control stack
- if (!mPRStack.isEmpty() && (mPRStack.peek().getRccId() == rccId)) {
- return;
- }
- int indexToPromote = -1;
- try {
- for (int index = mPRStack.size()-1; index >= 0; index--) {
- final PlayerRecord prse = mPRStack.elementAt(index);
- if (prse.getRccId() == rccId) {
- indexToPromote = index;
- break;
- }
+ synchronized(mPRStack) {
+ // ignore if given RCC ID is already at top of remote control stack
+ if (!mPRStack.isEmpty() && (mPRStack.peek().getRccId() == rccId)) {
+ return;
+ }
+ int indexToPromote = -1;
+ try {
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if (prse.getRccId() == rccId) {
+ indexToPromote = index;
+ break;
}
- if (indexToPromote >= 0) {
- if (DEBUG_RC) { Log.d(TAG, " moving RCC from index " + indexToPromote
- + " to " + (mPRStack.size()-1)); }
- final PlayerRecord prse = mPRStack.remove(indexToPromote);
- mPRStack.push(prse);
- // the RC stack changed, reevaluate the display
- checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- // not expected to happen, indicates improper concurrent modification
- Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
}
- }//synchronized(mPRStack)
- }//synchronized(mAudioFocusLock)
+ if (indexToPromote >= 0) {
+ if (DEBUG_RC) { Log.d(TAG, " moving RCC from index " + indexToPromote
+ + " to " + (mPRStack.size()-1)); }
+ final PlayerRecord prse = mPRStack.remove(indexToPromote);
+ mPRStack.push(prse);
+ // the RC stack changed, reevaluate the display
+ checkUpdateRemoteControlDisplay_syncPrs(RC_INFO_ALL);
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // not expected to happen, indicates improper concurrent modification
+ Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
+ }
+ }//synchronized(mPRStack)
}
/**
@@ -1621,12 +1566,10 @@
IBinder token) {
Log.i(TAG, " Remote Control registerMediaButtonIntent() for " + mediaIntent);
- synchronized(mAudioFocusLock) {
- synchronized(mPRStack) {
- if (pushMediaButtonReceiver_syncAfRcs(mediaIntent, eventReceiver, token)) {
- // new RC client, assume every type of information shall be queried
- checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
- }
+ synchronized(mPRStack) {
+ if (pushMediaButtonReceiver_syncPrs(mediaIntent, eventReceiver, token)) {
+ // new RC client, assume every type of information shall be queried
+ checkUpdateRemoteControlDisplay_syncPrs(RC_INFO_ALL);
}
}
}
@@ -1639,14 +1582,12 @@
{
Log.i(TAG, " Remote Control unregisterMediaButtonIntent() for " + mediaIntent);
- synchronized(mAudioFocusLock) {
- synchronized(mPRStack) {
- boolean topOfStackWillChange = isCurrentRcController(mediaIntent);
- removeMediaButtonReceiver_syncAfRcs(mediaIntent);
- if (topOfStackWillChange) {
- // current RC client will change, assume every type of info needs to be queried
- checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
- }
+ synchronized(mPRStack) {
+ boolean topOfStackWillChange = isCurrentRcController(mediaIntent);
+ removeMediaButtonReceiver_syncPrs(mediaIntent);
+ if (topOfStackWillChange) {
+ // current RC client will change, assume every type of info needs to be queried
+ checkUpdateRemoteControlDisplay_syncPrs(RC_INFO_ALL);
}
}
}
@@ -1697,42 +1638,40 @@
IRemoteControlClient rcClient, String callingPackageName) {
if (DEBUG_RC) Log.i(TAG, "Register remote control client rcClient="+rcClient);
int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
- synchronized(mAudioFocusLock) {
- synchronized(mPRStack) {
- // store the new display information
- try {
- for (int index = mPRStack.size()-1; index >= 0; index--) {
- final PlayerRecord prse = mPRStack.elementAt(index);
- if(prse.hasMatchingMediaButtonIntent(mediaIntent)) {
- prse.resetControllerInfoForRcc(rcClient, callingPackageName,
- Binder.getCallingUid());
+ synchronized(mPRStack) {
+ // store the new display information
+ try {
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if(prse.hasMatchingMediaButtonIntent(mediaIntent)) {
+ prse.resetControllerInfoForRcc(rcClient, callingPackageName,
+ Binder.getCallingUid());
- if (rcClient == null) {
- break;
- }
-
- rccId = prse.getRccId();
-
- // there is a new (non-null) client:
- // give the new client the displays (if any)
- if (mRcDisplays.size() > 0) {
- plugRemoteControlDisplaysIntoClient_syncRcStack(prse.getRcc());
- }
+ if (rcClient == null) {
break;
}
- }//for
- } catch (ArrayIndexOutOfBoundsException e) {
- // not expected to happen, indicates improper concurrent modification
- Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
- }
- // if the eventReceiver is at the top of the stack
- // then check for potential refresh of the remote controls
- if (isCurrentRcController(mediaIntent)) {
- checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
- }
- }//synchronized(mPRStack)
- }//synchronized(mAudioFocusLock)
+ rccId = prse.getRccId();
+
+ // there is a new (non-null) client:
+ // give the new client the displays (if any)
+ if (mRcDisplays.size() > 0) {
+ plugRemoteControlDisplaysIntoClient_syncPrs(prse.getRcc());
+ }
+ break;
+ }
+ }//for
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // not expected to happen, indicates improper concurrent modification
+ Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
+ }
+
+ // if the eventReceiver is at the top of the stack
+ // then check for potential refresh of the remote controls
+ if (isCurrentRcController(mediaIntent)) {
+ checkUpdateRemoteControlDisplay_syncPrs(RC_INFO_ALL);
+ }
+ }//synchronized(mPRStack)
return rccId;
}
@@ -1743,29 +1682,27 @@
protected void unregisterRemoteControlClient(PendingIntent mediaIntent,
IRemoteControlClient rcClient) {
if (DEBUG_RC) Log.i(TAG, "Unregister remote control client rcClient="+rcClient);
- synchronized(mAudioFocusLock) {
- synchronized(mPRStack) {
- boolean topRccChange = false;
- try {
- for (int index = mPRStack.size()-1; index >= 0; index--) {
- final PlayerRecord prse = mPRStack.elementAt(index);
- if ((prse.hasMatchingMediaButtonIntent(mediaIntent))
- && rcClient.equals(prse.getRcc())) {
- // we found the IRemoteControlClient to unregister
- prse.resetControllerInfoForNoRcc();
- topRccChange = (index == mPRStack.size()-1);
- // there can only be one matching RCC in the RC stack, we're done
- break;
- }
+ synchronized(mPRStack) {
+ boolean topRccChange = false;
+ try {
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if ((prse.hasMatchingMediaButtonIntent(mediaIntent))
+ && rcClient.equals(prse.getRcc())) {
+ // we found the IRemoteControlClient to unregister
+ prse.resetControllerInfoForNoRcc();
+ topRccChange = (index == mPRStack.size()-1);
+ // there can only be one matching RCC in the RC stack, we're done
+ break;
}
- } catch (ArrayIndexOutOfBoundsException e) {
- // not expected to happen, indicates improper concurrent modification
- Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
}
- if (topRccChange) {
- // no more RCC for the RCD, check for potential refresh of the remote controls
- checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
- }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // not expected to happen, indicates improper concurrent modification
+ Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
+ }
+ if (topRccChange) {
+ // no more RCC for the RCD, check for potential refresh of the remote controls
+ checkUpdateRemoteControlDisplay_syncPrs(RC_INFO_ALL);
}
}
}
@@ -1843,7 +1780,7 @@
* Plug each registered display into the specified client
* @param rcc, guaranteed non null
*/
- private void plugRemoteControlDisplaysIntoClient_syncRcStack(IRemoteControlClient rcc) {
+ private void plugRemoteControlDisplaysIntoClient_syncPrs(IRemoteControlClient rcc) {
final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
while (displayIterator.hasNext()) {
final DisplayInfoForServer di = displayIterator.next();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
index 26498ca..edfa36a 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
@@ -552,29 +552,72 @@
};
int availableFormatTag = CameraMetadataNative.getTag("android.scaler.availableFormats");
- // Write
- mMetadata.set(CameraCharacteristics.SCALER_AVAILABLE_FORMATS, availableFormats);
+ Key<int[]> formatKey = CameraCharacteristics.SCALER_AVAILABLE_FORMATS;
- byte[] availableFormatValues = mMetadata.readValues(availableFormatTag);
+ validateArrayMetadataReadWriteOverride(formatKey, availableFormats,
+ expectedIntValues, availableFormatTag);
- ByteBuffer bf = ByteBuffer.wrap(availableFormatValues).order(ByteOrder.nativeOrder());
+ //
+ // android.scaler.availableStreamConfigurations (int x n x 4 array)
+ //
+ final int OUTPUT = CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
+ int[] availableStreamConfigs = new int[] {
+ 0x20, 3280, 2464, OUTPUT, // RAW16
+ 0x23, 3264, 2448, OUTPUT, // YCbCr_420_888
+ 0x23, 3200, 2400, OUTPUT, // YCbCr_420_888
+ 0x100, 3264, 2448, OUTPUT, // ImageFormat.JPEG
+ 0x100, 3200, 2400, OUTPUT, // ImageFormat.JPEG
+ 0x100, 2592, 1944, OUTPUT, // ImageFormat.JPEG
+ 0x100, 2048, 1536, OUTPUT, // ImageFormat.JPEG
+ 0x100, 1920, 1080, OUTPUT // ImageFormat.JPEG
+ };
+ int[] expectedAvailableStreamConfigs = new int[] {
+ 0x20, 3280, 2464, OUTPUT, // RAW16
+ 0x23, 3264, 2448, OUTPUT, // YCbCr_420_888
+ 0x23, 3200, 2400, OUTPUT, // YCbCr_420_888
+ 0x21, 3264, 2448, OUTPUT, // BLOB
+ 0x21, 3200, 2400, OUTPUT, // BLOB
+ 0x21, 2592, 1944, OUTPUT, // BLOB
+ 0x21, 2048, 1536, OUTPUT, // BLOB
+ 0x21, 1920, 1080, OUTPUT // BLOB
+ };
+ int availableStreamConfigTag =
+ CameraMetadataNative.getTag("android.scaler.availableStreamConfigurations");
- assertEquals(expectedIntValues.length * 4, availableFormatValues.length);
- for (int i = 0; i < expectedIntValues.length; ++i) {
- assertEquals(expectedIntValues[i], bf.getInt());
- }
- // Read
- byte[] availableFormatsAsByteArray = new byte[expectedIntValues.length * 4];
- ByteBuffer availableFormatsByteBuffer =
- ByteBuffer.wrap(availableFormatsAsByteArray).order(ByteOrder.nativeOrder());
- for (int value : expectedIntValues) {
- availableFormatsByteBuffer.putInt(value);
- }
- mMetadata.writeValues(availableFormatTag, availableFormatsAsByteArray);
+ Key<int[]> configKey = CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
+ validateArrayMetadataReadWriteOverride(configKey, availableStreamConfigs,
+ expectedAvailableStreamConfigs, availableStreamConfigTag);
- int[] resultFormats = mMetadata.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS);
- assertNotNull("result available formats shouldn't be null", resultFormats);
- assertArrayEquals(availableFormats, resultFormats);
+ //
+ // android.scaler.availableMinFrameDurations (int x n x 4 array)
+
+ //
+ long[] availableMinDurations = new long[] {
+ 0x20, 3280, 2464, 33333336, // RAW16
+ 0x23, 3264, 2448, 33333336, // YCbCr_420_888
+ 0x23, 3200, 2400, 33333336, // YCbCr_420_888
+ 0x100, 3264, 2448, 33333336, // ImageFormat.JPEG
+ 0x100, 3200, 2400, 33333336, // ImageFormat.JPEG
+ 0x100, 2592, 1944, 33333336, // ImageFormat.JPEG
+ 0x100, 2048, 1536, 33333336, // ImageFormat.JPEG
+ 0x100, 1920, 1080, 33333336 // ImageFormat.JPEG
+ };
+ long[] expectedAvailableMinDurations = new long[] {
+ 0x20, 3280, 2464, 33333336, // RAW16
+ 0x23, 3264, 2448, 33333336, // YCbCr_420_888
+ 0x23, 3200, 2400, 33333336, // YCbCr_420_888
+ 0x21, 3264, 2448, 33333336, // BLOB
+ 0x21, 3200, 2400, 33333336, // BLOB
+ 0x21, 2592, 1944, 33333336, // BLOB
+ 0x21, 2048, 1536, 33333336, // BLOB
+ 0x21, 1920, 1080, 33333336 // BLOB
+ };
+ int availableMinDurationsTag =
+ CameraMetadataNative.getTag("android.scaler.availableMinFrameDurations");
+
+ Key<long[]> durationKey = CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
+ validateArrayMetadataReadWriteOverride(durationKey, availableMinDurations,
+ expectedAvailableMinDurations, availableMinDurationsTag);
//
// android.statistics.faces (Face x n array)
@@ -639,4 +682,59 @@
}
}
+
+ /**
+ * Validate metadata array tag read/write override.
+ *
+ * <p>Only support long and int array for now, can be easily extend to support other
+ * primitive arrays.</p>
+ */
+ private <T> void validateArrayMetadataReadWriteOverride(Key<T> key, T writeValues,
+ T readValues, int tag) {
+ Class<T> type = key.getType();
+ if (!type.isArray()) {
+ throw new IllegalArgumentException("This function expects an key with array type");
+ } else if (type != int[].class && type != long[].class) {
+ throw new IllegalArgumentException("This function expects long or int array values");
+ }
+
+ // Write
+ mMetadata.set(key, writeValues);
+
+ byte[] readOutValues = mMetadata.readValues(tag);
+
+ ByteBuffer bf = ByteBuffer.wrap(readOutValues).order(ByteOrder.nativeOrder());
+
+ int readValuesLength = Array.getLength(readValues);
+ int readValuesNumBytes = readValuesLength * 4;
+ if (type == long[].class) {
+ readValuesNumBytes = readValuesLength * 8;
+ }
+
+ assertEquals(readValuesNumBytes, readOutValues.length);
+ for (int i = 0; i < readValuesLength; ++i) {
+ if (type == int[].class) {
+ assertEquals(Array.getInt(readValues, i), bf.getInt());
+ } else if (type == long[].class) {
+ assertEquals(Array.getLong(readValues, i), bf.getLong());
+ }
+ }
+
+ // Read
+ byte[] readOutValuesAsByteArray = new byte[readValuesNumBytes];
+ ByteBuffer readOutValuesByteBuffer =
+ ByteBuffer.wrap(readOutValuesAsByteArray).order(ByteOrder.nativeOrder());
+ for (int i = 0; i < readValuesLength; ++i) {
+ if (type == int[].class) {
+ readOutValuesByteBuffer.putInt(Array.getInt(readValues, i));
+ } else if (type == long[].class) {
+ readOutValuesByteBuffer.putLong(Array.getLong(readValues, i));
+ }
+ }
+ mMetadata.writeValues(tag, readOutValuesAsByteArray);
+
+ T result = mMetadata.get(key);
+ assertNotNull(key.getName() + " result shouldn't be null", result);
+ assertArrayEquals(writeValues, result);
+ }
}
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index f68d1a9..48ef9db 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -30,6 +30,7 @@
import android.content.res.ObbInfo;
import android.content.res.ObbScanner;
import android.net.Uri;
+import android.os.Build;
import android.os.Environment;
import android.os.Environment.UserEnvironment;
import android.os.FileUtils;
@@ -341,11 +342,13 @@
// The .apk file
String codePath = packageURI.getPath();
File codeFile = new File(codePath);
+ NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codePath);
+ final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
// Calculate size of container needed to hold base APK.
final int sizeMb;
try {
- sizeMb = calculateContainerSize(codeFile, isForwardLocked);
+ sizeMb = calculateContainerSize(handle, codeFile, abi, isForwardLocked);
} catch (IOException e) {
Slog.w(TAG, "Problem when trying to copy " + codeFile.getPath());
return null;
@@ -408,7 +411,14 @@
final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME);
if (sharedLibraryDir.mkdir()) {
- int ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(codeFile, sharedLibraryDir);
+ int ret = PackageManager.INSTALL_SUCCEEDED;
+ if (abi >= 0) {
+ ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
+ sharedLibraryDir, Build.SUPPORTED_ABIS[abi]);
+ } else if (abi != PackageManager.NO_NATIVE_LIBRARIES) {
+ ret = abi;
+ }
+
if (ret != PackageManager.INSTALL_SUCCEEDED) {
Slog.e(TAG, "Could not copy native libraries to " + sharedLibraryDir.getPath());
PackageHelper.destroySdDir(newCid);
@@ -822,6 +832,17 @@
return availSdMb > sizeMb;
}
+ private int calculateContainerSize(File apkFile, boolean forwardLocked) throws IOException {
+ NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(apkFile);
+ final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
+
+ try {
+ return calculateContainerSize(handle, apkFile, abi, forwardLocked);
+ } finally {
+ handle.close();
+ }
+ }
+
/**
* Calculate the container size for an APK. Takes into account the
*
@@ -829,7 +850,8 @@
* @return size in megabytes (2^20 bytes)
* @throws IOException when there is a problem reading the file
*/
- private int calculateContainerSize(File apkFile, boolean forwardLocked) throws IOException {
+ private int calculateContainerSize(NativeLibraryHelper.ApkHandle apkHandle,
+ File apkFile, int abiIndex, boolean forwardLocked) throws IOException {
// Calculate size of container needed to hold base APK.
long sizeBytes = apkFile.length();
if (sizeBytes == 0 && !apkFile.exists()) {
@@ -838,7 +860,10 @@
// Check all the native files that need to be copied and add that to the
// container size.
- sizeBytes += NativeLibraryHelper.sumNativeBinariesLI(apkFile);
+ if (abiIndex >= 0) {
+ sizeBytes += NativeLibraryHelper.sumNativeBinariesLI(apkHandle,
+ Build.SUPPORTED_ABIS[abiIndex]);
+ }
if (forwardLocked) {
sizeBytes += PackageHelper.extractPublicFiles(apkFile.getPath(), null);
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
index 96da21f..8297878 100644
--- a/packages/SystemUI/res/layout/recents_task_view.xml
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -43,7 +43,11 @@
android:textSize="24sp"
android:textColor="#ffffffff"
android:text="@string/recents_empty_message"
- android:fontFamily="sans-serif-thin" />
+ android:fontFamily="sans-serif-thin"
+ android:singleLine="true"
+ android:maxLines="2"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal" />
<ImageView
android:id="@+id/activity_icon"
android:layout_width="@dimen/recents_task_view_activity_icon_size"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 77944c8..672c1d0 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -112,5 +112,7 @@
<integer name="recents_filter_animate_current_views_min_duration">175</integer>
<!-- The min animation duration for animating views that are newly visible. -->
<integer name="recents_filter_animate_new_views_min_duration">125</integer>
+ <!-- The min animation duration for animating views that are newly visible. -->
+ <integer name="recents_animate_task_bar_enter_duration">200</integer>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ce05639..ad10545 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -526,4 +526,12 @@
<string name="description_direction_up">Slide up for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
<!-- Description of the left direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
<string name="description_direction_left">"Slide left for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+
+ <!-- Zen mode: Summary notification content title. [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_notification_title">
+ <item quantity="one">Notification hidden</item>
+ <item quantity="other">%d notifications hidden</item>
+ </plurals>
+ <!-- Zen mode: Summary notification content text. [CHAR LIMIT=NONE] -->
+ <string name="zen_mode_notification_text">Touch to show</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 8543b97..4fb90cb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -44,6 +44,7 @@
import android.view.WindowManager;
import com.android.systemui.R;
+import java.util.Iterator;
import java.util.List;
/** A proxy implementation for the recents component */
@@ -57,8 +58,11 @@
Resources res = mContext.getResources();
float statusBarHeight = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height);
- mFirstTaskRect = (Rect) msg.getData().getParcelable("taskRect");
- mFirstTaskRect.offset(0, (int) statusBarHeight);
+ Bundle replyData = msg.getData().getParcelable(KEY_CONFIGURATION_DATA);
+ mSingleCountFirstTaskRect = replyData.getParcelable(KEY_SINGLE_TASK_STACK_RECT);
+ mSingleCountFirstTaskRect.offset(0, (int) statusBarHeight);
+ mMultipleCountFirstTaskRect = replyData.getParcelable(KEY_MULTIPLE_TASK_STACK_RECT);
+ mMultipleCountFirstTaskRect.offset(0, (int) statusBarHeight);
}
}
}
@@ -89,12 +93,20 @@
}
}
- final static int MSG_UPDATE_FOR_CONFIGURATION = 0;
- final static int MSG_UPDATE_TASK_THUMBNAIL = 1;
- final static int MSG_PRELOAD_TASKS = 2;
- final static int MSG_CANCEL_PRELOAD_TASKS = 3;
- final static int MSG_CLOSE_RECENTS = 4;
- final static int MSG_TOGGLE_RECENTS = 5;
+ final public static int MSG_UPDATE_FOR_CONFIGURATION = 0;
+ final public static int MSG_UPDATE_TASK_THUMBNAIL = 1;
+ final public static int MSG_PRELOAD_TASKS = 2;
+ final public static int MSG_CANCEL_PRELOAD_TASKS = 3;
+ final public static int MSG_CLOSE_RECENTS = 4;
+ final public static int MSG_TOGGLE_RECENTS = 5;
+
+ final public static String EXTRA_ANIMATING_WITH_THUMBNAIL = "recents.animatingWithThumbnail";
+ final public static String KEY_CONFIGURATION_DATA = "recents.data.updateForConfiguration";
+ final public static String KEY_WINDOW_RECT = "recents.windowRect";
+ final public static String KEY_SYSTEM_INSETS = "recents.systemInsets";
+ final public static String KEY_SINGLE_TASK_STACK_RECT = "recents.singleCountTaskRect";
+ final public static String KEY_MULTIPLE_TASK_STACK_RECT = "recents.multipleCountTaskRect";
+
final static int sMinToggleDelay = 425;
@@ -114,7 +126,8 @@
RecentsServiceConnection mConnection = new RecentsServiceConnection();
View mStatusBarView;
- Rect mFirstTaskRect = new Rect();
+ Rect mSingleCountFirstTaskRect = new Rect();
+ Rect mMultipleCountFirstTaskRect = new Rect();
long mLastToggleTime;
public AlternateRecentsComponent(Context context) {
@@ -190,8 +203,8 @@
// Try and update the recents configuration
try {
Bundle data = new Bundle();
- data.putParcelable("windowRect", rect);
- data.putParcelable("systemInsets", new Rect(0, statusBarHeight, 0, 0));
+ data.putParcelable(KEY_WINDOW_RECT, rect);
+ data.putParcelable(KEY_SYSTEM_INSETS, new Rect(0, statusBarHeight, 0, 0));
Message msg = Message.obtain(null, MSG_UPDATE_FOR_CONFIGURATION, 0, 0);
msg.setData(data);
msg.replyTo = mMessenger;
@@ -221,26 +234,29 @@
return null;
}
- Bitmap thumbnail = ssp.getTaskThumbnail(t.persistentId);
- return thumbnail;
+ return ssp.getTaskThumbnail(t.persistentId);
}
return null;
}
- /** Returns whether there is a first task */
- boolean hasFirstTask() {
+ /** Returns whether there is are multiple recents tasks */
+ boolean hasMultipleRecentsTask() {
+ // NOTE: Currently there's no method to get the number of non-home tasks, so we have to
+ // compute this ourselves
SystemServicesProxy ssp = mSystemServicesProxy;
- List<ActivityManager.RecentTaskInfo> tasks = ssp.getRecentTasks(1,
+ List<ActivityManager.RecentTaskInfo> tasks = ssp.getRecentTasks(4,
UserHandle.CURRENT.getIdentifier());
- for (ActivityManager.RecentTaskInfo t : tasks) {
+ Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
+ while (iter.hasNext()) {
+ ActivityManager.RecentTaskInfo t = iter.next();
+
// Skip tasks in the home stack
if (ssp.isInHomeStack(t.persistentId)) {
+ iter.remove();
continue;
}
-
- return true;
}
- return false;
+ return (tasks.size() > 1);
}
/** Converts from the device rotation to the degree */
@@ -287,8 +303,10 @@
// to launch the first task or dismiss itself
SystemServicesProxy ssp = mSystemServicesProxy;
List<ActivityManager.RunningTaskInfo> tasks = ssp.getRunningTasks(1);
+ boolean isTopTaskHome = false;
if (!tasks.isEmpty()) {
- ComponentName topActivity = tasks.get(0).topActivity;
+ ActivityManager.RunningTaskInfo topTask = tasks.get(0);
+ ComponentName topActivity = topTask.topActivity;
// Check if the front most activity is recents
if (topActivity.getPackageName().equals(sRecentsPackage) &&
@@ -311,16 +329,30 @@
mLastToggleTime = System.currentTimeMillis();
return;
}
+
+ // Determine whether the top task is currently home
+ isTopTaskHome = ssp.isInHomeStack(topTask.id);
}
// Otherwise, Recents is not the front-most activity and we should animate into it
- Rect taskRect = mFirstTaskRect;
- if (taskRect != null && taskRect.width() > 0 && taskRect.height() > 0 && hasFirstTask()) {
+ boolean hasMultipleTasks = hasMultipleRecentsTask();
+ Rect taskRect = hasMultipleTasks ? mMultipleCountFirstTaskRect : mSingleCountFirstTaskRect;
+ if (!isTopTaskHome && taskRect != null && taskRect.width() > 0 && taskRect.height() > 0) {
// Loading from thumbnail
Bitmap thumbnail;
Bitmap firstThumbnail = loadFirstTaskThumbnail();
- if (firstThumbnail == null) {
- // Load the thumbnail from the screenshot
+ if (firstThumbnail != null) {// Create the thumbnail
+ thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
+ Bitmap.Config.ARGB_8888);
+ int size = Math.min(firstThumbnail.getWidth(), firstThumbnail.getHeight());
+ Canvas c = new Canvas(thumbnail);
+ c.drawBitmap(firstThumbnail, new Rect(0, 0, size, size),
+ new Rect(0, 0, taskRect.width(), taskRect.height()), null);
+ c.setBitmap(null);
+ // Recycle the old thumbnail
+ firstThumbnail.recycle();
+ } else {
+ // Load the thumbnail from the screenshot if can't get one from the system
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Bitmap screenshot = takeScreenshot(display);
@@ -328,35 +360,24 @@
int size = Math.min(screenshot.getWidth(), screenshot.getHeight());
int statusBarHeight = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height);
- thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.height(),
+ thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(thumbnail);
c.drawBitmap(screenshot, new Rect(0, statusBarHeight, size, statusBarHeight + size),
- new Rect(0, 0, mFirstTaskRect.width(), mFirstTaskRect.height()), null);
+ new Rect(0, 0, taskRect.width(), taskRect.height()), null);
c.setBitmap(null);
- // Recycle the old screenshot
+ // Recycle the temporary screenshot
screenshot.recycle();
- } else {
- // Create the thumbnail
- thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.height(),
- Bitmap.Config.ARGB_8888);
- int size = Math.min(firstThumbnail.getWidth(), firstThumbnail.getHeight());
- Canvas c = new Canvas(thumbnail);
- c.drawBitmap(firstThumbnail, new Rect(0, 0, size, size),
- new Rect(0, 0, mFirstTaskRect.width(), mFirstTaskRect.height()), null);
- c.setBitmap(null);
- // Recycle the old thumbnail
- firstThumbnail.recycle();
}
ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView,
- thumbnail, mFirstTaskRect.left, mFirstTaskRect.top, null);
- startAlternateRecentsActivity(opts);
+ thumbnail, taskRect.left, taskRect.top, null);
+ startAlternateRecentsActivity(opts, true);
} else {
ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.recents_from_launcher_enter,
R.anim.recents_from_launcher_exit);
- startAlternateRecentsActivity(opts);
+ startAlternateRecentsActivity(opts, false);
}
Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsStartup,
@@ -365,11 +386,12 @@
}
/** Starts the recents activity */
- void startAlternateRecentsActivity(ActivityOptions opts) {
+ void startAlternateRecentsActivity(ActivityOptions opts, boolean animatingWithThumbnail) {
Intent intent = new Intent(sToggleRecentsAction);
intent.setClassName(sRecentsPackage, sRecentsActivity);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ intent.putExtra(EXTRA_ANIMATING_WITH_THUMBNAIL, animatingWithThumbnail);
if (opts != null) {
mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
UserHandle.USER_CURRENT));
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 86f188e..cde17f5e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -72,8 +72,6 @@
public static class Window {
// The dark background dim is set behind the empty recents view
public static final float DarkBackgroundDim = 0.5f;
- // The background dim is set behind the card stack
- public static final float BackgroundDim = 0.35f;
}
public static class RecentsTaskLoader {
@@ -98,11 +96,8 @@
}
public static class TaskView {
- public static final boolean AnimateFrontTaskIconOnEnterRecents = true;
- public static final boolean AnimateFrontTaskIconOnLeavingRecents = true;
-
- public static final boolean UseRoundedCorners = false;
- public static final float RoundedCornerRadiusDps = 3;
+ public static final boolean AnimateFrontTaskBarOnEnterRecents = true;
+ public static final boolean AnimateFrontTaskBarOnLeavingRecents = true;
}
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index dd75921..f61c28c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -43,6 +43,7 @@
boolean mVisible;
boolean mTaskLaunched;
+ // Broadcast receiver to handle messages from our RecentsService
BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -63,8 +64,21 @@
}
};
+ // Broadcast receiver to handle messages from the system
+ BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ finish();
+ }
+ };
+
/** Updates the set of recent tasks */
- void updateRecentsTasks() {
+ void updateRecentsTasks(Intent launchIntent) {
+ // Update the configuration based on the launch intent
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+ config.launchedWithThumbnailAnimation = launchIntent.getBooleanExtra(
+ AlternateRecentsComponent.EXTRA_ANIMATING_WITH_THUMBNAIL, false);
+
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
ArrayList<TaskStack> stacks = root.getStacks();
@@ -111,12 +125,6 @@
RecentsTaskLoader.initialize(this);
RecentsConfiguration.reinitialize(this);
- // Set the background dim
- WindowManager.LayoutParams wlp = getWindow().getAttributes();
- wlp.dimAmount = Constants.Values.Window.BackgroundDim;
- getWindow().setAttributes(wlp);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-
// Create the view hierarchy
mRecentsView = new RecentsView(this);
mRecentsView.setCallbacks(this);
@@ -134,7 +142,7 @@
setContentView(mContainerView);
// Update the recent tasks
- updateRecentsTasks();
+ updateRecentsTasks(getIntent());
}
@Override
@@ -154,7 +162,7 @@
RecentsConfiguration.reinitialize(this);
// Update the recent tasks
- updateRecentsTasks();
+ updateRecentsTasks(intent);
}
@Override
@@ -170,12 +178,37 @@
Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onResume]", "",
Console.AnsiRed);
super.onResume();
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+ "[RecentsActivity|onAttachedToWindow]", "",
+ Console.AnsiRed);
+ super.onAttachedToWindow();
// Register the broadcast receiver to handle messages from our service
IntentFilter filter = new IntentFilter();
filter.addAction(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
filter.addAction(RecentsService.ACTION_FINISH_RECENTS_ACTIVITY);
registerReceiver(mServiceBroadcastReceiver, filter);
+
+ // Register the broadcast receiver to handle messages when the screen is turned off
+ filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ registerReceiver(mScreenOffReceiver, filter);
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+ "[RecentsActivity|onDetachedFromWindow]", "",
+ Console.AnsiRed);
+ super.onDetachedFromWindow();
+
+ // Unregister any broadcast receivers we have registered
+ unregisterReceiver(mServiceBroadcastReceiver);
+ unregisterReceiver(mScreenOffReceiver);
}
@Override
@@ -183,9 +216,6 @@
Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onPause]", "",
Console.AnsiRed);
super.onPause();
-
- // Unregister any broadcast receivers we have registered
- unregisterReceiver(mServiceBroadcastReceiver);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 4a0de0b..21460bb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -17,6 +17,7 @@
package com.android.systemui.recents;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.util.DisplayMetrics;
@@ -38,6 +39,9 @@
public int filteringCurrentViewsMinAnimDuration;
public int filteringNewViewsMinAnimDuration;
+ public int taskBarEnterAnimDuration;
+
+ public boolean launchedWithThumbnailAnimation;
/** Private constructor */
private RecentsConfiguration() {}
@@ -62,6 +66,12 @@
DisplayMetrics dm = res.getDisplayMetrics();
mDisplayMetrics = dm;
+ boolean isLandscape = res.getConfiguration().orientation ==
+ Configuration.ORIENTATION_LANDSCAPE;
+ Console.log(Constants.DebugFlags.UI.MeasureAndLayout,
+ "[RecentsConfiguration|orientation]", isLandscape ? "Landscape" : "Portrait",
+ Console.AnsiGreen);
+
displayRect.set(0, 0, dm.widthPixels, dm.heightPixels);
animationPxMovementPerSecond =
res.getDimensionPixelSize(R.dimen.recents_animation_movement_in_dps_per_second);
@@ -69,6 +79,8 @@
res.getInteger(R.integer.recents_filter_animate_current_views_min_duration);
filteringNewViewsMinAnimDuration =
res.getInteger(R.integer.recents_filter_animate_new_views_min_duration);
+ taskBarEnterAnimDuration =
+ res.getInteger(R.integer.recents_animate_task_bar_enter_duration);
}
public void updateSystemInsets(Rect insets) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
index 22363bb..f78a999 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -26,6 +26,7 @@
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
+import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.TaskStackView;
import com.android.systemui.recents.views.TaskViewTransform;
@@ -50,36 +51,51 @@
Context context = mContext.get();
if (context == null) return;
- if (msg.what == RecentsService.MSG_UPDATE_RECENTS_FOR_CONFIGURATION) {
+ if (msg.what == AlternateRecentsComponent.MSG_UPDATE_FOR_CONFIGURATION) {
RecentsTaskLoader.initialize(context);
RecentsConfiguration.reinitialize(context);
try {
Bundle data = msg.getData();
- Rect windowRect = (Rect) data.getParcelable("windowRect");
- Rect systemInsets = (Rect) data.getParcelable("systemInsets");
+ Rect windowRect = data.getParcelable(AlternateRecentsComponent.KEY_WINDOW_RECT);
+ Rect systemInsets = data.getParcelable(AlternateRecentsComponent.KEY_SYSTEM_INSETS);
// Create a dummy task stack & compute the rect for the thumbnail to animate to
TaskStack stack = new TaskStack(context);
TaskStackView tsv = new TaskStackView(context, stack);
- // Since the nav bar height is already accounted for in the windowRect, don't pass
- // in a bottom inset
+ Bundle replyData = new Bundle();
+ TaskViewTransform transform;
+
+ // Calculate the target task rect for when there is one task
+ // NOTE: Since the nav bar height is already accounted for in the windowRect, don't
+ // pass in a bottom inset
+ stack.addTask(new Task());
tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top, 0);
tsv.boundScroll();
- TaskViewTransform transform = tsv.getStackTransform(0, tsv.getStackScroll());
- Rect taskRect = new Rect(transform.rect);
+ transform = tsv.getStackTransform(0, tsv.getStackScroll());
+ replyData.putParcelable(AlternateRecentsComponent.KEY_SINGLE_TASK_STACK_RECT,
+ new Rect(transform.rect));
- data.putParcelable("taskRect", taskRect);
+ // Also calculate the target task rect when there are multiple tasks
+ stack.addTask(new Task());
+ tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top, 0);
+ tsv.setStackScrollRaw(Integer.MAX_VALUE);
+ tsv.boundScroll();
+ transform = tsv.getStackTransform(1, tsv.getStackScroll());
+ replyData.putParcelable(AlternateRecentsComponent.KEY_MULTIPLE_TASK_STACK_RECT,
+ new Rect(transform.rect));
+
+ data.putParcelable(AlternateRecentsComponent.KEY_CONFIGURATION_DATA, replyData);
Message reply = Message.obtain(null,
- RecentsService.MSG_UPDATE_RECENTS_FOR_CONFIGURATION, 0, 0);
+ AlternateRecentsComponent.MSG_UPDATE_FOR_CONFIGURATION, 0, 0);
reply.setData(data);
msg.replyTo.send(reply);
} catch (RemoteException re) {
re.printStackTrace();
}
- } else if (msg.what == RecentsService.MSG_CLOSE_RECENTS) {
+ } else if (msg.what == AlternateRecentsComponent.MSG_CLOSE_RECENTS) {
// Do nothing
- } else if (msg.what == RecentsService.MSG_TOGGLE_RECENTS) {
+ } else if (msg.what == AlternateRecentsComponent.MSG_TOGGLE_RECENTS) {
// Send a broadcast to toggle recents
Intent intent = new Intent(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
intent.setPackage(context.getPackageName());
@@ -99,11 +115,6 @@
final static String ACTION_FINISH_RECENTS_ACTIVITY = "action_finish_recents_activity";
final static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
- // XXX: This should be getting the message from recents definition
- final static int MSG_UPDATE_RECENTS_FOR_CONFIGURATION = 0;
- final static int MSG_CLOSE_RECENTS = 4;
- final static int MSG_TOGGLE_RECENTS = 5;
-
Messenger mSystemUIMessenger = new Messenger(new SystemUIMessageHandler(this));
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
index d661f287..3c34e90 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -22,7 +22,6 @@
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
@@ -213,6 +212,7 @@
Console.log(Constants.DebugFlags.App.TaskDataLoader,
" [TaskResourceLoader|loadThumbnail]",
thumbnail);
+ thumbnail.setHasAlpha(false);
loadThumbnail = thumbnail;
mThumbnailCache.put(t.key, thumbnail);
} else {
@@ -331,13 +331,9 @@
// Create the default assets
Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ icon.eraseColor(0x00000000);
mDefaultThumbnail = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas();
- c.setBitmap(icon);
- c.drawColor(0x00000000);
- c.setBitmap(mDefaultThumbnail);
- c.drawColor(0x00000000);
- c.setBitmap(null);
+ mDefaultThumbnail.eraseColor(0x00000000);
mDefaultApplicationIcon = new BitmapDrawable(context.getResources(), icon);
Console.log(Constants.DebugFlags.App.TaskDataLoader,
"[RecentsTaskLoader|defaultBitmaps]",
@@ -362,18 +358,9 @@
return mSystemServicesProxy;
}
- /** Reload the set of recent tasks */
- SpaceNode reload(Context context, int preloadCount) {
- Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
- Resources res = context.getResources();
- ArrayList<Task> tasksToForceLoad = new ArrayList<Task>();
- TaskStack stack = new TaskStack(context);
- SpaceNode root = new SpaceNode(context);
- root.setStack(stack);
-
+ private List<ActivityManager.RecentTaskInfo> getRecentTasks(Context context) {
long t1 = System.currentTimeMillis();
- // Get the recent tasks
SystemServicesProxy ssp = mSystemServicesProxy;
List<ActivityManager.RecentTaskInfo> tasks =
ssp.getRecentTasks(25, UserHandle.CURRENT.getIdentifier());
@@ -401,6 +388,24 @@
}
}
+ return tasks;
+ }
+
+ /** Reload the set of recent tasks */
+ SpaceNode reload(Context context, int preloadCount) {
+ long t1 = System.currentTimeMillis();
+
+ Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
+ Resources res = context.getResources();
+ ArrayList<Task> tasksToForceLoad = new ArrayList<Task>();
+ TaskStack stack = new TaskStack(context);
+ SpaceNode root = new SpaceNode(context);
+ root.setStack(stack);
+
+ // Get the recent tasks
+ SystemServicesProxy ssp = mSystemServicesProxy;
+ List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(context);
+
// Add each task to the task stack
t1 = System.currentTimeMillis();
int taskCount = tasks.size();
@@ -454,6 +459,7 @@
"[RecentsTaskLoader|loadingTaskThumbnail]");
task.thumbnail = ssp.getTaskThumbnail(task.key.id);
if (task.thumbnail != null) {
+ task.thumbnail.setHasAlpha(false);
mThumbnailCache.put(task.key, task.thumbnail);
} else {
task.thumbnail = mDefaultThumbnail;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java
index efcd948..505238d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java
@@ -24,7 +24,6 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
-import android.graphics.Canvas;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -52,9 +51,7 @@
if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
// Create a dummy icon
mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(mDummyIcon);
- c.drawColor(0xFF999999);
- c.setBitmap(null);
+ mDummyIcon.eraseColor(0xFF999999);
}
}
@@ -117,9 +114,7 @@
// If we are mocking, then just return a dummy thumbnail
if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
Bitmap thumbnail = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(thumbnail);
- c.drawColor(0xff333333);
- c.setBitmap(null);
+ thumbnail.eraseColor(0xff333333);
return thumbnail;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index a0ff3b7..189f358 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -69,6 +69,10 @@
TaskCallbacks mCb;
+ public Task() {
+ // Only used by RecentsService for task rect calculations.
+ }
+
public Task(int id, boolean isActive, Intent intent, String activityTitle,
Bitmap activityIcon, int userId) {
this.key = new TaskKey(id, intent);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index a0e5b6a..21e2c1d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -43,7 +43,13 @@
ArrayList<Task> prevFilteredTasks = new ArrayList<Task>(mFilteredTasks);
mFilter = filter;
updateFilteredTasks();
- return !prevFilteredTasks.equals(mFilteredTasks);
+ if (!prevFilteredTasks.equals(mFilteredTasks)) {
+ return true;
+ } else {
+ // If the tasks are exactly the same pre/post filter, then just reset it
+ mFilter = null;
+ return false;
+ }
}
/** Removes the task filter and returns the previous touch state */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 1ebe231..ec28379 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -108,6 +108,7 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
+ int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
@@ -118,6 +119,7 @@
// We measure our stack views sans the status bar. It will handle the nav bar itself.
RecentsConfiguration config = RecentsConfiguration.getInstance();
+ int childWidth = width - config.systemInsets.right;
int childHeight = height - config.systemInsets.top;
// Measure each child
@@ -125,7 +127,7 @@
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
- child.measure(widthMeasureSpec,
+ child.measure(MeasureSpec.makeMeasureSpec(childWidth, widthMode),
MeasureSpec.makeMeasureSpec(childHeight, heightMode));
}
}
@@ -255,11 +257,11 @@
| Intent.FLAG_ACTIVITY_TASK_ON_HOME
| Intent.FLAG_ACTIVITY_NEW_TASK);
try {
+ UserHandle taskUser = new UserHandle(task.userId);
if (opts != null) {
- getContext().startActivityAsUser(i, opts.toBundle(),
- new UserHandle(task.userId));
+ getContext().startActivityAsUser(i, opts.toBundle(), taskUser);
} else {
- getContext().startActivityAsUser(i, new UserHandle(task.userId));
+ getContext().startActivityAsUser(i, taskUser);
}
} catch (ActivityNotFoundException anfe) {
Console.logError(getContext(), "Could not start Activity");
@@ -275,7 +277,7 @@
Constants.DebugFlags.App.TimeRecentsLaunchKey, "onTaskLaunched");
// Launch the app right away if there is no task view, otherwise, animate the icon out first
- if (tv == null || !Constants.Values.TaskView.AnimateFrontTaskIconOnLeavingRecents) {
+ if (tv == null || !Constants.Values.TaskView.AnimateFrontTaskBarOnLeavingRecents) {
post(launchRunnable);
} else {
tv.animateOnLeavingRecents(launchRunnable);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index fa06764..728aaad 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -171,7 +171,7 @@
transform.visible = false;
} else {
transform.rect.offset(0, transform.translationY);
- Utilities.scaleRectAboutCenter(transform.rect, scale);
+ Utilities.scaleRectAboutCenter(transform.rect, transform.scale);
transform.visible = Rect.intersects(mRect, transform.rect);
}
transform.t = t;
@@ -388,8 +388,14 @@
int stackHeight = mStackRectSansPeek.height();
int maxScrollHeight = taskHeight + (int) ((numTasks - 1) *
Constants.Values.TaskStackView.StackOverlapPct * taskHeight);
- mMinScroll = Math.min(stackHeight, maxScrollHeight) - stackHeight;
- mMaxScroll = maxScrollHeight - stackHeight;
+
+ if (numTasks <= 1) {
+ // If there is only one task, then center the task in the stack rect (sans peek)
+ mMinScroll = mMaxScroll = -(stackHeight - taskHeight) / 2;
+ } else {
+ mMinScroll = Math.min(stackHeight, maxScrollHeight) - stackHeight;
+ mMaxScroll = maxScrollHeight - stackHeight;
+ }
// Debug logging
if (Constants.DebugFlags.UI.MeasureAndLayout) {
@@ -479,8 +485,8 @@
// Clip against the next view (if we aren't animating its alpha)
nextTv = (TaskView) getChildAt(curIndex + 1);
if (nextTv.getAlpha() == 1f) {
- Rect curRect = tv.getClippingRect(mTmpRect, false);
- Rect nextRect = nextTv.getClippingRect(mTmpRect2, true);
+ Rect curRect = tv.getClippingRect(mTmpRect);
+ Rect nextRect = nextTv.getClippingRect(mTmpRect2);
RecentsConfiguration config = RecentsConfiguration.getInstance();
// The hit rects are relative to the task view, which needs to be offset by the
// system bar height
@@ -523,9 +529,8 @@
int minHeight = (int) (mStackRect.height() -
(Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height()));
int size = Math.min(minHeight, Math.min(mStackRect.width(), mStackRect.height()));
- int centerX = mStackRect.centerX();
- mTaskRect.set(centerX - size / 2, mStackRectSansPeek.top,
- centerX + size / 2, mStackRectSansPeek.top + size);
+ mTaskRect.set(mStackRect.left, mStackRectSansPeek.top,
+ mStackRect.right, mStackRectSansPeek.top + size);
// Update the scroll bounds
updateMinMaxScroll(false);
@@ -558,8 +563,9 @@
requestSynchronizeStackViewsWithModel();
synchronizeStackViewsWithModel();
- // Animate the icon of the first task view
- if (Constants.Values.TaskView.AnimateFrontTaskIconOnEnterRecents) {
+ // Animate the task bar of the first task view
+ if (config.launchedWithThumbnailAnimation &&
+ Constants.Values.TaskView.AnimateFrontTaskBarOnEnterRecents) {
TaskView tv = (TaskView) getChildAt(getChildCount() - 1);
if (tv != null) {
tv.animateOnEnterRecents();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index e99fecb..a3056ec 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -20,9 +20,8 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
-import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Color;
+import android.graphics.Outline;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -36,8 +35,6 @@
import com.android.systemui.recents.Utilities;
import com.android.systemui.recents.model.Task;
-import java.util.Random;
-
/* A task view */
public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks {
@@ -54,8 +51,6 @@
TaskBarView mBarView;
TaskViewCallbacks mCb;
- Path mRoundedRectClipPath = new Path();
-
public TaskView(Context context) {
this(context, null);
@@ -71,7 +66,6 @@
public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- setWillNotDraw(false);
}
@Override
@@ -85,31 +79,6 @@
}
}
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
- // Update the rounded rect clip path
- RecentsConfiguration config = RecentsConfiguration.getInstance();
- float radius = config.pxFromDp(Constants.Values.TaskView.RoundedCornerRadiusDps);
- mRoundedRectClipPath.reset();
- mRoundedRectClipPath.addRoundRect(new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()),
- radius, radius, Path.Direction.CW);
- }
-
- @Override
- protected void dispatchDraw(Canvas canvas) {
- int restoreCount = 0;
- if (Constants.Values.TaskView.UseRoundedCorners) {
- restoreCount = canvas.save();
- canvas.clipPath(mRoundedRectClipPath);
- }
- super.dispatchDraw(canvas);
- if (Constants.Values.TaskView.UseRoundedCorners) {
- canvas.restoreToCount(restoreCount);
- }
- }
-
/** Set callback */
void setCallbacks(TaskViewCallbacks cb) {
mCb = cb;
@@ -195,7 +164,7 @@
.translationY(0)
.setStartDelay(235)
.setInterpolator(BakedBezierInterpolator.INSTANCE)
- .setDuration(Utilities.calculateTranslationAnimationDuration(translate))
+ .setDuration(config.taskBarEnterAnimDuration)
.withLayer()
.start();
}
@@ -214,23 +183,21 @@
.setInterpolator(BakedBezierInterpolator.INSTANCE)
.setDuration(Utilities.calculateTranslationAnimationDuration(translate))
.withLayer()
- .withEndAction(r)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ post(r);
+ }
+ })
.start();
}
/** Returns the rect we want to clip (it may not be the full rect) */
- Rect getClippingRect(Rect outRect, boolean accountForRoundedRects) {
+ Rect getClippingRect(Rect outRect) {
getHitRect(outRect);
// XXX: We should get the hit rect of the thumbnail view and intersect, but this is faster
outRect.right = outRect.left + mThumbnailView.getRight();
outRect.bottom = outRect.top + mThumbnailView.getBottom();
- // We need to shrink the next rect by the rounded corners since those are draw on
- // top of the current view
- if (accountForRoundedRects) {
- RecentsConfiguration config = RecentsConfiguration.getInstance();
- float radius = config.pxFromDp(Constants.Values.TaskView.RoundedCornerRadiusDps);
- outRect.inset((int) radius, (int) radius);
- }
return outRect;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 844b964..f1299fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -109,9 +109,6 @@
public static final int EXPANDED_LEAVE_ALONE = -10000;
public static final int EXPANDED_FULL_OPEN = -10001;
- private static final String EXTRA_INTERCEPT = "android.intercept";
- private static final float INTERCEPTED_ALPHA = .2f;
-
protected CommandQueue mCommandQueue;
protected IStatusBarService mBarService;
protected H mHandler = createHandler();
@@ -1049,7 +1046,6 @@
if (DEBUG) {
Log.d(TAG, "addNotificationViews: added at " + pos);
}
- updateInterceptedState(entry);
updateExpansionStates();
updateNotificationIcons();
}
@@ -1082,32 +1078,10 @@
protected void setZenMode(int mode) {
if (!isDeviceProvisioned()) return;
- final boolean change = mZenMode != mode;
mZenMode = mode;
- final int N = mNotificationData.size();
- for (int i = 0; i < N; i++) {
- final NotificationData.Entry entry = mNotificationData.get(i);
- if (change && !shouldIntercept()) {
- entry.notification.getNotification().extras.putBoolean(EXTRA_INTERCEPT, false);
- }
- updateInterceptedState(entry);
- }
updateNotificationIcons();
}
- private boolean shouldIntercept() {
- return mZenMode != Settings.Global.ZEN_MODE_OFF;
- }
-
- protected boolean shouldIntercept(Notification n) {
- return shouldIntercept() && n.extras.getBoolean(EXTRA_INTERCEPT);
- }
-
- private void updateInterceptedState(NotificationData.Entry entry) {
- final boolean intercepted = shouldIntercept(entry.notification.getNotification());
- entry.row.findViewById(R.id.container).setAlpha(intercepted ? INTERCEPTED_ALPHA : 1);
- }
-
protected abstract void haltTicker();
protected abstract void setAreThereNotifications();
protected abstract void updateNotificationIcons();
@@ -1312,7 +1286,6 @@
} else {
entry.content.setOnClickListener(null);
}
- updateInterceptedState(entry);
}
protected void notifyHeadsUpScreenOn(boolean screenOn) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
new file mode 100644
index 0000000..d563968
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar;
+
+import android.app.Notification;
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Process;
+import android.service.notification.StatusBarNotification;
+import android.util.ArrayMap;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.NotificationData.Entry;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+
+public class InterceptedNotifications {
+ private static final String TAG = "InterceptedNotifications";
+ private static final String EXTRA_INTERCEPT = "android.intercept";
+
+ private final Context mContext;
+ private final PhoneStatusBar mBar;
+ private final ArrayMap<IBinder, StatusBarNotification> mIntercepted
+ = new ArrayMap<IBinder, StatusBarNotification>();
+
+ private Binder mSynKey;
+
+ public InterceptedNotifications(Context context, PhoneStatusBar bar) {
+ mContext = context;
+ mBar = bar;
+ }
+
+ public void releaseIntercepted() {
+ final int n = mIntercepted.size();
+ for (int i = 0; i < n; i++) {
+ final IBinder key = mIntercepted.keyAt(i);
+ final StatusBarNotification sbn = mIntercepted.valueAt(i);
+ sbn.getNotification().extras.putBoolean(EXTRA_INTERCEPT, false);
+ mBar.addNotification(key, sbn);
+ }
+ mIntercepted.clear();
+ updateSyntheticNotification();
+ }
+
+ public boolean tryIntercept(IBinder key, StatusBarNotification notification) {
+ if (!notification.getNotification().extras.getBoolean(EXTRA_INTERCEPT)) return false;
+ mIntercepted.put(key, notification);
+ updateSyntheticNotification();
+ return true;
+ }
+
+ public void remove(IBinder key) {
+ if (mIntercepted.remove(key) != null) {
+ updateSyntheticNotification();
+ }
+ }
+
+ public boolean isSyntheticEntry(Entry ent) {
+ return mSynKey != null && ent.key.equals(mSynKey);
+ }
+
+ public void update(IBinder key, StatusBarNotification notification) {
+ if (mIntercepted.containsKey(key)) {
+ mIntercepted.put(key, notification);
+ }
+ }
+
+ private void updateSyntheticNotification() {
+ if (mIntercepted.isEmpty()) {
+ if (mSynKey != null) {
+ mBar.removeNotification(mSynKey);
+ mSynKey = null;
+ }
+ return;
+ }
+ final Notification n = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.stat_sys_zen_limited)
+ .setContentTitle(mContext.getResources().getQuantityString(
+ R.plurals.zen_mode_notification_title,
+ mIntercepted.size(), mIntercepted.size()))
+ .setContentText(mContext.getString(R.string.zen_mode_notification_text))
+ .setOngoing(true)
+ .build();
+ final StatusBarNotification sbn = new StatusBarNotification(mContext.getPackageName(),
+ mContext.getBasePackageName(),
+ TAG.hashCode(), TAG, Process.myUid(), Process.myPid(), 0, n,
+ mBar.getCurrentUserHandle());
+ if (mSynKey == null) {
+ mSynKey = new Binder();
+ mBar.addNotification(mSynKey, sbn);
+ } else {
+ mBar.updateNotification(mSynKey, sbn);
+ }
+ final NotificationData.Entry entry = mBar.mNotificationData.findByKey(mSynKey);
+ entry.content.setOnClickListener(mSynClickListener);
+ }
+
+ private final View.OnClickListener mSynClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ releaseIntercepted();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 4730f2f..f3dd7e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -59,6 +59,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
+import android.provider.Settings.Global;
import android.service.notification.StatusBarNotification;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -89,11 +90,11 @@
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.GestureRecorder;
+import com.android.systemui.statusbar.InterceptedNotifications;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarIconView;
-
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.DateView;
@@ -101,7 +102,6 @@
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RotationLockController;
-
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import java.io.FileDescriptor;
@@ -347,6 +347,7 @@
}};
private Runnable mOnFlipRunnable;
+ private InterceptedNotifications mIntercepted;
public void setOnFlipRunnable(Runnable onFlipRunnable) {
mOnFlipRunnable = onFlipRunnable;
@@ -357,7 +358,11 @@
super.setZenMode(mode);
if (mModeIcon == null) return;
if (!isDeviceProvisioned()) return;
- mModeIcon.setVisibility(mode != Settings.Global.ZEN_MODE_OFF ? View.VISIBLE : View.GONE);
+ final boolean zen = mode != Settings.Global.ZEN_MODE_OFF;
+ mModeIcon.setVisibility(zen ? View.VISIBLE : View.GONE);
+ if (!zen) {
+ mIntercepted.releaseIntercepted();
+ }
}
@Override
@@ -365,7 +370,7 @@
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
updateDisplaySize();
-
+ mIntercepted = new InterceptedNotifications(mContext, this);
super.start(); // calls createAndAddWindows()
addNavigationBar();
@@ -931,49 +936,54 @@
mStatusIcons.removeViewAt(viewIndex);
}
+ public UserHandle getCurrentUserHandle() {
+ return new UserHandle(mCurrentUserId);
+ }
+
public void addNotification(IBinder key, StatusBarNotification notification) {
if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore());
Entry shadeEntry = createNotificationViews(key, notification);
if (shadeEntry == null) {
return;
}
- if (!shouldIntercept(notification.getNotification())) {
- if (mUseHeadsUp && shouldInterrupt(notification)) {
- if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
- Entry interruptionCandidate = new Entry(key, notification, null);
- ViewGroup holder = mHeadsUpNotificationView.getHolder();
- if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
- mInterruptingNotificationTime = System.currentTimeMillis();
- mInterruptingNotificationEntry = interruptionCandidate;
- shadeEntry.setInterruption();
+ if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(key, notification)) {
+ return;
+ }
+ if (mUseHeadsUp && shouldInterrupt(notification)) {
+ if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
+ Entry interruptionCandidate = new Entry(key, notification, null);
+ ViewGroup holder = mHeadsUpNotificationView.getHolder();
+ if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
+ mInterruptingNotificationTime = System.currentTimeMillis();
+ mInterruptingNotificationEntry = interruptionCandidate;
+ shadeEntry.setInterruption();
- // 1. Populate mHeadsUpNotificationView
- mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
+ // 1. Populate mHeadsUpNotificationView
+ mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
- // 2. Animate mHeadsUpNotificationView in
- mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
+ // 2. Animate mHeadsUpNotificationView in
+ mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
- // 3. Set alarm to age the notification off
- resetHeadsUpDecayTimer();
- }
- } else if (notification.getNotification().fullScreenIntent != null) {
- // Stop screensaver if the notification has a full-screen intent.
- // (like an incoming phone call)
- awakenDreams();
+ // 3. Set alarm to age the notification off
+ resetHeadsUpDecayTimer();
+ }
+ } else if (notification.getNotification().fullScreenIntent != null) {
+ // Stop screensaver if the notification has a full-screen intent.
+ // (like an incoming phone call)
+ awakenDreams();
- // not immersive & a full-screen alert should be shown
- if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
- try {
- notification.getNotification().fullScreenIntent.send();
- } catch (PendingIntent.CanceledException e) {
- }
- } else {
- // usual case: status bar visible & not immersive
+ // not immersive & a full-screen alert should be shown
+ if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
+ try {
+ notification.getNotification().fullScreenIntent.send();
+ } catch (PendingIntent.CanceledException e) {
+ }
+ } else {
+ // usual case: status bar visible & not immersive
- // show the ticker if there isn't already a heads up
- if (mInterruptingNotificationEntry == null) {
- tick(null, notification, true);
- }
+ // show the ticker if there isn't already a heads up
+ if (mInterruptingNotificationEntry == null) {
+ tick(null, notification, true);
}
}
addNotificationViews(shadeEntry);
@@ -991,6 +1001,12 @@
}
}
+ @Override
+ public void updateNotification(IBinder key, StatusBarNotification notification) {
+ super.updateNotification(key, notification);
+ mIntercepted.update(key, notification);
+ }
+
public void removeNotification(IBinder key) {
StatusBarNotification old = removeNotificationViews(key);
if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
@@ -1012,7 +1028,7 @@
animateCollapsePanels();
}
}
-
+ mIntercepted.remove(key);
setAreThereNotifications();
}
@@ -1129,7 +1145,7 @@
// in "public" mode (atop a secure keyguard), secret notifs are totally hidden
continue;
}
- if (shouldIntercept(ent.notification.getNotification())) {
+ if (mIntercepted.isSyntheticEntry(ent)) {
continue;
}
toShow.add(ent.icon);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 35f873e..c3db55e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3176,8 +3176,9 @@
// The active window also determined events from which
// windows are delivered.
synchronized (mLock) {
+ mFocusedWindowId = getFocusedWindowId();
if (mWindowsForAccessibilityCallback == null
- && windowId == getFocusedWindowId()) {
+ && windowId == mFocusedWindowId) {
mActiveWindowId = windowId;
}
}
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index b6e761c..7ec9b82 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -52,6 +52,7 @@
import android.os.storage.IMountShutdownObserver;
import android.os.storage.IObbActionListener;
import android.os.storage.OnObbStateChangeListener;
+import android.os.storage.StorageManager;
import android.os.storage.StorageResultCode;
import android.os.storage.StorageVolume;
import android.text.TextUtils;
@@ -2145,8 +2146,8 @@
}
}
- public int encryptStorage(String password) {
- if (TextUtils.isEmpty(password)) {
+ public int encryptStorage(int type, String password) {
+ if (TextUtils.isEmpty(password) && type != StorageManager.CRYPT_TYPE_DEFAULT) {
throw new IllegalArgumentException("password cannot be empty");
}
@@ -2160,7 +2161,7 @@
}
try {
- mConnector.execute("cryptfs", "enablecrypto", "inplace",
+ mConnector.execute("cryptfs", "enablecrypto", "inplace", CRYPTO_TYPES[type],
new SensitiveArg(toHex(password)));
} catch (NativeDaemonConnectorException e) {
// Encryption failed
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5bfb3fb..7607419 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2756,11 +2756,16 @@
debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
}
+ String requiredAbi = app.info.requiredCpuAbi;
+ if (requiredAbi == null) {
+ requiredAbi = Build.SUPPORTED_ABIS[0];
+ }
+
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags, mountExternal,
- app.info.targetSdkVersion, app.info.seinfo, null);
+ app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
synchronized (bs) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ff90cae..747d0a7 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -60,8 +60,8 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
-import android.content.ServiceConnection;
import android.content.IntentSender.SendIntentException;
+import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ContainerEncryptionParams;
@@ -74,14 +74,15 @@
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstrumentationInfo;
+import android.content.pm.ManifestDigest;
import android.content.pm.PackageCleanItem;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfoLite;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
-import android.content.pm.PackageUserState;
import android.content.pm.PackageParser.ActivityIntentInfo;
import android.content.pm.PackageStats;
+import android.content.pm.PackageUserState;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
@@ -89,7 +90,6 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
-import android.content.pm.ManifestDigest;
import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VerifierInfo;
@@ -100,6 +100,7 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
+import android.os.Environment.UserEnvironment;
import android.os.FileObserver;
import android.os.FileUtils;
import android.os.Handler;
@@ -116,7 +117,6 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.os.Environment.UserEnvironment;
import android.os.UserManager;
import android.security.KeyStore;
import android.security.SystemKeyStore;
@@ -2054,6 +2054,7 @@
pkg.applicationInfo.dataDir =
getDataPathForPackage(packageName, 0).getPath();
pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
+ pkg.applicationInfo.requiredCpuAbi = ps.requiredCpuAbiString;
}
return generatePackageInfo(pkg, flags, userId);
}
@@ -3994,6 +3995,8 @@
codePath = pkg.mScanPath;
// Set application objects path explicitly.
setApplicationInfoPaths(pkg, codePath, resPath);
+ // Applications can run with the primary Cpu Abi unless otherwise is specified
+ pkg.applicationInfo.requiredCpuAbi = null;
// Note that we invoke the following method only if we are about to unpack an application
PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
| SCAN_UPDATE_SIGNATURE, currentTime, user);
@@ -4565,6 +4568,7 @@
// the PkgSetting exists already and doesn't have to be created.
pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
destResourceFile, pkg.applicationInfo.nativeLibraryDir,
+ pkg.applicationInfo.requiredCpuAbi,
pkg.applicationInfo.flags, user, false);
if (pkgSetting == null) {
Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
@@ -4870,11 +4874,20 @@
}
try {
- if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
+ int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir);
+ if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
Slog.e(TAG, "Unable to copy native libraries");
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
return null;
}
+
+ // We've successfully copied native libraries across, so we make a
+ // note of what ABI we're using
+ if (copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
+ pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_ABIS[copyRet];
+ } else {
+ pkg.applicationInfo.requiredCpuAbi = null;
+ }
} catch (IOException e) {
Slog.e(TAG, "Unable to copy native libraries", e);
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
@@ -5430,7 +5443,21 @@
* If this is an internal application or our nativeLibraryPath points to
* the app-lib directory, unpack the libraries if necessary.
*/
- return NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
+ final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
+ try {
+ int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
+ if (abi >= 0) {
+ int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
+ nativeLibraryDir, Build.SUPPORTED_ABIS[abi]);
+ if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
+ return copyRet;
+ }
+ }
+
+ return abi;
+ } finally {
+ handle.close();
+ }
}
private void killApplication(String pkgName, int appId, String reason) {
@@ -8384,7 +8411,7 @@
}
try {
int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
- if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
+ if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
return copyRet;
}
} catch (IOException e) {
@@ -11898,8 +11925,17 @@
final File newNativeDir = new File(newNativePath);
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
- NativeLibraryHelper.copyNativeBinariesIfNeededLI(
- new File(newCodePath), newNativeDir);
+ // NOTE: We do not report any errors from the APK scan and library
+ // copy at this point.
+ NativeLibraryHelper.ApkHandle handle =
+ new NativeLibraryHelper.ApkHandle(newCodePath);
+ final int abi = NativeLibraryHelper.findSupportedAbi(
+ handle, Build.SUPPORTED_ABIS);
+ if (abi >= 0) {
+ NativeLibraryHelper.copyNativeBinariesIfNeededLI(
+ handle, newNativeDir, Build.SUPPORTED_ABIS[abi]);
+ }
+ handle.close();
}
final int[] users = sUserManager.getUserIds();
for (int user : users) {
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index b447861..15df3d2 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -30,8 +30,8 @@
SharedUserSetting sharedUser;
PackageSetting(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
- super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
+ String nativeLibraryPathString, String requiredCpuAbiString, int pVersionCode, int pkgFlags) {
+ super(name, realName, codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString, pVersionCode,
pkgFlags);
}
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 2a5698b9..c8af9d1 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -50,6 +50,7 @@
File resourcePath;
String resourcePathString;
String nativeLibraryPathString;
+ String requiredCpuAbiString;
long timeStamp;
long firstInstallTime;
long lastUpdateTime;
@@ -77,11 +78,11 @@
/* package name of the app that installed this package */
String installerPackageName;
PackageSettingBase(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
+ String nativeLibraryPathString, String requiredCpuAbiString, int pVersionCode, int pkgFlags) {
super(pkgFlags);
this.name = name;
this.realName = realName;
- init(codePath, resourcePath, nativeLibraryPathString, pVersionCode);
+ init(codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString, pVersionCode);
}
/**
@@ -98,6 +99,7 @@
resourcePath = base.resourcePath;
resourcePathString = base.resourcePathString;
nativeLibraryPathString = base.nativeLibraryPathString;
+ requiredCpuAbiString = base.requiredCpuAbiString;
timeStamp = base.timeStamp;
firstInstallTime = base.firstInstallTime;
lastUpdateTime = base.lastUpdateTime;
@@ -125,12 +127,13 @@
}
void init(File codePath, File resourcePath, String nativeLibraryPathString,
- int pVersionCode) {
+ String requiredCpuAbiString, int pVersionCode) {
this.codePath = codePath;
this.codePathString = codePath.toString();
this.resourcePath = resourcePath;
this.resourcePathString = resourcePath.toString();
this.nativeLibraryPathString = nativeLibraryPathString;
+ this.requiredCpuAbiString = requiredCpuAbiString;
this.versionCode = pVersionCode;
}
@@ -161,6 +164,7 @@
grantedPermissions = base.grantedPermissions;
gids = base.gids;
+ requiredCpuAbiString = base.requiredCpuAbiString;
timeStamp = base.timeStamp;
firstInstallTime = base.firstInstallTime;
lastUpdateTime = base.lastUpdateTime;
diff --git a/services/core/java/com/android/server/pm/PendingPackage.java b/services/core/java/com/android/server/pm/PendingPackage.java
index c17cc46..36c3a34 100644
--- a/services/core/java/com/android/server/pm/PendingPackage.java
+++ b/services/core/java/com/android/server/pm/PendingPackage.java
@@ -22,8 +22,8 @@
final int sharedId;
PendingPackage(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int sharedId, int pVersionCode, int pkgFlags) {
- super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
+ String nativeLibraryPathString, String requiredCpuAbiString, int sharedId, int pVersionCode, int pkgFlags) {
+ super(name, realName, codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString, pVersionCode,
pkgFlags);
this.sharedId = sharedId;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index d1e34a1..80f716c 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -217,10 +217,10 @@
PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
- String nativeLibraryPathString, int pkgFlags, UserHandle user, boolean add) {
+ String nativeLibraryPathString, String requiredCpuAbiString, int pkgFlags, UserHandle user, boolean add) {
final String name = pkg.packageName;
PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
- resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags,
+ resourcePath, nativeLibraryPathString, requiredCpuAbiString, pkg.mVersionCode, pkgFlags,
user, add, true /* allowInstall */);
return p;
}
@@ -302,7 +302,7 @@
p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
- p.nativeLibraryPathString, p.appId, p.versionCode, p.pkgFlags);
+ p.nativeLibraryPathString, p.requiredCpuAbiString, p.appId, p.versionCode, p.pkgFlags);
mDisabledSysPackages.remove(name);
return ret;
}
@@ -316,7 +316,7 @@
}
PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
+ String nativeLibraryPathString, String requiredCpuAbiString, int uid, int vc, int pkgFlags) {
PackageSetting p = mPackages.get(name);
if (p != null) {
if (p.appId == uid) {
@@ -326,7 +326,7 @@
"Adding duplicate package, keeping first: " + name);
return null;
}
- p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString,
+ p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString,
vc, pkgFlags);
p.appId = uid;
if (addUserIdLPw(uid, p, name)) {
@@ -395,10 +395,11 @@
private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
- String nativeLibraryPathString, int vc, int pkgFlags,
+ String nativeLibraryPathString, String requiredCpuAbiString, int vc, int pkgFlags,
UserHandle installUser, boolean add, boolean allowInstall) {
PackageSetting p = mPackages.get(name);
if (p != null) {
+ p.requiredCpuAbiString = requiredCpuAbiString;
if (!p.codePath.equals(codePath)) {
// Check to see if its a disabled system app
if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
@@ -442,7 +443,7 @@
if (origPackage != null) {
// We are consuming the data from an existing package.
p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
- nativeLibraryPathString, vc, pkgFlags);
+ nativeLibraryPathString, requiredCpuAbiString, vc, pkgFlags);
if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
+ name + " is adopting original package " + origPackage.name);
// Note that we will retain the new package's signature so
@@ -459,7 +460,7 @@
p.setTimeStamp(codePath.lastModified());
} else {
p = new PackageSetting(name, realName, codePath, resourcePath,
- nativeLibraryPathString, vc, pkgFlags);
+ nativeLibraryPathString, requiredCpuAbiString, vc, pkgFlags);
p.setTimeStamp(codePath.lastModified());
p.sharedUser = sharedUser;
// If this is not a system app, it starts out stopped.
@@ -585,6 +586,8 @@
&& !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) {
p.nativeLibraryPathString = nativeLibraryPath;
}
+ // Update the required Cpu Abi
+ p.requiredCpuAbiString = pkg.applicationInfo.requiredCpuAbi;
// Update version code if needed
if (pkg.mVersionCode != p.versionCode) {
p.versionCode = pkg.mVersionCode;
@@ -1551,6 +1554,9 @@
if (pkg.nativeLibraryPathString != null) {
serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
}
+ if (pkg.requiredCpuAbiString != null) {
+ serializer.attribute(null, "requiredCpuAbi", pkg.requiredCpuAbiString);
+ }
if (pkg.sharedUser == null) {
serializer.attribute(null, "userId", Integer.toString(pkg.appId));
} else {
@@ -1593,6 +1599,9 @@
if (pkg.nativeLibraryPathString != null) {
serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
}
+ if (pkg.requiredCpuAbiString != null) {
+ serializer.attribute(null, "requiredCpuAbi", pkg.requiredCpuAbiString);
+ }
serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
@@ -1861,7 +1870,7 @@
if (idObj != null && idObj instanceof SharedUserSetting) {
PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
(SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
- pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags,
+ pp.nativeLibraryPathString, pp.requiredCpuAbiString, pp.versionCode, pp.pkgFlags,
null, true /* add */, false /* allowInstall */);
if (p == null) {
PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -2281,6 +2290,8 @@
String codePathStr = parser.getAttributeValue(null, "codePath");
String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
+ String requiredCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
+
if (resourcePathStr == null) {
resourcePathStr = codePathStr;
}
@@ -2300,7 +2311,7 @@
pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
}
PackageSetting ps = new PackageSetting(name, realName, codePathFile,
- new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
+ new File(resourcePathStr), nativeLibraryPathStr, requiredCpuAbiString, versionCode, pkgFlags);
String timeStampStr = parser.getAttributeValue(null, "ft");
if (timeStampStr != null) {
try {
@@ -2367,6 +2378,7 @@
String codePathStr = null;
String resourcePathStr = null;
String nativeLibraryPathStr = null;
+ String requiredCpuAbiString = null;
String systemStr = null;
String installerPackageName = null;
String uidError = null;
@@ -2386,6 +2398,8 @@
codePathStr = parser.getAttributeValue(null, "codePath");
resourcePathStr = parser.getAttributeValue(null, "resourcePath");
nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
+ requiredCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
+
version = parser.getAttributeValue(null, "version");
if (version != null) {
try {
@@ -2462,7 +2476,7 @@
+ parser.getPositionDescription());
} else if (userId > 0) {
packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
- new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode,
+ new File(resourcePathStr), nativeLibraryPathStr, requiredCpuAbiString, userId, versionCode,
pkgFlags);
if (PackageManagerService.DEBUG_SETTINGS)
Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
@@ -2480,7 +2494,7 @@
userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
if (userId > 0) {
packageSetting = new PendingPackage(name.intern(), realName, new File(
- codePathStr), new File(resourcePathStr), nativeLibraryPathStr, userId,
+ codePathStr), new File(resourcePathStr), nativeLibraryPathStr, requiredCpuAbiString, userId,
versionCode, pkgFlags);
packageSetting.setTimeStamp(timeStamp);
packageSetting.firstInstallTime = firstInstallTime;
@@ -2509,6 +2523,7 @@
packageSetting.uidError = "true".equals(uidError);
packageSetting.installerPackageName = installerPackageName;
packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
+ packageSetting.requiredCpuAbiString = requiredCpuAbiString;
// Handle legacy string here for single-user mode
final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
if (enabledStr != null) {
@@ -3008,6 +3023,7 @@
pw.print(prefix); pw.print(" codePath="); pw.println(ps.codePathString);
pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
pw.print(prefix); pw.print(" nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
+ pw.print(prefix); pw.print(" requiredCpuAbi="); pw.println(ps.requiredCpuAbiString);
pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode);
if (ps.pkg != null) {
pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 972b088..79c4a50 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -151,8 +151,11 @@
private void removeUser(int userId) {
synchronized (mLock) {
+ UserState userState = mUserStates.get(userId);
+ if (userState == null) {
+ return;
+ }
// Release created sessions.
- UserState userState = getUserStateLocked(userId);
for (SessionState state : userState.sessionStateMap.values()) {
if (state.session != null) {
try {
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index 2ef3d5f..7c3ab6f 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -115,6 +115,7 @@
"android.database.ContentObserver", // for Digital clock
"com.android.i18n.phonenumbers.*", // for TextView with autolink attribute
"android.app.DatePickerDialog", // b.android.com/28318
+ "android.app.TimePickerDialog", // b.android.com/61515
},
excludeClasses,
new String[] {