Merge "AAPT2: Variety of small fixes to get the build working"
diff --git a/api/current.txt b/api/current.txt
index 51008c1..54e5ff8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22552,7 +22552,7 @@
method public int[] getObjectHandles(int, int, int);
method public android.mtp.MtpObjectInfo getObjectInfo(int);
method public long getParent(int);
- method public int getPartialObject(int, int, int, byte[]) throws java.io.IOException;
+ method public long getPartialObject(int, long, long, byte[]) throws java.io.IOException;
method public long getStorageId(int);
method public int[] getStorageIds();
method public android.mtp.MtpStorageInfo getStorageInfo(int);
@@ -29376,6 +29376,22 @@
field public static final java.lang.String _ID = "_id";
}
+ public class BlockedNumberContract {
+ method public static boolean isBlocked(android.content.Context, java.lang.String);
+ field public static final java.lang.String AUTHORITY = "com.android.blockednumber";
+ field public static final android.net.Uri AUTHORITY_URI;
+ }
+
+ public static class BlockedNumberContract.BlockedNumbers {
+ field public static final java.lang.String COLUMN_E164_NUMBER = "e164_number";
+ field public static final java.lang.String COLUMN_ID = "_id";
+ field public static final java.lang.String COLUMN_ORIGINAL_NUMBER = "original_number";
+ field public static final java.lang.String COLUMN_STRIPPED_NUMBER = "stripped_number";
+ field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/blocked_number";
+ field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/blocked_numbers";
+ field public static final android.net.Uri CONTENT_URI;
+ }
+
public class Browser {
ctor public Browser();
method public static final void sendString(android.content.Context, java.lang.String);
diff --git a/api/system-current.txt b/api/system-current.txt
index b3d31bb..635292d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24107,7 +24107,7 @@
method public int[] getObjectHandles(int, int, int);
method public android.mtp.MtpObjectInfo getObjectInfo(int);
method public long getParent(int);
- method public int getPartialObject(int, int, int, byte[]) throws java.io.IOException;
+ method public long getPartialObject(int, long, long, byte[]) throws java.io.IOException;
method public long getStorageId(int);
method public int[] getStorageIds();
method public android.mtp.MtpStorageInfo getStorageInfo(int);
@@ -31389,6 +31389,22 @@
field public static final java.lang.String _ID = "_id";
}
+ public class BlockedNumberContract {
+ method public static boolean isBlocked(android.content.Context, java.lang.String);
+ field public static final java.lang.String AUTHORITY = "com.android.blockednumber";
+ field public static final android.net.Uri AUTHORITY_URI;
+ }
+
+ public static class BlockedNumberContract.BlockedNumbers {
+ field public static final java.lang.String COLUMN_E164_NUMBER = "e164_number";
+ field public static final java.lang.String COLUMN_ID = "_id";
+ field public static final java.lang.String COLUMN_ORIGINAL_NUMBER = "original_number";
+ field public static final java.lang.String COLUMN_STRIPPED_NUMBER = "stripped_number";
+ field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/blocked_number";
+ field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/blocked_numbers";
+ field public static final android.net.Uri CONTENT_URI;
+ }
+
public class Browser {
ctor public Browser();
method public static final void sendString(android.content.Context, java.lang.String);
diff --git a/api/test-current.txt b/api/test-current.txt
index 1229ff6..81f8b73 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -22560,7 +22560,7 @@
method public int[] getObjectHandles(int, int, int);
method public android.mtp.MtpObjectInfo getObjectInfo(int);
method public long getParent(int);
- method public int getPartialObject(int, int, int, byte[]) throws java.io.IOException;
+ method public long getPartialObject(int, long, long, byte[]) throws java.io.IOException;
method public long getStorageId(int);
method public int[] getStorageIds();
method public android.mtp.MtpStorageInfo getStorageInfo(int);
@@ -29388,6 +29388,22 @@
field public static final java.lang.String _ID = "_id";
}
+ public class BlockedNumberContract {
+ method public static boolean isBlocked(android.content.Context, java.lang.String);
+ field public static final java.lang.String AUTHORITY = "com.android.blockednumber";
+ field public static final android.net.Uri AUTHORITY_URI;
+ }
+
+ public static class BlockedNumberContract.BlockedNumbers {
+ field public static final java.lang.String COLUMN_E164_NUMBER = "e164_number";
+ field public static final java.lang.String COLUMN_ID = "_id";
+ field public static final java.lang.String COLUMN_ORIGINAL_NUMBER = "original_number";
+ field public static final java.lang.String COLUMN_STRIPPED_NUMBER = "stripped_number";
+ field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/blocked_number";
+ field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/blocked_numbers";
+ field public static final android.net.Uri CONTENT_URI;
+ }
+
public class Browser {
ctor public Browser();
method public static final void sendString(android.content.Context, java.lang.String);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 519e5a0..e7f886d 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3043,7 +3043,7 @@
* This is a protected intent that can only be sent by the system.
* </p>
* <p class="note">
- * This requires the RECEIVE_MEDIA_RESOURCE_USAGE permission.
+ * This requires {@link android.Manifest.permission#RECEIVE_MEDIA_RESOURCE_USAGE} permission.
* </p>
*
* @hide
@@ -4097,10 +4097,10 @@
public static final String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
/**
- * Used as an int extra field in {@link android.content.Intent#ACTION_MEDIA_RESOURCE_GRANTED}
+ * Used as an int extra field in {@link #ACTION_MEDIA_RESOURCE_GRANTED}
* intents to specify the resource type granted. Possible values are
- * {@link android.content.Intent#EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC} or
- * {@link android.content.Intent#EXTRA_MEDIA_RESOURCE_TYPE_AUDIO_CODEC}.
+ * {@link #EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC} or
+ * {@link #EXTRA_MEDIA_RESOURCE_TYPE_AUDIO_CODEC}.
*
* @hide
*/
@@ -4108,7 +4108,7 @@
"android.intent.extra.MEDIA_RESOURCE_TYPE";
/**
- * Used as an int value for {@link android.content.Intent#EXTRA_MEDIA_RESOURCE_TYPE}
+ * Used as an int value for {@link #EXTRA_MEDIA_RESOURCE_TYPE}
* to represent that a video codec is allowed to use.
*
* @hide
@@ -4116,7 +4116,7 @@
public static final int EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC = 0;
/**
- * Used as an int value for {@link android.content.Intent#EXTRA_MEDIA_RESOURCE_TYPE}
+ * Used as an int value for {@link #EXTRA_MEDIA_RESOURCE_TYPE}
* to represent that a audio codec is allowed to use.
*
* @hide
diff --git a/core/java/android/provider/BlockedNumberContract.java b/core/java/android/provider/BlockedNumberContract.java
new file mode 100644
index 0000000..03e0e11
--- /dev/null
+++ b/core/java/android/provider/BlockedNumberContract.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 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.provider;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * Constants and methods to access blocked phone numbers for incoming calls and texts.
+ *
+ * TODO javadoc
+ * - Proper javadoc tagging.
+ * - Code sample?
+ * - Describe who can access it.
+ */
+public class BlockedNumberContract {
+ private BlockedNumberContract() {
+ }
+
+ /** The authority for the contacts provider */
+ public static final String AUTHORITY = "com.android.blockednumber";
+
+ /** A content:// style uri to the authority for the contacts provider */
+ public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
+
+ /**
+ * TODO javadoc
+ *
+ * Constants to interact with the blocked phone number list.
+ */
+ public static class BlockedNumbers {
+ private BlockedNumbers() {
+ }
+
+ /**
+ * TODO javadoc
+ *
+ * Content URI for the blocked numbers.
+ *
+ * Supported operations
+ * blocked
+ * - query
+ * - delete
+ * - insert
+ *
+ * blocked/ID
+ * - query (selection is not supported)
+ * - delete (selection is not supported)
+ */
+ public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI,
+ "blocked");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} itself providing a directory of blocked phone
+ * numbers.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/blocked_numbers";
+
+ /**
+ * The MIME type of a blocked phone number under {@link #CONTENT_URI}.
+ */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/blocked_number";
+
+ /**
+ * Auto-generated ID field which monotonically increases.
+ * <p>TYPE: long</p>
+ */
+ public static final String COLUMN_ID = "_id";
+
+ /**
+ * Phone number to block.
+ * <p>Must be specified in {@code insert}.
+ * <p>TYPE: String</p>
+ */
+ public static final String COLUMN_ORIGINAL_NUMBER = "original_number";
+
+ /**
+ * Phone number to block. The system generates it from {@link #COLUMN_ORIGINAL_NUMBER}
+ * by removing all formatting characters.
+ * <p>Must NOT be specified in {@code insert}.
+ * <p>TYPE: String</p>
+ */
+ public static final String COLUMN_STRIPPED_NUMBER = "stripped_number";
+
+ /**
+ * Phone number to block. The system generates it from {@link #COLUMN_ORIGINAL_NUMBER}
+ * by removing all formatting characters.
+ * <p>Optional in {@code insert}. When not specified, the system tries to generate it
+ * assuming the current country. (Which will still be null if the number is not valid.)
+ * <p>TYPE: String</p>
+ */
+ public static final String COLUMN_E164_NUMBER = "e164_number";
+
+ /** @hide */
+ public static final String COLUMN_INDEX_STRIPPED = "index_stripped";
+
+ /** @hide */
+ public static final String COLUMN_INDEX_E164 = "index_e164";
+ }
+
+ /** @hide */
+ public static final String METHOD_IS_BLOCKED = "is_blocked";
+
+ /** @hide */
+ public static final String RES_NUMBER_IS_BLOCKED = "blocked";
+
+ /**
+ * Returns whether a given number is in the blocked list.
+ *
+ * TODO This should probably catch IllegalArgumentException to guard against the case where
+ * the provider is encrypted or the user is not running.
+ * (See addEntryAndRemoveExpiredEntries() in
+ * http://ag/#/c/844426/3/core/java/android/provider/CallLog.java)
+ */
+ public static boolean isBlocked(Context context, String phoneNumber) {
+ final Bundle res = context.getContentResolver().call(AUTHORITY_URI,
+ METHOD_IS_BLOCKED, phoneNumber, null);
+ return res != null && res.getBoolean(RES_NUMBER_IS_BLOCKED, false);
+ }
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a6485e4..3e06ecf 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7456,10 +7456,12 @@
* The following keys are supported:
*
* <pre>
- * idle_duration (long)
+ * idle_duration2 (long)
* wallclock_threshold (long)
* parole_interval (long)
* parole_duration (long)
+ *
+ * idle_duration (long) // This is deprecated and used to circumvent b/26355386.
* </pre>
*
* <p>
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index e79f1b8..fdf5f84 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -62,6 +62,7 @@
private final SnapTarget mDismissStartTarget;
private final SnapTarget mDismissEndTarget;
+ private final SnapTarget mMiddleTarget;
public DividerSnapAlgorithm(Resources res, float minFlingVelocityPxPerSecond,
int displayWidth, int displayHeight, int dividerSize, boolean isHorizontalDivision,
@@ -80,6 +81,7 @@
mLastSplitTarget = mTargets.get(mTargets.size() - 2);
mDismissStartTarget = mTargets.get(0);
mDismissEndTarget = mTargets.get(mTargets.size() - 1);
+ mMiddleTarget = mTargets.get(mTargets.size() / 2);
}
public SnapTarget calculateSnapTarget(int position, float velocity) {
@@ -215,6 +217,10 @@
SnapTarget.FLAG_NONE));
}
+ public SnapTarget getMiddleTarget() {
+ return mMiddleTarget;
+ }
+
/**
* Represents a snap target for the divider.
*/
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index b692a18..5127408 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -218,6 +218,33 @@
}
/**
+ * Ensures that the argument long value is within the inclusive range.
+ *
+ * @param value a long value
+ * @param lower the lower endpoint of the inclusive range
+ * @param upper the upper endpoint of the inclusive range
+ * @param valueName the name of the argument to use if the check fails
+ *
+ * @return the validated long value
+ *
+ * @throws IllegalArgumentException if {@code value} was not within the range
+ */
+ public static long checkArgumentInRange(long value, long lower, long upper,
+ String valueName) {
+ if (value < lower) {
+ throw new IllegalArgumentException(
+ String.format(
+ "%s is out of range of [%d, %d] (too low)", valueName, lower, upper));
+ } else if (value > upper) {
+ throw new IllegalArgumentException(
+ String.format(
+ "%s is out of range of [%d, %d] (too high)", valueName, lower, upper));
+ }
+
+ return value;
+ }
+
+ /**
* Ensures that the array is not {@code null}, and none of its elements are {@code null}.
*
* @param value an array of boxed objects
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 56cb104..793df92 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -407,8 +407,9 @@
float canvasScaleY = 1.0f;
if (mCanvasMatrix.getSkewX() == 0 && mCanvasMatrix.getSkewY() == 0) {
// Only use the scale value when there's no skew or rotation in the canvas matrix.
- canvasScaleX = mCanvasMatrix.getScaleX();
- canvasScaleY = mCanvasMatrix.getScaleY();
+ // TODO: Add a cts test for drawing VD on a canvas with negative scaling factors.
+ canvasScaleX = fabs(mCanvasMatrix.getScaleX());
+ canvasScaleY = fabs(mCanvasMatrix.getScaleY());
}
int scaledWidth = (int) (mBounds.width() * canvasScaleX);
int scaledHeight = (int) (mBounds.height() * canvasScaleY);
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index d24c5e8..4379a99 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -21,6 +21,8 @@
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
+import com.android.internal.util.Preconditions;
+
import java.io.IOException;
/**
@@ -164,12 +166,14 @@
* of the data and speed of the devices.
*
* @param objectHandle handle of the object to read
- * @param offset Start index of reading range.
- * @param size Size of reading range.
+ * @param offset Start index of reading range. It must be a non-negative value at most
+ * 0xffffffff.
+ * @param size Size of reading range. It must be a non-negative value at most 0xffffffff. If
+ * 0xffffffff is specified, the method obtains the full bytes of object.
* @param buffer Array to write data.
* @return Size of bytes that are actually read.
*/
- public int getPartialObject(int objectHandle, int offset, int size, byte[] buffer)
+ public long getPartialObject(int objectHandle, long offset, long size, byte[] buffer)
throws IOException {
return native_get_partial_object(objectHandle, offset, size, buffer);
}
@@ -340,8 +344,8 @@
private native int[] native_get_object_handles(int storageId, int format, int objectHandle);
private native MtpObjectInfo native_get_object_info(int objectHandle);
private native byte[] native_get_object(int objectHandle, int objectSize);
- private native int native_get_partial_object(
- int objectHandle, int offset, int objectSize, byte[] buffer) throws IOException;
+ private native long native_get_partial_object(
+ int objectHandle, long offset, long objectSize, byte[] buffer) throws IOException;
private native byte[] native_get_thumbnail(int objectHandle);
private native boolean native_delete_object(int objectHandle);
private native long native_get_parent(int objectHandle);
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index 130dfe5..b1b3b62 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -372,12 +372,12 @@
return nullptr;
}
-static jint
+static jlong
android_mtp_MtpDevice_get_partial_object(JNIEnv *env,
jobject thiz,
jint objectID,
- jint offset,
- jint size,
+ jlong offset,
+ jlong size,
jbyteArray array)
{
if (!array) {
@@ -385,6 +385,22 @@
return -1;
}
+ if (offset < 0 || 0xffffffffL < offset) {
+ jniThrowException(
+ env,
+ "java/lang/IllegalArgumentException",
+ "Offset argument must be a 32-bit unsigned integer.");
+ return -1;
+ }
+
+ if (size < 0 || 0xffffffffL < size) {
+ jniThrowException(
+ env,
+ "java/lang/IllegalArgumentException",
+ "Size argument must be a 32-bit unsigned integer.");
+ return -1;
+ }
+
MtpDevice* const device = get_device_from_object(env, thiz);
if (!device) {
jniThrowException(env, "java/io/IOException", "Failed to obtain MtpDevice.");
@@ -393,16 +409,13 @@
JavaArrayWriter writer(env, array);
uint32_t written_size;
- bool success = device->readPartialObject(
+ const bool success = device->readPartialObject(
objectID, offset, size, &written_size, JavaArrayWriter::writeTo, &writer);
if (!success) {
jniThrowException(env, "java/io/IOException", "Failed to read data.");
return -1;
}
- // Note: assumption here is that a negative value will be treated as unsigned on the Java
- // level.
- // TODO: Make sure that actually holds.
- return static_cast<jint>(written_size);
+ return static_cast<jlong>(written_size);
}
static jbyteArray
@@ -615,7 +628,7 @@
{"native_get_object_info", "(I)Landroid/mtp/MtpObjectInfo;",
(void *)android_mtp_MtpDevice_get_object_info},
{"native_get_object", "(II)[B",(void *)android_mtp_MtpDevice_get_object},
- {"native_get_partial_object", "(III[B)I", (void *)android_mtp_MtpDevice_get_partial_object},
+ {"native_get_partial_object", "(IJJ[B)J", (void *)android_mtp_MtpDevice_get_partial_object},
{"native_get_thumbnail", "(I)[B",(void *)android_mtp_MtpDevice_get_thumbnail},
{"native_delete_object", "(I)Z", (void *)android_mtp_MtpDevice_delete_object},
{"native_get_parent", "(I)J", (void *)android_mtp_MtpDevice_get_parent},
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index ddeb8dc..60a2ee5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -110,9 +110,7 @@
/** Preloads the next task */
public void run() {
- // TODO: Temporarily skip this if multi stack is enabled
- /*
- RecentsConfiguration config = RecentsConfiguration.getInstance();
+ RecentsConfiguration config = Recents.getConfiguration();
if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
RecentsTaskLoader loader = Recents.getTaskLoader();
SystemServicesProxy ssp = Recents.getSystemServices();
@@ -134,7 +132,6 @@
launchOpts.onlyLoadPausedActivities = true;
loader.loadTasks(mContext, plan, launchOpts);
}
- */
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 2ee2168..8e68aec 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1179,8 +1179,12 @@
prev.cpuTimeAtResume = 0; // reset it
}
- // Notfiy when the task stack has changed
- mService.notifyTaskStackChangedLocked();
+ // Notify when the task stack has changed, but only if visibilities changed (not just
+ // focus).
+ if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause) {
+ mService.notifyTaskStackChangedLocked();
+ mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
+ }
}
private void addToStopping(ActivityRecord r) {
@@ -1257,6 +1261,7 @@
ActivityContainer container = containers.get(containerNdx);
container.setVisible(visible);
}
+ mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
}
// Find the first visible activity above the passed activity and if it is translucent return it
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 022b60b..e837d9a 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -399,6 +399,12 @@
private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
/**
+ * Used to keep track whether app visibilities got changed since the last pause. Useful to
+ * determine whether to invoke the task stack change listener after pausing.
+ */
+ boolean mAppVisibilitiesChangedSinceLastPause;
+
+ /**
* Description of a request to start a new activity, which has been held
* due to app switches being disabled.
*/
diff --git a/services/core/java/com/android/server/policy/ShortcutManager.java b/services/core/java/com/android/server/policy/ShortcutManager.java
index 9908624..9284442 100644
--- a/services/core/java/com/android/server/policy/ShortcutManager.java
+++ b/services/core/java/com/android/server/policy/ShortcutManager.java
@@ -26,6 +26,7 @@
import android.util.Log;
import android.util.SparseArray;
import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -47,8 +48,10 @@
private static final String ATTRIBUTE_CLASS = "class";
private static final String ATTRIBUTE_SHORTCUT = "shortcut";
private static final String ATTRIBUTE_CATEGORY = "category";
+ private static final String ATTRIBUTE_SHIFT = "shift";
private final SparseArray<ShortcutInfo> mShortcuts = new SparseArray<>();
+ private final SparseArray<ShortcutInfo> mShiftShortcuts = new SparseArray<>();
private final Context mContext;
@@ -75,17 +78,21 @@
public Intent getIntent(KeyCharacterMap kcm, int keyCode, int metaState) {
ShortcutInfo shortcut = null;
+ // If the Shift key is preesed, then search for the shift shortcuts.
+ boolean isShiftOn = (metaState & KeyEvent.META_SHIFT_ON) == KeyEvent.META_SHIFT_ON;
+ SparseArray<ShortcutInfo> shortcutMap = isShiftOn ? mShiftShortcuts : mShortcuts;
+
// First try the exact keycode (with modifiers).
int shortcutChar = kcm.get(keyCode, metaState);
if (shortcutChar != 0) {
- shortcut = mShortcuts.get(shortcutChar);
+ shortcut = shortcutMap.get(shortcutChar);
}
// Next try the primary character on that key.
if (shortcut == null) {
shortcutChar = Character.toLowerCase(kcm.getDisplayLabel(keyCode));
if (shortcutChar != 0) {
- shortcut = mShortcuts.get(shortcutChar);
+ shortcut = shortcutMap.get(shortcutChar);
}
}
@@ -114,6 +121,7 @@
String className = parser.getAttributeValue(null, ATTRIBUTE_CLASS);
String shortcutName = parser.getAttributeValue(null, ATTRIBUTE_SHORTCUT);
String categoryName = parser.getAttributeValue(null, ATTRIBUTE_CATEGORY);
+ String shiftName = parser.getAttributeValue(null, ATTRIBUTE_SHIFT);
if (TextUtils.isEmpty(shortcutName)) {
Log.w(TAG, "Unable to get shortcut for: " + packageName + "/" + className);
@@ -121,6 +129,7 @@
}
final int shortcutChar = shortcutName.charAt(0);
+ final boolean isShiftShortcut = (shiftName != null && shiftName.equals("true"));
final Intent intent;
final String title;
@@ -158,7 +167,11 @@
}
ShortcutInfo shortcut = new ShortcutInfo(title, intent);
- mShortcuts.put(shortcutChar, shortcut);
+ if (isShiftShortcut) {
+ mShiftShortcuts.put(shortcutChar, shortcut);
+ } else {
+ mShortcuts.put(shortcutChar, shortcut);
+ }
}
} catch (XmlPullParserException e) {
Log.w(TAG, "Got exception parsing bookmarks.", e);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index f4140f0..632c033 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -37,6 +37,7 @@
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.WindowManager.DOCKED_BOTTOM;
import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.DOCKED_LEFT;
@@ -549,20 +550,32 @@
outBounds.set(mService.mDockedStackCreateBounds);
return;
}
- // The initial bounds of the docked stack when it is created half the screen space and
- // its bounds can be adjusted after that. The bounds of all other stacks are adjusted
- // to occupy whatever screen space the docked stack isn't occupying.
+
+ // The initial bounds of the docked stack when it is created about half the screen space
+ // and its bounds can be adjusted after that. The bounds of all other stacks are
+ // adjusted to occupy whatever screen space the docked stack isn't occupying.
+ final DisplayInfo di = mDisplayContent.getDisplayInfo();
+ mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
+ mTmpRect2);
+ final int position = new DividerSnapAlgorithm(mService.mContext.getResources(),
+ 0 /* minFlingVelocityPxPerSecond */,
+ di.logicalWidth,
+ di.logicalHeight,
+ dockDividerWidth,
+ mService.mCurConfiguration.orientation == ORIENTATION_PORTRAIT,
+ mTmpRect2).getMiddleTarget().position;
+
if (dockOnTopOrLeft) {
if (splitHorizontally) {
- outBounds.right = displayRect.centerX() - dockDividerWidth / 2;
+ outBounds.right = position;
} else {
- outBounds.bottom = displayRect.centerY() - dockDividerWidth / 2;
+ outBounds.bottom = position;
}
} else {
if (splitHorizontally) {
- outBounds.left = displayRect.centerX() + dockDividerWidth / 2;
+ outBounds.left = position - dockDividerWidth;
} else {
- outBounds.top = displayRect.centerY() + dockDividerWidth / 2;
+ outBounds.top = position - dockDividerWidth;
}
}
return;
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 3f9d14d..4253cd4 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -280,6 +280,11 @@
mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);
}
+ @Override
+ public long getAppIdleRollingWindowDurationMillis() {
+ return mAppIdleWallclockThresholdMillis * 2;
+ }
+
private void cleanUpRemovedUsersLocked() {
final List<UserInfo> users = mUserManager.getUsers(true);
if (users == null || users.size() == 0) {
@@ -1107,7 +1112,13 @@
* Observe settings changes for {@link Settings.Global#APP_IDLE_CONSTANTS}.
*/
private class SettingsObserver extends ContentObserver {
- private static final String KEY_IDLE_DURATION = "idle_duration";
+ /**
+ * This flag has been used to disable app idle on older builds with bug b/26355386.
+ */
+ @Deprecated
+ private static final String KEY_IDLE_DURATION_OLD = "idle_duration";
+
+ private static final String KEY_IDLE_DURATION = "idle_duration2";
private static final String KEY_WALLCLOCK_THRESHOLD = "wallclock_threshold";
private static final String KEY_PAROLE_INTERVAL = "parole_interval";
private static final String KEY_PAROLE_DURATION = "parole_duration";
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 28204b1..224faf4 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -73,6 +73,7 @@
interface StatsUpdatedListener {
void onStatsUpdated();
+ long getAppIdleRollingWindowDurationMillis();
}
UserUsageStatsService(Context context, int userId, File usageStatsDir,
@@ -568,9 +569,11 @@
*/
void refreshAppIdleRollingWindow(final long currentTimeMillis, final long deviceUsageTime) {
// Start the rolling window for AppIdle requests.
+ final long startRangeMillis = currentTimeMillis -
+ mListener.getAppIdleRollingWindowDurationMillis();
+
List<IntervalStats> stats = mDatabase.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
- currentTimeMillis - (1000 * 60 * 60 * 24 * 2), currentTimeMillis,
- new StatCombiner<IntervalStats>() {
+ startRangeMillis, currentTimeMillis, new StatCombiner<IntervalStats>() {
@Override
public void combine(IntervalStats stats, boolean mutable,
List<IntervalStats> accumulatedResult) {