diff options
59 files changed, 751 insertions, 1229 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index f0017b93fa81..ba2e4ecd53be 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -232,6 +232,7 @@ package android.content { package android.content.pm { public class ActivityInfo extends android.content.pm.ComponentInfo implements android.os.Parcelable { + method public static boolean isTranslucentOrFloating(android.content.res.TypedArray); field public static final int RESIZE_MODE_RESIZEABLE = 2; // 0x2 } diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index fcab8c10db9e..c58b91e39d0f 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1555,6 +1555,7 @@ public class AppOpsManager { private final long[] mRejectTimes; private final int mDuration; private final int mProxyUid; + private final boolean mRunning; private final String mProxyPackageName; public OpEntry(int op, int mode, long time, long rejectTime, int duration, @@ -1566,12 +1567,13 @@ public class AppOpsManager { mTimes[0] = time; mRejectTimes[0] = rejectTime; mDuration = duration; + mRunning = duration == -1; mProxyUid = proxyUid; mProxyPackageName = proxyPackage; } public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration, - int proxyUid, String proxyPackage) { + boolean running, int proxyUid, String proxyPackage) { mOp = op; mMode = mode; mTimes = new long[_NUM_UID_STATE]; @@ -1579,10 +1581,16 @@ public class AppOpsManager { System.arraycopy(times, 0, mTimes, 0, _NUM_UID_STATE); System.arraycopy(rejectTimes, 0, mRejectTimes, 0, _NUM_UID_STATE); mDuration = duration; + mRunning = running; mProxyUid = proxyUid; mProxyPackageName = proxyPackage; } + public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration, + int proxyUid, String proxyPackage) { + this(op, mode, times, rejectTimes, duration, duration == -1, proxyUid, proxyPackage); + } + public int getOp() { return mOp; } @@ -1632,7 +1640,7 @@ public class AppOpsManager { } public boolean isRunning() { - return mDuration == -1; + return mRunning; } public int getDuration() { @@ -1659,6 +1667,7 @@ public class AppOpsManager { dest.writeLongArray(mTimes); dest.writeLongArray(mRejectTimes); dest.writeInt(mDuration); + dest.writeBoolean(mRunning); dest.writeInt(mProxyUid); dest.writeString(mProxyPackageName); } @@ -1669,6 +1678,7 @@ public class AppOpsManager { mTimes = source.createLongArray(); mRejectTimes = source.createLongArray(); mDuration = source.readInt(); + mRunning = source.readBoolean(); mProxyUid = source.readInt(); mProxyPackageName = source.readString(); } diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java index 5e7584122dd6..4c22c94266d7 100644 --- a/core/java/android/app/slice/SliceProvider.java +++ b/core/java/android/app/slice/SliceProvider.java @@ -15,6 +15,8 @@ */ package android.app.slice; +import static android.app.slice.Slice.SUBTYPE_COLOR; + import android.annotation.NonNull; import android.app.PendingIntent; import android.content.ComponentName; @@ -29,6 +31,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ProviderInfo; import android.database.ContentObserver; import android.database.Cursor; +import android.graphics.drawable.Icon; import android.net.Uri; import android.os.Binder; import android.os.Bundle; @@ -39,6 +42,8 @@ import android.os.StrictMode; import android.os.StrictMode.ThreadPolicy; import android.util.ArraySet; import android.util.Log; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; import java.util.ArrayList; import java.util.Arrays; @@ -472,12 +477,25 @@ public abstract class SliceProvider extends ContentProvider { } Slice.Builder parent = new Slice.Builder(sliceUri); Slice.Builder childAction = new Slice.Builder(parent) + .addIcon(Icon.createWithResource(context, + com.android.internal.R.drawable.ic_permission), null, + Collections.emptyList()) .addHints(Arrays.asList(Slice.HINT_TITLE, Slice.HINT_SHORTCUT)) .addAction(action, new Slice.Builder(parent).build(), null); + TypedValue tv = new TypedValue(); + new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light) + .getTheme().resolveAttribute(android.R.attr.colorAccent, tv, true); + int deviceDefaultAccent = tv.data; + parent.addSubSlice(new Slice.Builder(sliceUri.buildUpon().appendPath("permission").build()) + .addIcon(Icon.createWithResource(context, + com.android.internal.R.drawable.ic_arrow_forward), null, + Collections.emptyList()) .addText(getPermissionString(context, callingPackage), null, Collections.emptyList()) + .addInt(deviceDefaultAccent, SUBTYPE_COLOR, + Collections.emptyList()) .addSubSlice(childAction.build(), null) .build(), null); return parent.addHints(Arrays.asList(Slice.HINT_PERMISSION_REQUEST)).build(); diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 14617116bc7f..0e91a2927c79 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -1188,6 +1188,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * Determines whether the {@link Activity} is considered translucent or floating. * @hide */ + @TestApi public static boolean isTranslucentOrFloating(TypedArray attributes) { final boolean isTranslucent = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 15aedd7cf502..63de8bf49f8b 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1664,7 +1664,8 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device includes at least one form of audio - * output, such as speakers, audio jack or streaming over bluetooth + * output, as defined in the Android Compatibility Definition Document (CDD) + * <a href="https://source.android.com/compatibility/android-cdd#7_8_audio">section 7.8 Audio</a>. */ @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output"; diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 0ae5394e6cb9..3d76c2501440 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -138,6 +138,15 @@ public class Binder implements IBinder { } /** + * Dump proxy debug information. + * + * @hide + */ + public static void dumpProxyDebugInfo() { + BinderProxy.dumpProxyDebugInfo(); + } + + /** * Check if binder transaction tracing is enabled. * * @hide @@ -941,8 +950,7 @@ final class BinderProxy implements IBinder { // about to crash. final int totalUnclearedSize = unclearedSize(); if (totalUnclearedSize >= CRASH_AT_SIZE) { - dumpProxyInterfaceCounts(); - dumpPerUidProxyCounts(); + dumpProxyDebugInfo(); Runtime.getRuntime().gc(); throw new AssertionError("Binder ProxyMap has too many entries: " + totalSize + " (total), " + totalUnclearedSize + " (uncleared), " @@ -1027,6 +1035,14 @@ final class BinderProxy implements IBinder { private static ProxyMap sProxyMap = new ProxyMap(); /** + * @hide + */ + public static void dumpProxyDebugInfo() { + sProxyMap.dumpProxyInterfaceCounts(); + sProxyMap.dumpPerUidProxyCounts(); + } + + /** * Return a BinderProxy for IBinder. * This method is thread-hostile! The (native) caller serializes getInstance() calls using * gProxyLock. diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index 2d8b4d482b21..c86149907323 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -43,7 +43,7 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put("settings_bluetooth_while_driving", "false"); DEFAULT_FLAGS.put("settings_data_usage_v2", "true"); DEFAULT_FLAGS.put("settings_audio_switcher", "true"); - DEFAULT_FLAGS.put("settings_systemui_theme", "false"); + DEFAULT_FLAGS.put("settings_systemui_theme", "true"); } /** diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 7c814f4a5773..ed67075d38d6 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1630,6 +1630,8 @@ public final class ViewRootImpl implements ViewParent, contentInsets.top + outsets.top, contentInsets.right + outsets.right, contentInsets.bottom + outsets.bottom); } + contentInsets = ensureInsetsNonNegative(contentInsets, "content"); + stableInsets = ensureInsetsNonNegative(stableInsets, "stable"); mLastWindowInsets = new WindowInsets(contentInsets, null /* windowDecorInsets */, stableInsets, mContext.getResources().getConfiguration().isScreenRound(), @@ -1638,6 +1640,17 @@ public final class ViewRootImpl implements ViewParent, return mLastWindowInsets; } + private Rect ensureInsetsNonNegative(Rect insets, String kind) { + if (insets.left < 0 || insets.top < 0 || insets.right < 0 || insets.bottom < 0) { + Log.wtf(mTag, "Negative " + kind + "Insets: " + insets + ", mFirst=" + mFirst); + return new Rect(Math.max(0, insets.left), + Math.max(0, insets.top), + Math.max(0, insets.right), + Math.max(0, insets.bottom)); + } + return insets; + } + void dispatchApplyInsets(View host) { WindowInsets insets = getWindowInsets(true /* forceConstruct */); final boolean dispatchCutout = (mWindowAttributes.layoutInDisplayCutoutMode diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java index 294007946c77..9171959537c8 100644 --- a/core/java/com/android/internal/app/AssistUtils.java +++ b/core/java/com/android/internal/app/AssistUtils.java @@ -156,9 +156,12 @@ public class AssistUtils { if (activeServiceSupportsAssistGesture()) { return getActiveServiceComponentName(); } - - Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) - .getAssistIntent(false); + final SearchManager searchManager = + (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); + if (searchManager == null) { + return null; + } + final Intent intent = searchManager.getAssistIntent(false); PackageManager pm = mContext.getPackageManager(); ResolveInfo info = pm.resolveActivityAsUser(intent, PackageManager.MATCH_DEFAULT_ONLY, userId); diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 571878d183ee..4f567d239896 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -76,6 +76,7 @@ import android.widget.Space; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.ResolverActivity; import com.android.internal.app.ResolverActivity.TargetInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -932,7 +933,7 @@ public class ChooserActivity extends ResolverActivity { public static final int TARGET_SERVICE = 1; public static final int TARGET_STANDARD = 2; - private static final int MAX_SERVICE_TARGETS = 8; + private static final int MAX_SERVICE_TARGETS = 4; private static final int MAX_TARGETS_PER_SERVICE = 4; private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>(); @@ -1189,123 +1190,20 @@ public class ChooserActivity extends ResolverActivity { } } - static class RowScale { - private static final int DURATION = 400; - - float mScale; - ChooserRowAdapter mAdapter; - private final ObjectAnimator mAnimator; - - public static final FloatProperty<RowScale> PROPERTY = - new FloatProperty<RowScale>("scale") { - @Override - public void setValue(RowScale object, float value) { - object.mScale = value; - object.mAdapter.notifyDataSetChanged(); - } - - @Override - public Float get(RowScale object) { - return object.mScale; - } - }; - - public RowScale(@NonNull ChooserRowAdapter adapter, float from, float to) { - mAdapter = adapter; - mScale = from; - if (from == to) { - mAnimator = null; - return; - } - - mAnimator = ObjectAnimator.ofFloat(this, PROPERTY, from, to) - .setDuration(DURATION); - mAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - mAdapter.onAnimationStart(); - } - @Override - public void onAnimationEnd(Animator animation) { - mAdapter.onAnimationEnd(); - } - }); - } - - public RowScale setInterpolator(Interpolator interpolator) { - if (mAnimator != null) { - mAnimator.setInterpolator(interpolator); - } - return this; - } - - public float get() { - return mScale; - } - - public void startAnimation() { - if (mAnimator != null) { - mAnimator.start(); - } - } - - public void cancelAnimation() { - if (mAnimator != null) { - mAnimator.cancel(); - } - } - } - class ChooserRowAdapter extends BaseAdapter { private ChooserListAdapter mChooserListAdapter; private final LayoutInflater mLayoutInflater; private final int mColumnCount = 4; - private RowScale[] mServiceTargetScale; - private final Interpolator mInterpolator; private int mAnimationCount = 0; public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) { mChooserListAdapter = wrappedAdapter; mLayoutInflater = LayoutInflater.from(ChooserActivity.this); - mInterpolator = AnimationUtils.loadInterpolator(ChooserActivity.this, - android.R.interpolator.decelerate_quint); - wrappedAdapter.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { super.onChanged(); - final int rcount = getServiceTargetRowCount(); - if (mServiceTargetScale == null - || mServiceTargetScale.length != rcount) { - RowScale[] old = mServiceTargetScale; - int oldRCount = old != null ? old.length : 0; - mServiceTargetScale = new RowScale[rcount]; - if (old != null && rcount > 0) { - System.arraycopy(old, 0, mServiceTargetScale, 0, - Math.min(old.length, rcount)); - } - - for (int i = rcount; i < oldRCount; i++) { - old[i].cancelAnimation(); - } - - for (int i = oldRCount; i < rcount; i++) { - final RowScale rs = new RowScale(ChooserRowAdapter.this, 0.f, 1.f) - .setInterpolator(mInterpolator); - mServiceTargetScale[i] = rs; - } - - // Start the animations in a separate loop. - // The process of starting animations will result in - // binding views to set up initial values, and we must - // have ALL of the new RowScale objects created above before - // we get started. - for (int i = oldRCount; i < rcount; i++) { - mServiceTargetScale[i].startAnimation(); - } - } - notifyDataSetChanged(); } @@ -1313,39 +1211,10 @@ public class ChooserActivity extends ResolverActivity { public void onInvalidated() { super.onInvalidated(); notifyDataSetInvalidated(); - if (mServiceTargetScale != null) { - for (RowScale rs : mServiceTargetScale) { - rs.cancelAnimation(); - } - } } }); } - private float getRowScale(int rowPosition) { - final int start = getCallerTargetRowCount(); - final int end = start + getServiceTargetRowCount(); - if (rowPosition >= start && rowPosition < end) { - return mServiceTargetScale[rowPosition - start].get(); - } - return 1.f; - } - - public void onAnimationStart() { - final boolean lock = mAnimationCount == 0; - mAnimationCount++; - if (lock) { - mResolverDrawerLayout.setDismissLocked(true); - } - } - - public void onAnimationEnd() { - mAnimationCount--; - if (mAnimationCount == 0) { - mResolverDrawerLayout.setDismissLocked(false); - } - } - @Override public int getCount() { return (int) ( @@ -1360,9 +1229,9 @@ public class ChooserActivity extends ResolverActivity { (float) mChooserListAdapter.getCallerTargetCount() / mColumnCount); } + // There can be at most one row of service targets. public int getServiceTargetRowCount() { - return (int) Math.ceil( - (float) mChooserListAdapter.getServiceTargetCount() / mColumnCount); + return (int) mChooserListAdapter.getServiceTargetCount() == 0 ? 0 : 1; } @Override @@ -1485,8 +1354,7 @@ public class ChooserActivity extends ResolverActivity { } final int oldHeight = holder.row.getLayoutParams().height; - holder.row.getLayoutParams().height = Math.max(1, - (int) (holder.measuredRowHeight * getRowScale(rowPosition))); + holder.row.getLayoutParams().height = Math.max(1, holder.measuredRowHeight); if (holder.row.getLayoutParams().height != oldHeight) { holder.row.requestLayout(); } @@ -1728,7 +1596,7 @@ public class ChooserActivity extends ResolverActivity { final View v = mChooserRowAdapter.getView(pos, mCachedView, mListView); int height = ((RowViewHolder) (v.getTag())).measuredRowHeight; - offset += (int) (height * mChooserRowAdapter.getRowScale(pos)); + offset += (int) (height); if (vt >= 0) { mCachedViewType = vt; diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java index d1350403b32c..c9a916187d33 100644 --- a/core/java/com/android/internal/widget/MessagingGroup.java +++ b/core/java/com/android/internal/widget/MessagingGroup.java @@ -100,7 +100,6 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou super.onFinishInflate(); mMessageContainer = findViewById(R.id.group_message_container); mSenderName = findViewById(R.id.message_name); - mSenderName.addOnLayoutChangeListener(MessagingLayout.MESSAGING_PROPERTY_ANIMATOR); mAvatarView = findViewById(R.id.message_icon); mImageContainer = findViewById(R.id.messaging_group_icon_container); mSendingSpinner = findViewById(R.id.messaging_group_sending_progress); @@ -190,73 +189,66 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou } public void removeMessage(MessagingMessage messagingMessage) { - ViewGroup messageParent = (ViewGroup) messagingMessage.getView().getParent(); - messageParent.removeView(messagingMessage.getView()); + View view = messagingMessage.getView(); + boolean wasShown = view.isShown(); + ViewGroup messageParent = (ViewGroup) view.getParent(); + if (messageParent == null) { + return; + } + messageParent.removeView(view); Runnable recycleRunnable = () -> { - messageParent.removeTransientView(messagingMessage.getView()); + messageParent.removeTransientView(view); messagingMessage.recycle(); - if (mMessageContainer.getChildCount() == 0 - && mMessageContainer.getTransientViewCount() == 0 - && mImageContainer.getChildCount() == 0) { - ViewParent parent = getParent(); - if (parent instanceof ViewGroup) { - ((ViewGroup) parent).removeView(MessagingGroup.this); - } - setAvatar(null); - mAvatarView.setAlpha(1.0f); - mAvatarView.setTranslationY(0.0f); - mSenderName.setAlpha(1.0f); - mSenderName.setTranslationY(0.0f); - mIsolatedMessage = null; - mMessages = null; - sInstancePool.release(MessagingGroup.this); - } }; - if (isShown()) { - messageParent.addTransientView(messagingMessage.getView(), 0); - performRemoveAnimation(messagingMessage.getView(), recycleRunnable); - if (mMessageContainer.getChildCount() == 0 - && mImageContainer.getChildCount() == 0) { - removeGroupAnimated(null); - } + if (wasShown && !MessagingLinearLayout.isGone(view)) { + messageParent.addTransientView(view, 0); + performRemoveAnimation(view, recycleRunnable); } else { recycleRunnable.run(); } - } - private void removeGroupAnimated(Runnable endAction) { - performRemoveAnimation(mAvatarView, null); - performRemoveAnimation(mSenderName, null); - boolean endActionTriggered = false; - for (int i = mMessageContainer.getChildCount() - 1; i >= 0; i--) { - View child = mMessageContainer.getChildAt(i); - if (child.getVisibility() == View.GONE) { - continue; - } - final ViewGroup.LayoutParams lp = child.getLayoutParams(); - if (lp instanceof MessagingLinearLayout.LayoutParams - && ((MessagingLinearLayout.LayoutParams) lp).hide - && !((MessagingLinearLayout.LayoutParams) lp).visibleBefore) { - continue; - } - Runnable childEndAction = endActionTriggered ? null : endAction; - performRemoveAnimation(child, childEndAction); - endActionTriggered = true; - } + public void recycle() { if (mIsolatedMessage != null) { - performRemoveAnimation(mIsolatedMessage, !endActionTriggered ? endAction : null); - endActionTriggered = true; + mImageContainer.removeView(mIsolatedMessage); } - if (!endActionTriggered && endAction != null) { - endAction.run(); + for (int i = 0; i < mMessages.size(); i++) { + MessagingMessage message = mMessages.get(i); + mMessageContainer.removeView(message.getView()); + message.recycle(); } + setAvatar(null); + mAvatarView.setAlpha(1.0f); + mAvatarView.setTranslationY(0.0f); + mSenderName.setAlpha(1.0f); + mSenderName.setTranslationY(0.0f); + setAlpha(1.0f); + mIsolatedMessage = null; + mMessages = null; + mAddedMessages.clear(); + mFirstLayout = true; + MessagingPropertyAnimator.recycle(this); + sInstancePool.release(MessagingGroup.this); + } + + public void removeGroupAnimated(Runnable endAction) { + performRemoveAnimation(this, () -> { + setAlpha(1.0f); + MessagingPropertyAnimator.setToLaidOutPosition(this); + if (endAction != null) { + endAction.run(); + } + }); } public void performRemoveAnimation(View message, Runnable endAction) { - MessagingPropertyAnimator.fadeOut(message, endAction); - MessagingPropertyAnimator.startLocalTranslationTo(message, - (int) (-getHeight() * 0.5f), MessagingLayout.FAST_OUT_LINEAR_IN); + performRemoveAnimation(message, -message.getHeight(), endAction); + } + + private void performRemoveAnimation(View view, int disappearTranslation, Runnable endAction) { + MessagingPropertyAnimator.startLocalTranslationTo(view, disappearTranslation, + MessagingLayout.FAST_OUT_LINEAR_IN); + MessagingPropertyAnimator.fadeOut(view, endAction); } public CharSequence getSenderName() { @@ -341,6 +333,11 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou } } + @Override + public boolean hasOverlappingRendering() { + return false; + } + public Icon getAvatarSymbolIfMatching(CharSequence avatarName, String avatarSymbol, int layoutColor) { if (mAvatarName.equals(avatarName) && mAvatarSymbol.equals(avatarSymbol) @@ -458,6 +455,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (!mAddedMessages.isEmpty()) { + final boolean firstLayout = mFirstLayout; getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { @@ -466,7 +464,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou continue; } MessagingPropertyAnimator.fadeIn(message.getView()); - if (!mFirstLayout) { + if (!firstLayout) { MessagingPropertyAnimator.startLocalTranslationFrom(message.getView(), message.getView().getHeight(), MessagingLayout.LINEAR_OUT_SLOW_IN); diff --git a/core/java/com/android/internal/widget/MessagingImageMessage.java b/core/java/com/android/internal/widget/MessagingImageMessage.java index 9db74e82e382..607a3a9ab542 100644 --- a/core/java/com/android/internal/widget/MessagingImageMessage.java +++ b/core/java/com/android/internal/widget/MessagingImageMessage.java @@ -170,8 +170,6 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage public void recycle() { MessagingMessage.super.recycle(); - setAlpha(1.0f); - setTranslationY(0); setImageBitmap(null); mDrawable = null; sInstancePool.release(this); diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java index 03a734d8537e..0fd610908fd5 100644 --- a/core/java/com/android/internal/widget/MessagingLayout.java +++ b/core/java/com/android/internal/widget/MessagingLayout.java @@ -180,8 +180,13 @@ public class MessagingLayout extends FrameLayout { List<MessagingMessage> historicMessages = createMessages(newHistoricMessages, true /* isHistoric */); List<MessagingMessage> messages = createMessages(newMessages, false /* isHistoric */); + + ArrayList<MessagingGroup> oldGroups = new ArrayList<>(mGroups); addMessagesToGroups(historicMessages, messages, showSpinner); + // Let's first check which groups were removed altogether and remove them in one animation + removeGroups(oldGroups); + // Let's remove the remaining messages mMessages.forEach(REMOVE_MESSAGE); mHistoricMessages.forEach(REMOVE_MESSAGE); @@ -193,6 +198,31 @@ public class MessagingLayout extends FrameLayout { updateTitleAndNamesDisplay(); } + private void removeGroups(ArrayList<MessagingGroup> oldGroups) { + int size = oldGroups.size(); + for (int i = 0; i < size; i++) { + MessagingGroup group = oldGroups.get(i); + if (!mGroups.contains(group)) { + List<MessagingMessage> messages = group.getMessages(); + Runnable endRunnable = () -> { + mMessagingLinearLayout.removeTransientView(group); + group.recycle(); + }; + + boolean wasShown = group.isShown(); + mMessagingLinearLayout.removeView(group); + if (wasShown && !MessagingLinearLayout.isGone(group)) { + mMessagingLinearLayout.addTransientView(group, 0); + group.removeGroupAnimated(endRunnable); + } else { + endRunnable.run(); + } + mMessages.removeAll(messages); + mHistoricMessages.removeAll(messages); + } + } + } + private void updateTitleAndNamesDisplay() { ArrayMap<CharSequence, String> uniqueNames = new ArrayMap<>(); ArrayMap<Character, CharSequence> uniqueCharacters = new ArrayMap<>(); diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java index 991e3e7a80f9..64b1f241464b 100644 --- a/core/java/com/android/internal/widget/MessagingLinearLayout.java +++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java @@ -163,15 +163,6 @@ public class MessagingLinearLayout extends ViewGroup { } final LayoutParams lp = (LayoutParams) child.getLayoutParams(); MessagingChild messagingChild = (MessagingChild) child; - if (lp.hide) { - if (shown && lp.visibleBefore) { - messagingChild.hideAnimated(); - } - lp.visibleBefore = false; - continue; - } else { - lp.visibleBefore = true; - } final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); @@ -182,6 +173,19 @@ public class MessagingLinearLayout extends ViewGroup { } else { childLeft = paddingLeft + lp.leftMargin; } + if (lp.hide) { + if (shown && lp.visibleBefore) { + // We still want to lay out the child to have great animations + child.layout(childLeft, childTop, childLeft + childWidth, + childTop + lp.lastVisibleHeight); + messagingChild.hideAnimated(); + } + lp.visibleBefore = false; + continue; + } else { + lp.visibleBefore = true; + lp.lastVisibleHeight = childHeight; + } if (!first) { childTop += mSpacing; @@ -228,6 +232,18 @@ public class MessagingLinearLayout extends ViewGroup { return copy; } + public static boolean isGone(View view) { + if (view.getVisibility() == View.GONE) { + return true; + } + final ViewGroup.LayoutParams lp = view.getLayoutParams(); + if (lp instanceof MessagingLinearLayout.LayoutParams + && ((MessagingLinearLayout.LayoutParams) lp).hide) { + return true; + } + return false; + } + /** * Sets how many lines should be displayed at most */ @@ -263,6 +279,7 @@ public class MessagingLinearLayout extends ViewGroup { public boolean hide = false; public boolean visibleBefore = false; + public int lastVisibleHeight; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); diff --git a/core/java/com/android/internal/widget/MessagingMessage.java b/core/java/com/android/internal/widget/MessagingMessage.java index ffcb50309feb..74d0aae3634b 100644 --- a/core/java/com/android/internal/widget/MessagingMessage.java +++ b/core/java/com/android/internal/widget/MessagingMessage.java @@ -124,8 +124,7 @@ public interface MessagingMessage extends MessagingLinearLayout.MessagingChild { @Override default void hideAnimated() { setIsHidingAnimated(true); - getGroup().performRemoveAnimation(getState().getHostView(), - () -> setIsHidingAnimated(false)); + getGroup().performRemoveAnimation(getView(), () -> setIsHidingAnimated(false)); } default boolean hasOverlappingRendering() { @@ -133,7 +132,7 @@ public interface MessagingMessage extends MessagingLinearLayout.MessagingChild { } default void recycle() { - getState().reset(); + getState().recycle(); } default View getView() { diff --git a/core/java/com/android/internal/widget/MessagingMessageState.java b/core/java/com/android/internal/widget/MessagingMessageState.java index ac624728689d..1ba2b51dec44 100644 --- a/core/java/com/android/internal/widget/MessagingMessageState.java +++ b/core/java/com/android/internal/widget/MessagingMessageState.java @@ -72,7 +72,10 @@ public class MessagingMessageState { return mHostView; } - public void reset() { + public void recycle() { + mHostView.setAlpha(1.0f); + mHostView.setTranslationY(0); + MessagingPropertyAnimator.recycle(mHostView); mIsHidingAnimated = false; mIsHistoric = false; mGroup = null; diff --git a/core/java/com/android/internal/widget/MessagingPropertyAnimator.java b/core/java/com/android/internal/widget/MessagingPropertyAnimator.java index 7c3ab7f9547f..7703cb0f13db 100644 --- a/core/java/com/android/internal/widget/MessagingPropertyAnimator.java +++ b/core/java/com/android/internal/widget/MessagingPropertyAnimator.java @@ -31,111 +31,125 @@ import com.android.internal.R; * A listener that automatically starts animations when the layout bounds change. */ public class MessagingPropertyAnimator implements View.OnLayoutChangeListener { - static final long APPEAR_ANIMATION_LENGTH = 210; + private static final long APPEAR_ANIMATION_LENGTH = 210; private static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f); public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f); - private static final int TAG_LOCAL_TRANSLATION_ANIMATOR = R.id.tag_local_translation_y_animator; - private static final int TAG_LOCAL_TRANSLATION_Y = R.id.tag_local_translation_y; + private static final int TAG_TOP_ANIMATOR = R.id.tag_top_animator; + private static final int TAG_TOP = R.id.tag_top_override; private static final int TAG_LAYOUT_TOP = R.id.tag_layout_top; + private static final int TAG_FIRST_LAYOUT = R.id.tag_is_first_layout; private static final int TAG_ALPHA_ANIMATOR = R.id.tag_alpha_animator; private static final ViewClippingUtil.ClippingParameters CLIPPING_PARAMETERS = view -> view.getId() == com.android.internal.R.id.notification_messaging; - private static final IntProperty<View> LOCAL_TRANSLATION_Y = - new IntProperty<View>("localTranslationY") { + private static final IntProperty<View> TOP = + new IntProperty<View>("top") { @Override public void setValue(View object, int value) { - setLocalTranslationY(object, value); + setTop(object, value); } @Override public Integer get(View object) { - return getLocalTranslationY(object); + return getTop(object); } }; @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { - int oldHeight = oldBottom - oldTop; - Integer layoutTop = (Integer) v.getTag(TAG_LAYOUT_TOP); - if (layoutTop != null) { - oldTop = layoutTop; - } - int topChange = oldTop - top; - if (oldHeight == 0 || topChange == 0 || !v.isShown() || isGone(v)) { - // First layout + setLayoutTop(v, top); + if (isFirstLayout(v)) { + setFirstLayout(v, false /* first */); + setTop(v, top); return; } - if (layoutTop != null) { - v.setTagInternal(TAG_LAYOUT_TOP, top); - } - int newHeight = bottom - top; - int heightDifference = oldHeight - newHeight; - // Only add the difference if the height changes and it's getting smaller - heightDifference = Math.max(heightDifference, 0); - startLocalTranslationFrom(v, topChange + heightDifference + getLocalTranslationY(v)); + startTopAnimation(v, getTop(v), top, MessagingLayout.FAST_OUT_SLOW_IN); } - private boolean isGone(View view) { - if (view.getVisibility() == View.GONE) { - return true; - } - final ViewGroup.LayoutParams lp = view.getLayoutParams(); - if (lp instanceof MessagingLinearLayout.LayoutParams - && ((MessagingLinearLayout.LayoutParams) lp).hide) { + private static boolean isFirstLayout(View view) { + Boolean tag = (Boolean) view.getTag(TAG_FIRST_LAYOUT); + if (tag == null) { return true; } - return false; + return tag; } - public static void startLocalTranslationFrom(View v, int startTranslation) { - startLocalTranslationFrom(v, startTranslation, MessagingLayout.FAST_OUT_SLOW_IN); + public static void recycle(View view) { + setFirstLayout(view, true /* first */); } - public static void startLocalTranslationFrom(View v, int startTranslation, + private static void setFirstLayout(View view, boolean first) { + view.setTagInternal(TAG_FIRST_LAYOUT, first); + } + + private static void setLayoutTop(View view, int top) { + view.setTagInternal(TAG_LAYOUT_TOP, top); + } + + public static int getLayoutTop(View view) { + Integer tag = (Integer) view.getTag(TAG_LAYOUT_TOP); + if (tag == null) { + return getTop(view); + } + return tag; + } + + /** + * Start a translation animation from a start offset to the laid out location + * @param view The view to animate + * @param startTranslation The starting translation to start from. + * @param interpolator The interpolator to use. + */ + public static void startLocalTranslationFrom(View view, int startTranslation, Interpolator interpolator) { - startLocalTranslation(v, startTranslation, 0, interpolator); + startTopAnimation(view, getTop(view) + startTranslation, getLayoutTop(view), interpolator); } - public static void startLocalTranslationTo(View v, int endTranslation, + /** + * Start a translation animation from a start offset to the laid out location + * @param view The view to animate + * @param endTranslation The end translation to go to. + * @param interpolator The interpolator to use. + */ + public static void startLocalTranslationTo(View view, int endTranslation, Interpolator interpolator) { - startLocalTranslation(v, getLocalTranslationY(v), endTranslation, interpolator); + int top = getTop(view); + startTopAnimation(view, top, top + endTranslation, interpolator); } - public static int getLocalTranslationY(View v) { - Integer tag = (Integer) v.getTag(TAG_LOCAL_TRANSLATION_Y); + public static int getTop(View v) { + Integer tag = (Integer) v.getTag(TAG_TOP); if (tag == null) { - return 0; + return v.getTop(); } return tag; } - private static void setLocalTranslationY(View v, int value) { - v.setTagInternal(TAG_LOCAL_TRANSLATION_Y, value); + private static void setTop(View v, int value) { + v.setTagInternal(TAG_TOP, value); updateTopAndBottom(v); } private static void updateTopAndBottom(View v) { - int layoutTop = (int) v.getTag(TAG_LAYOUT_TOP); - int localTranslation = getLocalTranslationY(v); + int top = getTop(v); int height = v.getHeight(); - v.setTop(layoutTop + localTranslation); - v.setBottom(layoutTop + height + localTranslation); + v.setTop(top); + v.setBottom(height + top); } - private static void startLocalTranslation(final View v, int start, int end, + private static void startTopAnimation(final View v, int start, int end, Interpolator interpolator) { - ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_LOCAL_TRANSLATION_ANIMATOR); + ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_TOP_ANIMATOR); if (existing != null) { existing.cancel(); } - ObjectAnimator animator = ObjectAnimator.ofInt(v, LOCAL_TRANSLATION_Y, start, end); - Integer layoutTop = (Integer) v.getTag(TAG_LAYOUT_TOP); - if (layoutTop == null) { - layoutTop = v.getTop(); - v.setTagInternal(TAG_LAYOUT_TOP, layoutTop); + if (!v.isShown() || start == end + || (MessagingLinearLayout.isGone(v) && !isHidingAnimated(v))) { + setTop(v, end); + return; } - setLocalTranslationY(v, start); + ObjectAnimator animator = ObjectAnimator.ofInt(v, TOP, start, end); + setTop(v, start); animator.setInterpolator(interpolator); animator.setDuration(APPEAR_ANIMATION_LENGTH); animator.addListener(new AnimatorListenerAdapter() { @@ -143,12 +157,8 @@ public class MessagingPropertyAnimator implements View.OnLayoutChangeListener { @Override public void onAnimationEnd(Animator animation) { - v.setTagInternal(TAG_LOCAL_TRANSLATION_ANIMATOR, null); + v.setTagInternal(TAG_TOP_ANIMATOR, null); setClippingDeactivated(v, false); - if (!mCancelled) { - setLocalTranslationY(v, 0); - v.setTagInternal(TAG_LAYOUT_TOP, null); - } } @Override @@ -157,10 +167,17 @@ public class MessagingPropertyAnimator implements View.OnLayoutChangeListener { } }); setClippingDeactivated(v, true); - v.setTagInternal(TAG_LOCAL_TRANSLATION_ANIMATOR, animator); + v.setTagInternal(TAG_TOP_ANIMATOR, animator); animator.start(); } + private static boolean isHidingAnimated(View v) { + if (v instanceof MessagingLinearLayout.MessagingChild) { + return ((MessagingLinearLayout.MessagingChild) v).isHidingAnimated(); + } + return false; + } + public static void fadeIn(final View v) { ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_ALPHA_ANIMATOR); if (existing != null) { @@ -199,6 +216,13 @@ public class MessagingPropertyAnimator implements View.OnLayoutChangeListener { if (existing != null) { existing.cancel(); } + if (!view.isShown() || (MessagingLinearLayout.isGone(view) && !isHidingAnimated(view))) { + view.setAlpha(0.0f); + if (endAction != null) { + endAction.run(); + } + return; + } ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), 0.0f); animator.setInterpolator(ALPHA_OUT); @@ -224,10 +248,14 @@ public class MessagingPropertyAnimator implements View.OnLayoutChangeListener { } public static boolean isAnimatingTranslation(View v) { - return v.getTag(TAG_LOCAL_TRANSLATION_ANIMATOR) != null; + return v.getTag(TAG_TOP_ANIMATOR) != null; } public static boolean isAnimatingAlpha(View v) { return v.getTag(TAG_ALPHA_ANIMATOR) != null; } + + public static void setToLaidOutPosition(View view) { + setTop(view, getLayoutTop(view)); + } } diff --git a/core/java/com/android/internal/widget/MessagingTextMessage.java b/core/java/com/android/internal/widget/MessagingTextMessage.java index 219116e414f1..4081a866f993 100644 --- a/core/java/com/android/internal/widget/MessagingTextMessage.java +++ b/core/java/com/android/internal/widget/MessagingTextMessage.java @@ -92,8 +92,6 @@ public class MessagingTextMessage extends ImageFloatingTextView implements Messa public void recycle() { MessagingMessage.super.recycle(); - setAlpha(1.0f); - setTranslationY(0); sInstancePool.release(this); } diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto index 418e15be8504..9d2458863c9f 100644 --- a/core/proto/android/server/activitymanagerservice.proto +++ b/core/proto/android/server/activitymanagerservice.proto @@ -117,6 +117,7 @@ message ActivityRecordProto { optional bool visible = 4; optional bool front_of_task = 5; optional int32 proc_id = 6; + optional bool translucent = 7; } message KeyguardControllerProto { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 19e5e21d5093..dced0ad35c5f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -850,7 +850,7 @@ <!-- Used for permissions that are associated telephony features. --> <permission-group android:name="android.permission-group.CALL_LOG" - android:icon="@drawable/perm_group_phone_calls" + android:icon="@drawable/perm_group_call_log" android:label="@string/permgrouplab_calllog" android:description="@string/permgroupdesc_calllog" android:request="@string/permgrouprequest_calllog" diff --git a/core/res/res/drawable/ic_arrow_forward.xml b/core/res/res/drawable/ic_arrow_forward.xml new file mode 100644 index 000000000000..f1085703ef13 --- /dev/null +++ b/core/res/res/drawable/ic_arrow_forward.xml @@ -0,0 +1,24 @@ +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M12.0,4.0l-1.41,1.41L16.17,11.0L4.0,11.0l0.0,2.0l12.17,0.0l-5.58,5.59L12.0,20.0l8.0,-8.0z"/> +</vector> diff --git a/core/res/res/drawable/ic_permission.xml b/core/res/res/drawable/ic_permission.xml new file mode 100644 index 000000000000..00523509fcae --- /dev/null +++ b/core/res/res/drawable/ic_permission.xml @@ -0,0 +1,26 @@ +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="16.0" + android:viewportHeight="16.0"> + <path + android:fillColor="#FF000000" + android:pathData=" + M9.0,12l-2.0,0.0l0.0,-2.0l2.0,0.0l0.0,2.0z + m0.0,-4.0l-2.0,0.0l0.0,-4.0l2.0,0.0l0.0,4.0z"/> +</vector> diff --git a/core/res/res/drawable/perm_group_call_log.xml b/core/res/res/drawable/perm_group_call_log.xml new file mode 100644 index 000000000000..0dfdbee4e600 --- /dev/null +++ b/core/res/res/drawable/perm_group_call_log.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#000000" + android:pathData="M16.01,14.48l-2.62,2.62c-2.75,-1.49 -5.01,-3.75 -6.5,-6.5l2.62,-2.62c0.24,-0.24 0.34,-0.58 0.27,-0.9L9.13,3.82c-0.09,-0.47 -0.5,-0.8 -0.98,-0.8L4,3.01c-0.56,0 -1.03,0.47 -1,1.03c0.17,2.91 1.04,5.63 2.43,8.01c1.57,2.69 3.81,4.93 6.5,6.5c2.38,1.39 5.1,2.26 8.01,2.43c0.56,0.03 1.03,-0.44 1.03,-1v-4.15c0,-0.48 -0.34,-0.89 -0.8,-0.98l-3.26,-0.65C16.58,14.14 16.24,14.24 16.01,14.48z"/> + <path + android:fillColor="#000000" + android:pathData="M12,8h10V6H12V8zM12,4h10V2H12V4zM22,10H12v2h10V10z"/> +</vector> diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml index 47d04edfc281..bf7e0682e91b 100644 --- a/core/res/res/values/ids.xml +++ b/core/res/res/values/ids.xml @@ -140,15 +140,18 @@ <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_MOVE_WINDOW}. --> <item type="id" name="accessibilityActionMoveWindow" /> - <!-- A tag used to save an animator in local y translation --> - <item type="id" name="tag_local_translation_y_animator" /> + <!-- A tag used to save an animator in top --> + <item type="id" name="tag_top_animator" /> - <!-- A tag used to save the local translation y --> - <item type="id" name="tag_local_translation_y" /> + <!-- A tag used to save the current top override --> + <item type="id" name="tag_top_override" /> <!-- A tag used to save the original top of a view --> <item type="id" name="tag_layout_top" /> + <!-- A tag used to save whether a view was laid out before --> + <item type="id" name="tag_is_first_layout" /> + <!-- A tag used to save an animator in alpha --> <item type="id" name="tag_alpha_animator" /> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 770891184049..8a045a07938c 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3260,9 +3260,10 @@ <java-symbol type="id" name="message_name" /> <java-symbol type="id" name="message_icon" /> <java-symbol type="id" name="group_message_container" /> - <java-symbol type="id" name="tag_local_translation_y_animator" /> - <java-symbol type="id" name="tag_local_translation_y" /> + <java-symbol type="id" name="tag_top_animator" /> + <java-symbol type="id" name="tag_top_override" /> <java-symbol type="id" name="tag_layout_top" /> + <java-symbol type="id" name="tag_is_first_layout" /> <java-symbol type="id" name="tag_alpha_animator" /> <java-symbol type="id" name="clip_children_set_tag" /> <java-symbol type="id" name="clip_to_padding_tag" /> @@ -3383,4 +3384,6 @@ <java-symbol type="string" name="battery_saver_description_with_learn_more" /> <java-symbol type="drawable" name="ic_lock_lockdown" /> + <java-symbol type="drawable" name="ic_arrow_forward" /> + <java-symbol type="drawable" name="ic_permission" /> </resources> diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java new file mode 100644 index 000000000000..c8e46fcdf3fd --- /dev/null +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import android.content.Context; +import android.graphics.Rect; +import android.platform.test.annotations.Presubmit; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +@Presubmit +@SmallTest +@RunWith(AndroidJUnit4.class) +public class ViewRootImplTest { + + private Context mContext; + private ViewRootImplAccessor mViewRootImpl; + + @Before + public void setUp() throws Exception { + mContext = InstrumentationRegistry.getContext(); + + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + mViewRootImpl = new ViewRootImplAccessor( + new ViewRootImpl(mContext, mContext.getDisplay())); + }); + } + + @Test + public void negativeInsets_areSetToZero() throws Exception { + mViewRootImpl.getAttachInfo().getContentInsets().set(-10, -20, -30 , -40); + mViewRootImpl.getAttachInfo().getStableInsets().set(-10, -20, -30 , -40); + final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */); + + assertThat(insets.getSystemWindowInsets(), equalTo(new Rect())); + assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(), + insets.getStableInsetRight(), insets.getStableInsetBottom()), equalTo(new Rect())); + } + + @Test + public void negativeInsets_areSetToZero_positiveAreLeftAsIs() throws Exception { + mViewRootImpl.getAttachInfo().getContentInsets().set(-10, 20, -30 , 40); + mViewRootImpl.getAttachInfo().getStableInsets().set(10, -20, 30 , -40); + final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */); + + assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(0, 20, 0, 40))); + assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(), + insets.getStableInsetRight(), insets.getStableInsetBottom()), + equalTo(new Rect(10, 0, 30, 0))); + } + + @Test + public void positiveInsets_areLeftAsIs() throws Exception { + mViewRootImpl.getAttachInfo().getContentInsets().set(10, 20, 30 , 40); + mViewRootImpl.getAttachInfo().getStableInsets().set(10, 20, 30 , 40); + final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */); + + assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(10, 20, 30, 40))); + assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(), + insets.getStableInsetRight(), insets.getStableInsetBottom()), + equalTo(new Rect(10, 20, 30, 40))); + } + + private static class ViewRootImplAccessor { + + private final ViewRootImpl mViewRootImpl; + + ViewRootImplAccessor(ViewRootImpl viewRootImpl) { + mViewRootImpl = viewRootImpl; + } + + public ViewRootImpl get() { + return mViewRootImpl; + } + + AttachInfoAccessor getAttachInfo() throws Exception { + return new AttachInfoAccessor( + getField(mViewRootImpl, ViewRootImpl.class.getDeclaredField("mAttachInfo"))); + } + + WindowInsets getWindowInsets(boolean forceConstruct) throws Exception { + return (WindowInsets) invokeMethod(mViewRootImpl, + ViewRootImpl.class.getDeclaredMethod("getWindowInsets", boolean.class), + forceConstruct); + } + + class AttachInfoAccessor { + + private final Class<?> mClass; + private final Object mAttachInfo; + + AttachInfoAccessor(Object attachInfo) throws Exception { + mAttachInfo = attachInfo; + mClass = ViewRootImpl.class.getClassLoader().loadClass( + "android.view.View$AttachInfo"); + } + + Rect getContentInsets() throws Exception { + return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mContentInsets")); + } + + Rect getStableInsets() throws Exception { + return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mStableInsets")); + } + } + + private static Object getField(Object o, Field field) throws Exception { + field.setAccessible(true); + return field.get(o); + } + + private static Object invokeMethod(Object o, Method method, Object... args) + throws Exception { + method.setAccessible(true); + return method.invoke(o, args); + } + } +} diff --git a/docs/html/reference/_book.yaml b/docs/html/reference/_book.yaml deleted file mode 100644 index b902a61a6501..000000000000 --- a/docs/html/reference/_book.yaml +++ /dev/null @@ -1,853 +0,0 @@ -reference: -- title: Class Index - path: /reference/classes.html - status_text: no-toggle -- title: Package Index - path: /reference/packages.html - status_text: no-toggle -- title: android - path: /reference/android/package-summary.html - status_text: apilevel-1 -- title: android.accessibilityservice - path: /reference/android/accessibilityservice/package-summary.html - status_text: apilevel-4 -- title: android.accounts - path: /reference/android/accounts/package-summary.html - status_text: apilevel-5 -- title: android.animation - path: /reference/android/animation/package-summary.html - status_text: apilevel-11 -- title: android.annotation - path: /reference/android/annotation/package-summary.html - status_text: apilevel-16 -- title: android.app - path: /reference/android/app/package-summary.html - status_text: apilevel-1 -- title: android.app.admin - path: /reference/android/app/admin/package-summary.html - status_text: apilevel-8 -- title: android.app.assist - path: /reference/android/app/assist/package-summary.html - status_text: apilevel-23 -- title: android.app.backup - path: /reference/android/app/backup/package-summary.html - status_text: apilevel-8 -- title: android.app.job - path: /reference/android/app/job/package-summary.html - status_text: apilevel-21 -- title: android.app.usage - path: /reference/android/app/usage/package-summary.html - status_text: apilevel-21 -- title: android.appwidget - path: /reference/android/appwidget/package-summary.html - status_text: apilevel-3 -- title: android.bluetooth - path: /reference/android/bluetooth/package-summary.html - status_text: apilevel-5 -- title: android.bluetooth.le - path: /reference/android/bluetooth/le/package-summary.html - status_text: apilevel-21 -- title: android.companion - path: /reference/android/companion/package-summary.html - status_text: apilevel-O -- title: android.content - path: /reference/android/content/package-summary.html - status_text: apilevel-1 -- title: android.content.pm - path: /reference/android/content/pm/package-summary.html - status_text: apilevel-1 -- title: android.content.res - path: /reference/android/content/res/package-summary.html - status_text: apilevel-1 -- title: android.database - path: /reference/android/database/package-summary.html - status_text: apilevel-1 -- title: android.database.sqlite - path: /reference/android/database/sqlite/package-summary.html - status_text: apilevel-1 -- title: android.databinding - path: /reference/android/databinding/package-summary.html - status_text: apilevel- -- title: android.drm - path: /reference/android/drm/package-summary.html - status_text: apilevel-11 -- title: android.gesture - path: /reference/android/gesture/package-summary.html - status_text: apilevel-4 -- title: android.graphics - path: /reference/android/graphics/package-summary.html - status_text: apilevel-1 -- title: android.graphics.drawable - path: /reference/android/graphics/drawable/package-summary.html - status_text: apilevel-1 -- title: android.graphics.drawable.shapes - path: /reference/android/graphics/drawable/shapes/package-summary.html - status_text: apilevel-1 -- title: android.graphics.fonts - path: /reference/android/graphics/fonts/package-summary.html - status_text: apilevel-O -- title: android.graphics.pdf - path: /reference/android/graphics/pdf/package-summary.html - status_text: apilevel-19 -- title: android.hardware - path: /reference/android/hardware/package-summary.html - status_text: apilevel-1 -- title: android.hardware.camera2 - path: /reference/android/hardware/camera2/package-summary.html - status_text: apilevel-21 -- title: android.hardware.camera2.params - path: /reference/android/hardware/camera2/params/package-summary.html - status_text: apilevel-21 -- title: android.hardware.display - path: /reference/android/hardware/display/package-summary.html - status_text: apilevel-17 -- title: android.hardware.fingerprint - path: /reference/android/hardware/fingerprint/package-summary.html - status_text: apilevel-23 -- title: android.hardware.input - path: /reference/android/hardware/input/package-summary.html - status_text: apilevel-16 -- title: android.hardware.usb - path: /reference/android/hardware/usb/package-summary.html - status_text: apilevel-12 -- title: android.icu.lang - path: /reference/android/icu/lang/package-summary.html - status_text: apilevel-24 -- title: android.icu.math - path: /reference/android/icu/math/package-summary.html - status_text: apilevel-24 -- title: android.icu.text - path: /reference/android/icu/text/package-summary.html - status_text: apilevel-24 -- title: android.icu.util - path: /reference/android/icu/util/package-summary.html - status_text: apilevel-24 -- title: android.inputmethodservice - path: /reference/android/inputmethodservice/package-summary.html - status_text: apilevel-3 -- title: android.location - path: /reference/android/location/package-summary.html - status_text: apilevel-1 -- title: android.media - path: /reference/android/media/package-summary.html - status_text: apilevel-1 -- title: android.media.audiofx - path: /reference/android/media/audiofx/package-summary.html - status_text: apilevel-9 -- title: android.media.browse - path: /reference/android/media/browse/package-summary.html - status_text: apilevel-21 -- title: android.media.effect - path: /reference/android/media/effect/package-summary.html - status_text: apilevel-14 -- title: android.media.midi - path: /reference/android/media/midi/package-summary.html - status_text: apilevel-23 -- title: android.media.projection - path: /reference/android/media/projection/package-summary.html - status_text: apilevel-21 -- title: android.media.session - path: /reference/android/media/session/package-summary.html - status_text: apilevel-21 -- title: android.media.tv - path: /reference/android/media/tv/package-summary.html - status_text: apilevel-21 -- title: android.mtp - path: /reference/android/mtp/package-summary.html - status_text: apilevel-12 -- title: android.net - path: /reference/android/net/package-summary.html - status_text: apilevel-1 -- title: android.net.http - path: /reference/android/net/http/package-summary.html - status_text: apilevel-1 -- title: android.net.nsd - path: /reference/android/net/nsd/package-summary.html - status_text: apilevel-16 -- title: android.net.rtp - path: /reference/android/net/rtp/package-summary.html - status_text: apilevel-12 -- title: android.net.sip - path: /reference/android/net/sip/package-summary.html - status_text: apilevel-9 -- title: android.net.wifi - path: /reference/android/net/wifi/package-summary.html - status_text: apilevel-1 -- title: android.net.wifi.aware - path: /reference/android/net/wifi/aware/package-summary.html - status_text: apilevel-O -- title: android.net.wifi.hotspot2 - path: /reference/android/net/wifi/hotspot2/package-summary.html - status_text: apilevel-O -- title: android.net.wifi.hotspot2.omadm - path: /reference/android/net/wifi/hotspot2/omadm/package-summary.html - status_text: apilevel-O -- title: android.net.wifi.hotspot2.pps - path: /reference/android/net/wifi/hotspot2/pps/package-summary.html - status_text: apilevel-O -- title: android.net.wifi.p2p - path: /reference/android/net/wifi/p2p/package-summary.html - status_text: apilevel-14 -- title: android.net.wifi.p2p.nsd - path: /reference/android/net/wifi/p2p/nsd/package-summary.html - status_text: apilevel-16 -- title: android.nfc - path: /reference/android/nfc/package-summary.html - status_text: apilevel-9 -- title: android.nfc.cardemulation - path: /reference/android/nfc/cardemulation/package-summary.html - status_text: apilevel-19 -- title: android.nfc.tech - path: /reference/android/nfc/tech/package-summary.html - status_text: apilevel-10 -- title: android.opengl - path: /reference/android/opengl/package-summary.html - status_text: apilevel-1 -- title: android.os - path: /reference/android/os/package-summary.html - status_text: apilevel-1 -- title: android.os.health - path: /reference/android/os/health/package-summary.html - status_text: apilevel-24 -- title: android.os.storage - path: /reference/android/os/storage/package-summary.html - status_text: apilevel-9 -- title: android.preference - path: /reference/android/preference/package-summary.html - status_text: apilevel-1 -- title: android.print - path: /reference/android/print/package-summary.html - status_text: apilevel-19 -- title: android.print.pdf - path: /reference/android/print/pdf/package-summary.html - status_text: apilevel-19 -- title: android.printservice - path: /reference/android/printservice/package-summary.html - status_text: apilevel-19 -- title: android.provider - path: /reference/android/provider/package-summary.html - status_text: apilevel-1 -- title: android.renderscript - path: /reference/android/renderscript/package-summary.html - status_text: apilevel-11 -- title: android.sax - path: /reference/android/sax/package-summary.html - status_text: apilevel-1 -- title: android.security - path: /reference/android/security/package-summary.html - status_text: apilevel-14 -- title: android.security.keystore - path: /reference/android/security/keystore/package-summary.html - status_text: apilevel-23 -- title: android.service.autofill - path: /reference/android/service/autofill/package-summary.html - status_text: apilevel-O -- title: android.service.carrier - path: /reference/android/service/carrier/package-summary.html - status_text: apilevel-22 -- title: android.service.chooser - path: /reference/android/service/chooser/package-summary.html - status_text: apilevel-23 -- title: android.service.dreams - path: /reference/android/service/dreams/package-summary.html - status_text: apilevel-17 -- title: android.service.media - path: /reference/android/service/media/package-summary.html - status_text: apilevel-21 -- title: android.service.notification - path: /reference/android/service/notification/package-summary.html - status_text: apilevel-18 -- title: android.service.quicksettings - path: /reference/android/service/quicksettings/package-summary.html - status_text: apilevel-24 -- title: android.service.restrictions - path: /reference/android/service/restrictions/package-summary.html - status_text: apilevel-21 -- title: android.service.textservice - path: /reference/android/service/textservice/package-summary.html - status_text: apilevel-14 -- title: android.service.voice - path: /reference/android/service/voice/package-summary.html - status_text: apilevel-21 -- title: android.service.vr - path: /reference/android/service/vr/package-summary.html - status_text: apilevel-24 -- title: android.service.wallpaper - path: /reference/android/service/wallpaper/package-summary.html - status_text: apilevel-7 -- title: android.speech - path: /reference/android/speech/package-summary.html - status_text: apilevel-3 -- title: android.speech.tts - path: /reference/android/speech/tts/package-summary.html - status_text: apilevel-4 -- title: android.support.animation - path: /reference/android/support/animation/package-summary.html - status_text: apilevel-25.3.0 -- title: android.support.annotation - path: /reference/android/support/annotation/package-summary.html - status_text: apilevel- -- title: android.support.app.recommendation - path: /reference/android/support/app/recommendation/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.compat - path: /reference/android/support/compat/package-summary.html - status_text: apilevel- -- title: android.support.coreui - path: /reference/android/support/coreui/package-summary.html - status_text: apilevel- -- title: android.support.coreutils - path: /reference/android/support/coreutils/package-summary.html - status_text: apilevel- -- title: android.support.customtabs - path: /reference/android/support/customtabs/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.design - path: /reference/android/support/design/package-summary.html - status_text: apilevel- -- title: android.support.design.widget - path: /reference/android/support/design/widget/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.dynamicanimation - path: /reference/android/support/dynamicanimation/package-summary.html - status_text: apilevel- -- title: android.support.exifinterface - path: /reference/android/support/exifinterface/package-summary.html - status_text: apilevel- -- title: android.support.fragment - path: /reference/android/support/fragment/package-summary.html - status_text: apilevel- -- title: android.support.graphics.drawable - path: /reference/android/support/graphics/drawable/package-summary.html - status_text: apilevel-23.2.0 -- title: android.support.graphics.drawable.animated - path: /reference/android/support/graphics/drawable/animated/package-summary.html - status_text: apilevel- -- title: android.support.media - path: /reference/android/support/media/package-summary.html - status_text: apilevel-25.1.0 -- title: android.support.media.instantvideo - path: /reference/android/support/media/instantvideo/package-summary.html - status_text: apilevel- -- title: android.support.media.instantvideo.preload - path: /reference/android/support/media/instantvideo/preload/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.support.media.instantvideo.widget - path: /reference/android/support/media/instantvideo/widget/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.support.media.tv - path: /reference/android/support/media/tv/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.support.mediacompat - path: /reference/android/support/mediacompat/package-summary.html - status_text: apilevel- -- title: android.support.multidex - path: /reference/android/support/multidex/package-summary.html - status_text: apilevel- -- title: android.support.percent - path: /reference/android/support/percent/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.recommendation - path: /reference/android/support/recommendation/package-summary.html - status_text: apilevel- -- title: android.support.transition - path: /reference/android/support/transition/package-summary.html - status_text: apilevel-24.2.0 -- title: android.support.v13 - path: /reference/android/support/v13/package-summary.html - status_text: apilevel- -- title: android.support.v13.app - path: /reference/android/support/v13/app/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v13.view - path: /reference/android/support/v13/view/package-summary.html - status_text: apilevel-24.0.0 -- title: android.support.v13.view.inputmethod - path: /reference/android/support/v13/view/inputmethod/package-summary.html - status_text: apilevel-25.0.0 -- title: android.support.v14.preference - path: /reference/android/support/v14/preference/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v17.leanback - path: /reference/android/support/v17/leanback/package-summary.html - status_text: apilevel- -- title: android.support.v17.leanback.app - path: /reference/android/support/v17/leanback/app/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v17.leanback.database - path: /reference/android/support/v17/leanback/database/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v17.leanback.graphics - path: /reference/android/support/v17/leanback/graphics/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v17.leanback.media - path: /reference/android/support/v17/leanback/media/package-summary.html - status_text: apilevel-25.1.0 -- title: android.support.v17.leanback.system - path: /reference/android/support/v17/leanback/system/package-summary.html - status_text: apilevel-22.2.1 -- title: android.support.v17.leanback.widget - path: /reference/android/support/v17/leanback/widget/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v17.leanback.widget.picker - path: /reference/android/support/v17/leanback/widget/picker/package-summary.html - status_text: apilevel-23.2.0 -- title: android.support.v17.preference - path: /reference/android/support/v17/preference/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v4 - path: /reference/android/support/v4/package-summary.html - status_text: apilevel- -- title: android.support.v4.accessibilityservice - path: /reference/android/support/v4/accessibilityservice/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.app - path: /reference/android/support/v4/app/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.content - path: /reference/android/support/v4/content/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.content.pm - path: /reference/android/support/v4/content/pm/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v4.content.res - path: /reference/android/support/v4/content/res/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v4.database - path: /reference/android/support/v4/database/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.graphics - path: /reference/android/support/v4/graphics/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.graphics.drawable - path: /reference/android/support/v4/graphics/drawable/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.hardware.display - path: /reference/android/support/v4/hardware/display/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.hardware.fingerprint - path: /reference/android/support/v4/hardware/fingerprint/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v4.math - path: /reference/android/support/v4/math/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.support.v4.media - path: /reference/android/support/v4/media/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.media.session - path: /reference/android/support/v4/media/session/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.net - path: /reference/android/support/v4/net/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.os - path: /reference/android/support/v4/os/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.print - path: /reference/android/support/v4/print/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.provider - path: /reference/android/support/v4/provider/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.text - path: /reference/android/support/v4/text/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.text.util - path: /reference/android/support/v4/text/util/package-summary.html - status_text: apilevel-24.2.0 -- title: android.support.v4.util - path: /reference/android/support/v4/util/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.view - path: /reference/android/support/v4/view/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.view.accessibility - path: /reference/android/support/v4/view/accessibility/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.view.animation - path: /reference/android/support/v4/view/animation/package-summary.html - status_text: apilevel-22.1.0 -- title: android.support.v4.widget - path: /reference/android/support/v4/widget/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.app - path: /reference/android/support/v7/app/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.appcompat - path: /reference/android/support/v7/appcompat/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v7.cardview - path: /reference/android/support/v7/cardview/package-summary.html - status_text: apilevel- -- title: android.support.v7.content.res - path: /reference/android/support/v7/content/res/package-summary.html - status_text: apilevel-24.0.0 -- title: android.support.v7.graphics - path: /reference/android/support/v7/graphics/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.graphics.drawable - path: /reference/android/support/v7/graphics/drawable/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v7.gridlayout - path: /reference/android/support/v7/gridlayout/package-summary.html - status_text: apilevel- -- title: android.support.v7.media - path: /reference/android/support/v7/media/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.mediarouter - path: /reference/android/support/v7/mediarouter/package-summary.html - status_text: apilevel- -- title: android.support.v7.palette - path: /reference/android/support/v7/palette/package-summary.html - status_text: apilevel- -- title: android.support.v7.preference - path: /reference/android/support/v7/preference/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v7.recyclerview - path: /reference/android/support/v7/recyclerview/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v7.util - path: /reference/android/support/v7/util/package-summary.html - status_text: apilevel-22.1.0 -- title: android.support.v7.view - path: /reference/android/support/v7/view/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.widget - path: /reference/android/support/v7/widget/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.widget.helper - path: /reference/android/support/v7/widget/helper/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v7.widget.util - path: /reference/android/support/v7/widget/util/package-summary.html - status_text: apilevel-22.1.0 -- title: android.support.v8.renderscript - path: /reference/android/support/v8/renderscript/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.wearable - path: /reference/android/support/wearable/package-summary.html - status_text: apilevel- -- title: android.support.wearable.view - path: /reference/android/support/wearable/view/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.system - path: /reference/android/system/package-summary.html - status_text: apilevel-21 -- title: android.telecom - path: /reference/android/telecom/package-summary.html - status_text: apilevel-21 -- title: android.telephony - path: /reference/android/telephony/package-summary.html - status_text: apilevel-1 -- title: android.telephony.cdma - path: /reference/android/telephony/cdma/package-summary.html - status_text: apilevel-5 -- title: android.telephony.gsm - path: /reference/android/telephony/gsm/package-summary.html - status_text: apilevel-1 -- title: android.test - path: /reference/android/test/package-summary.html - status_text: apilevel-1 -- title: android.test.mock - path: /reference/android/test/mock/package-summary.html - status_text: apilevel-1 -- title: android.test.suitebuilder - path: /reference/android/test/suitebuilder/package-summary.html - status_text: apilevel-1 -- title: android.test.suitebuilder.annotation - path: /reference/android/test/suitebuilder/annotation/package-summary.html - status_text: apilevel-1 -- title: android.text - path: /reference/android/text/package-summary.html - status_text: apilevel-1 -- title: android.text.format - path: /reference/android/text/format/package-summary.html - status_text: apilevel-3 -- title: android.text.method - path: /reference/android/text/method/package-summary.html - status_text: apilevel-1 -- title: android.text.style - path: /reference/android/text/style/package-summary.html - status_text: apilevel-1 -- title: android.text.util - path: /reference/android/text/util/package-summary.html - status_text: apilevel-1 -- title: android.transition - path: /reference/android/transition/package-summary.html - status_text: apilevel-19 -- title: android.util - path: /reference/android/util/package-summary.html - status_text: apilevel-1 -- title: android.view - path: /reference/android/view/package-summary.html - status_text: apilevel-1 -- title: android.view.accessibility - path: /reference/android/view/accessibility/package-summary.html - status_text: apilevel-4 -- title: android.view.animation - path: /reference/android/view/animation/package-summary.html - status_text: apilevel-1 -- title: android.view.autofill - path: /reference/android/view/autofill/package-summary.html - status_text: apilevel-O -- title: android.view.inputmethod - path: /reference/android/view/inputmethod/package-summary.html - status_text: apilevel-3 -- title: android.view.textclassifier - path: /reference/android/view/textclassifier/package-summary.html - status_text: apilevel-O -- title: android.view.textservice - path: /reference/android/view/textservice/package-summary.html - status_text: apilevel-14 -- title: android.webkit - path: /reference/android/webkit/package-summary.html - status_text: apilevel-1 -- title: android.widget - path: /reference/android/widget/package-summary.html - status_text: apilevel-1 -- title: com.android.test.runner - path: /reference/com/android/test/runner/package-summary.html - status_text: apilevel- -- title: dalvik.annotation - path: /reference/dalvik/annotation/package-summary.html - status_text: apilevel-1 -- title: dalvik.bytecode - path: /reference/dalvik/bytecode/package-summary.html - status_text: apilevel-1 -- title: dalvik.system - path: /reference/dalvik/system/package-summary.html - status_text: apilevel-1 -- title: java.awt.font - path: /reference/java/awt/font/package-summary.html - status_text: apilevel-1 -- title: java.beans - path: /reference/java/beans/package-summary.html - status_text: apilevel-3 -- title: java.io - path: /reference/java/io/package-summary.html - status_text: apilevel-1 -- title: java.lang - path: /reference/java/lang/package-summary.html - status_text: apilevel-1 -- title: java.lang.annotation - path: /reference/java/lang/annotation/package-summary.html - status_text: apilevel-1 -- title: java.lang.invoke - path: /reference/java/lang/invoke/package-summary.html - status_text: apilevel-O -- title: java.lang.ref - path: /reference/java/lang/ref/package-summary.html - status_text: apilevel-1 -- title: java.lang.reflect - path: /reference/java/lang/reflect/package-summary.html - status_text: apilevel-1 -- title: java.math - path: /reference/java/math/package-summary.html - status_text: apilevel-1 -- title: java.net - path: /reference/java/net/package-summary.html - status_text: apilevel-1 -- title: java.nio - path: /reference/java/nio/package-summary.html - status_text: apilevel-1 -- title: java.nio.channels - path: /reference/java/nio/channels/package-summary.html - status_text: apilevel-1 -- title: java.nio.channels.spi - path: /reference/java/nio/channels/spi/package-summary.html - status_text: apilevel-1 -- title: java.nio.charset - path: /reference/java/nio/charset/package-summary.html - status_text: apilevel-1 -- title: java.nio.charset.spi - path: /reference/java/nio/charset/spi/package-summary.html - status_text: apilevel-1 -- title: java.nio.file - path: /reference/java/nio/file/package-summary.html - status_text: apilevel-O -- title: java.nio.file.attribute - path: /reference/java/nio/file/attribute/package-summary.html - status_text: apilevel-O -- title: java.nio.file.spi - path: /reference/java/nio/file/spi/package-summary.html - status_text: apilevel-O -- title: java.security - path: /reference/java/security/package-summary.html - status_text: apilevel-1 -- title: java.security.acl - path: /reference/java/security/acl/package-summary.html - status_text: apilevel-1 -- title: java.security.cert - path: /reference/java/security/cert/package-summary.html - status_text: apilevel-1 -- title: java.security.interfaces - path: /reference/java/security/interfaces/package-summary.html - status_text: apilevel-1 -- title: java.security.spec - path: /reference/java/security/spec/package-summary.html - status_text: apilevel-1 -- title: java.sql - path: /reference/java/sql/package-summary.html - status_text: apilevel-1 -- title: java.text - path: /reference/java/text/package-summary.html - status_text: apilevel-1 -- title: java.time - path: /reference/java/time/package-summary.html - status_text: apilevel-O -- title: java.time.chrono - path: /reference/java/time/chrono/package-summary.html - status_text: apilevel-O -- title: java.time.format - path: /reference/java/time/format/package-summary.html - status_text: apilevel-O -- title: java.time.temporal - path: /reference/java/time/temporal/package-summary.html - status_text: apilevel-O -- title: java.time.zone - path: /reference/java/time/zone/package-summary.html - status_text: apilevel-O -- title: java.util - path: /reference/java/util/package-summary.html - status_text: apilevel-1 -- title: java.util.concurrent - path: /reference/java/util/concurrent/package-summary.html - status_text: apilevel-1 -- title: java.util.concurrent.atomic - path: /reference/java/util/concurrent/atomic/package-summary.html - status_text: apilevel-1 -- title: java.util.concurrent.locks - path: /reference/java/util/concurrent/locks/package-summary.html - status_text: apilevel-1 -- title: java.util.function - path: /reference/java/util/function/package-summary.html - status_text: apilevel-24 -- title: java.util.jar - path: /reference/java/util/jar/package-summary.html - status_text: apilevel-1 -- title: java.util.logging - path: /reference/java/util/logging/package-summary.html - status_text: apilevel-1 -- title: java.util.prefs - path: /reference/java/util/prefs/package-summary.html - status_text: apilevel-1 -- title: java.util.regex - path: /reference/java/util/regex/package-summary.html - status_text: apilevel-1 -- title: java.util.stream - path: /reference/java/util/stream/package-summary.html - status_text: apilevel-24 -- title: java.util.zip - path: /reference/java/util/zip/package-summary.html - status_text: apilevel-1 -- title: javax.crypto - path: /reference/javax/crypto/package-summary.html - status_text: apilevel-1 -- title: javax.crypto.interfaces - path: /reference/javax/crypto/interfaces/package-summary.html - status_text: apilevel-1 -- title: javax.crypto.spec - path: /reference/javax/crypto/spec/package-summary.html - status_text: apilevel-1 -- title: javax.microedition.khronos.egl - path: /reference/javax/microedition/khronos/egl/package-summary.html - status_text: apilevel-1 -- title: javax.microedition.khronos.opengles - path: /reference/javax/microedition/khronos/opengles/package-summary.html - status_text: apilevel-1 -- title: javax.net - path: /reference/javax/net/package-summary.html - status_text: apilevel-1 -- title: javax.net.ssl - path: /reference/javax/net/ssl/package-summary.html - status_text: apilevel-1 -- title: javax.security.auth - path: /reference/javax/security/auth/package-summary.html - status_text: apilevel-1 -- title: javax.security.auth.callback - path: /reference/javax/security/auth/callback/package-summary.html - status_text: apilevel-1 -- title: javax.security.auth.login - path: /reference/javax/security/auth/login/package-summary.html - status_text: apilevel-1 -- title: javax.security.auth.x500 - path: /reference/javax/security/auth/x500/package-summary.html - status_text: apilevel-1 -- title: javax.security.cert - path: /reference/javax/security/cert/package-summary.html - status_text: apilevel-1 -- title: javax.sql - path: /reference/javax/sql/package-summary.html - status_text: apilevel-1 -- title: javax.xml - path: /reference/javax/xml/package-summary.html - status_text: apilevel-1 -- title: javax.xml.datatype - path: /reference/javax/xml/datatype/package-summary.html - status_text: apilevel-8 -- title: javax.xml.namespace - path: /reference/javax/xml/namespace/package-summary.html - status_text: apilevel-8 -- title: javax.xml.parsers - path: /reference/javax/xml/parsers/package-summary.html - status_text: apilevel-1 -- title: javax.xml.transform - path: /reference/javax/xml/transform/package-summary.html - status_text: apilevel-8 -- title: javax.xml.transform.dom - path: /reference/javax/xml/transform/dom/package-summary.html - status_text: apilevel-8 -- title: javax.xml.transform.sax - path: /reference/javax/xml/transform/sax/package-summary.html - status_text: apilevel-8 -- title: javax.xml.transform.stream - path: /reference/javax/xml/transform/stream/package-summary.html - status_text: apilevel-8 -- title: javax.xml.validation - path: /reference/javax/xml/validation/package-summary.html - status_text: apilevel-8 -- title: javax.xml.xpath - path: /reference/javax/xml/xpath/package-summary.html - status_text: apilevel-8 -- title: junit.framework - path: /reference/junit/framework/package-summary.html - status_text: apilevel-1 -- title: junit.runner - path: /reference/junit/runner/package-summary.html - status_text: apilevel-1 -- title: org.apache.http.conn - path: /reference/org/apache/http/conn/package-summary.html - status_text: apilevel-1 -- title: org.apache.http.conn.scheme - path: /reference/org/apache/http/conn/scheme/package-summary.html - status_text: apilevel-1 -- title: org.apache.http.conn.ssl - path: /reference/org/apache/http/conn/ssl/package-summary.html - status_text: apilevel-1 -- title: org.apache.http.params - path: /reference/org/apache/http/params/package-summary.html - status_text: apilevel-1 -- title: org.json - path: /reference/org/json/package-summary.html - status_text: apilevel-1 -- title: org.w3c.dom - path: /reference/org/w3c/dom/package-summary.html - status_text: apilevel-1 -- title: org.w3c.dom.ls - path: /reference/org/w3c/dom/ls/package-summary.html - status_text: apilevel-8 -- title: org.xml.sax - path: /reference/org/xml/sax/package-summary.html - status_text: apilevel-1 -- title: org.xml.sax.ext - path: /reference/org/xml/sax/ext/package-summary.html - status_text: apilevel-1 -- title: org.xml.sax.helpers - path: /reference/org/xml/sax/helpers/package-summary.html - status_text: apilevel-1 -- title: org.xmlpull.v1 - path: /reference/org/xmlpull/v1/package-summary.html - status_text: apilevel-1 -- title: org.xmlpull.v1.sax2 - path: /reference/org/xmlpull/v1/sax2/package-summary.html - status_text: apilevel-1 diff --git a/docs/html/reference/_project.yaml b/docs/html/reference/_project.yaml deleted file mode 100644 index e5c26e7fdd8f..000000000000 --- a/docs/html/reference/_project.yaml +++ /dev/null @@ -1,6 +0,0 @@ -name: "Reference" -home_url: /reference/ -description: "API Reference packages and classes." -content_license: cc3-apache2 -buganizer_id: 30209417 -parent_project_metadata_path: /develop/_project.yaml diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml index 3185ea215262..e50a3757d14f 100644 --- a/media/tests/MediaFrameworkTest/AndroidManifest.xml +++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml @@ -24,7 +24,7 @@ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> - <application> + <application android:networkSecurityConfig="@xml/network_security_config"> <uses-library android:name="android.test.runner" /> <activity android:label="@string/app_name" android:name="MediaFrameworkTest" diff --git a/media/tests/MediaFrameworkTest/res/xml/network_security_config.xml b/media/tests/MediaFrameworkTest/res/xml/network_security_config.xml new file mode 100644 index 000000000000..c15c09cbf2d5 --- /dev/null +++ b/media/tests/MediaFrameworkTest/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<network-security-config> + <base-config cleartextTrafficPermitted="true"/> +</network-security-config> diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index 28e8db9e488b..e1a602b53d9d 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -214,4 +214,7 @@ <!-- Default for Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS --> <string name="def_backup_agent_timeout_parameters"></string> + + <!-- Default for Settings.System.VIBRATE_WHEN_RINGING --> + <bool name="def_vibrate_when_ringing">false</bool> </resources> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index fbe52d191c30..960d30524b95 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -2935,7 +2935,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 168; + private static final int SETTINGS_VERSION = 169; private final int mUserId; @@ -3805,6 +3805,21 @@ public class SettingsProvider extends ContentProvider { currentVersion = 168; } + if (currentVersion == 168) { + // Version 168: by default, vibrate for phone calls + final SettingsState systemSettings = getSystemSettingsLocked(userId); + final Setting currentSetting = systemSettings.getSettingLocked( + Settings.System.VIBRATE_WHEN_RINGING); + if (currentSetting.isNull()) { + systemSettings.insertSettingLocked( + Settings.System.VIBRATE_WHEN_RINGING, + getContext().getResources().getBoolean( + R.bool.def_vibrate_when_ringing) ? "1" : "0", + null, true, SettingsState.SYSTEM_PACKAGE_NAME); + } + currentVersion = 169; + } + // vXXX: Add new settings above this point. if (currentVersion != newVersion) { diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 88edd12ab2f4..7871020a92aa 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -211,6 +211,8 @@ <!-- Permission necessary to change car audio volume through CarAudioManager --> <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" /> + <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" /> + <application android:name=".SystemUIApplication" android:persistent="true" diff --git a/packages/SystemUI/res/drawable-hdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-hdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..0899d3515f1b --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-mdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..22664496db76 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/drawable-xhdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-xhdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..3328add435fb --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/drawable-xxhdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-xxhdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..ed651da88800 --- /dev/null +++ b/packages/SystemUI/res/drawable-xxhdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/drawable-xxxhdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-xxxhdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..06e120239eb2 --- /dev/null +++ b/packages/SystemUI/res/drawable-xxxhdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index d675d0f82906..975055ce72e6 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -138,7 +138,7 @@ <color name="remote_input_accent">#eeeeee</color> <color name="quick_step_track_background_dark">#61000000</color> - <color name="quick_step_track_background_light">#4DFFFFFF</color> + <color name="quick_step_track_background_light">#33FFFFFF</color> <!-- Keyboard shortcuts colors --> <color name="ksh_application_group_color">#fff44336</color> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 1aee7bc311a9..9a3bdf271dc0 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -867,6 +867,8 @@ <!-- The size of corner radius of the arrow in the onboarding toast. --> <dimen name="recents_onboarding_toast_arrow_corner_radius">2dp</dimen> + <!-- The start margin of quick scrub onboarding toast. --> + <dimen name="recents_quick_scrub_onboarding_margin_start">8dp</dimen> <!-- The min alpha to apply to a task affiliation group color. --> <item name="recents_task_affiliation_color_min_alpha_percentage" format="float" type="dimen">0.6</item> @@ -939,7 +941,7 @@ <dimen name="rounded_corner_content_padding">0dp</dimen> <dimen name="nav_content_padding">0dp</dimen> <dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen> - <dimen name="nav_quick_scrub_track_thickness">2dp</dimen> + <dimen name="nav_quick_scrub_track_thickness">10dp</dimen> <!-- Navigation bar shadow params. --> <dimen name="nav_key_button_shadow_offset_x">0dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java index 56cb88870d65..19f8416860a2 100644 --- a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java @@ -14,6 +14,8 @@ package com.android.systemui; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; + import android.app.Activity; import android.app.AlertDialog; import android.app.slice.SliceManager; @@ -61,7 +63,9 @@ public class SlicePermissionActivity extends Activity implements OnClickListener .setNegativeButton(R.string.slice_permission_deny, this) .setPositiveButton(R.string.slice_permission_allow, this) .setOnDismissListener(this) - .show(); + .create(); + dialog.getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); + dialog.show(); TextView t1 = dialog.getWindow().getDecorView().findViewById(R.id.text1); t1.setText(getString(R.string.slice_permission_text_1, app2)); TextView t2 = dialog.getWindow().getDecorView().findViewById(R.id.text2); diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index 8cfba2cc53d7..ab822696d382 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -184,9 +184,15 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { return; } boolean selected = mLastExpansion == 1f; + + // Disable accessibility temporarily while we update selected state purely for the + // marquee. This will ensure that accessibility doesn't announce the TYPE_VIEW_SELECTED + // event on any of the children. + setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); for (int i = 0; i < mPages.size(); i++) { mPages.get(i).setSelected(i == getCurrentItem() ? selected : false); } + setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); } public void setPageListener(PageListener listener) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java index 086c87ba10a5..8d8e20669a1f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java @@ -393,7 +393,20 @@ public class RecentsOnboarding { if (!mLayoutAttachedToWindow && orientation == Configuration.ORIENTATION_PORTRAIT) { mLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE); - mWindowManager.addView(mLayout, getWindowLayoutParams()); + final int gravity; + final int x; + if (stringRes == R.string.recents_swipe_up_onboarding) { + gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + x = 0; + } else { + int layoutDirection = + mContext.getResources().getConfiguration().getLayoutDirection(); + gravity = Gravity.BOTTOM | (layoutDirection == View.LAYOUT_DIRECTION_LTR + ? Gravity.LEFT : Gravity.RIGHT); + x = mContext.getResources().getDimensionPixelSize( + R.dimen.recents_quick_scrub_onboarding_margin_start); + } + mWindowManager.addView(mLayout, getWindowLayoutParams(gravity, x)); mLayout.setAlpha(0); mLayout.animate() .alpha(1f) @@ -459,19 +472,19 @@ public class RecentsOnboarding { pw.println(" }"); } - private WindowManager.LayoutParams getWindowLayoutParams() { + private WindowManager.LayoutParams getWindowLayoutParams(int gravity, int x) { int flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, - 0, -mNavBarHeight / 2, + ViewGroup.LayoutParams.WRAP_CONTENT, + x, -mNavBarHeight / 2, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, flags, PixelFormat.TRANSLUCENT); lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; lp.setTitle("RecentsOnboarding"); - lp.gravity = Gravity.BOTTOM; + lp.gravity = gravity; return lp; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java index 8ede2246301b..879ac92b95d0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java @@ -16,11 +16,8 @@ package com.android.systemui.statusbar.notification; -import android.util.ArraySet; import android.util.Pools; import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; import android.view.animation.Interpolator; import android.widget.ImageView; import android.widget.ProgressBar; @@ -411,7 +408,8 @@ public class TransformState { mOwnPosition[1] -= (1.0f - mTransformedView.getScaleY()) * mTransformedView.getPivotY(); // Remove local translations - mOwnPosition[1] -= MessagingPropertyAnimator.getLocalTranslationY(mTransformedView); + mOwnPosition[1] -= MessagingPropertyAnimator.getTop(mTransformedView) + - MessagingPropertyAnimator.getLayoutTop(mTransformedView); return mOwnPosition; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java index 3c0b22660c17..894ea62b1b61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java @@ -114,6 +114,10 @@ public class ButtonDispatcher { return mVisibility != null ? mVisibility : View.VISIBLE; } + public boolean isVisible() { + return getVisibility() == View.VISIBLE; + } + public float getAlpha() { return mAlpha != null ? mAlpha : 1; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 6c66cabf0da8..0fd8df09eaaa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -336,13 +336,14 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav int x = (int) event.getX(); int y = (int) event.getY(); mDownHitTarget = HIT_TARGET_NONE; - if (mBackButtonBounds.contains(x, y)) { + if (getBackButton().isVisible() && mBackButtonBounds.contains(x, y)) { mDownHitTarget = HIT_TARGET_BACK; - } else if (mHomeButtonBounds.contains(x, y)) { + } else if (getHomeButton().isVisible() && mHomeButtonBounds.contains(x, y)) { mDownHitTarget = HIT_TARGET_HOME; - } else if (mRecentsButtonBounds.contains(x, y)) { + } else if (getRecentsButton().isVisible() && mRecentsButtonBounds.contains(x, y)) { mDownHitTarget = HIT_TARGET_OVERVIEW; - } else if (mRotationButtonBounds.contains(x, y)) { + } else if (getRotateSuggestionButton().isVisible() + && mRotationButtonBounds.contains(x, y)) { mDownHitTarget = HIT_TARGET_ROTATION; } break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java index b55fe47f1f2d..860b77e1b251 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java @@ -29,14 +29,13 @@ import android.animation.AnimatorSet; import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Matrix; -import android.graphics.Paint; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.RemoteException; import android.util.FloatProperty; @@ -55,6 +54,7 @@ import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.shared.system.NavigationBarCompat; +import com.android.internal.graphics.ColorUtils; /** * Class to detect gestures on the navigation bar and implement quick scrub. @@ -63,7 +63,8 @@ public class QuickStepController implements GestureHelper { private static final String TAG = "QuickStepController"; private static final int ANIM_IN_DURATION_MS = 150; - private static final int ANIM_OUT_DURATION_MS = 100; + private static final int ANIM_OUT_DURATION_MS = 134; + private static final float TRACK_SCALE = 0.95f; private NavigationBarView mNavigationBarView; @@ -76,6 +77,7 @@ public class QuickStepController implements GestureHelper { private boolean mIsVertical; private boolean mIsRTL; private float mTrackAlpha; + private float mTrackScale = TRACK_SCALE; private int mLightTrackColor; private int mDarkTrackColor; private float mDarkIntensity; @@ -85,7 +87,7 @@ public class QuickStepController implements GestureHelper { private final Handler mHandler = new Handler(); private final Rect mTrackRect = new Rect(); - private final Paint mTrackPaint = new Paint(); + private final Drawable mTrackDrawable; private final OverviewProxyService mOverviewEventSender; private final int mTrackThickness; private final int mTrackEndPadding; @@ -108,6 +110,20 @@ public class QuickStepController implements GestureHelper { } }; + private final FloatProperty<QuickStepController> mTrackScaleProperty = + new FloatProperty<QuickStepController>("TrackScale") { + @Override + public void setValue(QuickStepController controller, float scale) { + mTrackScale = scale; + mNavigationBarView.invalidate(); + } + + @Override + public Float get(QuickStepController controller) { + return mTrackScale; + } + }; + private final FloatProperty<QuickStepController> mNavBarAlphaProperty = new FloatProperty<QuickStepController>("NavBarAlpha") { @Override @@ -139,7 +155,7 @@ public class QuickStepController implements GestureHelper { mOverviewEventSender = Dependency.get(OverviewProxyService.class); mTrackThickness = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_thickness); mTrackEndPadding = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_edge_padding); - mTrackPaint.setAlpha(0); + mTrackDrawable = context.getDrawable(R.drawable.qs_scrubber_track).mutate(); } public void setComponents(NavigationBarView navigationBarView) { @@ -296,9 +312,17 @@ public class QuickStepController implements GestureHelper { } int color = (int) mTrackColorEvaluator.evaluate(mDarkIntensity, mLightTrackColor, mDarkTrackColor); - mTrackPaint.setColor(color); - mTrackPaint.setAlpha((int) (mTrackPaint.getAlpha() * mTrackAlpha)); - canvas.drawRect(mTrackRect, mTrackPaint); + int colorAlpha = ColorUtils.setAlphaComponent(color, + (int) (Color.alpha(color) * mTrackAlpha)); + mTrackDrawable.setTint(colorAlpha); + + // Scale the track, but apply the inverse scale from the nav bar + canvas.save(); + canvas.scale(mTrackScale / mNavigationBarView.getScaleX(), + 1f / mNavigationBarView.getScaleY(), + mTrackRect.centerX(), mTrackRect.centerY()); + mTrackDrawable.draw(canvas); + canvas.restore(); } @Override @@ -322,6 +346,7 @@ public class QuickStepController implements GestureHelper { x2 = x1 + width - 2 * mTrackEndPadding; } mTrackRect.set(x1, y1, x2, y2); + mTrackDrawable.setBounds(mTrackRect); } @Override @@ -387,7 +412,9 @@ public class QuickStepController implements GestureHelper { mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light); mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark); - ObjectAnimator trackAnimator = ObjectAnimator.ofFloat(this, mTrackAlphaProperty, 1f); + ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this, + PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 1f), + PropertyValuesHolder.ofFloat(mTrackScaleProperty, 1f)); trackAnimator.setInterpolator(ALPHA_IN); trackAnimator.setDuration(ANIM_IN_DURATION_MS); ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 0f); @@ -438,7 +465,9 @@ public class QuickStepController implements GestureHelper { mTrackAnimator.cancel(); } - ObjectAnimator trackAnimator = ObjectAnimator.ofFloat(this, mTrackAlphaProperty, 0f); + ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this, + PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 0f), + PropertyValuesHolder.ofFloat(mTrackScaleProperty, TRACK_SCALE)); trackAnimator.setInterpolator(ALPHA_OUT); trackAnimator.setDuration(ANIM_OUT_DURATION_MS); ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 1f); diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index 3beebcba6c5d..aa86ea8b03e2 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -812,11 +812,12 @@ public class AppOpsService extends IAppOpsService.Stub { resOps = new ArrayList<>(); for (int j=0; j<pkgOps.size(); j++) { Op curOp = pkgOps.valueAt(j); - long duration = curOp.duration == -1 + final boolean running = curOp.duration == -1; + long duration = running ? (elapsedNow - curOp.startRealtime) : curOp.duration; resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, - curOp.rejectTime, (int) duration, curOp.proxyUid, + curOp.rejectTime, (int) duration, running, curOp.proxyUid, curOp.proxyPackageName)); } } else { @@ -826,11 +827,12 @@ public class AppOpsService extends IAppOpsService.Stub { if (resOps == null) { resOps = new ArrayList<>(); } - long duration = curOp.duration == -1 + final boolean running = curOp.duration == -1; + final long duration = running ? (elapsedNow - curOp.startRealtime) : curOp.duration; resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, - curOp.rejectTime, (int) duration, curOp.proxyUid, + curOp.rejectTime, (int) duration, running, curOp.proxyUid, curOp.proxyPackageName)); } } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 4c2a94092e23..ca715b51a328 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -119,7 +119,7 @@ public final class ActiveServices { // How long the startForegroundService() grace period is to get around to // calling startForeground() before we ANR + stop it. - static final int SERVICE_START_FOREGROUND_TIMEOUT = 5*1000; + static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000; final ActivityManagerService mAm; @@ -501,6 +501,18 @@ public final class ActiveServices { } } + // At this point we've applied allowed-to-start policy based on whether this was + // an ordinary startService() or a startForegroundService(). Now, only require that + // the app follow through on the startForegroundService() -> startForeground() + // contract if it actually targets O+. + if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) { + if (DEBUG_BACKGROUND_CHECK || DEBUG_FOREGROUND_SERVICE) { + Slog.i(TAG, "startForegroundService() but host targets " + + r.appInfo.targetSdkVersion + " - not requiring startForeground()"); + } + fgRequired = false; + } + NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked( callingUid, r.packageName, service, service.getFlags(), null, r.userId); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c25f8ff843a8..e95a9327cfb3 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -15305,6 +15305,7 @@ public class ActivityManagerService extends IActivityManager.Stub public void onLimitReached(int uid) { Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid " + Process.myUid()); + Binder.dumpProxyDebugInfo(); if (uid == Process.SYSTEM_UID) { Slog.i(TAG, "Skipping kill (uid is SYSTEM)"); } else { diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index ef5a5a322aa8..d456f6255426 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -115,6 +115,7 @@ import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK; import static com.android.server.am.ActivityRecordProto.IDENTIFIER; import static com.android.server.am.ActivityRecordProto.PROC_ID; import static com.android.server.am.ActivityRecordProto.STATE; +import static com.android.server.am.ActivityRecordProto.TRANSLUCENT; import static com.android.server.am.ActivityRecordProto.VISIBLE; import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT; import static com.android.server.wm.IdentifierProto.HASH_CODE; @@ -2412,11 +2413,16 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } // Compute configuration based on max supported width and height. - outBounds.set(0, 0, maxActivityWidth, maxActivityHeight); - // Position the activity frame on the opposite side of the nav bar. - final int navBarPosition = service.mWindowManager.getNavBarPosition(); - final int left = navBarPosition == NAV_BAR_LEFT ? appBounds.right - outBounds.width() : 0; - outBounds.offsetTo(left, 0 /* top */); + // Also account for the left / top insets (e.g. from display cutouts), which will be clipped + // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app + // bounds would end up too small. + outBounds.set(0, 0, maxActivityWidth + appBounds.left, maxActivityHeight + appBounds.top); + + if (service.mWindowManager.getNavBarPosition() == NAV_BAR_LEFT) { + // Position the activity frame on the opposite side of the nav bar. + outBounds.left = appBounds.right - maxActivityWidth; + outBounds.right = appBounds.right; + } } boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) { @@ -2980,6 +2986,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo if (app != null) { proto.write(PROC_ID, app.pid); } + proto.write(TRANSLUCENT, !fullscreen); proto.end(token); } } diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 4e6307dbca8a..0f8c5269a95c 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -1015,26 +1015,25 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt locationListener = mFusedLocationListener; } - if (!locationManager.isProviderEnabled(provider)) { - Log.w(TAG, "Unable to request location since " + provider - + " provider does not exist or is not enabled."); - return; - } - Log.i(TAG, String.format( "GNSS HAL Requesting location updates from %s provider for %d millis.", provider, durationMillis)); - locationManager.requestLocationUpdates(provider, - LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0, - locationListener, mHandler.getLooper()); - locationListener.numLocationUpdateRequest++; - mHandler.postDelayed(() -> { - if (--locationListener.numLocationUpdateRequest == 0) { - Log.i(TAG, String.format("Removing location updates from %s provider.", provider)); - locationManager.removeUpdates(locationListener); - } - }, durationMillis); + try { + locationManager.requestLocationUpdates(provider, + LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0, + locationListener, mHandler.getLooper()); + locationListener.numLocationUpdateRequest++; + mHandler.postDelayed(() -> { + if (--locationListener.numLocationUpdateRequest == 0) { + Log.i(TAG, + String.format("Removing location updates from %s provider.", provider)); + locationManager.removeUpdates(locationListener); + } + }, durationMillis); + } catch (IllegalArgumentException e) { + Log.w(TAG, "Unable to request location.", e); + } } private void injectBestLocation(Location location) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index e810b1adaac3..d496ab67fec4 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17260,17 +17260,6 @@ public class PackageManagerService extends IPackageManager.Stub + "Persistent apps are not updateable."); return; } - // Prevent apps from downgrading their targetSandbox. - final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion; - final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion; - if (oldTargetSandbox == 2 && newTargetSandbox != 2) { - res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE, - "Package " + pkg.packageName + " new target sandbox " - + newTargetSandbox + " is incompatible with the previous value of" - + oldTargetSandbox + "."); - return; - } - // Prevent installing of child packages if (oldPackage.parentPackage != null) { res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index a735297b06c2..7ffd5ed07a31 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -6161,7 +6161,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { sendSystemKeyToStatusBarAsync(event.getKeyCode()); TelecomManager telecomManager = getTelecommService(); - if (telecomManager != null) { + if (telecomManager != null && !mHandleVolumeKeysInWM) { + // When {@link #mHandleVolumeKeysInWM} is set, volume key events + // should be dispatched to WM. if (telecomManager.isRinging()) { // If an incoming call is ringing, either VOLUME key means // "silence ringer". We handle these keys here, rather than diff --git a/services/core/java/com/android/server/power/BatterySaverPolicy.java b/services/core/java/com/android/server/power/BatterySaverPolicy.java index 91ef3d4a576e..ed2b79e7380c 100644 --- a/services/core/java/com/android/server/power/BatterySaverPolicy.java +++ b/services/core/java/com/android/server/power/BatterySaverPolicy.java @@ -392,7 +392,7 @@ public class BatterySaverPolicy extends ContentObserver { mForceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK, true); mOptionalSensorsDisabled = parser.getBoolean(KEY_OPTIONAL_SENSORS_DISABLED, true); mAodDisabled = parser.getBoolean(KEY_AOD_DISABLED, true); - mSendTronLog = parser.getBoolean(KEY_SEND_TRON_LOG, true); + mSendTronLog = parser.getBoolean(KEY_SEND_TRON_LOG, false); // Get default value from Settings.Secure final int defaultGpsMode = Settings.Secure.getInt(mContentResolver, SECURE_KEY_GPS_MODE, diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index b8431b1d8ad8..65c8e96a0774 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -22,7 +22,9 @@ import static com.android.server.wm.AlphaAnimationSpecProto.TO; import static com.android.server.wm.AnimationSpecProto.ALPHA; import android.graphics.Rect; +import android.util.Log; import android.util.proto.ProtoOutputStream; +import android.view.Surface; import android.view.SurfaceControl; import com.android.internal.annotations.VisibleForTesting; @@ -171,14 +173,18 @@ class Dimmer { */ private DimState getDimState(WindowContainer container) { if (mDimState == null) { - final SurfaceControl ctl = makeDimLayer(); - mDimState = new DimState(ctl); - /** - * See documentation on {@link #dimAbove} to understand lifecycle management of Dim's - * via state resetting for Dim's with containers. - */ - if (container == null) { - mDimState.mDontReset = true; + try { + final SurfaceControl ctl = makeDimLayer(); + mDimState = new DimState(ctl); + /** + * See documentation on {@link #dimAbove} to understand lifecycle management of + * Dim's via state resetting for Dim's with containers. + */ + if (container == null) { + mDimState.mDontReset = true; + } + } catch (Surface.OutOfResourcesException e) { + Log.w(TAG, "OutOfResourcesException creating dim surface"); } } @@ -189,6 +195,11 @@ class Dimmer { private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer, float alpha) { final DimState d = getDimState(container); + + if (d == null) { + return; + } + if (container != null) { // The dim method is called from WindowState.prepareSurfaces(), which is always called // in the correct Z from lowest Z to highest. This ensures that the dim layer is always @@ -208,10 +219,11 @@ class Dimmer { * @param t A Transaction in which to finish the dim. */ void stopDim(SurfaceControl.Transaction t) { - DimState d = getDimState(null); - t.hide(d.mDimLayer); - d.isVisible = false; - d.mDontReset = false; + if (mDimState != null) { + t.hide(mDimState.mDimLayer); + mDimState.isVisible = false; + mDimState.mDontReset = false; + } } /** diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index 7211533c1b44..2bfff269e457 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -206,6 +206,9 @@ class SurfaceAnimationRunner { } } }); + a.mAnim = anim; + mRunningAnimations.put(a.mLeash, a); + anim.start(); if (a.mAnimSpec.canSkipFirstFrame()) { // If we can skip the first frame, we start one frame later. @@ -215,8 +218,6 @@ class SurfaceAnimationRunner { // Immediately start the animation by manually applying an animation frame. Otherwise, the // start time would only be set in the next frame, leading to a delay. anim.doAnimationFrame(mChoreographer.getFrameTime()); - a.mAnim = anim; - mRunningAnimations.put(a.mLeash, a); } private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) { diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java index c366e4d6108b..7b775f568292 100644 --- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java +++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java @@ -54,7 +54,7 @@ public class WindowManagerDebugConfig { static final boolean DEBUG_STARTING_WINDOW_VERBOSE = false; static final boolean DEBUG_STARTING_WINDOW = DEBUG_STARTING_WINDOW_VERBOSE || false; static final boolean DEBUG_WALLPAPER = false; - static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER; + static final boolean DEBUG_WALLPAPER_LIGHT = true || DEBUG_WALLPAPER; static final boolean DEBUG_DRAG = false; static final boolean DEBUG_SCREEN_ON = false; static final boolean DEBUG_SCREENSHOT = false; diff --git a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java index ea0fe455672b..7f397d6a2cfc 100644 --- a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java @@ -18,6 +18,8 @@ package com.android.server.appops; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; @@ -36,6 +38,8 @@ import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.List; + /** * Tests app ops version upgrades */ @@ -107,6 +111,46 @@ public class AppOpsActiveWatcherTest { verifyNoMoreInteractions(listener); } + @Test + public void testIsRunning() throws Exception { + final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); + // Start the op + appOpsManager.startOp(AppOpsManager.OP_CAMERA); + + assertTrue("Camera should be running", isCameraOn(appOpsManager)); + + // Finish the op + appOpsManager.finishOp(AppOpsManager.OP_CAMERA); + + assertFalse("Camera should not be running", isCameraOn(appOpsManager)); + } + + private boolean isCameraOn(AppOpsManager appOpsManager) { + List<AppOpsManager.PackageOps> packages + = appOpsManager.getPackagesForOps(new int[] {AppOpsManager.OP_CAMERA}); + // AppOpsManager can return null when there is no requested data. + if (packages != null) { + final int numPackages = packages.size(); + for (int packageInd = 0; packageInd < numPackages; packageInd++) { + AppOpsManager.PackageOps packageOp = packages.get(packageInd); + List<AppOpsManager.OpEntry> opEntries = packageOp.getOps(); + if (opEntries != null) { + final int numOps = opEntries.size(); + for (int opInd = 0; opInd < numOps; opInd++) { + AppOpsManager.OpEntry opEntry = opEntries.get(opInd); + if (opEntry.getOp() == AppOpsManager.OP_CAMERA) { + if (opEntry.isRunning()) { + return true; + } + } + } + } + } + } + + return false; + } + private static Context getContext() { return InstrumentationRegistry.getContext(); } |