Merge "Allowing isRound and outsetBottom properties to be passed to ActivityView." into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index 6723108..c796cdb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2166,18 +2166,22 @@
field public static final int Theme_Material_Dialog = 16974386; // 0x1030232
field public static final int Theme_Material_DialogWhenLarge = 16974390; // 0x1030236
field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974391; // 0x1030237
+ field public static final int Theme_Material_Dialog_Alert = 16974570; // 0x10302ea
field public static final int Theme_Material_Dialog_MinWidth = 16974387; // 0x1030233
field public static final int Theme_Material_Dialog_NoActionBar = 16974388; // 0x1030234
field public static final int Theme_Material_Dialog_NoActionBar_MinWidth = 16974389; // 0x1030235
+ field public static final int Theme_Material_Dialog_Presentation = 16974571; // 0x10302eb
field public static final int Theme_Material_InputMethod = 16974392; // 0x1030238
field public static final int Theme_Material_Light = 16974402; // 0x1030242
field public static final int Theme_Material_Light_DarkActionBar = 16974403; // 0x1030243
field public static final int Theme_Material_Light_Dialog = 16974404; // 0x1030244
field public static final int Theme_Material_Light_DialogWhenLarge = 16974408; // 0x1030248
field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974409; // 0x1030249
+ field public static final int Theme_Material_Light_Dialog_Alert = 16974572; // 0x10302ec
field public static final int Theme_Material_Light_Dialog_MinWidth = 16974405; // 0x1030245
field public static final int Theme_Material_Light_Dialog_NoActionBar = 16974406; // 0x1030246
field public static final int Theme_Material_Light_Dialog_NoActionBar_MinWidth = 16974407; // 0x1030247
+ field public static final int Theme_Material_Light_Dialog_Presentation = 16974573; // 0x10302ed
field public static final int Theme_Material_Light_NoActionBar = 16974410; // 0x103024a
field public static final int Theme_Material_Light_NoActionBar_Fullscreen = 16974411; // 0x103024b
field public static final int Theme_Material_Light_NoActionBar_Overscan = 16974412; // 0x103024c
@@ -2566,7 +2570,7 @@
field public static final int Widget_Material_Light_SeekBar = 16974534; // 0x10302c6
field public static final int Widget_Material_Light_SegmentedButton = 16974535; // 0x10302c7
field public static final int Widget_Material_Light_Spinner = 16974537; // 0x10302c9
- field public static final int Widget_Material_Light_Spinner_Form = 16974567; // 0x10302e7
+ field public static final int Widget_Material_Light_Spinner_Underlined = 16974567; // 0x10302e7
field public static final int Widget_Material_Light_StackView = 16974536; // 0x10302c8
field public static final int Widget_Material_Light_Tab = 16974538; // 0x10302ca
field public static final int Widget_Material_Light_TabWidget = 16974539; // 0x10302cb
@@ -2593,7 +2597,7 @@
field public static final int Widget_Material_SeekBar = 16974471; // 0x1030287
field public static final int Widget_Material_SegmentedButton = 16974472; // 0x1030288
field public static final int Widget_Material_Spinner = 16974474; // 0x103028a
- field public static final int Widget_Material_Spinner_Form = 16974566; // 0x10302e6
+ field public static final int Widget_Material_Spinner_Underlined = 16974566; // 0x10302e6
field public static final int Widget_Material_StackView = 16974473; // 0x1030289
field public static final int Widget_Material_Tab = 16974475; // 0x103028b
field public static final int Widget_Material_TabWidget = 16974476; // 0x103028c
@@ -4506,8 +4510,8 @@
}
public class KeyguardManager {
+ method public android.content.Intent createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence);
method public deprecated void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult);
- method public android.content.Intent getConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence);
method public boolean inKeyguardRestrictedInputMode();
method public boolean isKeyguardLocked();
method public boolean isKeyguardSecure();
@@ -5450,7 +5454,6 @@
method public boolean getScreenCaptureDisabled(android.content.ComponentName);
method public boolean getStorageEncryption(android.content.ComponentName);
method public int getStorageEncryptionStatus();
- method public java.util.List<java.lang.String> getTrustAgentFeaturesEnabled(android.content.ComponentName, android.content.ComponentName);
method public boolean getUninstallBlocked(android.content.ComponentName, java.lang.String);
method public boolean hasCaCertInstalled(byte[]);
method public boolean hasGrantedPolicy(android.content.ComponentName, int);
@@ -5498,7 +5501,6 @@
method public void setScreenCaptureDisabled(android.content.ComponentName, boolean);
method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public int setStorageEncryption(android.content.ComponentName, boolean);
- method public void setTrustAgentFeaturesEnabled(android.content.ComponentName, android.content.ComponentName, java.util.List<java.lang.String>);
method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
method public void uninstallAllUserCaCerts(android.content.ComponentName);
diff --git a/api/removed.txt b/api/removed.txt
index 1b8aef4..1fde099 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -1,3 +1,11 @@
+package android.app {
+
+ public class KeyguardManager {
+ method public android.content.Intent getConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence);
+ }
+
+}
+
package android.media {
public class AudioFormat {
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 50e3a10..e055237 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -56,6 +56,13 @@
public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION";
/**
+ * @removed
+ */
+ public Intent getConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) {
+ return createConfirmDeviceCredentialIntent(title, description);
+ }
+
+ /**
* Get an intent to prompt the user to confirm credentials (pin, pattern or password)
* for the current user of the device. The caller is expected to launch this activity using
* {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
@@ -63,7 +70,7 @@
*
* @return the intent for launching the activity or null if no password is required.
**/
- public Intent getConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) {
+ public Intent createConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) {
if (!isKeyguardSecure()) return null;
Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL);
intent.putExtra(EXTRA_TITLE, title);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 26c72a5..3f82157 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2562,6 +2562,7 @@
* @param agent Which component to enable features for.
* @param features List of features to enable. Consult specific TrustAgent documentation for
* the feature list.
+ * @hide
*/
public void setTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent,
List<String> features) {
@@ -2582,6 +2583,7 @@
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param agent Which component to get enabled features for.
* @return List of enabled features.
+ * @hide
*/
public List<String> getTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent) {
if (mService != null) {
@@ -2689,10 +2691,10 @@
* Called by a profile or device owner to set the permitted accessibility services. When
* set by a device owner or profile owner the restriction applies to all profiles of the
* user the device owner or profile owner is an admin for.
- *
+ *
* By default the user can use any accessiblity service. When zero or more packages have
* been added, accessiblity services that are not in the list and not part of the system
- * can not be enabled by the user.
+ * can not be enabled by the user.
*
* <p> Calling with a null value for the list disables the restriction so that all services
* can be used, calling with an empty list only allows the builtin system's services.
diff --git a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
index caabed3..ca0935c 100644
--- a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
+++ b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
@@ -26,8 +26,8 @@
* Keep up-to-date with frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h
*/
- oneway void onCameraError(int errorCode, in CaptureResultExtras resultExtras);
- oneway void onCameraIdle();
+ oneway void onDeviceError(int errorCode, in CaptureResultExtras resultExtras);
+ oneway void onDeviceIdle();
oneway void onCaptureStarted(in CaptureResultExtras resultExtras, long timestamp);
oneway void onResultReceived(in CameraMetadataNative result,
in CaptureResultExtras resultExtras);
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index 621968b..9ca1fba 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -74,7 +74,7 @@
private boolean mSkipUnconfigure = false;
/** Is the session in the process of aborting? Pay attention to BUSY->IDLE transitions. */
- private boolean mAborting;
+ private volatile boolean mAborting;
/**
* Create a new CameraCaptureSession.
@@ -346,6 +346,20 @@
}
/**
+ * Whether currently in mid-abort.
+ *
+ * <p>This is used by the implementation to set the capture failure
+ * reason, in lieu of more accurate error codes from the camera service.
+ * Unsynchronized to avoid deadlocks between simultaneous session->device,
+ * device->session calls.</p>
+ *
+ * <p>Package-private.</p>
+ */
+ boolean isAborting() {
+ return mAborting;
+ }
+
+ /**
* Post calls into a CameraCaptureSession.StateListener to the user-specified {@code handler}.
*/
private StateListener createUserStateListenerProxy(Handler handler, StateListener listener) {
@@ -502,8 +516,8 @@
// TODO: Queue captures during abort instead of failing them
// since the app won't be able to distinguish the two actives
+ // Don't signal the application since there's no clean mapping here
Log.w(TAG, "Device is now busy; do not submit new captures (TODO: allow this)");
- mStateListener.onActive(session);
}
@Override
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 79ce9df..513d222 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -384,7 +384,7 @@
catch (IllegalArgumentException e) {
// OK. camera service can reject stream config if it's not supported by HAL
// This is only the result of a programmer misusing the camera2 api.
- Log.e(TAG, "Stream configuration failed", e);
+ Log.w(TAG, "Stream configuration failed");
return false;
}
@@ -1097,31 +1097,51 @@
*/
static final int ERROR_CAMERA_SERVICE = 2;
+ /**
+ * Camera has encountered an error processing a single request.
+ */
+ static final int ERROR_CAMERA_REQUEST = 3;
+
+ /**
+ * Camera has encountered an error producing metadata for a single capture
+ */
+ static final int ERROR_CAMERA_RESULT = 4;
+
+ /**
+ * Camera has encountered an error producing an image buffer for a single capture
+ */
+ static final int ERROR_CAMERA_BUFFER = 5;
+
@Override
public IBinder asBinder() {
return this;
}
@Override
- public void onCameraError(final int errorCode, CaptureResultExtras resultExtras) {
- Runnable r = null;
+ public void onDeviceError(final int errorCode, CaptureResultExtras resultExtras) {
+ if (DEBUG) {
+ Log.d(TAG, String.format(
+ "Device error received, code %d, frame number %d, request ID %d, subseq ID %d",
+ errorCode, resultExtras.getFrameNumber(), resultExtras.getRequestId(),
+ resultExtras.getSubsequenceId()));
+ }
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) {
return; // Camera already closed
}
- mInError = true;
switch (errorCode) {
case ERROR_CAMERA_DISCONNECTED:
- r = mCallOnDisconnected;
+ CameraDeviceImpl.this.mDeviceHandler.post(mCallOnDisconnected);
break;
default:
Log.e(TAG, "Unknown error from camera device: " + errorCode);
// no break
case ERROR_CAMERA_DEVICE:
case ERROR_CAMERA_SERVICE:
- r = new Runnable() {
+ mInError = true;
+ Runnable r = new Runnable() {
@Override
public void run() {
if (!CameraDeviceImpl.this.isClosed()) {
@@ -1129,21 +1149,19 @@
}
}
};
+ CameraDeviceImpl.this.mDeviceHandler.post(r);
+ break;
+ case ERROR_CAMERA_REQUEST:
+ case ERROR_CAMERA_RESULT:
+ case ERROR_CAMERA_BUFFER:
+ onCaptureErrorLocked(errorCode, resultExtras);
break;
}
- CameraDeviceImpl.this.mDeviceHandler.post(r);
-
- // Fire onCaptureSequenceCompleted
- if (DEBUG) {
- Log.v(TAG, String.format("got error frame %d", resultExtras.getFrameNumber()));
- }
- mFrameNumberTracker.updateTracker(resultExtras.getFrameNumber(), /*error*/true);
- checkAndFireSequenceComplete();
}
}
@Override
- public void onCameraIdle() {
+ public void onDeviceIdle() {
if (DEBUG) {
Log.d(TAG, "Camera now idle");
}
@@ -1246,7 +1264,6 @@
final CaptureRequest request = holder.getRequest(resultExtras.getSubsequenceId());
-
Runnable resultDispatch = null;
// Either send a partial result or the final capture completed result
@@ -1290,11 +1307,67 @@
if (!isPartialResult) {
checkAndFireSequenceComplete();
}
-
}
}
- }
+ /**
+ * Called by onDeviceError for handling single-capture failures.
+ */
+ private void onCaptureErrorLocked(int errorCode, CaptureResultExtras resultExtras) {
+
+ final int requestId = resultExtras.getRequestId();
+ final int subsequenceId = resultExtras.getSubsequenceId();
+ final long frameNumber = resultExtras.getFrameNumber();
+ final CaptureListenerHolder holder =
+ CameraDeviceImpl.this.mCaptureListenerMap.get(requestId);
+
+ final CaptureRequest request = holder.getRequest(subsequenceId);
+
+ // No way to report buffer errors right now
+ if (errorCode == ERROR_CAMERA_BUFFER) {
+ Log.e(TAG, String.format("Lost output buffer reported for frame %d", frameNumber));
+ return;
+ }
+
+ boolean mayHaveBuffers = (errorCode == ERROR_CAMERA_RESULT);
+
+ // This is only approximate - exact handling needs the camera service and HAL to
+ // disambiguate between request failures to due abort and due to real errors.
+ // For now, assume that if the session believes we're mid-abort, then the error
+ // is due to abort.
+ int reason = (mCurrentSession != null && mCurrentSession.isAborting()) ?
+ CaptureFailure.REASON_FLUSHED :
+ CaptureFailure.REASON_ERROR;
+
+ final CaptureFailure failure = new CaptureFailure(
+ request,
+ reason,
+ /*dropped*/ mayHaveBuffers,
+ requestId,
+ frameNumber);
+
+ Runnable failureDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!CameraDeviceImpl.this.isClosed()){
+ holder.getListener().onCaptureFailed(
+ CameraDeviceImpl.this,
+ request,
+ failure);
+ }
+ }
+ };
+ holder.getHandler().post(failureDispatch);
+
+ // Fire onCaptureSequenceCompleted if appropriate
+ if (DEBUG) {
+ Log.v(TAG, String.format("got error frame %d", frameNumber));
+ }
+ mFrameNumberTracker.updateTracker(frameNumber, /*error*/true);
+ checkAndFireSequenceComplete();
+ }
+
+ } // public class CameraDeviceCallbacks
/**
* Default handler management.
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index 5cbf109..410934e 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -211,7 +211,7 @@
}
@Override
- public void onCameraError(final int errorCode, final CaptureResultExtras resultExtras) {
+ public void onDeviceError(final int errorCode, final CaptureResultExtras resultExtras) {
Message msg = getHandler().obtainMessage(CAMERA_ERROR,
/*arg1*/ errorCode, /*arg2*/ 0,
/*obj*/ resultExtras);
@@ -219,7 +219,7 @@
}
@Override
- public void onCameraIdle() {
+ public void onDeviceIdle() {
Message msg = getHandler().obtainMessage(CAMERA_IDLE);
getHandler().sendMessage(msg);
}
@@ -267,11 +267,11 @@
case CAMERA_ERROR: {
int errorCode = msg.arg1;
CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj;
- mCallbacks.onCameraError(errorCode, resultExtras);
+ mCallbacks.onDeviceError(errorCode, resultExtras);
break;
}
case CAMERA_IDLE:
- mCallbacks.onCameraIdle();
+ mCallbacks.onDeviceIdle();
break;
case CAPTURE_STARTED: {
long timestamp = msg.arg2 & 0xFFFFFFFFL;
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index 1cf7797..ffc55f1 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -97,7 +97,7 @@
Log.d(TAG, "doing onError callback.");
}
try {
- mDeviceCallbacks.onCameraError(errorCode, extras);
+ mDeviceCallbacks.onDeviceError(errorCode, extras);
} catch (RemoteException e) {
throw new IllegalStateException(
"Received remote exception during onCameraError callback: ", e);
@@ -125,7 +125,7 @@
Log.d(TAG, "doing onIdle callback.");
}
try {
- mDeviceCallbacks.onCameraIdle();
+ mDeviceCallbacks.onDeviceIdle();
} catch (RemoteException e) {
throw new IllegalStateException(
"Received remote exception during onCameraIdle callback: ", e);
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index 337ae60..3ef5b37 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -89,6 +89,7 @@
/**
* A white list of features that the given trust agent should support when otherwise disabled
* by device policy.
+ * @hide
*/
public static final String KEY_FEATURES = "trust_agent_features";
@@ -184,6 +185,7 @@
*
* @param options Option feature bundle.
* @return true if the {@link TrustAgentService} supports this feature.
+ * @hide
*/
public boolean onSetTrustAgentFeaturesEnabled(Bundle options) {
return false;
diff --git a/core/res/res/drawable/progress_horizontal_material.xml b/core/res/res/drawable/progress_horizontal_material.xml
index d7440a9..7a1079c 100644
--- a/core/res/res/drawable/progress_horizontal_material.xml
+++ b/core/res/res/drawable/progress_horizontal_material.xml
@@ -17,7 +17,8 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@id/background">
<nine-patch android:src="@drawable/progress_mtrl_alpha"
- android:tint="?attr/colorControlNormal" />
+ android:tint="?attr/colorControlNormal"
+ android:alpha="0.5" />
</item>
<item android:id="@id/secondaryProgress">
<scale android:scaleWidth="100%">
diff --git a/core/res/res/values-television/dimens.xml b/core/res/res/values-television/dimens.xml
index 8266642..69c3da5 100644
--- a/core/res/res/values-television/dimens.xml
+++ b/core/res/res/values-television/dimens.xml
@@ -16,8 +16,8 @@
<resources>
<!-- Lighting and shadow properties -->
- <dimen name="light_y">-300dp</dimen>
- <item type="dimen" format="float" name="ambient_shadow_alpha">0.4</item>
- <item type="dimen" format="float" name="spot_shadow_alpha">0.4</item>
+ <dimen name="light_y">-400dp</dimen>
+ <item type="dimen" format="float" name="ambient_shadow_alpha">0.06</item>
+ <item type="dimen" format="float" name="spot_shadow_alpha">0.3</item>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 82125fe..35658cf 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2535,12 +2535,17 @@
<public type="style" name="TextAppearance.StatusBar.Material.EventContent.Time" />
<public type="style" name="TextAppearance.StatusBar.Material.EventContent.Emphasis" />
- <public type="style" name="Widget.Material.Spinner.Form" />
- <public type="style" name="Widget.Material.Light.Spinner.Form" />
+ <public type="style" name="Widget.Material.Spinner.Underlined" />
+ <public type="style" name="Widget.Material.Light.Spinner.Underlined" />
<public type="style" name="TextAppearance.Material.Widget.Toolbar.Title" />
<public type="style" name="TextAppearance.Material.Widget.Toolbar.Subtitle" />
+ <public type="style" name="Theme.Material.Dialog.Alert" />
+ <public type="style" name="Theme.Material.Dialog.Presentation" />
+ <public type="style" name="Theme.Material.Light.Dialog.Alert" />
+ <public type="style" name="Theme.Material.Light.Dialog.Presentation" />
+
<public-padding type="string" name="l_resource_pad" end="0x01040030" />
<public type="string" name="config_webSettingsDefaultTextEncoding" />
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index fb70d6b..3ee5552 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -308,7 +308,7 @@
<style name="TextAppearance.Material.Widget.TextView.PopupMenu" parent="TextAppearance.Material.Menu" />
<style name="TextAppearance.Material.Widget.TextView.SpinnerItem" />
- <style name="TextAppearance.Material.Widget.DropDownItem">
+ <style name="TextAppearance.Material.Widget.DropDownItem" parent="TextAppearance.Material.Menu">
<item name="textColor">?attr/textColorPrimaryDisableOnly</item>
</style>
@@ -759,7 +759,7 @@
<item name="overlapAnchor">true</item>
</style>
- <style name="Widget.Material.Spinner.Form">
+ <style name="Widget.Material.Spinner.Underlined">
<item name="background">@drawable/spinner_textfield_background_material</item>
</style>
@@ -1022,7 +1022,7 @@
<style name="Widget.Material.Light.Spinner" parent="Widget.Material.Spinner" />
<style name="Widget.Material.Light.Spinner.DropDown" parent="Widget.Material.Spinner.DropDown"/>
<style name="Widget.Material.Light.Spinner.DropDown.ActionBar" parent="Widget.Material.Spinner.DropDown.ActionBar"/>
- <style name="Widget.Material.Light.Spinner.Form" parent="Widget.Material.Spinner.Form" />
+ <style name="Widget.Material.Light.Spinner.Underlined" parent="Widget.Material.Spinner.Underlined" />
<style name="Widget.Material.Light.TabWidget" parent="Widget.Material.TabWidget"/>
<style name="Widget.Material.Light.WebTextView" parent="Widget.Material.WebTextView"/>
<style name="Widget.Material.Light.WebView" parent="Widget.Material.WebView"/>
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index 0bc4fdf..4c8b4f1 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -346,22 +346,24 @@
private boolean mCanConstantState;
private boolean mCheckedConstantState;
- public AnimatedRotateState(AnimatedRotateState source, AnimatedRotateDrawable owner,
+ public AnimatedRotateState(AnimatedRotateState orig, AnimatedRotateDrawable owner,
Resources res) {
- if (source != null) {
+ if (orig != null) {
if (res != null) {
- mDrawable = source.mDrawable.getConstantState().newDrawable(res);
+ mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
} else {
- mDrawable = source.mDrawable.getConstantState().newDrawable();
+ mDrawable = orig.mDrawable.getConstantState().newDrawable();
}
mDrawable.setCallback(owner);
- mDrawable.setLayoutDirection(source.mDrawable.getLayoutDirection());
- mPivotXRel = source.mPivotXRel;
- mPivotX = source.mPivotX;
- mPivotYRel = source.mPivotYRel;
- mPivotY = source.mPivotY;
- mFramesCount = source.mFramesCount;
- mFrameDuration = source.mFrameDuration;
+ mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
+ mDrawable.setBounds(orig.mDrawable.getBounds());
+ mDrawable.setLevel(orig.mDrawable.getLevel());
+ mPivotXRel = orig.mPivotXRel;
+ mPivotX = orig.mPivotX;
+ mPivotYRel = orig.mPivotYRel;
+ mPivotY = orig.mPivotY;
+ mFramesCount = orig.mFramesCount;
+ mFrameDuration = orig.mFrameDuration;
mCanConstantState = mCheckedConstantState = true;
}
}
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index f116376..61ef81b 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -285,6 +285,8 @@
}
mDrawable.setCallback(owner);
mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
+ mDrawable.setBounds(orig.mDrawable.getBounds());
+ mDrawable.setLevel(orig.mDrawable.getLevel());
mOrientation = orig.mOrientation;
mGravity = orig.mGravity;
mCheckedConstantState = mCanConstantState = true;
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index dd0f06f..a20b6d8 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -400,6 +400,8 @@
}
mDrawable.setCallback(owner);
mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
+ mDrawable.setBounds(orig.mDrawable.getBounds());
+ mDrawable.setLevel(orig.mDrawable.getLevel());
mInsetLeft = orig.mInsetLeft;
mInsetTop = orig.mInsetTop;
mInsetRight = orig.mInsetRight;
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 43bc89a..001ed88 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -961,20 +961,22 @@
// Default empty constructor.
}
- ChildDrawable(ChildDrawable or, LayerDrawable owner, Resources res) {
+ ChildDrawable(ChildDrawable orig, LayerDrawable owner, Resources res) {
if (res != null) {
- mDrawable = or.mDrawable.getConstantState().newDrawable(res);
+ mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
} else {
- mDrawable = or.mDrawable.getConstantState().newDrawable();
+ mDrawable = orig.mDrawable.getConstantState().newDrawable();
}
mDrawable.setCallback(owner);
- mDrawable.setLayoutDirection(or.mDrawable.getLayoutDirection());
- mThemeAttrs = or.mThemeAttrs;
- mInsetL = or.mInsetL;
- mInsetT = or.mInsetT;
- mInsetR = or.mInsetR;
- mInsetB = or.mInsetB;
- mId = or.mId;
+ mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
+ mDrawable.setBounds(orig.mDrawable.getBounds());
+ mDrawable.setLevel(orig.mDrawable.getLevel());
+ mThemeAttrs = orig.mThemeAttrs;
+ mInsetL = orig.mInsetL;
+ mInsetT = orig.mInsetT;
+ mInsetR = orig.mInsetR;
+ mInsetB = orig.mInsetB;
+ mId = orig.mId;
}
}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index ca32751f..7402bdb 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -33,7 +33,6 @@
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
-import android.util.Log;
import com.android.internal.R;
@@ -41,6 +40,7 @@
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.util.Arrays;
/**
* Drawable that shows a ripple effect in response to state changes. The
@@ -88,7 +88,6 @@
* @attr ref android.R.styleable#RippleDrawable_color
*/
public class RippleDrawable extends LayerDrawable {
- private static final String LOG_TAG = RippleDrawable.class.getSimpleName();
private static final PorterDuffXfermode DST_IN = new PorterDuffXfermode(Mode.DST_IN);
private static final PorterDuffXfermode SRC_ATOP = new PorterDuffXfermode(Mode.SRC_ATOP);
private static final PorterDuffXfermode SRC_OVER = new PorterDuffXfermode(Mode.SRC_OVER);
@@ -215,10 +214,14 @@
final Ripple[] ripples = mAnimatingRipples;
for (int i = 0; i < count; i++) {
ripples[i].jump();
- ripples[i] = null;
+ }
+ if (ripples != null) {
+ Arrays.fill(ripples, 0, count, null);
}
mAnimatingRipplesCount = 0;
mClearingHotspots = false;
+
+ invalidateSelf();
}
@Override
@@ -549,6 +552,15 @@
mAnimatingRipples[mAnimatingRipplesCount++] = mRipple;
}
+ @Override
+ public void invalidateSelf() {
+ // Don't invalidate when we're clearing hotspots. We'll handle that
+ // manually when we're done.
+ if (!mClearingHotspots) {
+ super.invalidateSelf();
+ }
+ }
+
private void removeRipple() {
if (mRipple != null) {
mRipple.exit();
@@ -572,7 +584,9 @@
final Ripple[] ripples = mAnimatingRipples;
for (int i = 0; i < count; i++) {
ripples[i].cancel();
- ripples[i] = null;
+ }
+ if (ripples != null) {
+ Arrays.fill(ripples, 0, count, null);
}
mAnimatingRipplesCount = 0;
mClearingHotspots = false;
@@ -680,7 +694,7 @@
final int count = mAnimatingRipplesCount;
final int index = getRippleIndex(ripple);
if (index >= 0) {
- System.arraycopy(ripples, index + 1, ripples, index + 1 - 1, count - (index + 1));
+ System.arraycopy(ripples, index + 1, ripples, index, count - (index + 1));
ripples[count - 1] = null;
mAnimatingRipplesCount--;
invalidateSelf();
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 63b9e02..70482a6 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -507,21 +507,23 @@
private boolean mCanConstantState;
private boolean mCheckedConstantState;
- public RotateState(RotateState source, RotateDrawable owner, Resources res) {
- if (source != null) {
+ public RotateState(RotateState orig, RotateDrawable owner, Resources res) {
+ if (orig != null) {
if (res != null) {
- mDrawable = source.mDrawable.getConstantState().newDrawable(res);
+ mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
} else {
- mDrawable = source.mDrawable.getConstantState().newDrawable();
+ mDrawable = orig.mDrawable.getConstantState().newDrawable();
}
mDrawable.setCallback(owner);
- mDrawable.setLayoutDirection(source.mDrawable.getLayoutDirection());
- mPivotXRel = source.mPivotXRel;
- mPivotX = source.mPivotX;
- mPivotYRel = source.mPivotYRel;
- mPivotY = source.mPivotY;
- mFromDegrees = mCurrentDegrees = source.mFromDegrees;
- mToDegrees = source.mToDegrees;
+ mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
+ mDrawable.setBounds(orig.mDrawable.getBounds());
+ mDrawable.setLevel(orig.mDrawable.getLevel());
+ mPivotXRel = orig.mPivotXRel;
+ mPivotX = orig.mPivotX;
+ mPivotYRel = orig.mPivotYRel;
+ mPivotY = orig.mPivotY;
+ mFromDegrees = mCurrentDegrees = orig.mFromDegrees;
+ mToDegrees = orig.mToDegrees;
mCanConstantState = mCheckedConstantState = true;
}
}
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index a954474..b40038a 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -295,6 +295,8 @@
}
mDrawable.setCallback(owner);
mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
+ mDrawable.setBounds(orig.mDrawable.getBounds());
+ mDrawable.setLevel(orig.mDrawable.getLevel());
mScaleWidth = orig.mScaleWidth;
mScaleHeight = orig.mScaleHeight;
mGravity = orig.mGravity;
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index dae539b..bce4074 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -4290,7 +4290,8 @@
if ((state == 0) && ((device & mBecomingNoisyIntentDevices) != 0)) {
int devices = 0;
for (int dev : mConnectedDevices.keySet()) {
- if ((dev & mBecomingNoisyIntentDevices) != 0) {
+ if (((dev & AudioSystem.DEVICE_BIT_IN) == 0) &&
+ ((dev & mBecomingNoisyIntentDevices) != 0)) {
devices |= dev;
}
}
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 9b9c767..4f74bdd 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -151,6 +151,10 @@
/**
* Constructs a new Builder with the defaults format values.
+ * If not provided, the maximum number of streams is 1 (see {@link #setMaxStreams(int)} to
+ * change it), and the audio attributes have a usage value of
+ * {@link AudioAttributes#USAGE_MEDIA} (see {@link #setAudioAttributes(AudioAttributes)} to
+ * change them).
*/
public Builder() {
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index b6bb578..cc50c43 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -245,7 +245,7 @@
* android.hardware.camera2.CaptureResultExtras)
*/
@Override
- public void onCameraError(int errorCode, CaptureResultExtras resultExtras)
+ public void onDeviceError(int errorCode, CaptureResultExtras resultExtras)
throws RemoteException {
// TODO Auto-generated method stub
@@ -283,7 +283,7 @@
* @see android.hardware.camera2.ICameraDeviceCallbacks#onCameraIdle()
*/
@Override
- public void onCameraIdle() throws RemoteException {
+ public void onDeviceIdle() throws RemoteException {
// TODO Auto-generated method stub
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 7b2e7dd..3cae19d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -88,10 +88,10 @@
/*
* (non-Javadoc)
* @see
- * android.hardware.camera2.ICameraDeviceCallbacks#onCameraError(int,
+ * android.hardware.camera2.ICameraDeviceCallbacks#onDeviceError(int,
* android.hardware.camera2.CaptureResultExtras)
*/
- public void onCameraError(int errorCode, CaptureResultExtras resultExtras)
+ public void onDeviceError(int errorCode, CaptureResultExtras resultExtras)
throws RemoteException {
// TODO Auto-generated method stub
@@ -99,9 +99,9 @@
/*
* (non-Javadoc)
- * @see android.hardware.camera2.ICameraDeviceCallbacks#onCameraIdle()
+ * @see android.hardware.camera2.ICameraDeviceCallbacks#onDeviceIdle()
*/
- public void onCameraIdle() throws RemoteException {
+ public void onDeviceIdle() throws RemoteException {
// TODO Auto-generated method stub
}
@@ -432,7 +432,7 @@
// Cancel and make sure we eventually quiesce
status = mCameraUser.cancelRequest(streamingId, null);
- verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(1)).onCameraIdle();
+ verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(1)).onDeviceIdle();
// Submit a few capture requests
int requestId1 = submitCameraRequest(request, /* streaming */false);
@@ -442,7 +442,7 @@
int requestId5 = submitCameraRequest(request, /* streaming */false);
// And wait for more idle
- verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(2)).onCameraIdle();
+ verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(2)).onDeviceIdle();
}
@@ -472,7 +472,7 @@
status = mCameraUser.flush(null);
assertEquals(CameraBinderTestUtils.NO_ERROR, status);
- verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(1)).onCameraIdle();
+ verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(1)).onDeviceIdle();
// Now a streaming request
int streamingId = submitCameraRequest(request, /* streaming */true);
@@ -484,7 +484,7 @@
status = mCameraUser.flush(null);
assertEquals(CameraBinderTestUtils.NO_ERROR, status);
- verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(2)).onCameraIdle();
+ verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(2)).onDeviceIdle();
// TODO: When errors are hooked up, count that errors + successful
// requests equal to 5.
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index e940b18..c84edf7 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -123,10 +123,10 @@
<!-- The min animation duration for animating views that are newly visible. -->
<integer name="recents_filter_animate_new_views_duration">250</integer>
<!-- The min animation duration for animating the task bar in. -->
- <integer name="recents_animate_task_bar_enter_duration">275</integer>
+ <integer name="recents_animate_task_bar_enter_duration">225</integer>
<!-- The animation delay for animating the first task in. This should roughly be the animation
duration of the transition in to recents. -->
- <integer name="recents_animate_task_bar_enter_delay">300</integer>
+ <integer name="recents_animate_task_bar_enter_delay">275</integer>
<!-- The min animation duration for animating the task bar out. -->
<integer name="recents_animate_task_exit_to_home_duration">225</integer>
<!-- The min animation duration for animating the task bar out. -->
@@ -143,6 +143,8 @@
<integer name="recents_nav_bar_scrim_enter_duration">400</integer>
<!-- The animation duration for animating the removal of a task view. -->
<integer name="recents_animate_task_view_remove_duration">250</integer>
+ <!-- The animation duration for scrolling the stack to a particular item. -->
+ <integer name="recents_animate_task_stack_scroll_duration">225</integer>
<!-- The minimum alpha for the dim applied to cards that go deeper into the stack. -->
<integer name="recents_max_task_stack_view_dim">96</integer>
<!-- The delay to enforce between each alt-tab key press. -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index bc941ca..5555aa7 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -195,17 +195,14 @@
<!-- The size of the application icon in the recents task view. -->
<dimen name="recents_task_view_application_icon_size">48dp</dimen>
- <!-- The size of the activity icon in the recents task view. -->
- <dimen name="recents_task_view_activity_icon_size">60dp</dimen>
-
<!-- The radius of the rounded corners on a task view. -->
<dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
<!-- The min translation in the Z index for the last task. -->
- <dimen name="recents_task_view_z_min">25dp</dimen>
+ <dimen name="recents_task_view_z_min">20dp</dimen>
<!-- The max translation in the Z index for the last task. -->
- <dimen name="recents_task_view_z_max">100dp</dimen>
+ <dimen name="recents_task_view_z_max">80dp</dimen>
<!-- The amount to translate when animating the removal of a task. -->
<dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>
@@ -231,6 +228,9 @@
<!-- The side padding for the task stack as a percentage of the width. -->
<item name="recents_stack_width_padding_percentage" format="float" type="dimen">0.04444</item>
+ <!-- The overscroll percentage allowed on the stack. -->
+ <item name="recents_stack_overscroll_percentage" format="float" type="dimen">0.0875</item>
+
<!-- The top offset for the task stack. -->
<dimen name="recents_stack_top_padding">16dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index b39fe24..70f6031 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -33,8 +33,7 @@
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>
-
- <item name="android:ambientShadowAlpha">0.30</item>
+ <item name="android:ambientShadowAlpha">0.35</item>
</style>
<!-- Animations for a non-full-screen window or activity. -->
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 0b36bdbd..d328660 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -22,7 +22,6 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -36,7 +35,6 @@
import com.android.systemui.RecentsComponent;
import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskGrouping;
@@ -99,6 +97,7 @@
long mLastToggleTime;
public AlternateRecentsComponent(Context context) {
+ RecentsTaskLoader.initialize(context);
Resources res = context.getResources();
mContext = context;
mSystemServicesProxy = new SystemServicesProxy(context);
@@ -176,8 +175,9 @@
}
void showRelativeAffiliatedTask(boolean showNextTask) {
- TaskStack stack = RecentsTaskLoader.getShallowTaskStack(mSystemServicesProxy,
- Integer.MAX_VALUE, mContext.getResources());
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ TaskStack stack = loader.getTaskStack(mSystemServicesProxy, mContext.getResources(),
+ -1, -1, false, null, null);
// Return early if there are no tasks
if (stack.getTaskCount() == 0) return;
@@ -385,16 +385,8 @@
toTask);
if (toTransform != null && toTask.key != null) {
Rect toTaskRect = toTransform.rect;
- ActivityInfo info = mSystemServicesProxy.getActivityInfo(
- toTask.key.baseIntent.getComponent(), toTask.key.userId);
- if (toTask.activityIcon == null) {
- toTask.activityIcon = mSystemServicesProxy.getActivityIcon(info,
- toTask.key.userId);
- }
- if (toTask.activityLabel == null) {
- toTask.activityLabel = mSystemServicesProxy.getActivityLabel(info);
- }
+ // XXX: Reduce the memory usage the to the task bar height
Bitmap thumbnail = Bitmap.createBitmap(toTaskRect.width(), toTaskRect.height(),
Bitmap.Config.ARGB_8888);
if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
@@ -420,8 +412,9 @@
TaskViewTransform getThumbnailTransitionTransform(int runningTaskId, boolean isTopTaskHome,
Task runningTaskOut) {
// Get the stack of tasks that we are animating into
- TaskStack stack = RecentsTaskLoader.getShallowTaskStack(mSystemServicesProxy, -1,
- mContext.getResources());
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ TaskStack stack = loader.getTaskStack(mSystemServicesProxy, mContext.getResources(),
+ runningTaskId, -1, false, null, null);
if (stack.getTaskCount() == 0) {
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index a5b845d..2f9715f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -343,7 +343,6 @@
super.onCreate(savedInstanceState);
// Initialize the loader and the configuration
- RecentsTaskLoader.initialize(this);
mConfig = RecentsConfiguration.reinitialize(this,
RecentsTaskLoader.getInstance().getSystemServicesProxy());
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 9803687..5d8181c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -67,9 +67,11 @@
public int searchBarSpaceHeightPx;
/** Task stack */
+ public int taskStackScrollDuration;
public int taskStackMaxDim;
public int taskStackTopPaddingPx;
public float taskStackWidthPaddingPct;
+ public float taskStackOverscrollPct;
/** Task view animation and styles */
public int taskViewEnterFromHomeDuration;
@@ -195,9 +197,14 @@
searchBarAppWidgetId = settings.getInt(Constants.Values.App.Key_SearchAppWidgetId, -1);
// Task stack
+ taskStackScrollDuration =
+ res.getInteger(R.integer.recents_animate_task_stack_scroll_duration);
TypedValue widthPaddingPctValue = new TypedValue();
res.getValue(R.dimen.recents_stack_width_padding_percentage, widthPaddingPctValue, true);
taskStackWidthPaddingPct = widthPaddingPctValue.getFloat();
+ TypedValue stackOverscrollPctValue = new TypedValue();
+ res.getValue(R.dimen.recents_stack_overscroll_percentage, stackOverscrollPctValue, true);
+ taskStackOverscrollPct = stackOverscrollPctValue.getFloat();
taskStackMaxDim = res.getInteger(R.integer.recents_max_task_stack_view_dim);
taskStackTopPaddingPx = res.getDimensionPixelSize(R.dimen.recents_stack_top_padding);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
index 31011ae..60e89bf 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
@@ -16,7 +16,6 @@
package com.android.systemui.recents.model;
-import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.Looper;
@@ -36,7 +35,7 @@
}
PackageCallbacks mCb;
- List<ActivityManager.RecentTaskInfo> mTasks;
+ List<Task.TaskKey> mTasks;
SystemServicesProxy mSystemServicesProxy;
/** Registers the broadcast receivers with the specified callbacks. */
@@ -64,7 +63,7 @@
}
/** Sets the list of tasks to match against package broadcast changes. */
- void setTasks(List<ActivityManager.RecentTaskInfo> tasks) {
+ void setTasks(List<Task.TaskKey> tasks) {
mTasks = tasks;
}
@@ -75,7 +74,7 @@
// Identify all the tasks that should be removed as a result of the package being removed.
// Using a set to ensure that we callback once per unique component.
HashSet<ComponentName> componentsToRemove = new HashSet<ComponentName>();
- for (ActivityManager.RecentTaskInfo t : mTasks) {
+ for (Task.TaskKey t : mTasks) {
ComponentName cn = t.baseIntent.getComponent();
if (cn.getPackageName().equals(packageName)) {
componentsToRemove.add(cn);
@@ -99,7 +98,7 @@
// Using a set to ensure that we callback once per unique component.
HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
HashSet<ComponentName> componentsToRemove = new HashSet<ComponentName>();
- for (ActivityManager.RecentTaskInfo t : mTasks) {
+ for (Task.TaskKey t : mTasks) {
ComponentName cn = t.baseIntent.getComponent();
if (cn.getPackageName().equals(packageName)) {
if (componentsKnownToExist.contains(cn)) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index b93c126..a93e244 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -35,11 +35,16 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedHashSet;
+import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
+/** Handle to an ActivityInfo */
+class ActivityInfoHandle {
+ ActivityInfo info;
+}
+
/** A bitmap load queue */
class TaskResourceLoadQueue {
ConcurrentLinkedQueue<Task> mQueue = new ConcurrentLinkedQueue<Task>();
@@ -230,7 +235,6 @@
static RecentsTaskLoader sInstance;
SystemServicesProxy mSystemServicesProxy;
- DrawableLruCache mTaskDescriptionIconCache;
DrawableLruCache mApplicationIconCache;
BitmapLruCache mThumbnailCache;
StringLruCache mActivityLabelCache;
@@ -274,7 +278,6 @@
mSystemServicesProxy = new SystemServicesProxy(context);
mPackageMonitor = new RecentsPackageMonitor();
mLoadQueue = new TaskResourceLoadQueue();
- mTaskDescriptionIconCache = new DrawableLruCache(iconCacheSize);
mApplicationIconCache = new DrawableLruCache(iconCacheSize);
mThumbnailCache = new BitmapLruCache(thumbnailCacheSize);
mActivityLabelCache = new StringLruCache(100);
@@ -301,103 +304,151 @@
}
/** Gets the list of recent tasks, ordered from back to front. */
- private static List<ActivityManager.RecentTaskInfo> getRecentTasks(SystemServicesProxy ssp,
- int numTasks) {
- // Set a default number of tasks to query if none is provided
- if (numTasks < 0) {
- RecentsConfiguration config = RecentsConfiguration.getInstance();
- numTasks = config.maxNumTasksToLoad;
- }
+ private static List<ActivityManager.RecentTaskInfo> getRecentTasks(SystemServicesProxy ssp) {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
List<ActivityManager.RecentTaskInfo> tasks =
- ssp.getRecentTasks(numTasks, UserHandle.CURRENT.getIdentifier());
+ ssp.getRecentTasks(config.maxNumTasksToLoad,
+ UserHandle.CURRENT.getIdentifier());
Collections.reverse(tasks);
return tasks;
}
+ /** Returns the activity icon using as many cached values as we can. */
+ public Drawable getAndUpdateActivityIcon(Task.TaskKey taskKey,
+ ActivityManager.TaskDescription td, SystemServicesProxy ssp,
+ Resources res, ActivityInfoHandle infoHandle, boolean preloadTask) {
+ // Return the cached activity icon if it exists
+ Drawable icon = mApplicationIconCache.getAndInvalidateIfModified(taskKey);
+ if (icon != null) {
+ return icon;
+ }
+ // Return the task description icon if it exists
+ if (td != null && td.getIcon() != null) {
+ icon = ssp.getBadgedIcon(new BitmapDrawable(res, td.getIcon()), taskKey.userId);
+ mApplicationIconCache.put(taskKey, icon);
+ return icon;
+ }
+ // If we are preloading this task, continue to load the activity icon
+ if (preloadTask) {
+ // All short paths failed, load the icon from the activity info and cache it
+ if (infoHandle.info == null) {
+ infoHandle.info = ssp.getActivityInfo(taskKey.baseIntent.getComponent(),
+ taskKey.userId);
+ }
+ icon = ssp.getActivityIcon(infoHandle.info, taskKey.userId);
+ mApplicationIconCache.put(taskKey, icon);
+ return icon;
+ }
+ // If we are not preloading, return the default icon to show
+ return null;
+ }
+
+ /** Returns the activity label using as many cached values as we can. */
+ public String getAndUpdateActivityLabel(Task.TaskKey taskKey,
+ ActivityManager.TaskDescription td, SystemServicesProxy ssp,
+ ActivityInfoHandle infoHandle) {
+ // Return the task description label if it exists
+ if (td != null && td.getLabel() != null) {
+ return td.getLabel();
+ }
+ // Return the cached activity label if it exists
+ String label = mActivityLabelCache.getAndInvalidateIfModified(taskKey);
+ if (label != null) {
+ return label;
+ }
+ // All short paths failed, load the label from the activity info and cache it
+ if (infoHandle.info == null) {
+ infoHandle.info = ssp.getActivityInfo(taskKey.baseIntent.getComponent(),
+ taskKey.userId);
+ }
+ label = ssp.getActivityLabel(infoHandle.info);
+ mActivityLabelCache.put(taskKey, label);
+ return label;
+ }
+
+ /** Returns the activity's primary color. */
+ public int getActivityPrimaryColor(ActivityManager.TaskDescription td,
+ RecentsConfiguration config) {
+ if (td != null && td.getPrimaryColor() != 0) {
+ return td.getPrimaryColor();
+ }
+ return config.taskBarViewDefaultBackgroundColor;
+ }
+
/** Reload the set of recent tasks */
public SpaceNode reload(Context context, int preloadCount) {
- RecentsConfiguration config = RecentsConfiguration.getInstance();
- Resources res = context.getResources();
- LinkedHashSet<Task> tasksToLoad = new LinkedHashSet<Task>();
- ArrayList<Task> tasksToAdd = new ArrayList<Task>();
- TaskStack stack = new TaskStack();
+ ArrayList<Task.TaskKey> taskKeys = new ArrayList<Task.TaskKey>();
+ ArrayList<Task> tasksToLoad = new ArrayList<Task>();
+ TaskStack stack = getTaskStack(mSystemServicesProxy, context.getResources(),
+ -1, preloadCount, true, taskKeys, tasksToLoad);
SpaceNode root = new SpaceNode();
root.setStack(stack);
- // Get the recent tasks
- SystemServicesProxy ssp = mSystemServicesProxy;
- List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp, -1);
+ // Start the task loader and add all the tasks we need to load
+ mLoader.start(context);
+ mLoadQueue.addTasks(tasksToLoad);
- // From back to front, add each task to the task stack
+ // Update the package monitor with the list of packages to listen for
+ mPackageMonitor.setTasks(taskKeys);
+
+ return root;
+ }
+
+ /** Creates a lightweight stack of the current recent tasks, without thumbnails and icons. */
+ public TaskStack getTaskStack(SystemServicesProxy ssp, Resources res,
+ int preloadTaskId, int preloadTaskCount,
+ boolean loadTaskThumbnails, List<Task.TaskKey> taskKeysOut,
+ List<Task> tasksToLoadOut) {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+ List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp);
+ HashMap<ComponentName, ActivityInfoHandle> activityInfoCache =
+ new HashMap<ComponentName, ActivityInfoHandle>();
+ ArrayList<Task> tasksToAdd = new ArrayList<Task>();
+ TaskStack stack = new TaskStack();
+
int taskCount = tasks.size();
for (int i = 0; i < taskCount; i++) {
ActivityManager.RecentTaskInfo t = tasks.get(i);
+
+ // Get an existing activity info handle if possible
+ ComponentName cn = t.baseIntent.getComponent();
+ ActivityInfoHandle infoHandle = new ActivityInfoHandle();
+ boolean hasCachedActivityInfo = false;
+ if (activityInfoCache.containsKey(cn)) {
+ infoHandle = activityInfoCache.get(cn);
+ hasCachedActivityInfo = true;
+ }
+
+ // Compose the task key
Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.baseIntent, t.userId,
t.firstActiveTime, t.lastActiveTime);
- ComponentName cn = t.baseIntent.getComponent();
- ActivityInfo info = null;
- ActivityManager.TaskDescription av = t.taskDescription;
- String activityLabel = null;
- Drawable activityIcon = mDefaultApplicationIcon;
- int activityColor = config.taskBarViewDefaultBackgroundColor;
- boolean loadedActivityIcon = false;
- if (av != null) {
- activityLabel = av.getLabel();
- activityIcon = mTaskDescriptionIconCache.getAndInvalidateIfModified(taskKey);
- if (activityIcon == null) {
- activityIcon = (av.getIcon() != null) ?
- ssp.getBadgedIcon(new BitmapDrawable(res, av.getIcon()), t.userId) : null;
- if (activityIcon != null) {
- mTaskDescriptionIconCache.put(taskKey, activityIcon);
- }
- }
- if (av.getPrimaryColor() != 0) {
- activityColor = av.getPrimaryColor();
- }
- loadedActivityIcon = (activityIcon != null);
- }
- // If there is no activity label, then try and read it from the label cache before
- // loading it from the system
- if (activityLabel == null) {
- activityLabel = mActivityLabelCache.getAndInvalidateIfModified(taskKey);
- if (activityLabel == null) {
- if (info == null) {
- info = ssp.getActivityInfo(cn, t.userId);
- }
- activityLabel = ssp.getActivityLabel(info);
- mActivityLabelCache.put(taskKey, activityLabel);
- }
+ // Determine whether to preload this task
+ boolean preloadTask = false;
+ if (preloadTaskId > 0) {
+ preloadTask = (t.id == preloadTaskId);
+ } else if (preloadTaskCount > 0) {
+ preloadTask = (i >= (taskCount - preloadTaskCount));
}
- // Create a new task
+ // Load the label, icon, and color
+ String activityLabel = getAndUpdateActivityLabel(taskKey, t.taskDescription,
+ ssp, infoHandle);
+ Drawable activityIcon = getAndUpdateActivityIcon(taskKey, t.taskDescription,
+ ssp, res, infoHandle, preloadTask);
+ int activityColor = getActivityPrimaryColor(t.taskDescription, config);
+
+ // Update the activity info cache
+ if (!hasCachedActivityInfo && infoHandle.info != null) {
+ activityInfoCache.put(cn, infoHandle);
+ }
+
+ // Add the task to the stack
Task task = new Task(taskKey, (t.id > -1), t.affiliatedTaskId, t.affiliatedTaskColor,
activityLabel, activityIcon, activityColor, (i == (taskCount - 1)),
config.lockToAppEnabled);
- // Preload the specified number of apps
- if (i >= (taskCount - preloadCount)) {
- // Load the icon from the cache if possible (only if we don't have an activity icon)
- if (!loadedActivityIcon) {
- task.applicationIcon =
- mApplicationIconCache.getAndInvalidateIfModified(taskKey);
- if (task.applicationIcon == null) {
- // Load the icon from the system
- if (info == null) {
- info = ssp.getActivityInfo(cn, t.userId);
- }
- task.applicationIcon = ssp.getActivityIcon(info, taskKey.userId);
- if (task.applicationIcon != null) {
- mApplicationIconCache.put(taskKey, task.applicationIcon);
- }
- }
- if (task.applicationIcon == null) {
- // Either the task has changed since the last active time, or it was not
- // previously cached, so try and load the task anew.
- tasksToLoad.add(task);
- }
- }
-
+ if (preloadTask && loadTaskThumbnails) {
// Load the thumbnail from the cache if possible
task.thumbnail = mThumbnailCache.getAndInvalidateIfModified(taskKey);
if (task.thumbnail == null) {
@@ -408,54 +459,20 @@
mThumbnailCache.put(taskKey, task.thumbnail);
}
}
- if (task.thumbnail == null) {
+ if (task.thumbnail == null && tasksToLoadOut != null) {
// Either the task has changed since the last active time, or it was not
// previously cached, so try and load the task anew.
- tasksToLoad.add(task);
+ tasksToLoadOut.add(task);
}
}
+ // Add to the list of task keys
+ if (taskKeysOut != null) {
+ taskKeysOut.add(taskKey);
+ }
// Add the task to the stack
tasksToAdd.add(task);
}
-
- // Simulate the groupings that we describe
- stack.setTasks(tasksToAdd);
- stack.createAffiliatedGroupings(config);
-
- // Start the task loader and add all the tasks we need to load
- mLoader.start(context);
- mLoadQueue.addTasks(tasksToLoad);
-
- // Update the package monitor with the list of packages to listen for
- mPackageMonitor.setTasks(tasks);
-
- return root;
- }
-
- /** Creates a lightweight stack of the current recent tasks, without thumbnails and icons. */
- public static TaskStack getShallowTaskStack(SystemServicesProxy ssp, int numTasks,
- Resources resources) {
- RecentsConfiguration config = RecentsConfiguration.getInstance();
- List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp, numTasks);
- ArrayList<Task> tasksToAdd = new ArrayList<Task>();
- TaskStack stack = new TaskStack();
-
- int taskCount = tasks.size();
- for (int i = 0; i < taskCount; i++) {
- ActivityManager.RecentTaskInfo t = tasks.get(i);
- ActivityManager.TaskDescription av = t.taskDescription;
-
- BitmapDrawable icon = null;
- if (av.getIcon() != null) {
- icon = new BitmapDrawable(resources, av.getIcon());
- }
- Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.baseIntent, t.userId,
- t.firstActiveTime, t.lastActiveTime);
- tasksToAdd.add(new Task(taskKey, true, t.affiliatedTaskId, t.affiliatedTaskColor,
- av.getLabel(), icon, av.getPrimaryColor(), (i == (taskCount - 1)),
- config.lockToAppEnabled));
- }
stack.setTasks(tasksToAdd);
stack.createAffiliatedGroupings(config);
return stack;
@@ -525,21 +542,18 @@
// We are leaving recents, so trim the data a bit
mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 2);
mApplicationIconCache.trimToSize(mMaxIconCacheSize / 2);
- mTaskDescriptionIconCache.trimToSize(mMaxIconCacheSize / 2);
break;
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
// We are going to be low on memory
mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 4);
mApplicationIconCache.trimToSize(mMaxIconCacheSize / 4);
- mTaskDescriptionIconCache.trimToSize(mMaxIconCacheSize / 4);
break;
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
// We are low on memory, so release everything
mThumbnailCache.evictAll();
mApplicationIconCache.evictAll();
- mTaskDescriptionIconCache.evictAll();
// The cache is small, only clear the label cache when we are critical
mActivityLabelCache.evictAll();
break;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
index 34f73c6..d6889d0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -33,6 +33,8 @@
Rect mClipRect = new Rect();
Rect mOutlineClipRect = new Rect();
int mCornerRadius;
+ float mAlpha = 1f;
+ final float mMinAlpha = 0.25f;
ObjectAnimator mClipTopAnimator;
ObjectAnimator mClipRightAnimator;
@@ -51,6 +53,7 @@
@Override
public void getOutline(View view, Outline outline) {
+ outline.setAlpha(mMinAlpha + mAlpha / (1f - mMinAlpha));
outline.setRoundRect(Math.max(mClipRect.left, mOutlineClipRect.left),
Math.max(mClipRect.top, mOutlineClipRect.top),
mSourceView.getMeasuredWidth() - Math.max(mClipRect.right, mOutlineClipRect.right),
@@ -58,6 +61,14 @@
mCornerRadius);
}
+ /** Sets the view outline alpha. */
+ void setAlpha(float alpha) {
+ if (Float.compare(alpha, mAlpha) != 0) {
+ mAlpha = alpha;
+ mSourceView.invalidateOutline();
+ }
+ }
+
/** Animates the top clip. */
void animateClipTop(int top, int duration, ValueAnimator.AnimatorUpdateListener updateListener) {
if (mClipTopAnimator != null) {
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 47fda5b..1ac3bc3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -477,10 +477,10 @@
if (!task.group.isFrontMostTask(task)) {
// For affiliated tasks that are behind other tasks, we must animate the front cards
// out of view before starting the task transition
- stackView.startLaunchTaskAnimation(tv, launchRunnable);
+ stackView.startLaunchTaskAnimation(tv, launchRunnable, lockToTask);
} else {
// Otherwise, we can start the task transition immediately
- stackView.startLaunchTaskAnimation(tv, null);
+ stackView.startLaunchTaskAnimation(tv, null, lockToTask);
postDelayed(launchRunnable, 17);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
index e0298ab..fa44551 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
@@ -28,6 +28,7 @@
import android.view.VelocityTracker;
import android.view.View;
import android.view.animation.LinearInterpolator;
+import com.android.systemui.recents.RecentsConfiguration;
/**
* This class facilitates swipe to dismiss. It defines an interface to be implemented by the
@@ -50,7 +51,7 @@
private int DEFAULT_ESCAPE_ANIMATION_DURATION = 75; // ms
private int MAX_ESCAPE_ANIMATION_DURATION = 150; // ms
private int MAX_DISMISS_VELOCITY = 2000; // dp/sec
- private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms
+ private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 250; // ms
public static float ALPHA_FADE_START = 0.15f; // fraction of thumbnail width
// where fade starts
@@ -265,6 +266,7 @@
ValueAnimator anim = createTranslationAnimation(view, 0);
int duration = SNAP_ANIM_LEN;
anim.setDuration(duration);
+ anim.setInterpolator(RecentsConfiguration.getInstance().linearOutSlowInInterpolator);
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
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 861011f..dbed136 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -105,7 +105,7 @@
mFilterAlgorithm = new TaskStackViewFilterAlgorithm(mConfig, this, mViewPool);
mStackScroller = new TaskStackViewScroller(context, mConfig, mLayoutAlgorithm);
mStackScroller.setCallbacks(this);
- mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
+ mTouchHandler = new TaskStackViewTouchHandler(context, this, mConfig, mStackScroller);
mUIDozeTrigger = new DozeTrigger(mConfig.taskBarDismissDozeDelaySeconds, new Runnable() {
@Override
public void run() {
@@ -647,17 +647,17 @@
}
/** Animates a task view in this stack as it launches. */
- public void startLaunchTaskAnimation(TaskView tv, final Runnable r) {
+ public void startLaunchTaskAnimation(TaskView tv, Runnable r, boolean lockToTask) {
Task launchTargetTask = tv.getTask();
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView t = (TaskView) getChildAt(i);
if (t == tv) {
- t.startLaunchTaskAnimation(r, true, true);
+ t.startLaunchTaskAnimation(r, true, true, lockToTask);
} else {
boolean occludesLaunchTarget = launchTargetTask.group.isTaskAboveTask(t.getTask(),
launchTargetTask);
- t.startLaunchTaskAnimation(null, false, occludesLaunchTarget);
+ t.startLaunchTaskAnimation(null, false, occludesLaunchTarget, lockToTask);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
index 2c0dc44..5852b88 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
@@ -133,12 +133,8 @@
stopBoundScrollAnimation();
mScrollAnimator = ObjectAnimator.ofFloat(this, "stackScroll", curScroll, newScroll);
- mScrollAnimator.setDuration(200);
- // We would have to project the difference into the screen coords, and then use that as the
- // duration
-// mScrollAnimator.setDuration(Utilities.calculateTranslationAnimationDuration(newScroll -
-// curScroll, 250));
- mScrollAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
+ mScrollAnimator.setDuration(mConfig.taskStackScrollDuration);
+ mScrollAnimator.setInterpolator(mConfig.linearOutSlowInInterpolator);
mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 374a27f..8f9b4c2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -23,11 +23,13 @@
import android.view.ViewConfiguration;
import android.view.ViewParent;
import com.android.systemui.recents.Constants;
+import com.android.systemui.recents.RecentsConfiguration;
/* Handles touch events for a TaskStackView. */
class TaskStackViewTouchHandler implements SwipeHelper.Callback {
static int INACTIVE_POINTER_ID = -1;
+ RecentsConfiguration mConfig;
TaskStackView mSv;
TaskStackViewScroller mScroller;
VelocityTracker mVelocityTracker;
@@ -52,7 +54,8 @@
SwipeHelper mSwipeHelper;
boolean mInterceptedBySwipeHelper;
- public TaskStackViewTouchHandler(Context context, TaskStackView sv, TaskStackViewScroller scroller) {
+ public TaskStackViewTouchHandler(Context context, TaskStackView sv,
+ RecentsConfiguration config, TaskStackViewScroller scroller) {
ViewConfiguration configuration = ViewConfiguration.get(context);
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
@@ -60,6 +63,7 @@
mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
mSv = sv;
mScroller = scroller;
+ mConfig = config;
float densityScale = context.getResources().getDisplayMetrics().density;
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, mPagingTouchSlop);
@@ -258,7 +262,7 @@
if (Float.compare(overScrollAmount, 0f) != 0) {
// Bound the overscroll to a fixed amount, and inversely scale the y-movement
// relative to how close we are to the max overscroll
- float maxOverScroll = 0.25f;
+ float maxOverScroll = mConfig.taskStackOverscrollPct;
deltaP *= (1f - (Math.min(maxOverScroll, overScrollAmount)
/ maxOverScroll));
}
@@ -280,7 +284,6 @@
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
if (mIsScrolling && (Math.abs(velocity) > mMinimumVelocity)) {
- // XXX: Should this be calculated as a percentage of a curve?
int overscrollRange = (int) (Math.min(1f,
Math.abs((float) velocity / mMaximumVelocity)) *
Constants.Values.TaskStackView.TaskStackOverscrollRange);
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 dfbcce1..eecc170 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -471,7 +471,7 @@
/** Animates this task view as it exits recents */
void startLaunchTaskAnimation(final Runnable postAnimRunnable, boolean isLaunchingTask,
- boolean occludesLaunchTarget) {
+ boolean occludesLaunchTarget, boolean lockToTask) {
if (isLaunchingTask) {
// Disable the thumbnail clip
mThumbnailView.disableTaskBarClip();
@@ -487,11 +487,14 @@
}
// Animate the action button away
- float toScale = 0.9f;
+ if (!lockToTask) {
+ float toScale = 0.9f;
+ mActionButtonView.animate()
+ .scaleX(toScale)
+ .scaleY(toScale);
+ }
mActionButtonView.animate()
.alpha(0f)
- .scaleX(toScale)
- .scaleY(toScale)
.setStartDelay(0)
.setDuration(mConfig.taskBarExitAnimDuration)
.setInterpolator(mConfig.fastOutLinearInInterpolator)
@@ -621,6 +624,7 @@
/** Sets the current task progress. */
public void setTaskProgress(float p) {
mTaskProgress = p;
+ mViewBounds.setAlpha(p);
updateDimFromTaskProgress();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index e6eca22..8b4c2c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -202,7 +202,7 @@
}
public void setDark(boolean dark, boolean fade) {
- if (mDark == dark) return;
+ if (mDark == dark || mContractedChild == null) return;
mDark = dark;
setImageViewDark(dark, fade, com.android.internal.R.id.right_icon);
setImageViewDark(dark, fade, com.android.internal.R.id.icon);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 5a836c8..e382a9f 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -545,6 +545,7 @@
private static final int MSG_DISPATCH_SHOW_RECENTS = 9;
private static final int MSG_DISPATCH_SHOW_GLOBAL_ACTIONS = 10;
private static final int MSG_HIDE_BOOT_MESSAGE = 11;
+ private static final int MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK = 12;
private class PolicyHandler extends Handler {
@Override
@@ -590,6 +591,9 @@
case MSG_HIDE_BOOT_MESSAGE:
handleHideBootMessage();
break;
+ case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK:
+ launchVoiceAssistWithWakeLock(msg.arg1 != 0);
+ break;
}
}
}
@@ -2342,11 +2346,11 @@
} else if (keyCode == KeyEvent.KEYCODE_VOICE_ASSIST) {
if (!down) {
Intent voiceIntent;
- if (!keyguardOn && mPowerManager.isInteractive()) {
+ if (!keyguardOn) {
voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
} else {
voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
- voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, keyguardOn);
+ voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true);
}
mContext.startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF);
}
@@ -4445,6 +4449,19 @@
}
break;
}
+ case KeyEvent.KEYCODE_VOICE_ASSIST: {
+ // Only do this if we would otherwise not pass it to the user. In that case,
+ // interceptKeyBeforeDispatching would apply a similar but different policy in
+ // order to invoke voice assist actions. Note that we need to make a copy of the
+ // key event here because the original key event will be recycled when we return.
+ if ((result & ACTION_PASS_TO_USER) == 0 && !down) {
+ mBroadcastWakeLock.acquire();
+ Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK,
+ keyguardActive ? 1 : 0, 0);
+ msg.setAsynchronous(true);
+ msg.sendToTarget();
+ }
+ }
}
if (useHapticFeedback) {
@@ -4551,6 +4568,14 @@
}
}
+ void launchVoiceAssistWithWakeLock(boolean keyguardActive) {
+ Intent voiceIntent =
+ new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
+ voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, keyguardActive);
+ mContext.startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF);
+ mBroadcastWakeLock.release();
+ }
+
BroadcastReceiver mDockReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 9674ca2..de5e7cb 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -1963,8 +1963,9 @@
return packages;
}
- // Called from the backup task: record that the given app has been successfully
- // backed up at least once
+ // Called from the backup tasks: record that the given app has been successfully
+ // backed up at least once. This includes both key/value and full-data backups
+ // through the transport.
void logBackupComplete(String packageName) {
if (packageName.equals(PACKAGE_MANAGER_SENTINEL)) return;
@@ -3837,6 +3838,7 @@
// Success!
EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS,
currentPackage.packageName);
+ logBackupComplete(currentPackage.packageName);
}
cleanUpPipes(transportPipes);
cleanUpPipes(enginePipes);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 972a86d..6ca536c 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3816,6 +3816,11 @@
* of affiliations.
*/
void cleanupRecentTasksLocked(int userId) {
+ if (mRecentTasks == null) {
+ // Happens when called from the packagemanager broadcast before boot.
+ return;
+ }
+
final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
final IPackageManager pm = AppGlobals.getPackageManager();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5093f97..89878ef 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11051,34 +11051,34 @@
Slog.w(TAG, "Attempt to delete null packageName.");
return false;
}
- PackageParser.Package p;
+ PackageParser.Package pkg;
boolean dataOnly = false;
final int appId;
synchronized (mPackages) {
- p = mPackages.get(packageName);
- if (p == null) {
+ pkg = mPackages.get(packageName);
+ if (pkg == null) {
dataOnly = true;
PackageSetting ps = mSettings.mPackages.get(packageName);
if ((ps == null) || (ps.pkg == null)) {
Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
return false;
}
- p = ps.pkg;
+ pkg = ps.pkg;
}
if (!dataOnly) {
// need to check this only for fully installed applications
- if (p == null) {
+ if (pkg == null) {
Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
return false;
}
- final ApplicationInfo applicationInfo = p.applicationInfo;
+ final ApplicationInfo applicationInfo = pkg.applicationInfo;
if (applicationInfo == null) {
Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
}
- if (p != null && p.applicationInfo != null) {
- appId = p.applicationInfo.uid;
+ if (pkg != null && pkg.applicationInfo != null) {
+ appId = pkg.applicationInfo.uid;
} else {
appId = -1;
}
@@ -11090,6 +11090,19 @@
return false;
}
removeKeystoreDataIfNeeded(userId, appId);
+
+ // Create a native library symlink only if we have native libraries
+ // and if the native libraries are 32 bit libraries. We do not provide
+ // this symlink for 64 bit libraries.
+ if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
+ !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
+ final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
+ if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
+ Slog.w(TAG, "Failed linking native library dir");
+ return false;
+ }
+ }
+
return true;
}
@@ -12914,6 +12927,17 @@
Bundle extras) throws RemoteException {
Slog.d(TAG, "Install result for move: "
+ PackageManager.installStatusToString(returnCode, msg));
+
+ // We usually have a new package now after the install, but if
+ // we failed we need to clear the pending flag on the original
+ // package object.
+ synchronized (mPackages) {
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg != null) {
+ pkg.mOperationPending = false;
+ }
+ }
+
final int status = PackageManager.installStatusToPublicStatus(returnCode);
switch (status) {
case PackageInstaller.STATUS_SUCCESS:
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index ad87993..8ded7ca 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1576,6 +1576,7 @@
String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE);
String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE);
if (multiple != null) {
+ values.clear();
int count = Integer.parseInt(multiple);
while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (type == XmlPullParser.START_TAG
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 09c4e20..9ceac41 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -41,11 +41,11 @@
void addAppToken(int addPos, AppWindowToken wtoken) {
final int lastPos = mAppTokens.size();
- if (addPos > lastPos) {
- // We lost an app token. Don't crash though.
- Slog.e(TAG, "Task.addAppToken: Out of bounds attempt token=" + wtoken + " addPos="
- + addPos + " lastPos=" + lastPos);
- addPos = lastPos;
+ for (int pos = 0; pos < lastPos && pos < addPos; ++pos) {
+ if (mAppTokens.get(pos).removed) {
+ // addPos assumes removed tokens are actually gone.
+ ++addPos;
+ }
}
mAppTokens.add(addPos, wtoken);
mDeferRemoval = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e144bde..c70cb22 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2382,7 +2382,6 @@
origId = Binder.clearCallingIdentity();
if (addToken) {
- Slog.w("BadTokenDebug", "addWindow: Adding token=" + token + " attrs.token=" + attrs.token);
mTokenMap.put(attrs.token, token);
}
win.attach();
@@ -2664,9 +2663,7 @@
+ token.windows.size());
if (token.windows.size() == 0) {
if (!token.explicit) {
- WindowToken wtoken = mTokenMap.remove(token.token);
- Slog.w("BadTokenDebug", "removeWindowInnerLocked: Removing token=" + token + " removed=" +
- wtoken + " Callers=" + Debug.getCallers(4));
+ mTokenMap.remove(token.token);
} else if (atoken != null) {
atoken.firstWindowDrawn = false;
}
@@ -3452,7 +3449,6 @@
return;
}
wtoken = new WindowToken(this, token, type, true);
- Slog.w("BadTokenDebug", "addWindowToken: Adding token=" + token + " wtoken=" + wtoken);
mTokenMap.put(token, wtoken);
if (type == TYPE_WALLPAPER) {
mWallpaperTokens.add(wtoken);
@@ -3471,8 +3467,6 @@
synchronized(mWindowMap) {
DisplayContent displayContent = null;
WindowToken wtoken = mTokenMap.remove(token);
- Slog.w("BadTokenDebug", "removeWindowToken: Removing token=" + token + " removed=" + wtoken
- + " Callers=" + Debug.getCallers(3));
if (wtoken != null) {
boolean delayed = false;
if (!wtoken.hidden) {
@@ -3589,7 +3583,6 @@
task.addAppToken(addPos, atoken);
}
- Slog.w("BadTokenDebug", "addAppToken: Adding token=" + token.asBinder() + " atoken=" + atoken);
mTokenMap.put(token.asBinder(), atoken);
// Application tokens start out hidden.
@@ -4689,7 +4682,6 @@
final long origId = Binder.clearCallingIdentity();
synchronized(mWindowMap) {
WindowToken basewtoken = mTokenMap.remove(token);
- Slog.w("BadTokenDebug", "removeAppToke: Removing token=" + token + " removed=" + basewtoken);
if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
delayed = setTokenVisibilityLocked(wtoken, null, false,