Merge "Fix a flicker when window is removed during entering animation" into nyc-dev
diff --git a/core/java/android/content/ContentValues.java b/core/java/android/content/ContentValues.java
index 0d25f80..7ed827c 100644
--- a/core/java/android/content/ContentValues.java
+++ b/core/java/android/content/ContentValues.java
@@ -230,11 +230,12 @@
}
/**
- * Gets a value. Valid value types are {@link String}, {@link Boolean}, and
- * {@link Number} implementations.
+ * Gets a value. Valid value types are {@link String}, {@link Boolean},
+ * {@link Number}, and {@code byte[]} implementations.
*
* @param key the value to get
- * @return the data for the value
+ * @return the data for the value, or {@code null} if the value is missing or if {@code null}
+ * was previously added with the given {@code key}
*/
public Object get(String key) {
return mValues.get(key);
@@ -255,7 +256,7 @@
* Gets a value and converts it to a Long.
*
* @param key the value to get
- * @return the Long value, or null if the value is missing or cannot be converted
+ * @return the Long value, or {@code null} if the value is missing or cannot be converted
*/
public Long getAsLong(String key) {
Object value = mValues.get(key);
@@ -280,7 +281,7 @@
* Gets a value and converts it to an Integer.
*
* @param key the value to get
- * @return the Integer value, or null if the value is missing or cannot be converted
+ * @return the Integer value, or {@code null} if the value is missing or cannot be converted
*/
public Integer getAsInteger(String key) {
Object value = mValues.get(key);
@@ -305,7 +306,7 @@
* Gets a value and converts it to a Short.
*
* @param key the value to get
- * @return the Short value, or null if the value is missing or cannot be converted
+ * @return the Short value, or {@code null} if the value is missing or cannot be converted
*/
public Short getAsShort(String key) {
Object value = mValues.get(key);
@@ -330,7 +331,7 @@
* Gets a value and converts it to a Byte.
*
* @param key the value to get
- * @return the Byte value, or null if the value is missing or cannot be converted
+ * @return the Byte value, or {@code null} if the value is missing or cannot be converted
*/
public Byte getAsByte(String key) {
Object value = mValues.get(key);
@@ -355,7 +356,7 @@
* Gets a value and converts it to a Double.
*
* @param key the value to get
- * @return the Double value, or null if the value is missing or cannot be converted
+ * @return the Double value, or {@code null} if the value is missing or cannot be converted
*/
public Double getAsDouble(String key) {
Object value = mValues.get(key);
@@ -380,7 +381,7 @@
* Gets a value and converts it to a Float.
*
* @param key the value to get
- * @return the Float value, or null if the value is missing or cannot be converted
+ * @return the Float value, or {@code null} if the value is missing or cannot be converted
*/
public Float getAsFloat(String key) {
Object value = mValues.get(key);
@@ -405,7 +406,7 @@
* Gets a value and converts it to a Boolean.
*
* @param key the value to get
- * @return the Boolean value, or null if the value is missing or cannot be converted
+ * @return the Boolean value, or {@code null} if the value is missing or cannot be converted
*/
public Boolean getAsBoolean(String key) {
Object value = mValues.get(key);
@@ -428,7 +429,8 @@
* any other types to byte arrays.
*
* @param key the value to get
- * @return the byte[] value, or null is the value is missing or not a byte[]
+ * @return the {@code byte[]} value, or {@code null} is the value is missing or not a
+ * {@code byte[]}
*/
public byte[] getAsByteArray(String key) {
Object value = mValues.get(key);
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 50e7356..0f64b92 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1431,10 +1431,9 @@
* row. The keys should be the column names and the values the
* column values
* @param conflictAlgorithm for insert conflict resolver
- * @return the row ID of the newly inserted row
- * OR the primary key of the existing row if the input param 'conflictAlgorithm' =
- * {@link #CONFLICT_IGNORE}
- * OR -1 if any error
+ * @return the row ID of the newly inserted row OR <code>-1</code> if either the
+ * input parameter <code>conflictAlgorithm</code> = {@link #CONFLICT_IGNORE}
+ * or an error occurred.
*/
public long insertWithOnConflict(String table, String nullColumnHack,
ContentValues initialValues, int conflictAlgorithm) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 9b74fc0..fe24230 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1803,7 +1803,21 @@
*/
public final void setSurfaceInsets(View view, boolean manual, boolean preservePrevious) {
final int surfaceInset = (int) Math.ceil(view.getZ() * 2);
- surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
+ // Partial workaround for b/28318973. Every inset change causes a freeform window
+ // to jump a little for a few frames. If we never allow surface insets to decrease,
+ // they will stabilize quickly (often from the very beginning, as most windows start
+ // as focused).
+ // TODO(b/22668382) to fix this properly.
+ if (surfaceInset == 0) {
+ // OK to have 0 (this is the case for non-freeform windows).
+ surfaceInsets.set(0, 0, 0, 0);
+ } else {
+ surfaceInsets.set(
+ Math.max(surfaceInset, surfaceInsets.left),
+ Math.max(surfaceInset, surfaceInsets.top),
+ Math.max(surfaceInset, surfaceInsets.right),
+ Math.max(surfaceInset, surfaceInsets.bottom));
+ }
hasManualSurfaceInsets = manual;
preservePreviousSurfaceInsets = preservePrevious;
}
diff --git a/core/res/res/values/styles_holo.xml b/core/res/res/values/styles_holo.xml
index fdf9e31..8ca12ae 100644
--- a/core/res/res/values/styles_holo.xml
+++ b/core/res/res/values/styles_holo.xml
@@ -1172,7 +1172,8 @@
<style name="Widget.Holo.Light.FastScroll" parent="Widget.Holo.FastScroll" />
- <style name="Widget.Holo.SuggestionItem" parent="TextAppearance.Holo.Medium">
+ <style name="Widget.Holo.SuggestionItem">
+ <item name="textAppearance">@android:style/TextAppearance.Holo.Medium</item>
<item name="background">@color/white</item>
<item name="drawablePadding">8dip</item>
<item name="gravity">start|center_vertical</item>
@@ -1188,9 +1189,9 @@
<item name="textColor">@color/black</item>
</style>
- <style name="TextAppearance.Holo.SuggestionHighlight" parent="TextAppearance.SuggestionHighlight" />
+ <style name="TextAppearance.Holo.SuggestionHighlight" parent="@android:style/TextAppearance.SuggestionHighlight" />
- <style name="Widget.Holo.SuggestionButton" parent="Widget.Holo.SuggestionItem">
+ <style name="Widget.Holo.SuggestionButton" parent="@android:style/Widget.Holo.SuggestionItem">
<item name="background">#E9E9E9</item>
<item name="textColor">@color/black</item>
</style>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 6752e3c..3ed8daa 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -1001,7 +1001,8 @@
<item name="contentDescription">@string/media_route_button_content_description</item>
</style>
- <style name="Widget.Material.SuggestionItem" parent="@android:style/TextAppearance.Material.Body1">
+ <style name="Widget.Material.SuggestionItem">
+ <item name="textAppearance">@android:style/TextAppearance.Material.Body1</item>
<item name="textColor">?attr/textColorSecondary</item>
<item name="drawablePadding">8dip</item>
<item name="gravity">start|center_vertical</item>
@@ -1016,11 +1017,12 @@
<item name="textSize">14sp</item>
</style>
- <style name="TextAppearance.Material.TextSuggestionHighlight" parent="Widget.Material.SuggestionItem">
+ <style name="TextAppearance.Material.TextSuggestionHighlight">
<item name="textColor">?attr/textColorPrimary</item>
</style>
- <style name="Widget.Material.SuggestionButton" parent="@android:style/TextAppearance.Material.Button">
+ <style name="Widget.Material.SuggestionButton">
+ <item name="textAppearance">@android:style/TextAppearance.Material.Button</item>
<item name="textColor">?attr/colorAccent</item>
<item name="drawablePadding">8dip</item>
<item name="gravity">start|center_vertical</item>
diff --git a/docs/html/preview/api-overview.jd b/docs/html/preview/api-overview.jd
index 110418a..dc78bb9 100644
--- a/docs/html/preview/api-overview.jd
+++ b/docs/html/preview/api-overview.jd
@@ -733,19 +733,21 @@
<p>
Android N introduces APK Signature Scheme v2, a new app-signing scheme that
- offers faster app install times and better protection against unauthorized
- alterations to APK files. Android Studio 2.2 and Gradle provide built-in
- support for APK Signature Scheme v2.
+ offers faster app install times and more protection against unauthorized
+ alterations to APK files. By default, Android Studio 2.2 and the Android
+ Plugin for Gradle 2.2 sign your app using both APK Signature Scheme v2 and
+ the traditional signing scheme, which uses JAR signing.
</p>
<p>
- Although we recommend applying APK Signature Scheme v2 to your app, the new
- scheme is not mandatory. If your app doesn't build properly when using the
- APK Signature Scheme v2, you can use the traditional signing scheme—which
- uses JAR signing—instead. To use the traditional scheme, open the
- module-level <code>build.gradle</code> file and add the
- <code>v2SigningEnabled</code> parameter to your release signing
- configuration, setting this parameter's value to <code>false</code>:
+ Although we recommend applying APK Signature Scheme v2 to your app, this new
+ scheme is not mandatory. If your app doesn't build properly when using APK
+ Signature Scheme v2, you can disable the new scheme. The disabling process
+ causes Android Studio 2.2 and the Android Plugin for Gradle 2.2 to sign your
+ app using only the traditional signing scheme. To sign with only the
+ traditional scheme, open the module-level <code>build.gradle</code> file, then
+ add the line <code>v2SigningEnabled false</code> to your release signing
+ configuration:
</p>
<pre>
@@ -764,12 +766,18 @@
}
</pre>
+<p class="caution"><strong>Caution: </strong> If you sign your app using APK
+ Signature Scheme v2 and make further changes to the app, the app's signature
+ is invalidated. For this reason, use tools such as <code>zipalign</code>
+ before signing your app using APK Signature Scheme v2, not after.
+</p>
+
<p>
- For more information, see the following guides, which describe how to <a href=
- "{@docRoot}studio/tools/publishing/app-signing.html#release-mode"> sign an app
- in Android Studio</a> and how to <a href=
+ For more information, read the Android Studio documents that describe how to
+ <a href="{@docRoot}studio/tools/publishing/app-signing.html#release-mode">
+ sign an app</a> in Android Studio and how to <a href=
"{@docRoot}studio/tools/building/configuring-gradle.html#signing"> configure
- the Gradle build file for signing apps</a>.
+ the build file for signing apps</a> using the Android Plugin for Gradle.
</p>
<h2 id="scoped_directory_access">Scoped directory access</h2>
diff --git a/docs/html/preview/features/data-saver.jd b/docs/html/preview/features/data-saver.jd
index d5cdf27..c4cab18 100644
--- a/docs/html/preview/features/data-saver.jd
+++ b/docs/html/preview/features/data-saver.jd
@@ -14,7 +14,7 @@
<a href="#status">Checking Data Saver Preferences</a>
<ol>
<li>
- <a href="#request-whitelist">Requesting Whitelist Permissions</a>
+ <a href="#request-whitelist">Requesting whitelist permissions</a>
</li>
</ol>
</li>
@@ -138,15 +138,17 @@
If your app needs to use data in the background, it can request whitelist
permissions by sending a
<code>Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS</code>
- (<code>"android.settings.IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS"</code>)
- intent with a <code>package:<your-app-id></code> URI.
+ intent containing a URI of your app's package name: for example,
+ <code>package:MY_APP_ID</code>.
</p>
<p>
- Sending the intent and URI launches the <strong>Settings</strong> app, and
- displays your app's <strong>App Data Usage</strong> page to the user. The
- user can then decide whether to enable background data for your app.
- It is good practice to prompt the user before sending this intent.
+ Sending the intent and URI launches the <strong>Settings</strong> app and
+ displays data usage settings for your app. The user can then decide whether
+ to enable background data for your app. Before you send this intent, it is
+ good practice to first ask the user if they want to launch the
+ <strong>Settings</strong> app for the purpose of enabling background data
+ usage.
</p>
<h2 id="monitor-changes">
@@ -156,9 +158,8 @@
<p>
Apps can monitor changes to Data Saver preferences by creating a {@link
android.content.BroadcastReceiver} to listen for {@code
- ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED} ({@code
- "android.net.conn.RESTRICT_BACKGROUND_CHANGED"}) and dynamically registering
- the receiver with {@link android.content.Context#registerReceiver
+ ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED} and dynamically
+ registering the receiver with {@link android.content.Context#registerReceiver
Context.registerReceiver()}. When an app receives this broadcast, it should
<a href="#status">check if the new Data Saver preferences affect its
permissions</a> by calling {@code
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 6e1ff06..5b2ce07 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -123,6 +123,7 @@
private final Rect mTouchRegion = new Rect();
private boolean mAnimatingForIme;
private boolean mAdjustedForIme;
+ private int mImeHeight;
private WindowState mDelayedImeWin;
private boolean mAdjustedForDivider;
private float mDividerAnimationStart;
@@ -296,8 +297,9 @@
void setAdjustedForIme(
boolean adjustedForIme, boolean adjustedForDivider,
- boolean animate, WindowState imeWin) {
- if (mAdjustedForIme != adjustedForIme || mAdjustedForDivider != adjustedForDivider) {
+ boolean animate, WindowState imeWin, int imeHeight) {
+ if (mAdjustedForIme != adjustedForIme || (adjustedForIme && mImeHeight != imeHeight)
+ || mAdjustedForDivider != adjustedForDivider) {
if (animate) {
startImeAdjustAnimation(adjustedForIme, adjustedForDivider, imeWin);
} else {
@@ -305,10 +307,15 @@
notifyAdjustedForImeChanged(adjustedForIme || adjustedForDivider, 0 /* duration */);
}
mAdjustedForIme = adjustedForIme;
+ mImeHeight = imeHeight;
mAdjustedForDivider = adjustedForDivider;
}
}
+ int getImeHeightAdjustedFor() {
+ return mImeHeight;
+ }
+
void positionDockedStackedDivider(Rect frame) {
TaskStack stack = mDisplayContent.getDockedStackLocked();
if (stack == null) {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 58468f6..7426329 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -849,10 +849,10 @@
*
* @param imeWin The IME window.
*/
- void setAdjustedForIme(WindowState imeWin) {
+ void setAdjustedForIme(WindowState imeWin, boolean forceUpdate) {
mImeWin = imeWin;
mImeGoingAway = false;
- if (!mAdjustedForIme) {
+ if (!mAdjustedForIme || forceUpdate) {
mAdjustedForIme = true;
mAdjustImeAmount = 0f;
mAdjustDividerAmount = 0f;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d817036..8fa9efb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7566,6 +7566,9 @@
final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
final boolean dockMinimized = displayContent.mDividerControllerLocked.isMinimizedDock();
+ final int imeHeight = mPolicy.getInputMethodWindowVisibleHeightLw();
+ final boolean imeHeightChanged = imeVisible &&
+ imeHeight != displayContent.mDividerControllerLocked.getImeHeightAdjustedFor();
// The divider could be adjusted for IME position, or be thinner than usual,
// or both. There are three possible cases:
@@ -7579,13 +7582,13 @@
final TaskStack stack = stacks.get(i);
final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
if (stack.isVisibleLocked() && (imeOnBottom || isDockedOnBottom)) {
- stack.setAdjustedForIme(imeWin);
+ stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
} else {
stack.resetAdjustedForIme(false);
}
}
displayContent.mDividerControllerLocked.setAdjustedForIme(
- imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin);
+ imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
} else {
final ArrayList<TaskStack> stacks = displayContent.getStacks();
for (int i = stacks.size() - 1; i >= 0; --i) {
@@ -7593,7 +7596,7 @@
stack.resetAdjustedForIme(!dockVisible);
}
displayContent.mDividerControllerLocked.setAdjustedForIme(
- false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin);
+ false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
}
}