Merge "Lock relevant fields on channel update" into oc-dev
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 588a1bf..b60aed6 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -51,6 +51,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.IUserManager;
import android.os.ParcelFileDescriptor;
import android.os.Process;
@@ -347,7 +348,7 @@
private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
@Override
- public void send(int code, Intent intent, String resolvedType,
+ public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
try {
mResult.offer(intent, 5, TimeUnit.SECONDS);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 6fa0a6d..a8183f2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -976,7 +976,7 @@
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
- if (getApplicationInfo().targetSdkVersion >= O && mActivityInfo.isFixedOrientation()) {
+ if (getApplicationInfo().targetSdkVersion > O && mActivityInfo.isFixedOrientation()) {
final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
ta.recycle();
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 0dfaf6a..e9ee1386 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -169,7 +169,8 @@
* Sets how long a {@link PendingIntent} can be temporarily whitelist to by bypass restrictions
* such as Power Save mode.
*/
- public abstract void setPendingIntentWhitelistDuration(IIntentSender target, long duration);
+ public abstract void setPendingIntentWhitelistDuration(IIntentSender target,
+ IBinder whitelistToken, long duration);
/**
* Allow DeviceIdleController to tell us about what apps are whitelisted.
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 424e783..2de205b 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -65,6 +65,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.IStorageManager;
+import android.os.storage.StorageManager;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
@@ -376,7 +377,9 @@
checkMode(mode);
if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
if (isCredentialProtectedStorage()
- && !getSystemService(UserManager.class).isUserUnlocked() && !isBuggy()) {
+ && !getSystemService(StorageManager.class).isUserKeyUnlocked(
+ UserHandle.myUserId())
+ && !isBuggy()) {
throw new IllegalStateException("SharedPreferences in credential encrypted "
+ "storage are not available until after user is unlocked");
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 68fce75..9552d17 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -562,8 +562,8 @@
void notifyLockedProfile(int userId);
void startConfirmDeviceCredentialIntent(in Intent intent, in Bundle options);
void sendIdleJobTrigger();
- int sendIntentSender(in IIntentSender target, int code, in Intent intent,
- in String resolvedType, in IIntentReceiver finishedReceiver,
+ int sendIntentSender(in IIntentSender target, in IBinder whitelistToken, int code,
+ in Intent intent, in String resolvedType, in IIntentReceiver finishedReceiver,
in String requiredPermission, in Bundle options);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 06509ae..4294eab 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -42,8 +42,10 @@
import android.media.session.MediaSession;
import android.net.Uri;
import android.os.BadParcelableException;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -835,6 +837,22 @@
public ArraySet<PendingIntent> allPendingIntents;
/**
+ * Token identifying the notification that is applying doze/bgcheck whitelisting to the
+ * pending intents inside of it, so only those will get the behavior.
+ *
+ * @hide
+ */
+ static public IBinder whitelistToken;
+
+ /**
+ * Must be set by a process to start associating tokens with Notification objects
+ * coming in to it. This is set by NotificationManagerService.
+ *
+ * @hide
+ */
+ static public IBinder processWhitelistToken;
+
+ /**
* {@link #extras} key: this is the title of the notification,
* as supplied to {@link Builder#setContentTitle(CharSequence)}.
*/
@@ -1823,6 +1841,13 @@
{
int version = parcel.readInt();
+ whitelistToken = parcel.readStrongBinder();
+ if (whitelistToken == null) {
+ whitelistToken = processWhitelistToken;
+ }
+ // Propagate this token to all pending intents that are unmarshalled from the parcel.
+ parcel.setClassCookie(PendingIntent.class, whitelistToken);
+
when = parcel.readLong();
creationTime = parcel.readLong();
if (parcel.readInt() != 0) {
@@ -1929,6 +1954,7 @@
* @hide
*/
public void cloneInto(Notification that, boolean heavy) {
+ that.whitelistToken = this.whitelistToken;
that.when = this.when;
that.creationTime = this.creationTime;
that.mSmallIcon = this.mSmallIcon;
@@ -2158,6 +2184,7 @@
private void writeToParcelImpl(Parcel parcel, int flags) {
parcel.writeInt(1);
+ parcel.writeStrongBinder(whitelistToken);
parcel.writeLong(when);
parcel.writeLong(creationTime);
if (mSmallIcon == null && icon != 0) {
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index dc432af..11d9b5e 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -93,6 +93,7 @@
*/
public final class PendingIntent implements Parcelable {
private final IIntentSender mTarget;
+ private IBinder mWhitelistToken;
/** @hide */
@IntDef(flag = true,
@@ -656,7 +657,7 @@
*
*/
public IntentSender getIntentSender() {
- return new IntentSender(mTarget);
+ return new IntentSender(mTarget, mWhitelistToken);
}
/**
@@ -870,7 +871,7 @@
intent.resolveTypeIfNeeded(context.getContentResolver())
: null;
int res = ActivityManager.getService().sendIntentSender(
- mTarget, code, intent, resolvedType,
+ mTarget, mWhitelistToken, code, intent, resolvedType,
onFinished != null
? new FinishedDispatcher(this, onFinished, handler)
: null,
@@ -1085,7 +1086,9 @@
= new Parcelable.Creator<PendingIntent>() {
public PendingIntent createFromParcel(Parcel in) {
IBinder target = in.readStrongBinder();
- return target != null ? new PendingIntent(target) : null;
+ return target != null
+ ? new PendingIntent(target, in.getClassCookie(PendingIntent.class))
+ : null;
}
public PendingIntent[] newArray(int size) {
@@ -1108,31 +1111,39 @@
}
/**
- * Convenience function for reading either a Messenger or null pointer from
- * a Parcel. You must have previously written the Messenger with
+ * Convenience function for reading either a PendingIntent or null pointer from
+ * a Parcel. You must have previously written the PendingIntent with
* {@link #writePendingIntentOrNullToParcel}.
*
- * @param in The Parcel containing the written Messenger.
+ * @param in The Parcel containing the written PendingIntent.
*
- * @return Returns the Messenger read from the Parcel, or null if null had
+ * @return Returns the PendingIntent read from the Parcel, or null if null had
* been written.
*/
@Nullable
public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) {
IBinder b = in.readStrongBinder();
- return b != null ? new PendingIntent(b) : null;
+ return b != null ? new PendingIntent(b, in.getClassCookie(PendingIntent.class)) : null;
}
/*package*/ PendingIntent(IIntentSender target) {
mTarget = target;
}
- /*package*/ PendingIntent(IBinder target) {
+ /*package*/ PendingIntent(IBinder target, Object cookie) {
mTarget = IIntentSender.Stub.asInterface(target);
+ if (cookie != null) {
+ mWhitelistToken = (IBinder)cookie;
+ }
}
/** @hide */
public IIntentSender getTarget() {
return mTarget;
}
+
+ /** @hide */
+ public IBinder getWhitelistToken() {
+ return mWhitelistToken;
+ }
}
diff --git a/core/java/android/content/IIntentSender.aidl b/core/java/android/content/IIntentSender.aidl
index 45c62d4..21ea2fe 100644
--- a/core/java/android/content/IIntentSender.aidl
+++ b/core/java/android/content/IIntentSender.aidl
@@ -22,6 +22,6 @@
/** @hide */
oneway interface IIntentSender {
- void send(int code, in Intent intent, String resolvedType,
+ void send(int code, in Intent intent, String resolvedType, in IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission, in Bundle options);
}
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 4adb5b7..0a456b5 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -56,6 +56,7 @@
*/
public class IntentSender implements Parcelable {
private final IIntentSender mTarget;
+ IBinder mWhitelistToken;
/**
* Exception thrown when trying to send through a PendingIntent that
@@ -187,7 +188,7 @@
String resolvedType = intent != null ?
intent.resolveTypeIfNeeded(context.getContentResolver())
: null;
- int res = ActivityManager.getService().sendIntentSender(mTarget,
+ int res = ActivityManager.getService().sendIntentSender(mTarget, mWhitelistToken,
code, intent, resolvedType,
onFinished != null
? new FinishedDispatcher(this, onFinished, handler)
@@ -365,6 +366,12 @@
}
/** @hide */
+ public IntentSender(IIntentSender target, IBinder whitelistToken) {
+ mTarget = target;
+ mWhitelistToken = whitelistToken;
+ }
+
+ /** @hide */
public IntentSender(IBinder target) {
mTarget = IIntentSender.Stub.asInterface(target);
}
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 65025fb..8d85880 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -1548,6 +1548,7 @@
Parcel p = Parcel.obtain();
p.setDataPosition(0);
p.appendFrom(parcel, offset, length);
+ p.adoptClassCookies(parcel);
if (DEBUG) Log.d(TAG, "Retrieving " + Integer.toHexString(System.identityHashCode(this))
+ ": " + length + " bundle bytes starting at " + offset);
p.setDataPosition(0);
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index c5c743b..38a5395 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -204,6 +204,8 @@
private boolean mOwnsNativeParcelObject;
private long mNativeSize;
+ private ArrayMap<Class, Object> mClassCookies;
+
private RuntimeException mStack;
private static final int POOL_SIZE = 6;
@@ -497,6 +499,24 @@
return nativeCompareData(mNativePtr, other.mNativePtr);
}
+ /** @hide */
+ public final void setClassCookie(Class clz, Object cookie) {
+ if (mClassCookies == null) {
+ mClassCookies = new ArrayMap<>();
+ }
+ mClassCookies.put(clz, cookie);
+ }
+
+ /** @hide */
+ public final Object getClassCookie(Class clz) {
+ return mClassCookies != null ? mClassCookies.get(clz) : null;
+ }
+
+ /** @hide */
+ public final void adoptClassCookies(Parcel from) {
+ mClassCookies = from.mClassCookies;
+ }
+
/**
* Report whether the parcel contains any marshalled file descriptors.
*/
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d8eb950..3121945 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2858,6 +2858,14 @@
*/
static final int PFLAG3_SCROLL_INDICATOR_END = 0x2000;
+ /**
+ * Flag indicating that when layout is completed we should notify
+ * that the view was entered for autofill purposes. To minimize
+ * showing autofill for views not visible to the user we evaluate
+ * user visibility which cannot be done until the view is laid out.
+ */
+ static final int PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT = 0x4000;
+
static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
static final int SCROLL_INDICATORS_NONE = 0x0000;
@@ -6845,8 +6853,15 @@
if (isAutofillable() && isAttachedToWindow()) {
AutofillManager afm = getAutofillManager();
if (afm != null) {
- if (enter && hasWindowFocus() && isFocused() && isVisibleToUser()) {
- afm.notifyViewEntered(this);
+ if (enter && hasWindowFocus() && isFocused()) {
+ // We have not been laid out yet, hence cannot evaluate
+ // whether this view is visible to the user, we will do
+ // the evaluation once layout is complete.
+ if (!isLaidOut()) {
+ mPrivateFlags3 |= PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT;
+ } else if (isVisibleToUser()) {
+ afm.notifyViewEntered(this);
+ }
} else if (!hasWindowFocus() || !isFocused()) {
afm.notifyViewExited(this);
}
@@ -19305,6 +19320,11 @@
mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
+
+ if ((mPrivateFlags3 & PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT) != 0) {
+ mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT;
+ notifyEnterOrExitForAutoFillIfNeeded(true);
+ }
}
/**
diff --git a/packages/SettingsLib/src/com/android/settingslib/accessibility/LinkAccessibilityHelper.java b/packages/SettingsLib/src/com/android/settingslib/accessibility/LinkAccessibilityHelper.java
deleted file mode 100644
index 74b0c6b..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/accessibility/LinkAccessibilityHelper.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settingslib.accessibility;
-
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
-import android.support.v4.widget.ExploreByTouchHelper;
-import android.text.Layout;
-import android.text.Spanned;
-import android.text.style.ClickableSpan;
-import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.TextView;
-
-import java.util.List;
-
-/**
- * COPIED FROM SETUP WIZARD An accessibility delegate that allows {@link
- * android.text.style.ClickableSpan} to be focused and clicked by accessibility services.
- *
- * <p>Sample usage:
- *
- * <pre>
- * LinkAccessibilityHelper mAccessibilityHelper;
- *
- * private void init() {
- * mAccessibilityHelper = new LinkAccessibilityHelper(myTextView);
- * ViewCompat.setAccessibilityDelegate(myTextView, mLinkHelper);
- * }
- *
- * {@literal @}Override
- * protected boolean dispatchHoverEvent({@literal @}NonNull MotionEvent event) {
- * if (mAccessibilityHelper != null && mAccessibilityHelper.dispatchHoverEvent(event)) {
- * return true;
- * }
- * return super.dispatchHoverEvent(event);
- * }
- * </pre>
- *
- * @see android.support.v4.widget.ExploreByTouchHelper
- */
-public class LinkAccessibilityHelper extends ExploreByTouchHelper {
-
- private static final String TAG = "LinkAccessibilityHelper";
-
- private final TextView mView;
- private final Rect mTempRect = new Rect();
-
- public LinkAccessibilityHelper(TextView view) {
- super(view);
- mView = view;
- }
-
- @Override
- protected int getVirtualViewAt(float x, float y) {
- final CharSequence text = mView.getText();
- if (text instanceof Spanned) {
- final Spanned spannedText = (Spanned) text;
- final int offset = getOffsetForPosition(mView, x, y);
- ClickableSpan[] linkSpans = spannedText.getSpans(offset, offset, ClickableSpan.class);
- if (linkSpans.length == 1) {
- ClickableSpan linkSpan = linkSpans[0];
- return spannedText.getSpanStart(linkSpan);
- }
- }
- return INVALID_ID;
- }
-
- @Override
- protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
- final CharSequence text = mView.getText();
- if (text instanceof Spanned) {
- final Spanned spannedText = (Spanned) text;
- ClickableSpan[] linkSpans =
- spannedText.getSpans(0, spannedText.length(), ClickableSpan.class);
- for (ClickableSpan span : linkSpans) {
- virtualViewIds.add(spannedText.getSpanStart(span));
- }
- }
- }
-
- @Override
- protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
- final ClickableSpan span = getSpanForOffset(virtualViewId);
- if (span != null) {
- event.setContentDescription(getTextForSpan(span));
- } else {
- Log.e(TAG, "LinkSpan is null for offset: " + virtualViewId);
- event.setContentDescription(mView.getText());
- }
- }
-
- @Override
- protected void onPopulateNodeForVirtualView(
- int virtualViewId, AccessibilityNodeInfoCompat info) {
- final ClickableSpan span = getSpanForOffset(virtualViewId);
- if (span != null) {
- info.setContentDescription(getTextForSpan(span));
- } else {
- Log.e(TAG, "LinkSpan is null for offset: " + virtualViewId);
- info.setContentDescription(mView.getText());
- }
- info.setFocusable(true);
- info.setClickable(true);
- getBoundsForSpan(span, mTempRect);
- if (mTempRect.isEmpty()) {
- Log.e(TAG, "LinkSpan bounds is empty for: " + virtualViewId);
- mTempRect.set(0, 0, 1, 1);
- }
- info.setBoundsInParent(mTempRect);
- info.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
- }
-
- @Override
- protected boolean onPerformActionForVirtualView(
- int virtualViewId, int action, Bundle arguments) {
- if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
- ClickableSpan span = getSpanForOffset(virtualViewId);
- if (span != null) {
- span.onClick(mView);
- return true;
- } else {
- Log.e(TAG, "LinkSpan is null for offset: " + virtualViewId);
- }
- }
- return false;
- }
-
- private ClickableSpan getSpanForOffset(int offset) {
- CharSequence text = mView.getText();
- if (text instanceof Spanned) {
- Spanned spannedText = (Spanned) text;
- ClickableSpan[] spans = spannedText.getSpans(offset, offset, ClickableSpan.class);
- if (spans.length == 1) {
- return spans[0];
- }
- }
- return null;
- }
-
- private CharSequence getTextForSpan(ClickableSpan span) {
- CharSequence text = mView.getText();
- if (text instanceof Spanned) {
- Spanned spannedText = (Spanned) text;
- return spannedText.subSequence(
- spannedText.getSpanStart(span), spannedText.getSpanEnd(span));
- }
- return text;
- }
-
- // Find the bounds of a span. If it spans multiple lines, it will only return the bounds for the
- // section on the first line.
- private Rect getBoundsForSpan(ClickableSpan span, Rect outRect) {
- CharSequence text = mView.getText();
- outRect.setEmpty();
- if (text instanceof Spanned) {
- final Layout layout = mView.getLayout();
- if (layout != null) {
- Spanned spannedText = (Spanned) text;
- final int spanStart = spannedText.getSpanStart(span);
- final int spanEnd = spannedText.getSpanEnd(span);
- final float xStart = layout.getPrimaryHorizontal(spanStart);
- final float xEnd = layout.getPrimaryHorizontal(spanEnd);
- final int lineStart = layout.getLineForOffset(spanStart);
- final int lineEnd = layout.getLineForOffset(spanEnd);
- layout.getLineBounds(lineStart, outRect);
- if (lineEnd == lineStart) {
- // If the span is on a single line, adjust both the left and right bounds
- // so outrect is exactly bounding the span.
- outRect.left = (int) Math.min(xStart, xEnd);
- outRect.right = (int) Math.max(xStart, xEnd);
- } else {
- // If the span wraps across multiple lines, only use the first line (as returned
- // by layout.getLineBounds above), and adjust the "start" of outrect to where
- // the span starts, leaving the "end" of outrect at the end of the line.
- // ("start" being left for LTR, and right for RTL)
- if (layout.getParagraphDirection(lineStart) == Layout.DIR_RIGHT_TO_LEFT) {
- outRect.right = (int) xStart;
- } else {
- outRect.left = (int) xStart;
- }
- }
-
- // Offset for padding
- outRect.offset(mView.getTotalPaddingLeft(), mView.getTotalPaddingTop());
- }
- }
- return outRect;
- }
-
- // Compat implementation of TextView#getOffsetForPosition().
-
- private static int getOffsetForPosition(TextView view, float x, float y) {
- if (view.getLayout() == null) return -1;
- final int line = getLineAtCoordinate(view, y);
- return getOffsetAtCoordinate(view, line, x);
- }
-
- private static float convertToLocalHorizontalCoordinate(TextView view, float x) {
- x -= view.getTotalPaddingLeft();
- // Clamp the position to inside of the view.
- x = Math.max(0.0f, x);
- x = Math.min(view.getWidth() - view.getTotalPaddingRight() - 1, x);
- x += view.getScrollX();
- return x;
- }
-
- private static int getLineAtCoordinate(TextView view, float y) {
- y -= view.getTotalPaddingTop();
- // Clamp the position to inside of the view.
- y = Math.max(0.0f, y);
- y = Math.min(view.getHeight() - view.getTotalPaddingBottom() - 1, y);
- y += view.getScrollY();
- return view.getLayout().getLineForVertical((int) y);
- }
-
- private static int getOffsetAtCoordinate(TextView view, int line, float x) {
- x = convertToLocalHorizontalCoordinate(view, x);
- return view.getLayout().getOffsetForHorizontal(line, x);
- }
-}
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/LinkTextView.java b/packages/SettingsLib/src/com/android/settingslib/widget/LinkTextView.java
index da86536..8b9315c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/widget/LinkTextView.java
+++ b/packages/SettingsLib/src/com/android/settingslib/widget/LinkTextView.java
@@ -16,32 +16,25 @@
package com.android.settingslib.widget;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.v4.view.ViewCompat;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
-import android.view.MotionEvent;
import android.widget.TextView;
-import com.android.settingslib.accessibility.LinkAccessibilityHelper;
+
/**
- * Copied from setup wizard. This TextView performs two functions. The first is to make it so the
- * link behaves properly and becomes clickable. The second is that it makes the link visible to
- * accessibility services.
+ * Copied from setup wizard. This TextView performed two functions. The first is to make it so the
+ * link behaves properly and becomes clickable. The second was that it made the link visible to
+ * accessibility services, but from O forward support for links is provided natively.
*/
public class LinkTextView extends TextView {
- private LinkAccessibilityHelper mAccessibilityHelper;
-
public LinkTextView(Context context) {
this(context, null);
}
public LinkTextView(Context context, AttributeSet attrs) {
super(context, attrs);
- mAccessibilityHelper = new LinkAccessibilityHelper(this);
- ViewCompat.setAccessibilityDelegate(this, mAccessibilityHelper);
}
@Override
@@ -55,12 +48,4 @@
}
}
}
-
- @Override
- protected boolean dispatchHoverEvent(@NonNull MotionEvent event) {
- if (mAccessibilityHelper.dispatchHoverEvent(event)) {
- return true;
- }
- return super.dispatchHoverEvent(event);
- }
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 90c65580..8f24ec7 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -767,17 +767,22 @@
mDockedStackMinimized = minimized;
} else if (mDockedStackMinimized != minimized) {
mIsInMinimizeInteraction = true;
- if (minimized && (mCurrentAnimator == null || !mCurrentAnimator.isRunning())) {
+ if (minimized && (mCurrentAnimator == null || !mCurrentAnimator.isRunning())
+ && (mDividerPositionBeforeMinimized <= 0 || !mAdjustedForIme)) {
mDividerPositionBeforeMinimized = getCurrentPosition();
}
mMinimizedSnapAlgorithm = null;
mDockedStackMinimized = minimized;
initializeSnapAlgorithm();
- stopDragging(getCurrentPosition(), minimized ?
- mMinimizedSnapAlgorithm.getMiddleTarget() :
- mSnapAlgorithm.calculateNonDismissingSnapTarget(
+ stopDragging(minimized
+ ? mDividerPositionBeforeMinimized
+ : getCurrentPosition(),
+ minimized
+ ? mMinimizedSnapAlgorithm.getMiddleTarget()
+ : mSnapAlgorithm.calculateNonDismissingSnapTarget(
mDividerPositionBeforeMinimized),
animDuration, Interpolators.FAST_OUT_SLOW_IN, 0);
+ setAdjustedForIme(false, animDuration);
}
if (!minimized) {
mBackground.animate().withEndAction(mResetBackgroundRunnable);
@@ -820,6 +825,9 @@
.setDuration(animDuration)
.start();
mAdjustedForIme = adjustedForIme;
+ if (mHomeStackResizable && adjustedForIme) {
+ mDividerPositionBeforeMinimized = getCurrentPosition();
+ }
}
private void resetBackground() {
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index a12ebb2..35f4fae 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -27,11 +27,13 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.ICancellationSignal;
import android.os.Message;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.service.autofill.AutofillService;
import android.service.autofill.FillRequest;
@@ -43,6 +45,7 @@
import android.text.format.DateUtils;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.HandlerCaller;
import com.android.server.FgThread;
@@ -63,6 +66,9 @@
// How long after the last interaction with the service we would unbind
private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
+ // How long after we make a remote request to a fill service we timeout
+ private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
+
private final Context mContext;
private final ComponentName mComponentName;
@@ -413,12 +419,18 @@
private static final class PendingFillRequest extends PendingRequest {
private final Object mLock = new Object();
+
private final WeakReference<RemoteFillService> mWeakService;
private final FillRequest mRequest;
private final IFillCallback mCallback;
private ICancellationSignal mCancellation;
+
+ @GuardedBy("mLock")
private boolean mCancelled;
+ @GuardedBy("mLock")
+ private boolean mCompleted;
+
public PendingFillRequest(FillRequest request, RemoteFillService service) {
mRequest = request;
mWeakService = new WeakReference<>(service);
@@ -443,8 +455,15 @@
@Override
public void onSuccess(FillResponse response) {
+ synchronized (mLock) {
+ if (mCompleted) {
+ return;
+ }
+ mCompleted = true;
+ }
RemoteFillService remoteService = mWeakService.get();
if (remoteService != null) {
+ service.mHandler.getHandler().removeCallbacks(PendingFillRequest.this);
remoteService.dispatchOnFillRequestSuccess(PendingFillRequest.this,
getCallingUid(), request.getFlags(), response);
}
@@ -452,13 +471,29 @@
@Override
public void onFailure(CharSequence message) {
+ synchronized (mLock) {
+ if (mCompleted) {
+ return;
+ }
+ mCompleted = true;
+ }
RemoteFillService remoteService = mWeakService.get();
if (remoteService != null) {
+ service.mHandler.getHandler().removeCallbacks(PendingFillRequest.this);
remoteService.dispatchOnFillRequestFailure(
PendingFillRequest.this, message);
}
}
};
+ service.mHandler.getHandler().postAtTime(() -> {
+ cancel();
+ try {
+ mCallback.onFailure(null);
+ } catch (RemoteException e) {
+ /* ignore */
+ }
+ }, PendingFillRequest.this,
+ SystemClock.uptimeMillis() + TIMEOUT_REMOTE_REQUEST_MILLIS);
}
@Override
@@ -496,10 +531,15 @@
}
private static final class PendingSaveRequest extends PendingRequest {
+ private final Object mLock = new Object();
+
private final WeakReference<RemoteFillService> mWeakService;
private final SaveRequest mRequest;
private final ISaveCallback mCallback;
+ @GuardedBy("mLock")
+ private boolean mCompleted;
+
public PendingSaveRequest(@NonNull SaveRequest request,
@NonNull RemoteFillService service) {
mRequest = request;
@@ -507,8 +547,16 @@
mCallback = new ISaveCallback.Stub() {
@Override
public void onSuccess() {
+ synchronized (mLock) {
+ if (mCompleted) {
+ return;
+ }
+ mCompleted = true;
+ }
+ cancel();
RemoteFillService service = mWeakService.get();
if (service != null) {
+ service.mHandler.getHandler().removeCallbacks(PendingSaveRequest.this);
service.dispatchOnSaveRequestSuccess(
PendingSaveRequest.this);
}
@@ -516,13 +564,29 @@
@Override
public void onFailure(CharSequence message) {
+ synchronized (mLock) {
+ if (mCompleted) {
+ return;
+ }
+ mCompleted = true;
+ }
RemoteFillService service = mWeakService.get();
if (service != null) {
+ service.mHandler.getHandler().removeCallbacks(PendingSaveRequest.this);
service.dispatchOnSaveRequestFailure(
PendingSaveRequest.this, message);
}
}
};
+ service.mHandler.getHandler().postAtTime(() -> {
+ cancel();
+ try {
+ mCallback.onFailure(null);
+ } catch (RemoteException e) {
+ /* ignore */
+ }
+ }, PendingSaveRequest.this,
+ SystemClock.uptimeMillis() + TIMEOUT_REMOTE_REQUEST_MILLIS);
}
@Override
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 1ed46a0..5e03508 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1493,12 +1493,13 @@
mAm.updateOomAdjLocked(r.binding.service.app, false);
}
}
+
+ mAm.updateOomAdjLocked();
+
} finally {
Binder.restoreCallingIdentity(origId);
}
- mAm.updateOomAdjLocked();
-
return true;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7304c22..e76ffb1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1472,6 +1472,20 @@
boolean mOrigWaitForDebugger = false;
boolean mAlwaysFinishActivities = false;
boolean mForceResizableActivities;
+ /**
+ * Flag that indicates if multi-window is enabled.
+ *
+ * For any particular form of multi-window to be enabled, generic multi-window must be enabled
+ * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
+ * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
+ * At least one of the forms of multi-window must be enabled in order for this flag to be
+ * initialized to 'true'.
+ *
+ * @see #mSupportsSplitScreenMultiWindow
+ * @see #mSupportsFreeformWindowManagement
+ * @see #mSupportsPictureInPicture
+ * @see #mSupportsMultiDisplay
+ */
boolean mSupportsMultiWindow;
boolean mSupportsSplitScreenMultiWindow;
boolean mSupportsFreeformWindowManagement;
@@ -4598,7 +4612,7 @@
mAppSwitchesAllowedTime = 0;
}
}
- int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
+ int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, null,
resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
return ret;
}
@@ -7504,11 +7518,12 @@
}
@Override
- public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
+ public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
+ Intent intent, String resolvedType,
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
if (target instanceof PendingIntentRecord) {
return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
- finishedReceiver, requiredPermission, options);
+ whitelistToken, finishedReceiver, requiredPermission, options);
} else {
if (intent == null) {
// Weird case: someone has given us their own custom IIntentSender, and now
@@ -7520,7 +7535,8 @@
intent = new Intent(Intent.ACTION_MAIN);
}
try {
- target.send(code, intent, resolvedType, null, requiredPermission, options);
+ target.send(code, intent, resolvedType, whitelistToken, null,
+ requiredPermission, options);
} catch (RemoteException e) {
}
// Platform code can rely on getting a result back when the send is done, but if
@@ -7817,11 +7833,15 @@
// be guarded by permission checking.
int getUidState(int uid) {
synchronized (this) {
- UidRecord uidRec = mActiveUids.get(uid);
- return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
+ return getUidStateLocked(uid);
}
}
+ int getUidStateLocked(int uid) {
+ UidRecord uidRec = mActiveUids.get(uid);
+ return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
+ }
+
@Override
public boolean isInMultiWindowMode(IBinder token) {
final long origId = Binder.clearCallingIdentity();
@@ -13926,16 +13946,23 @@
mAlwaysFinishActivities = alwaysFinishActivities;
mSupportsLeanbackOnly = supportsLeanbackOnly;
mForceResizableActivities = forceResizable;
- if (supportsMultiWindow || forceResizable) {
+ final boolean multiWindowFormEnabled = freeformWindowManagement
+ || supportsSplitScreenMultiWindow
+ || supportsPictureInPicture
+ || supportsMultiDisplay;
+ if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
mSupportsMultiWindow = true;
- mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
+ mSupportsFreeformWindowManagement = freeformWindowManagement;
+ mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
+ mSupportsPictureInPicture = supportsPictureInPicture;
+ mSupportsMultiDisplay = supportsMultiDisplay;
} else {
mSupportsMultiWindow = false;
mSupportsFreeformWindowManagement = false;
+ mSupportsSplitScreenMultiWindow = false;
+ mSupportsPictureInPicture = false;
+ mSupportsMultiDisplay = false;
}
- mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
- mSupportsPictureInPicture = supportsPictureInPicture;
- mSupportsMultiDisplay = supportsMultiDisplay;
mWindowManager.setForceResizableTasks(mForceResizableActivities);
mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
// This happens before any activities are started, so we can change global configuration
@@ -23642,12 +23669,13 @@
}
@Override
- public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
+ public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
+ long duration) {
if (!(target instanceof PendingIntentRecord)) {
Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
return;
}
- ((PendingIntentRecord) target).setWhitelistDurationLocked(duration);
+ ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index dab122f..6eae9e6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -22,11 +22,8 @@
import android.app.IActivityContainer;
import android.app.IActivityController;
import android.app.IActivityManager;
-import android.app.IInstrumentationWatcher;
import android.app.IStopUserCallback;
-import android.app.Instrumentation;
import android.app.ProfilerInfo;
-import android.app.UiAutomationConnection;
import android.app.WaitResult;
import android.app.usage.ConfigurationStats;
import android.app.usage.IUsageStatsManager;
@@ -37,7 +34,6 @@
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.pm.IPackageManager;
-import android.content.pm.InstrumentationInfo;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 5c57be2..f13dad7 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -2180,7 +2180,7 @@
void setRequestedOrientation(int requestedOrientation) {
if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen
- && appInfo.targetSdkVersion >= O) {
+ && appInfo.targetSdkVersion > O) {
throw new IllegalStateException("Only fullscreen activities can request orientation");
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 8b7efff..4049500 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -4731,7 +4731,7 @@
checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
pendingIntent.key.requestResolvedType);
- return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
+ return pendingIntent.sendInner(0, null, null, null, null, null, null, null, 0,
FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
}
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 7ba67c5..6eca3fa 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -32,6 +32,7 @@
import android.os.RemoteException;
import android.os.TransactionTooLargeException;
import android.os.UserHandle;
+import android.util.ArrayMap;
import android.util.Slog;
import android.util.TimeUtils;
@@ -51,7 +52,7 @@
final WeakReference<PendingIntentRecord> ref;
boolean sent = false;
boolean canceled = false;
- private long whitelistDuration = 0;
+ private ArrayMap<IBinder, Long> whitelistDuration;
private RemoteCallbackList<IResultReceiver> mCancelCallbacks;
String stringName;
@@ -194,8 +195,19 @@
ref = new WeakReference<PendingIntentRecord>(this);
}
- void setWhitelistDurationLocked(long duration) {
- this.whitelistDuration = duration;
+ void setWhitelistDurationLocked(IBinder whitelistToken, long duration) {
+ if (duration > 0) {
+ if (whitelistDuration == null) {
+ whitelistDuration = new ArrayMap<>();
+ }
+ whitelistDuration.put(whitelistToken, duration);
+ } else if (whitelistDuration != null) {
+ whitelistDuration.remove(whitelistToken);
+ if (whitelistDuration.size() <= 0) {
+ whitelistDuration = null;
+ }
+
+ }
this.stringName = null;
}
@@ -219,19 +231,20 @@
return listeners;
}
- public void send(int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver,
- String requiredPermission, Bundle options) {
- sendInner(code, intent, resolvedType, finishedReceiver,
- requiredPermission, null, null, 0, 0, 0, options, null);
- }
-
- public int sendWithResult(int code, Intent intent, String resolvedType,
+ public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
- return sendInner(code, intent, resolvedType, finishedReceiver,
+ sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver,
requiredPermission, null, null, 0, 0, 0, options, null);
}
- int sendInner(int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver,
+ public int sendWithResult(int code, Intent intent, String resolvedType, IBinder whitelistToken,
+ IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
+ return sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver,
+ requiredPermission, null, null, 0, 0, 0, options, null);
+ }
+
+ int sendInner(int code, Intent intent, String resolvedType, IBinder whitelistToken,
+ IIntentReceiver finishedReceiver,
String requiredPermission, IBinder resultTo, String resultWho, int requestCode,
int flagsMask, int flagsValues, Bundle options, IActivityContainer container) {
if (intent != null) intent.setDefusable(true);
@@ -276,20 +289,29 @@
final long origId = Binder.clearCallingIdentity();
- if (whitelistDuration > 0) {
- StringBuilder tag = new StringBuilder(64);
- tag.append("pendingintent:");
- UserHandle.formatUid(tag, callingUid);
- tag.append(":");
- if (finalIntent.getAction() != null) {
- tag.append(finalIntent.getAction());
- } else if (finalIntent.getComponent() != null) {
- finalIntent.getComponent().appendShortString(tag);
- } else if (finalIntent.getData() != null) {
- tag.append(finalIntent.getData());
+ if (whitelistDuration != null) {
+ Long duration = whitelistDuration.get(whitelistToken);
+ if (duration != null) {
+ int procState = owner.getUidState(callingUid);
+ if (!ActivityManager.isProcStateBackground(procState)) {
+ StringBuilder tag = new StringBuilder(64);
+ tag.append("pendingintent:");
+ UserHandle.formatUid(tag, callingUid);
+ tag.append(":");
+ if (finalIntent.getAction() != null) {
+ tag.append(finalIntent.getAction());
+ } else if (finalIntent.getComponent() != null) {
+ finalIntent.getComponent().appendShortString(tag);
+ } else if (finalIntent.getData() != null) {
+ tag.append(finalIntent.getData());
+ }
+ owner.tempWhitelistForPendingIntentLocked(callingPid,
+ callingUid, uid, duration, tag.toString());
+ } else {
+ Slog.w(TAG, "Not doing whitelist " + this + ": caller state="
+ + procState);
+ }
}
- owner.tempWhitelistForPendingIntentLocked(callingPid,
- callingUid, uid, whitelistDuration, tag.toString());
}
boolean sendFinish = finishedReceiver != null;
@@ -425,10 +447,17 @@
pw.print(prefix); pw.print("sent="); pw.print(sent);
pw.print(" canceled="); pw.println(canceled);
}
- if (whitelistDuration != 0) {
+ if (whitelistDuration != null) {
pw.print(prefix);
pw.print("whitelistDuration=");
- TimeUtils.formatDuration(whitelistDuration, pw);
+ for (int i = 0; i < whitelistDuration.size(); i++) {
+ if (i != 0) {
+ pw.print(", ");
+ }
+ pw.print(Integer.toHexString(System.identityHashCode(whitelistDuration.keyAt(i))));
+ pw.print(":");
+ TimeUtils.formatDuration(whitelistDuration.valueAt(i), pw);
+ }
pw.println();
}
if (mCancelCallbacks != null) {
@@ -451,9 +480,16 @@
sb.append(key.packageName);
sb.append(' ');
sb.append(key.typeName());
- if (whitelistDuration > 0) {
+ if (whitelistDuration != null) {
sb.append( " (whitelist: ");
- TimeUtils.formatDuration(whitelistDuration, sb);
+ for (int i = 0; i < whitelistDuration.size(); i++) {
+ if (i != 0) {
+ sb.append(",");
+ }
+ sb.append(Integer.toHexString(System.identityHashCode(whitelistDuration.keyAt(i))));
+ sb.append(":");
+ TimeUtils.formatDuration(whitelistDuration.valueAt(i), sb);
+ }
sb.append(")");
}
sb.append('}');
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 598597b..da919ec 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -344,6 +344,7 @@
private static final int MY_UID = Process.myUid();
private static final int MY_PID = Process.myPid();
+ private static final IBinder WHITELIST_TOKEN = new Binder();
private RankingHandler mRankingHandler;
private long mLastOverRateLogTime;
private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
@@ -983,6 +984,7 @@
public NotificationManagerService(Context context) {
super(context);
+ Notification.processWhitelistToken = WHITELIST_TOKEN;
}
// TODO - replace these methods with a single VisibleForTesting constructor
@@ -3256,7 +3258,8 @@
for (int i = 0; i < intentCount; i++) {
PendingIntent pendingIntent = notification.allPendingIntents.valueAt(i);
if (pendingIntent != null) {
- am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(), duration);
+ am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(),
+ WHITELIST_TOKEN, duration);
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index c1d68b8..3e920d4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -48,6 +48,7 @@
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.RemoteException;
import android.os.ShellCommand;
import android.os.SystemProperties;
@@ -1686,7 +1687,7 @@
private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
@Override
- public void send(int code, Intent intent, String resolvedType,
+ public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
try {
mResult.offer(intent, 5, TimeUnit.SECONDS);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 423bc0c..a8d19e9 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -4607,6 +4607,9 @@
} catch (IOException e) {
Slog.e(TAG, "Failed to read last_reboot_reason file", e);
}
+ if (line == null) {
+ return PowerManager.SHUTDOWN_REASON_UNKNOWN;
+ }
switch (line) {
case REASON_SHUTDOWN:
return PowerManager.SHUTDOWN_REASON_SHUTDOWN;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 982561c..96ea5e5 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1248,11 +1248,11 @@
*/
@Override
int getOrientation(int candidate) {
- // We do not allow non-fullscreen apps to influence orientation at and beyond O. While we do
+ // We do not allow non-fullscreen apps to influence orientation beyond O. While we do
// throw an exception in {@link Activity#onCreate} and
// {@link Activity#setRequestedOrientation}, we also ignore the orientation here so that
// other calculations aren't affected.
- if (!fillsParent() && mTargetSdk >= O) {
+ if (!fillsParent() && mTargetSdk > O) {
// Can't specify orientation if app doesn't fill parent.
return SCREEN_ORIENTATION_UNSET;
}
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 15648bd..ba73180 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -762,6 +762,15 @@
return 1;
}
+ // Now add any dependencies passed in.
+ for (size_t i = 0; i < bundle->getPackageIncludes().size(); i++) {
+ const String8& assetPath = bundle->getPackageIncludes()[i];
+ if (!assets.addAssetPath(assetPath, NULL)) {
+ fprintf(stderr, "ERROR: included asset path %s could not be loaded\n", assetPath.string());
+ return 1;
+ }
+ }
+
// Make a dummy config for retrieving resources... we need to supply
// non-default values for some configs so that we can retrieve resources
// in the app that don't have a default. The most important of these is
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 01930d0..e45d142 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -27,7 +27,7 @@
static const char* sMajorVersion = "2";
// Update minor version whenever a feature or flag is added.
-static const char* sMinorVersion = "14";
+static const char* sMinorVersion = "15";
int PrintVersion() {
std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "."
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 5413b33..c192d69 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -114,6 +114,7 @@
std::string output_path;
Maybe<std::string> res_dir;
bool pseudolocalize = false;
+ bool no_png_crunch = false;
bool legacy_mode = false;
bool verbose = false;
};
@@ -663,6 +664,7 @@
"Generate resources for pseudo-locales "
"(en-XA and ar-XB)",
&options.pseudolocalize)
+ .OptionalSwitch("--no-crunch", "Disables PNG processing", &options.no_png_crunch)
.OptionalSwitch("--legacy", "Treat errors that used to be valid in AAPT as warnings",
&options.legacy_mode)
.OptionalSwitch("-v", "Enables verbose logging", &verbose);
@@ -738,7 +740,8 @@
if (!CompileXml(&context, options, path_data, archive_writer.get(), output_filename)) {
error = true;
}
- } else if (path_data.extension == "png" || path_data.extension == "9.png") {
+ } else if (!options.no_png_crunch &&
+ (path_data.extension == "png" || path_data.extension == "9.png")) {
if (!CompilePng(&context, options, path_data, archive_writer.get(), output_filename)) {
error = true;
}
diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md
index 0291720..e92565f 100644
--- a/tools/aapt2/readme.md
+++ b/tools/aapt2/readme.md
@@ -1,5 +1,13 @@
# Android Asset Packaging Tool 2.0 (AAPT2) release notes
+## Version 2.15
+### `aapt2 compile ...`
+- Add `--no-crunch` option to avoid processing PNGs during the compile phase. Note that this
+ shouldn't be used as a performance optimization, as once the PNG is processed, its result is
+ cached for incremental linking. This should only be used if the developer has specially
+ pre-processed the PNG and wants it byte-for-byte identical to the input.
+ NOTE: 9-patches will not be processed correctly with this flag set.
+
## Version 2.14
### `aapt2 link ...`
- If an app is building with a minSdkVersion < 26 and a --package-id XX where XX > 7F, aapt2
diff --git a/vr/Android.mk b/vr/Android.mk
new file mode 100644
index 0000000..5b65d3f
--- /dev/null
+++ b/vr/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2017 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.
+LOCAL_PATH := $(call my-dir)
+
+# Library to perform dlopen on the actual shared library.
+include $(CLEAR_VARS)
+LOCAL_MODULE := libdvr_loader
+LOCAL_MODULE_OWNER := google
+LOCAL_SRC_FILES := dvr_library_loader.cpp
+include $(BUILD_SHARED_LIBRARY)
+
+# Java platform library for vr stuff.
+include $(CLEAR_VARS)
+LOCAL_MODULE := com.google.vr.platform
+LOCAL_MODULE_OWNER := google
+LOCAL_REQUIRED_MODULES := libdvr_loader libdvr
+LOCAL_SRC_FILES := $(call all-java-files-under, java)
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := com.google.vr.platform.xml
+LOCAL_SRC_FILES := com.google.vr.platform.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_OWNER := google
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+include $(BUILD_PREBUILT)
diff --git a/vr/com.google.vr.platform.xml b/vr/com.google.vr.platform.xml
new file mode 100644
index 0000000..952b476
--- /dev/null
+++ b/vr/com.google.vr.platform.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<permissions>
+ <library name="com.google.vr.platform"
+ file="/system/framework/com.google.vr.platform.jar" />
+</permissions>
diff --git a/vr/dvr_library_loader.cpp b/vr/dvr_library_loader.cpp
new file mode 100644
index 0000000..0b4298a
--- /dev/null
+++ b/vr/dvr_library_loader.cpp
@@ -0,0 +1,25 @@
+#include <dlfcn.h>
+#include <jni.h>
+
+#include <string>
+
+extern "C" {
+
+JNIEXPORT jlong JNICALL
+Java_com_google_vr_platform_Dvr_nativeLoadLibrary(
+ JNIEnv* env, jclass, jstring java_library) {
+ if (!java_library)
+ return 0;
+
+ // Convert the Java String object to a C++ null-terminated string.
+ const char* data = env->GetStringUTFChars(java_library, NULL);
+ size_t size = env->GetStringUTFLength(java_library);
+ std::string library(data, size);
+ env->ReleaseStringUTFChars(java_library, data);
+
+ // Return the handle to the requested library.
+ return reinterpret_cast<jlong>(
+ dlopen(library.c_str(), RTLD_NOW | RTLD_LOCAL));
+}
+
+} // extern "C"
diff --git a/vr/java/com/google/vr/platform/DeviceInfo.java b/vr/java/com/google/vr/platform/DeviceInfo.java
new file mode 100644
index 0000000..f6da66b
--- /dev/null
+++ b/vr/java/com/google/vr/platform/DeviceInfo.java
@@ -0,0 +1,19 @@
+package com.google.vr.platform;
+
+import android.os.SystemProperties;
+
+/**
+ * Class to get information about the vr device.
+ * @hide
+ */
+public class DeviceInfo {
+
+ private static final String VR_MODE_BOOT = "ro.boot.vr";
+
+ /**
+ * Returns true if this device boots directly in VR mode.
+ */
+ public static boolean getVrBoot() {
+ return SystemProperties.getBoolean(VR_MODE_BOOT, false);
+ }
+}
diff --git a/vr/java/com/google/vr/platform/Dvr.java b/vr/java/com/google/vr/platform/Dvr.java
new file mode 100644
index 0000000..b07d634
--- /dev/null
+++ b/vr/java/com/google/vr/platform/Dvr.java
@@ -0,0 +1,22 @@
+package com.google.vr.platform;
+
+/**
+ * Class to load the dvr api.
+ * @hide
+ */
+public class Dvr {
+ /**
+ * Opens a shared library containing the dvr api and returns the handle to it.
+ *
+ * @return A Long object describing the handle returned by dlopen.
+ */
+ public static Long loadLibrary() {
+ // Load a thin JNI library that runs dlopen on request.
+ System.loadLibrary("dvr_loader");
+
+ // Performs dlopen on the library and returns the handle.
+ return nativeLoadLibrary("libdvr.so");
+ }
+
+ private static native long nativeLoadLibrary(String library);
+}