diff options
Diffstat (limited to 'core/java')
21 files changed, 398 insertions, 120 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index a285932..7a636db 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -213,6 +213,13 @@ public class ActivityManager { public static final int BROADCAST_STICKY_CANT_HAVE_PERMISSION = -1; /** + * Result for IActivityManager.broadcastIntent: trying to send a broadcast + * to a stopped user. Fail. + * @hide + */ + public static final int BROADCAST_FAILED_USER_STOPPED = -2; + + /** * Type for IActivityManaqer.getIntentSender: this PendingIntent is * for a sendBroadcast operation. * @hide diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index bc7114b..c3028b7 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -2279,6 +2279,20 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case START_IN_PLACE_ANIMATION_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + final Bundle bundle; + if (data.readInt() == 0) { + bundle = null; + } else { + bundle = data.readBundle(); + } + final ActivityOptions options = bundle == null ? null : new ActivityOptions(bundle); + startInPlaceAnimationOnFrontMostApplication(options); + reply.writeNoException(); + return true; + } + case REQUEST_VISIBLE_BEHIND_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); @@ -5298,6 +5312,24 @@ class ActivityManagerProxy implements IActivityManager } @Override + public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions options) + throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + if (options == null) { + data.writeInt(0); + } else { + data.writeInt(1); + data.writeBundle(options.toBundle()); + } + mRemote.transact(START_IN_PLACE_ANIMATION_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + reply.readException(); + data.recycle(); + reply.recycle(); + } + + @Override public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index cd6a4f5..3d390bf 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -63,6 +63,12 @@ public class ActivityOptions { public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes"; /** + * Custom in-place animation resource ID. + * @hide + */ + public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:animInPlaceRes"; + + /** * Bitmap for thumbnail animation. * @hide */ @@ -132,11 +138,14 @@ public class ActivityOptions { public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8; /** @hide */ public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9; + /** @hide */ + public static final int ANIM_CUSTOM_IN_PLACE = 10; private String mPackageName; private int mAnimationType = ANIM_NONE; private int mCustomEnterResId; private int mCustomExitResId; + private int mCustomInPlaceResId; private Bitmap mThumbnail; private int mStartX; private int mStartY; @@ -198,6 +207,30 @@ public class ActivityOptions { return opts; } + /** + * Creates an ActivityOptions specifying a custom animation to run in place on an existing + * activity. + * + * @param context Who is defining this. This is the application that the + * animation resources will be loaded from. + * @param animId A resource ID of the animation resource to use for + * the incoming activity. + * @return Returns a new ActivityOptions object that you can use to + * supply these options as the options Bundle when running an in-place animation. + * @hide + */ + public static ActivityOptions makeCustomInPlaceAnimation(Context context, int animId) { + if (animId == 0) { + throw new RuntimeException("You must specify a valid animation."); + } + + ActivityOptions opts = new ActivityOptions(); + opts.mPackageName = context.getPackageName(); + opts.mAnimationType = ANIM_CUSTOM_IN_PLACE; + opts.mCustomInPlaceResId = animId; + return opts; + } + private void setOnAnimationStartedListener(Handler handler, OnAnimationStartedListener listener) { if (listener != null) { @@ -540,6 +573,10 @@ public class ActivityOptions { opts.getBinder(KEY_ANIM_START_LISTENER)); break; + case ANIM_CUSTOM_IN_PLACE: + mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0); + break; + case ANIM_SCALE_UP: mStartX = opts.getInt(KEY_ANIM_START_X, 0); mStartY = opts.getInt(KEY_ANIM_START_Y, 0); @@ -592,6 +629,11 @@ public class ActivityOptions { } /** @hide */ + public int getCustomInPlaceResId() { + return mCustomInPlaceResId; + } + + /** @hide */ public Bitmap getThumbnail() { return mThumbnail; } @@ -689,6 +731,9 @@ public class ActivityOptions { } mAnimationStartedListener = otherOptions.mAnimationStartedListener; break; + case ANIM_CUSTOM_IN_PLACE: + mCustomInPlaceResId = otherOptions.mCustomInPlaceResId; + break; case ANIM_SCALE_UP: mStartX = otherOptions.mStartX; mStartY = otherOptions.mStartY; @@ -756,6 +801,9 @@ public class ActivityOptions { b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener != null ? mAnimationStartedListener.asBinder() : null); break; + case ANIM_CUSTOM_IN_PLACE: + b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId); + break; case ANIM_SCALE_UP: b.putInt(KEY_ANIM_START_X, mStartX); b.putInt(KEY_ANIM_START_Y, mStartY); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index efcb197..6433f3f 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -456,6 +456,9 @@ public interface IActivityManager extends IInterface { throws RemoteException; public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException; + public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) + throws RemoteException; + public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException; public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException; public void backgroundResourcesReleased(IBinder token) throws RemoteException; @@ -781,4 +784,5 @@ public interface IActivityManager extends IInterface { int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237; int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238; int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239; + int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240; } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index d3ff79d..9157b1b 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -62,13 +62,16 @@ import java.util.Collections; import java.util.List; /** - * Public interface for managing policies enforced on a device. Most clients - * of this class must have published a {@link DeviceAdminReceiver} that the user - * has currently enabled. + * Public interface for managing policies enforced on a device. Most clients of this class must be + * registered with the system as a + * <a href={@docRoot}guide/topics/admin/device-admin.html">device administrator</a>. Additionally, + * a device administrator may be registered as either a profile or device owner. A given method is + * accessible to all device administrators unless the documentation for that method specifies that + * it is restricted to either device or profile owners. * * <div class="special reference"> * <h3>Developer Guides</h3> - * <p>For more information about managing policies for device adminstration, read the + * <p>For more information about managing policies for device administration, read the * <a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a> * developer guide.</p> * </div> @@ -2586,6 +2589,10 @@ public class DevicePolicyManager { * <p>The application restrictions are only made visible to the target application and the * profile or device owner. * + * <p>If the restrictions are not available yet, but may be applied in the near future, + * the admin can notify the target application of that by adding + * {@link UserManager#KEY_RESTRICTIONS_PENDING} to the settings parameter. + * * <p>The calling device admin must be a profile or device owner; if it is not, a security * exception will be thrown. * @@ -2593,6 +2600,8 @@ public class DevicePolicyManager { * @param packageName The name of the package to update restricted settings for. * @param settings A {@link Bundle} to be parsed by the receiving application, conveying a new * set of active restrictions. + * + * @see UserManager#KEY_RESTRICTIONS_PENDING */ public void setApplicationRestrictions(ComponentName admin, String packageName, Bundle settings) { diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl index 8a44c8e..0a2d4f5 100644 --- a/core/java/android/app/backup/IBackupManager.aidl +++ b/core/java/android/app/backup/IBackupManager.aidl @@ -291,4 +291,16 @@ interface IBackupManager { * {@hide} */ void opComplete(int token); + + /** + * Make the device's backup and restore machinery (in)active. When it is inactive, + * the device will not perform any backup operations, nor will it deliver data for + * restore, although clients can still safely call BackupManager methods. + * + * @param whichUser User handle of the defined user whose backup active state + * is to be adjusted. + * @param makeActive {@code true} when backup services are to be made active; + * {@code false} otherwise. + */ + void setBackupServiceActive(int whichUser, boolean makeActive); } diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl index 992f601..cd4535a 100644 --- a/core/java/android/bluetooth/IBluetooth.aidl +++ b/core/java/android/bluetooth/IBluetooth.aidl @@ -98,4 +98,7 @@ interface IBluetooth boolean isActivityAndEnergyReportingSupported(); void getActivityEnergyInfoFromController(); BluetoothActivityEnergyInfo reportActivityInfo(); + + // for dumpsys support + String dump(); } diff --git a/core/java/android/net/RssiCurve.java b/core/java/android/net/RssiCurve.java index f653f37..8ebe9e8 100644 --- a/core/java/android/net/RssiCurve.java +++ b/core/java/android/net/RssiCurve.java @@ -27,8 +27,8 @@ import java.util.Objects; * A curve defining the network score over a range of RSSI values. * * <p>For each RSSI bucket, the score may be any byte. Scores have no absolute meaning and are only - * considered relative to other scores assigned by the same scorer. Networks with no score are all - * considered equivalent and ranked below any network with a score. + * considered relative to other scores assigned by the same scorer. Networks with no score are + * treated equivalently to a network with score {@link Byte#MIN_VALUE}, and will not be used. * * <p>For example, consider a curve starting at -110 dBm with a bucket width of 10 and the * following buckets: {@code [-20, -10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120]}. @@ -52,6 +52,7 @@ import java.util.Objects; */ @SystemApi public class RssiCurve implements Parcelable { + private static final int DEFAULT_ACTIVE_NETWORK_RSSI_BOOST = 25; /** The starting dBm of the curve. */ public final int start; @@ -63,6 +64,15 @@ public class RssiCurve implements Parcelable { public final byte[] rssiBuckets; /** + * The RSSI boost to give this network when active, in dBm. + * + * <p>When the system is connected to this network, it will pretend that the network has this + * much higher of an RSSI. This is to avoid switching networks when another network has only a + * slightly higher score. + */ + public final int activeNetworkRssiBoost; + + /** * Construct a new {@link RssiCurve}. * * @param start the starting dBm of the curve. @@ -70,12 +80,25 @@ public class RssiCurve implements Parcelable { * @param rssiBuckets the score for each RSSI bucket. */ public RssiCurve(int start, int bucketWidth, byte[] rssiBuckets) { + this(start, bucketWidth, rssiBuckets, DEFAULT_ACTIVE_NETWORK_RSSI_BOOST); + } + + /** + * Construct a new {@link RssiCurve}. + * + * @param start the starting dBm of the curve. + * @param bucketWidth the width of each RSSI bucket, in dBm. + * @param rssiBuckets the score for each RSSI bucket. + * @param activeNetworkRssiBoost the RSSI boost to apply when this network is active, in dBm. + */ + public RssiCurve(int start, int bucketWidth, byte[] rssiBuckets, int activeNetworkRssiBoost) { this.start = start; this.bucketWidth = bucketWidth; if (rssiBuckets == null || rssiBuckets.length == 0) { throw new IllegalArgumentException("rssiBuckets must be at least one element large."); } this.rssiBuckets = rssiBuckets; + this.activeNetworkRssiBoost = activeNetworkRssiBoost; } private RssiCurve(Parcel in) { @@ -84,6 +107,7 @@ public class RssiCurve implements Parcelable { int bucketCount = in.readInt(); rssiBuckets = new byte[bucketCount]; in.readByteArray(rssiBuckets); + activeNetworkRssiBoost = in.readInt(); } @Override @@ -97,6 +121,7 @@ public class RssiCurve implements Parcelable { out.writeInt(bucketWidth); out.writeInt(rssiBuckets.length); out.writeByteArray(rssiBuckets); + out.writeInt(activeNetworkRssiBoost); } /** @@ -108,6 +133,23 @@ public class RssiCurve implements Parcelable { * @return the score for the given RSSI. */ public byte lookupScore(int rssi) { + return lookupScore(rssi, false /* isActiveNetwork */); + } + + /** + * Lookup the score for a given RSSI value. + * + * @param rssi The RSSI to lookup. If the RSSI falls below the start of the curve, the score at + * the start of the curve will be returned. If it falls after the end of the curve, the + * score at the end of the curve will be returned. + * @param isActiveNetwork Whether this network is currently active. + * @return the score for the given RSSI. + */ + public byte lookupScore(int rssi, boolean isActiveNetwork) { + if (isActiveNetwork) { + rssi += activeNetworkRssiBoost; + } + int index = (rssi - start) / bucketWidth; // Snap the index to the closest bucket if it falls outside the curve. @@ -136,12 +178,13 @@ public class RssiCurve implements Parcelable { return start == rssiCurve.start && bucketWidth == rssiCurve.bucketWidth && - Arrays.equals(rssiBuckets, rssiCurve.rssiBuckets); + Arrays.equals(rssiBuckets, rssiCurve.rssiBuckets) && + activeNetworkRssiBoost == rssiCurve.activeNetworkRssiBoost; } @Override public int hashCode() { - return Objects.hash(start, bucketWidth, rssiBuckets); + return Objects.hash(start, bucketWidth, rssiBuckets, activeNetworkRssiBoost); } @Override @@ -150,7 +193,9 @@ public class RssiCurve implements Parcelable { sb.append("RssiCurve[start=") .append(start) .append(",bucketWidth=") - .append(bucketWidth); + .append(bucketWidth) + .append(",activeNetworkRssiBoost=") + .append(activeNetworkRssiBoost); sb.append(",buckets="); for (int i = 0; i < rssiBuckets.length; i++) { diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 3234e77..8ffd8f4 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -371,6 +371,24 @@ public class UserManager { */ public static final String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam"; + /** + * Application restriction key that is used to indicate the pending arrival + * of real restrictions for the app. + * + * <p> + * Applications that support restrictions should check for the presence of this key. + * A <code>true</code> value indicates that restrictions may be applied in the near + * future but are not available yet. It is the responsibility of any + * management application that sets this flag to update it when the final + * restrictions are enforced. + * + * <p/>Key for application restrictions. + * <p/>Type: Boolean + * @see android.app.admin.DevicePolicyManager#addApplicationRestriction() + * @see android.app.admin.DevicePolicyManager#getApplicationRestriction() + */ + public static final String KEY_RESTRICTIONS_PENDING = "restrictions_pending"; + /** @hide */ public static final int PIN_VERIFICATION_FAILED_INCORRECT = -3; /** @hide */ diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1ea520d..88c3897 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4588,13 +4588,6 @@ public final class Settings { public static final String ANR_SHOW_BACKGROUND = "anr_show_background"; /** - * (Experimental). If nonzero, WebView uses data reduction proxy to save network - * bandwidth. Otherwise, WebView does not use data reduction proxy. - * @hide - */ - public static final String WEBVIEW_DATA_REDUCTION_PROXY = "webview_data_reduction_proxy"; - - /** * The {@link ComponentName} string of the service to be used as the voice recognition * service. * diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java index 00d60c0..d6c997f 100644 --- a/core/java/android/service/trust/TrustAgentService.java +++ b/core/java/android/service/trust/TrustAgentService.java @@ -94,31 +94,6 @@ public class TrustAgentService extends Service { private static final int MSG_TRUST_TIMEOUT = 3; /** - * Container class for a list of configuration options and helper methods - */ - public static final class Configuration { - public final List<PersistableBundle> options; - public Configuration(List<PersistableBundle> opts) { - options = opts; - } - - /** - * Very basic method to determine if all bundles have the given feature, regardless - * of type. - * @param option String to search for. - * @return true if found in all bundles. - */ - public boolean hasOption(String option) { - if (options == null || options.size() == 0) return false; - final int N = options.size(); - for (int i = 0; i < N; i++) { - if (!options.get(i).containsKey(option)) return false; - } - return true; - } - } - - /** * Class containing raw data for a given configuration request. */ private static final class ConfigurationData { @@ -147,7 +122,7 @@ public class TrustAgentService extends Service { break; case MSG_CONFIGURE: ConfigurationData data = (ConfigurationData) msg.obj; - boolean result = onConfigure(new Configuration(data.options)); + boolean result = onConfigure(data.options); try { synchronized (mLock) { mCallback.onConfigureCompleted(result, data.token); @@ -212,7 +187,7 @@ public class TrustAgentService extends Service { * @param options bundle containing all options or null if none. * @return true if the {@link TrustAgentService} supports configuration options. */ - public boolean onConfigure(Configuration options) { + public boolean onConfigure(List<PersistableBundle> options) { return false; } diff --git a/core/java/android/transition/ChangeTransform.java b/core/java/android/transition/ChangeTransform.java index 3fd28a6..a159b40 100644 --- a/core/java/android/transition/ChangeTransform.java +++ b/core/java/android/transition/ChangeTransform.java @@ -17,11 +17,14 @@ package android.transition; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.animation.FloatArrayEvaluator; import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; +import android.animation.PropertyValuesHolder; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Matrix; +import android.graphics.Path; +import android.graphics.PointF; import android.util.AttributeSet; import android.util.Property; import android.view.GhostView; @@ -56,16 +59,35 @@ public class ChangeTransform extends Transition { PROPNAME_PARENT_MATRIX, }; - private static final Property<View, Matrix> ANIMATION_MATRIX_PROPERTY = - new Property<View, Matrix>(Matrix.class, "animationMatrix") { + /** + * This property sets the animation matrix properties that are not translations. + */ + private static final Property<PathAnimatorMatrix, float[]> NON_TRANSLATIONS_PROPERTY = + new Property<PathAnimatorMatrix, float[]>(float[].class, "nonTranslations") { @Override - public Matrix get(View object) { + public float[] get(PathAnimatorMatrix object) { return null; } @Override - public void set(View object, Matrix value) { - object.setAnimationMatrix(value); + public void set(PathAnimatorMatrix object, float[] value) { + object.setValues(value); + } + }; + + /** + * This property sets the translation animation matrix properties. + */ + private static final Property<PathAnimatorMatrix, PointF> TRANSLATIONS_PROPERTY = + new Property<PathAnimatorMatrix, PointF>(PointF.class, "translations") { + @Override + public PointF get(PathAnimatorMatrix object) { + return null; + } + + @Override + public void set(PathAnimatorMatrix object, PointF value) { + object.setTranslation(value); } }; @@ -261,8 +283,23 @@ public class ChangeTransform extends Transition { final View view = endValues.view; setIdentityTransforms(view); - ObjectAnimator animator = ObjectAnimator.ofObject(view, ANIMATION_MATRIX_PROPERTY, - new TransitionUtils.MatrixEvaluator(), startMatrix, endMatrix); + final float[] startMatrixValues = new float[9]; + startMatrix.getValues(startMatrixValues); + final float[] endMatrixValues = new float[9]; + endMatrix.getValues(endMatrixValues); + final PathAnimatorMatrix pathAnimatorMatrix = + new PathAnimatorMatrix(view, startMatrixValues); + + PropertyValuesHolder valuesProperty = PropertyValuesHolder.ofObject( + NON_TRANSLATIONS_PROPERTY, new FloatArrayEvaluator(new float[9]), + startMatrixValues, endMatrixValues); + Path path = getPathMotion().getPath(startMatrixValues[Matrix.MTRANS_X], + startMatrixValues[Matrix.MTRANS_Y], endMatrixValues[Matrix.MTRANS_X], + endMatrixValues[Matrix.MTRANS_Y]); + PropertyValuesHolder translationProperty = PropertyValuesHolder.ofObject( + TRANSLATIONS_PROPERTY, null, path); + ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(pathAnimatorMatrix, + valuesProperty, translationProperty); final Matrix finalEndMatrix = endMatrix; @@ -285,14 +322,13 @@ public class ChangeTransform extends Transition { view.setTagInternal(R.id.parentMatrix, null); } } - ANIMATION_MATRIX_PROPERTY.set(view, null); + view.setAnimationMatrix(null); transforms.restore(view); } @Override public void onAnimationPause(Animator animation) { - ValueAnimator animator = (ValueAnimator) animation; - Matrix currentMatrix = (Matrix) animator.getAnimatedValue(); + Matrix currentMatrix = pathAnimatorMatrix.getMatrix(); setCurrentMatrix(currentMatrix); } @@ -457,4 +493,47 @@ public class ChangeTransform extends Transition { mGhostView.setVisibility(View.VISIBLE); } } + + /** + * PathAnimatorMatrix allows the translations and the rest of the matrix to be set + * separately. This allows the PathMotion to affect the translations while scale + * and rotation are evaluated separately. + */ + private static class PathAnimatorMatrix { + private final Matrix mMatrix = new Matrix(); + private final View mView; + private final float[] mValues; + private float mTranslationX; + private float mTranslationY; + + public PathAnimatorMatrix(View view, float[] values) { + mView = view; + mValues = values.clone(); + mTranslationX = mValues[Matrix.MTRANS_X]; + mTranslationY = mValues[Matrix.MTRANS_Y]; + setAnimationMatrix(); + } + + public void setValues(float[] values) { + System.arraycopy(values, 0, mValues, 0, values.length); + setAnimationMatrix(); + } + + public void setTranslation(PointF translation) { + mTranslationX = translation.x; + mTranslationY = translation.y; + setAnimationMatrix(); + } + + private void setAnimationMatrix() { + mValues[Matrix.MTRANS_X] = mTranslationX; + mValues[Matrix.MTRANS_Y] = mTranslationY; + mMatrix.setValues(mValues); + mView.setAnimationMatrix(mMatrix); + } + + public Matrix getMatrix() { + return mMatrix; + } + } } diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 1b57c24..b86455a 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -242,7 +242,7 @@ class GLES20Canvas extends HardwareCanvas { void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) { layer.setLayerPaint(paint); - nDrawLayer(mRenderer, layer.getLayer(), x, y); + nDrawLayer(mRenderer, layer.getLayerHandle(), x, y); } private static native void nDrawLayer(long renderer, long layer, float x, float y); diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java index 0c2e944..a130bda 100644 --- a/core/java/android/view/HardwareLayer.java +++ b/core/java/android/view/HardwareLayer.java @@ -126,8 +126,8 @@ final class HardwareLayer { mRenderer.detachSurfaceTexture(mFinalizer.get()); } - public long getLayer() { - return nGetLayer(mFinalizer.get()); + public long getLayerHandle() { + return mFinalizer.get(); } public void setSurfaceTexture(SurfaceTexture surface) { @@ -153,6 +153,5 @@ final class HardwareLayer { private static native void nUpdateRenderLayer(long layerUpdater, long displayList, int left, int top, int right, int bottom); - private static native long nGetLayer(long layerUpdater); private static native int nGetTexName(long layerUpdater); } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 6aa86c7..7b20e72 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -96,6 +96,7 @@ interface IWindowManager void overridePendingAppTransitionAspectScaledThumb(in Bitmap srcThumb, int startX, int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp); + void overridePendingAppTransitionInPlace(String packageName, int anim); void executeAppTransition(); void setAppStartingWindow(IBinder token, String pkg, int theme, in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 90fdbe2..19142b8 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -604,15 +604,6 @@ public class Surface implements Parcelable { mHwuiRenderer = 0; } } - - @Override - protected void finalize() throws Throwable { - try { - destroy(); - } finally { - super.finalize(); - } - } } private static native long nHwuiCreate(long rootNode, long surface); diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 00a8884..5579c13 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -66,6 +66,8 @@ public class ThreadedRenderer extends HardwareRenderer { private static final int SYNC_OK = 0; // Needs a ViewRoot invalidate private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0; + // Spoiler: the reward is GPU-accelerated drawing, better find that Surface! + private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1; private static final String[] VISUALIZERS = { PROFILE_PROPERTY_VISUALIZE_BARS, @@ -336,6 +338,12 @@ public class ThreadedRenderer extends HardwareRenderer { int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos, recordDuration, view.getResources().getDisplayMetrics().density); + if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) { + setEnabled(false); + // Invalidate since we failed to draw. This should fetch a Surface + // if it is still needed or do nothing if we are no longer drawing + attachInfo.mViewRootImpl.invalidate(); + } if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) { attachInfo.mViewRootImpl.invalidate(); } diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java index 45d1403..443884a 100644 --- a/core/java/android/widget/DateTimeView.java +++ b/core/java/android/widget/DateTimeView.java @@ -32,6 +32,7 @@ import android.widget.RemoteViews.RemoteView; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; // @@ -62,8 +63,8 @@ public class DateTimeView extends TextView { int mLastDisplay = -1; DateFormat mLastFormat; - private boolean mAttachedToWindow; private long mUpdateTimeMillis; + private static final ThreadLocal<ReceiverInfo> sReceiverInfo = new ThreadLocal<ReceiverInfo>(); public DateTimeView(Context context) { super(context); @@ -76,15 +77,21 @@ public class DateTimeView extends TextView { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - registerReceivers(); - mAttachedToWindow = true; + ReceiverInfo ri = sReceiverInfo.get(); + if (ri == null) { + ri = new ReceiverInfo(); + sReceiverInfo.set(ri); + } + ri.addView(this); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - unregisterReceivers(); - mAttachedToWindow = false; + final ReceiverInfo ri = sReceiverInfo.get(); + if (ri != null) { + ri.removeView(this); + } } @android.view.RemotableViewMethod @@ -204,49 +211,86 @@ public class DateTimeView extends TextView { } } - private void registerReceivers() { - Context context = getContext(); + void clearFormatAndUpdate() { + mLastFormat = null; + update(); + } - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_TIME_TICK); - filter.addAction(Intent.ACTION_TIME_CHANGED); - filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); - filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); - context.registerReceiver(mBroadcastReceiver, filter); + private static class ReceiverInfo { + private final ArrayList<DateTimeView> mAttachedViews = new ArrayList<DateTimeView>(); + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_TIME_TICK.equals(action)) { + if (System.currentTimeMillis() < getSoonestUpdateTime()) { + // The update() function takes a few milliseconds to run because of + // all of the time conversions it needs to do, so we can't do that + // every minute. + return; + } + } + // ACTION_TIME_CHANGED can also signal a change of 12/24 hr. format. + updateAll(); + } + }; - Uri uri = Settings.System.getUriFor(Settings.System.DATE_FORMAT); - context.getContentResolver().registerContentObserver(uri, true, mContentObserver); - } + private final ContentObserver mObserver = new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange) { + updateAll(); + } + }; - private void unregisterReceivers() { - Context context = getContext(); - context.unregisterReceiver(mBroadcastReceiver); - context.getContentResolver().unregisterContentObserver(mContentObserver); - } + public void addView(DateTimeView v) { + final boolean register = mAttachedViews.isEmpty(); + mAttachedViews.add(v); + if (register) { + register(v.getContext().getApplicationContext()); + } + } - private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intent.ACTION_TIME_TICK.equals(action)) { - if (System.currentTimeMillis() < mUpdateTimeMillis) { - // The update() function takes a few milliseconds to run because of - // all of the time conversions it needs to do, so we can't do that - // every minute. - return; + public void removeView(DateTimeView v) { + mAttachedViews.remove(v); + if (mAttachedViews.isEmpty()) { + unregister(v.getContext().getApplicationContext()); + } + } + + void updateAll() { + final int count = mAttachedViews.size(); + for (int i = 0; i < count; i++) { + mAttachedViews.get(i).clearFormatAndUpdate(); + } + } + + long getSoonestUpdateTime() { + long result = Long.MAX_VALUE; + final int count = mAttachedViews.size(); + for (int i = 0; i < count; i++) { + final long time = mAttachedViews.get(i).mUpdateTimeMillis; + if (time < result) { + result = time; } } - // ACTION_TIME_CHANGED can also signal a change of 12/24 hr. format. - mLastFormat = null; - update(); + return result; } - }; - private ContentObserver mContentObserver = new ContentObserver(new Handler()) { - @Override - public void onChange(boolean selfChange) { - mLastFormat = null; - update(); + void register(Context context) { + final IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_TIME_TICK); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + context.registerReceiver(mReceiver, filter); + + final Uri uri = Settings.System.getUriFor(Settings.System.DATE_FORMAT); + context.getContentResolver().registerContentObserver(uri, true, mObserver); } - }; + + void unregister(Context context) { + context.unregisterReceiver(mReceiver); + context.getContentResolver().unregisterContentObserver(mObserver); + } + } } diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java index 86f580d..b5338df 100644 --- a/core/java/com/android/internal/os/ProcessCpuTracker.java +++ b/core/java/com/android/internal/os/ProcessCpuTracker.java @@ -23,8 +23,11 @@ import android.os.Process; import android.os.StrictMode; import android.os.SystemClock; import android.util.Slog; + import com.android.internal.util.FastPrintWriter; +import libcore.io.IoUtils; + import java.io.File; import java.io.FileInputStream; import java.io.PrintWriter; @@ -325,7 +328,12 @@ public class ProcessCpuTracker { mBaseIdleTime = idletime; } - mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats); + final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads(); + try { + mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats); + } finally { + StrictMode.setThreadPolicy(savedPolicy); + } final float[] loadAverages = mLoadAverageData; if (Process.readProcFile("/proc/loadavg", LOAD_AVERAGE_FORMAT, @@ -847,12 +855,7 @@ public class ProcessCpuTracker { } catch (java.io.FileNotFoundException e) { } catch (java.io.IOException e) { } finally { - if (is != null) { - try { - is.close(); - } catch (java.io.IOException e) { - } - } + IoUtils.closeQuietly(is); StrictMode.setThreadPolicy(savedPolicy); } return null; diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 57472f8..a3c0db4 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -42,5 +42,6 @@ oneway interface IStatusBar void toggleRecentApps(); void preloadRecentApps(); void cancelPreloadRecentApps(); + void showScreenPinningRequest(); } diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java index d26f79e..7ad3470 100644 --- a/core/java/com/android/internal/util/StateMachine.java +++ b/core/java/com/android/internal/util/StateMachine.java @@ -1940,13 +1940,19 @@ public class StateMachine { * @param args */ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println(getName() + ":"); - pw.println(" total records=" + getLogRecCount()); + pw.println(this.toString()); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getName() + ":\n"); + sb.append(" total records=" + getLogRecCount() + "\n"); for (int i = 0; i < getLogRecSize(); i++) { - pw.printf(" rec[%d]: %s\n", i, getLogRec(i).toString()); - pw.flush(); + sb.append(" rec[" + i + "]: " + getLogRec(i).toString() + "\n"); } - pw.println("curState=" + getCurrentState().getName()); + sb.append("curState=" + getCurrentState().getName()); + return sb.toString(); } /** |
