diff options
116 files changed, 2398 insertions, 494 deletions
diff --git a/api/current.txt b/api/current.txt index e1d1af66230e..533b577034db 100644 --- a/api/current.txt +++ b/api/current.txt @@ -43913,6 +43913,7 @@ package android.view { field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea field public static final int TYPE_BASE_APPLICATION = 1; // 0x1 field public static final int TYPE_CHANGED = 2; // 0x2 + field public static final int TYPE_DRAWN_APPLICATION = 4; // 0x4 field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9 diff --git a/api/system-current.txt b/api/system-current.txt index 9d045b3a5829..c33fe6eed6cc 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -47093,6 +47093,7 @@ package android.view { field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea field public static final int TYPE_BASE_APPLICATION = 1; // 0x1 field public static final int TYPE_CHANGED = 2; // 0x2 + field public static final int TYPE_DRAWN_APPLICATION = 4; // 0x4 field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9 diff --git a/api/test-current.txt b/api/test-current.txt index ed078d2fe623..3b5c2231ccf2 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -43994,6 +43994,7 @@ package android.view { field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea field public static final int TYPE_BASE_APPLICATION = 1; // 0x1 field public static final int TYPE_CHANGED = 2; // 0x2 + field public static final int TYPE_DRAWN_APPLICATION = 4; // 0x4 field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9 diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 9f0205098a98..3d3dc9cc3418 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -714,7 +714,7 @@ public class Build { public static final int N = 24; /** - * N MR1: Still ¯\_(シ)_/¯. + * N MR1: Nougat++. */ public static final int N_MR1 = 25; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 9383a8b1f4a9..1d6927a8cd00 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -5345,6 +5345,13 @@ public final class Settings { public static final String LONG_PRESS_TIMEOUT = "long_press_timeout"; /** + * The duration in milliseconds between the first tap's up event and the second tap's + * down event for an interaction to be considered part of the same multi-press. + * @hide + */ + public static final String MULTI_PRESS_TIMEOUT = "multi_press_timeout"; + + /** * List of the enabled print services. * * N and beyond uses {@link #DISABLED_PRINT_SERVICES}. But this might be used in an upgrade diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index a5900e6b2f3a..c7eca44c8749 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -379,9 +379,9 @@ public class TextureView extends View { if (createNewSurface) { // Create a new SurfaceTexture for the layer. mSurface = new SurfaceTexture(false); - mLayer.setSurfaceTexture(mSurface); nCreateNativeWindow(mSurface); } + mLayer.setSurfaceTexture(mSurface); mSurface.setDefaultBufferSize(getWidth(), getHeight()); mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 0642cd8cb841..67f5bfc451a4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -23858,7 +23858,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * on the screen. */ private boolean shouldDrawRoundScrollbar() { - if (!mResources.getConfiguration().isScreenRound()) { + if (!mResources.getConfiguration().isScreenRound() || mAttachInfo == null) { return false; } diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 4d584a3df4fb..9a73d0b1bfaa 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -64,6 +64,12 @@ public class ViewConfiguration { private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500; /** + * Defines the default duration in milliseconds between the first tap's up event and the second + * tap's down event for an interaction to be considered part of the same multi-press. + */ + private static final int DEFAULT_MULTI_PRESS_TIMEOUT = 300; + + /** * Defines the time between successive key repeats in milliseconds. */ private static final int KEY_REPEAT_DELAY = 50; @@ -441,6 +447,16 @@ public class ViewConfiguration { } /** + * @return the duration in milliseconds between the first tap's up event and the second tap's + * down event for an interaction to be considered part of the same multi-press. + * @hide + */ + public static int getMultiPressTimeout() { + return AppGlobals.getIntCoreSetting(Settings.Secure.MULTI_PRESS_TIMEOUT, + DEFAULT_MULTI_PRESS_TIMEOUT); + } + + /** * @return the time before the first key repeat in milliseconds. */ public static int getKeyRepeatTimeout() { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 4dc1009fe446..03c97bd9b00c 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -6039,7 +6039,8 @@ public final class ViewRootImpl implements ViewParent, return true; } return mEvent instanceof MotionEvent - && mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER); + && (mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER) + || mEvent.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER)); } public boolean shouldSendToSynthesizer() { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 1b37ed47c392..0dbf00dd75aa 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -221,6 +221,7 @@ public interface WindowManager extends ViewManager { * @see #TYPE_BASE_APPLICATION * @see #TYPE_APPLICATION * @see #TYPE_APPLICATION_STARTING + * @see #TYPE_DRAWN_APPLICATION * @see #TYPE_APPLICATION_PANEL * @see #TYPE_APPLICATION_MEDIA * @see #TYPE_APPLICATION_SUB_PANEL @@ -244,6 +245,7 @@ public interface WindowManager extends ViewManager { @ViewDebug.IntToString(from = TYPE_BASE_APPLICATION, to = "TYPE_BASE_APPLICATION"), @ViewDebug.IntToString(from = TYPE_APPLICATION, to = "TYPE_APPLICATION"), @ViewDebug.IntToString(from = TYPE_APPLICATION_STARTING, to = "TYPE_APPLICATION_STARTING"), + @ViewDebug.IntToString(from = TYPE_DRAWN_APPLICATION, to = "TYPE_DRAWN_APPLICATION"), @ViewDebug.IntToString(from = TYPE_APPLICATION_PANEL, to = "TYPE_APPLICATION_PANEL"), @ViewDebug.IntToString(from = TYPE_APPLICATION_MEDIA, to = "TYPE_APPLICATION_MEDIA"), @ViewDebug.IntToString(from = TYPE_APPLICATION_SUB_PANEL, to = "TYPE_APPLICATION_SUB_PANEL"), @@ -315,6 +317,13 @@ public interface WindowManager extends ViewManager { public static final int TYPE_APPLICATION_STARTING = 3; /** + * Window type: a variation on TYPE_APPLICATION that ensures the window + * manager will wait for this window to be drawn before the app is shown. + * In multiuser systems shows only on the owning user's window. + */ + public static final int TYPE_DRAWN_APPLICATION = 4; + + /** * End of types of application windows. */ public static final int LAST_APPLICATION_WINDOW = 99; @@ -1581,6 +1590,15 @@ public interface WindowManager extends ViewManager { public static final int ROTATION_ANIMATION_JUMPCUT = 2; /** + * Value for {@link #rotationAnimation} to specify seamless rotation mode. + * This works like JUMPCUT but will fall back to CROSSFADE if rotation + * can't be applied without pausing the screen. + * + * @hide + */ + public static final int ROTATION_ANIMATION_SEAMLESS = 3; + + /** * Define the exit and entry animations used on this window when the device is rotated. * This only has an affect if the incoming and outgoing topmost * opaque windows have the #FLAG_FULLSCREEN bit set and are not covered diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 366fc1a7dd5b..92ab3246e354 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -101,6 +101,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATIO import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION; import static com.android.internal.policy.PhoneWindow.FEATURE_OPTIONS_PANEL; /** @hide */ @@ -1860,7 +1861,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind } final WindowManager.LayoutParams attrs = mWindow.getAttributes(); final boolean isApplication = attrs.type == TYPE_BASE_APPLICATION || - attrs.type == TYPE_APPLICATION; + attrs.type == TYPE_APPLICATION || attrs.type == TYPE_DRAWN_APPLICATION; // Only a non floating application window on one of the allowed workspaces can get a caption if (!mWindow.isFloating() && isApplication && StackId.hasWindowDecor(mStackId)) { // Dependent on the brightness of the used title we either use the diff --git a/core/java/com/android/internal/widget/WatchHeaderListView.java b/core/java/com/android/internal/widget/WatchHeaderListView.java index 3d32d86cd49c..4fd19c37bf47 100644 --- a/core/java/com/android/internal/widget/WatchHeaderListView.java +++ b/core/java/com/android/internal/widget/WatchHeaderListView.java @@ -103,7 +103,8 @@ public class WatchHeaderListView extends ListView { @Override public int getHeaderViewsCount() { - return mTopPanel == null ? super.getHeaderViewsCount() : super.getHeaderViewsCount() + 1; + return mTopPanel == null ? super.getHeaderViewsCount() + : super.getHeaderViewsCount() + (mTopPanel.getVisibility() == GONE ? 0 : 1); } private void wrapAdapterIfNecessary() { @@ -133,7 +134,7 @@ public class WatchHeaderListView extends ListView { } private int getTopPanelCount() { - return mTopPanel == null ? 0 : 1; + return (mTopPanel == null || mTopPanel.getVisibility() == GONE) ? 0 : 1; } @Override @@ -143,33 +144,19 @@ public class WatchHeaderListView extends ListView { @Override public boolean areAllItemsEnabled() { - return mTopPanel == null && super.areAllItemsEnabled(); + return getTopPanelCount() == 0 && super.areAllItemsEnabled(); } @Override public boolean isEnabled(int position) { - if (mTopPanel != null) { - if (position == 0) { - return false; - } else { - return super.isEnabled(position - 1); - } - } - - return super.isEnabled(position); + int topPanelCount = getTopPanelCount(); + return position < topPanelCount ? false : super.isEnabled(position - topPanelCount); } @Override public Object getItem(int position) { - if (mTopPanel != null) { - if (position == 0) { - return null; - } else { - return super.getItem(position - 1); - } - } - - return super.getItem(position); + int topPanelCount = getTopPanelCount(); + return position < topPanelCount ? null : super.getItem(position - topPanelCount); } @Override @@ -187,15 +174,9 @@ public class WatchHeaderListView extends ListView { @Override public View getView(int position, View convertView, ViewGroup parent) { - if (mTopPanel != null) { - if (position == 0) { - return mTopPanel; - } else { - return super.getView(position - 1, convertView, parent); - } - } - - return super.getView(position, convertView, parent); + int topPanelCount = getTopPanelCount(); + return position < topPanelCount + ? mTopPanel : super.getView(position - topPanelCount, convertView, parent); } @Override diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp index 9515a0e336aa..7a8a574b119e 100644 --- a/core/jni/android_hardware_location_ContextHubService.cpp +++ b/core/jni/android_hardware_location_ContextHubService.cpp @@ -603,6 +603,8 @@ static void passOnOsResponse(uint32_t hubHandle, uint32_t msgType, env->CallIntMethod(db.jniInfo.jContextHubService, db.jniInfo.contextHubServiceMsgReceiptCallback, jheader, jmsg); + env->DeleteLocalRef(jmsg); + env->DeleteLocalRef(jheader); delete[] msg; } diff --git a/core/res/res/anim/watch_switch_thumb_to_off_animation.xml b/core/res/res/anim/watch_switch_thumb_to_off_animation.xml index cd02e0db2fd5..c300894d5541 100644 --- a/core/res/res/anim/watch_switch_thumb_to_off_animation.xml +++ b/core/res/res/anim/watch_switch_thumb_to_off_animation.xml @@ -1,4 +1,5 @@ -<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2016 The Android Open Source Project +<?xml version="1.0" encoding="utf-8"?> +<!-- 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 @@ -17,20 +18,34 @@ android:interpolator="@android:interpolator/linear" android:propertyName="pathData" android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" + android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" + android:valueType="pathType" /> + <objectAnimator + android:duration="49" + android:interpolator="@android:interpolator/linear" + android:propertyName="pathData" + android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueTo="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueType="pathType" /> <objectAnimator - android:duration="66" + android:duration="83" android:interpolator="@android:interpolator/linear" android:propertyName="pathData" android:valueFrom="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueTo="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueType="pathType" /> <objectAnimator - android:duration="66" + android:duration="50" android:interpolator="@android:interpolator/linear" android:propertyName="pathData" android:valueFrom="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueType="pathType" /> + <objectAnimator + android:duration="33" + android:interpolator="@android:interpolator/linear" + android:propertyName="pathData" + android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" + android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" + android:valueType="pathType" /> </set> diff --git a/core/res/res/anim/watch_switch_thumb_to_on_animation.xml b/core/res/res/anim/watch_switch_thumb_to_on_animation.xml index e64421776605..c300894d5541 100644 --- a/core/res/res/anim/watch_switch_thumb_to_on_animation.xml +++ b/core/res/res/anim/watch_switch_thumb_to_on_animation.xml @@ -18,20 +18,34 @@ android:interpolator="@android:interpolator/linear" android:propertyName="pathData" android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" + android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" + android:valueType="pathType" /> + <objectAnimator + android:duration="49" + android:interpolator="@android:interpolator/linear" + android:propertyName="pathData" + android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueTo="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueType="pathType" /> <objectAnimator - android:duration="66" + android:duration="83" android:interpolator="@android:interpolator/linear" android:propertyName="pathData" android:valueFrom="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueTo="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueType="pathType" /> <objectAnimator - android:duration="66" + android:duration="50" android:interpolator="@android:interpolator/linear" android:propertyName="pathData" android:valueFrom="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" android:valueType="pathType" /> + <objectAnimator + android:duration="33" + android:interpolator="@android:interpolator/linear" + android:propertyName="pathData" + android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" + android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z" + android:valueType="pathType" /> </set> diff --git a/core/res/res/color/watch_switch_thumb_color_material.xml b/core/res/res/color/watch_switch_thumb_color_material.xml index d4796a032631..f78d9b62a509 100644 --- a/core/res/res/color/watch_switch_thumb_color_material.xml +++ b/core/res/res/color/watch_switch_thumb_color_material.xml @@ -10,9 +10,9 @@ See the License for the specific language governing permissions and limitations under the License. --> - <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:color="?android:colorButtonNormal" android:state_enabled="false" /> - <item android:color="?android:colorControlActivated" android:state_checked="true" /> - <item android:color="?android:colorButtonNormal" /> -</selector>
\ No newline at end of file + <item android:color="?attr/colorButtonNormal" android:alpha="?attr/disabledAlpha" + android:state_enabled="false" /> + <item android:color="?attr/colorControlActivated" android:state_checked="true" /> + <item android:color="?attr/colorButtonNormal" /> +</selector> diff --git a/core/res/res/values-round-watch/styles_material.xml b/core/res/res/color/watch_switch_track_color_material.xml index a2f3c0243189..402a536b4d12 100644 --- a/core/res/res/values-round-watch/styles_material.xml +++ b/core/res/res/color/watch_switch_track_color_material.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2016 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,8 +13,9 @@ See the License for the specific language governing permissions and limitations under the License. --> -<resources> - <style name="TextAppearance.Material.AlertDialogMessage" parent="TextAppearance.Material.Body1"> - <item name="textAlignment">center</item> - </style> -</resources> +<!-- Used for the background of switch track for watch switch preference. --> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="false" + android:alpha="0.4" android:color="?attr/colorPrimary" /> + <item android:color="?attr/colorPrimary" /> +</selector> diff --git a/core/res/res/layout-notround-watch/alert_dialog_header_micro.xml b/core/res/res/layout-notround-watch/alert_dialog_title_material.xml index fc840d9fa73f..307c6db91c3a 100644 --- a/core/res/res/layout-notround-watch/alert_dialog_header_micro.xml +++ b/core/res/res/layout-notround-watch/alert_dialog_title_material.xml @@ -30,12 +30,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@null" /> - <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle" + <TextView android:id="@+id/alertTitle" style="?android:attr/windowTitleStyle" - android:ellipsize="end" - android:layout_marginStart="8dp" android:layout_marginBottom="8dp" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textAlignment="viewStart" /> + android:layout_height="wrap_content" /> </LinearLayout> diff --git a/core/res/res/layout-round-watch/alert_dialog_header_micro.xml b/core/res/res/layout-round-watch/alert_dialog_title_material.xml index 6f7ae02388a3..027991106c5a 100644 --- a/core/res/res/layout-round-watch/alert_dialog_header_micro.xml +++ b/core/res/res/layout-round-watch/alert_dialog_title_material.xml @@ -27,12 +27,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@null" /> - <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle" + <TextView android:id="@+id/alertTitle" style="?android:attr/windowTitleStyle" - android:ellipsize="end" android:layout_marginTop="36dp" - android:layout_marginBottom="4dp" + android:layout_marginBottom="8dp" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textAlignment="center" /> + android:layout_height="wrap_content" /> </FrameLayout> diff --git a/core/res/res/layout-watch/alert_dialog_material.xml b/core/res/res/layout-watch/alert_dialog_material.xml index ce8e20a12187..002dde83cd93 100644 --- a/core/res/res/layout-watch/alert_dialog_material.xml +++ b/core/res/res/layout-watch/alert_dialog_material.xml @@ -39,7 +39,7 @@ <include android:id="@+id/title_template" android:layout_width="match_parent" android:layout_height="wrap_content" - layout="@layout/alert_dialog_header_micro"/> + layout="@layout/alert_dialog_title_material"/> </FrameLayout> <!-- Content Panel --> @@ -50,7 +50,8 @@ <TextView android:id="@+id/message" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.Material.Body1" + android:gravity="@integer/config_dialogTextGravity" + android:textAppearance="@style/TextAppearance.Material.Subhead" android:paddingStart="?dialogPreferredPadding" android:paddingEnd="?dialogPreferredPadding" android:paddingTop="8dip" @@ -77,6 +78,7 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_gravity="bottom" android:orientation="vertical" android:minHeight="@dimen/alert_dialog_button_bar_height" android:paddingBottom="?dialogPreferredPadding" diff --git a/core/res/res/layout-watch/date_picker_dialog.xml b/core/res/res/layout-watch/date_picker_dialog.xml new file mode 100644 index 000000000000..b8772bc5ea3c --- /dev/null +++ b/core/res/res/layout-watch/date_picker_dialog.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2007 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. +--> + +<DatePicker xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/datePicker" + android:layout_gravity="center_horizontal" + android:gravity="center_horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:spinnersShown="true" + android:calendarViewShown="false" + android:datePickerMode="@integer/date_picker_mode" /> diff --git a/core/res/res/layout-watch/preference_widget_switch.xml b/core/res/res/layout-watch/preference_widget_switch.xml index 37d0c6bf1af6..ffc00b4d1c1a 100644 --- a/core/res/res/layout-watch/preference_widget_switch.xml +++ b/core/res/res/layout-watch/preference_widget_switch.xml @@ -24,7 +24,7 @@ android:thumb="@drawable/watch_switch_thumb_material_anim" android:thumbTint="@color/watch_switch_thumb_color_material" android:track="@drawable/watch_switch_track_material" - android:trackTint="?android:colorPrimary" + android:trackTint="@color/watch_switch_track_color_material" android:focusable="false" android:clickable="false" android:background="@null" /> diff --git a/core/res/res/layout-watch/time_picker_dialog.xml b/core/res/res/layout-watch/time_picker_dialog.xml new file mode 100644 index 000000000000..788602bf09ba --- /dev/null +++ b/core/res/res/layout-watch/time_picker_dialog.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +** +** Copyright 2007, 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. +*/ +--> + +<TimePicker xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/timePicker" + android:layout_gravity="center_horizontal" + android:gravity="center_horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:timePickerMode="@integer/time_picker_mode" /> diff --git a/core/res/res/layout/date_picker_legacy_holo.xml b/core/res/res/layout/date_picker_legacy_holo.xml index b465d97339a2..a6e93c99160d 100644 --- a/core/res/res/layout/date_picker_legacy_holo.xml +++ b/core/res/res/layout/date_picker_legacy_holo.xml @@ -41,8 +41,8 @@ android:id="@+id/month" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="16dip" - android:layout_marginBottom="16dip" + android:layout_marginTop="@dimen/picker_top_margin" + android:layout_marginBottom="@dimen/picker_bottom_margin" android:layout_marginStart="8dip" android:layout_marginEnd="8dip" android:focusable="true" @@ -54,8 +54,8 @@ android:id="@+id/day" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="16dip" - android:layout_marginBottom="16dip" + android:layout_marginTop="@dimen/picker_top_margin" + android:layout_marginBottom="@dimen/picker_bottom_margin" android:layout_marginStart="8dip" android:layout_marginEnd="8dip" android:focusable="true" @@ -67,8 +67,8 @@ android:id="@+id/year" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="16dip" - android:layout_marginBottom="16dip" + android:layout_marginTop="@dimen/picker_top_margin" + android:layout_marginBottom="@dimen/picker_bottom_margin" android:layout_marginStart="8dip" android:layout_marginEnd="16dip" android:focusable="true" diff --git a/core/res/res/layout/number_picker_material.xml b/core/res/res/layout/number_picker_material.xml index b0455857e79e..6fbd2b279f0c 100644 --- a/core/res/res/layout/number_picker_material.xml +++ b/core/res/res/layout/number_picker_material.xml @@ -22,4 +22,4 @@ android:gravity="center" android:singleLine="true" android:background="@null" - android:textAppearance="@style/TextAppearance.Material.Body1" /> + android:textAppearance="@style/TextAppearance.Material.NumberPicker" /> diff --git a/core/res/res/layout/time_picker_legacy_material.xml b/core/res/res/layout/time_picker_legacy_material.xml index c6b7d3a70d97..ee56266390f1 100644 --- a/core/res/res/layout/time_picker_legacy_material.xml +++ b/core/res/res/layout/time_picker_legacy_material.xml @@ -40,8 +40,8 @@ android:id="@+id/hour" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="16dip" - android:layout_marginBottom="16dip" + android:layout_marginTop="@dimen/picker_top_margin" + android:layout_marginBottom="@dimen/picker_bottom_margin" android:focusable="true" android:focusableInTouchMode="true" /> @@ -62,8 +62,8 @@ android:id="@+id/minute" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="16dip" - android:layout_marginBottom="16dip" + android:layout_marginTop="@dimen/picker_top_margin" + android:layout_marginBottom="@dimen/picker_bottom_margin" android:focusable="true" android:focusableInTouchMode="true" /> @@ -75,8 +75,8 @@ android:id="@+id/amPm" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="16dip" - android:layout_marginBottom="16dip" + android:layout_marginTop="@dimen/picker_top_margin" + android:layout_marginBottom="@dimen/picker_bottom_margin" android:layout_marginStart="8dip" android:layout_marginEnd="8dip" android:focusable="true" diff --git a/core/res/res/values-notround-watch/styles_material.xml b/core/res/res/values-notround-watch/config_material.xml index cd8521f48421..a99674f3f060 100644 --- a/core/res/res/values-notround-watch/styles_material.xml +++ b/core/res/res/values-notround-watch/config_material.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2016 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,6 +13,13 @@ See the License for the specific language governing permissions and limitations under the License. --> -<resources> - <style name="TextAppearance.Material.AlertDialogMessage" parent="TextAppearance.Material.Body1"/> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds, only for Material theme. Do not translate. + + NOTE: The naming convention is "config_camelCaseValue". --> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Gravity that should be used for dialog text styles. Equivalent to: Gravity.START | Gravity.TOP --> + <integer name="config_dialogTextGravity">0x00800033</integer> </resources> diff --git a/core/res/res/values-round-watch/config_material.xml b/core/res/res/values-round-watch/config_material.xml index bf445ef3fd0e..871e910eb042 100644 --- a/core/res/res/values-round-watch/config_material.xml +++ b/core/res/res/values-round-watch/config_material.xml @@ -19,4 +19,7 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Don't clip on round screens so the list can scroll past the rounded edges. --> <bool name="config_preferenceFragmentClipToPadding">false</bool> + + <!-- Gravity that should be used for dialog text styles. Equivalent to: Gravity.CENTER_HORIZONTAL | Gravity.TOP --> + <integer name="config_dialogTextGravity">0x00000031</integer> </resources> diff --git a/core/res/res/values-w180dp-notround-watch/dimens_material.xml b/core/res/res/values-w180dp-notround-watch/dimens_material.xml new file mode 100644 index 000000000000..79acf84b7e3f --- /dev/null +++ b/core/res/res/values-w180dp-notround-watch/dimens_material.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<resources> + <dimen name="text_size_display_4_material">80sp</dimen> + <dimen name="text_size_display_3_material">50sp</dimen> + <dimen name="text_size_display_2_material">40sp</dimen> + <dimen name="text_size_display_1_material">30sp</dimen> + <dimen name="text_size_headline_material">20sp</dimen> + <dimen name="text_size_title_material">18sp</dimen> + <dimen name="text_size_subhead_material">18sp</dimen> + <dimen name="text_size_title_material_toolbar">18dp</dimen> + <dimen name="text_size_subtitle_material_toolbar">18dp</dimen> + <dimen name="text_size_menu_material">18sp</dimen> + <dimen name="text_size_menu_header_material">16sp</dimen> + <dimen name="text_size_body_2_material">16sp</dimen> + <dimen name="text_size_body_1_material">16sp</dimen> + <dimen name="text_size_caption_material">14sp</dimen> + <dimen name="text_size_button_material">16sp</dimen> + + <dimen name="text_size_large_material">18sp</dimen> + <dimen name="text_size_medium_material">16sp</dimen> + <dimen name="text_size_small_material">14sp</dimen> +</resources> diff --git a/core/res/res/values-w210dp-round-watch/dimens_material.xml b/core/res/res/values-w210dp-round-watch/dimens_material.xml new file mode 100644 index 000000000000..79acf84b7e3f --- /dev/null +++ b/core/res/res/values-w210dp-round-watch/dimens_material.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<resources> + <dimen name="text_size_display_4_material">80sp</dimen> + <dimen name="text_size_display_3_material">50sp</dimen> + <dimen name="text_size_display_2_material">40sp</dimen> + <dimen name="text_size_display_1_material">30sp</dimen> + <dimen name="text_size_headline_material">20sp</dimen> + <dimen name="text_size_title_material">18sp</dimen> + <dimen name="text_size_subhead_material">18sp</dimen> + <dimen name="text_size_title_material_toolbar">18dp</dimen> + <dimen name="text_size_subtitle_material_toolbar">18dp</dimen> + <dimen name="text_size_menu_material">18sp</dimen> + <dimen name="text_size_menu_header_material">16sp</dimen> + <dimen name="text_size_body_2_material">16sp</dimen> + <dimen name="text_size_body_1_material">16sp</dimen> + <dimen name="text_size_caption_material">14sp</dimen> + <dimen name="text_size_button_material">16sp</dimen> + + <dimen name="text_size_large_material">18sp</dimen> + <dimen name="text_size_medium_material">16sp</dimen> + <dimen name="text_size_small_material">14sp</dimen> +</resources> diff --git a/core/res/res/values-watch/config_material.xml b/core/res/res/values-watch/config_material.xml index 81b53e71b5d7..104d122e01d3 100644 --- a/core/res/res/values-watch/config_material.xml +++ b/core/res/res/values-watch/config_material.xml @@ -29,7 +29,4 @@ <!-- Always overscan by default to ensure onApplyWindowInsets will always be called. --> <bool name="config_windowOverscanByDefault">true</bool> - - <!-- Due to the smaller screen size, have dialog titles occupy more than 1 line. --> - <integer name="config_dialogWindowTitleMaxLines">3</integer> </resources> diff --git a/core/res/res/values-watch/dimens_material.xml b/core/res/res/values-watch/dimens_material.xml index d579434d5e30..b48cde62158a 100644 --- a/core/res/res/values-watch/dimens_material.xml +++ b/core/res/res/values-watch/dimens_material.xml @@ -14,5 +14,29 @@ limitations under the License. --> <resources> + <dimen name="text_size_display_4_material">71sp</dimen> + <dimen name="text_size_display_3_material">44sp</dimen> + <dimen name="text_size_display_2_material">36sp</dimen> + <dimen name="text_size_display_1_material">27sp</dimen> + <dimen name="text_size_headline_material">18sp</dimen> + <dimen name="text_size_title_material">16sp</dimen> + <dimen name="text_size_subhead_material">16sp</dimen> + <dimen name="text_size_title_material_toolbar">16dp</dimen> + <dimen name="text_size_subtitle_material_toolbar">16dp</dimen> + <dimen name="text_size_menu_material">16sp</dimen> + <dimen name="text_size_menu_header_material">14sp</dimen> + <dimen name="text_size_body_2_material">14sp</dimen> + <dimen name="text_size_body_1_material">14sp</dimen> + <dimen name="text_size_caption_material">12sp</dimen> + <dimen name="text_size_button_material">14sp</dimen> + + <dimen name="text_size_large_material">16sp</dimen> + <dimen name="text_size_medium_material">14sp</dimen> + <dimen name="text_size_small_material">12sp</dimen> + <item name="text_line_spacing_multiplier_material" format="float" type="dimen">1.2</item> + + <!-- Date and time picker legacy dimens --> + <dimen name="picker_top_margin">1dip</dimen> + <dimen name="picker_bottom_margin">1dip</dimen> </resources> diff --git a/core/res/res/layout-watch/number_picker_material.xml b/core/res/res/values-watch/integers.xml index a1c0921482ad..46ed97d83182 100644 --- a/core/res/res/layout-watch/number_picker_material.xml +++ b/core/res/res/values-watch/integers.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -** +/* ** Copyright 2012, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,16 +16,10 @@ ** limitations under the License. */ --> +<resources> + <!-- Specifies date picker mode to be 'spinner' --> + <integer name="date_picker_mode_material">1</integer> -<merge xmlns:android="http://schemas.android.com/apk/res/android"> - - <view class="android.widget.NumberPicker$CustomEditText" - android:textAppearance="?android:attr/textAppearanceLarge" - android:id="@+id/numberpicker_input" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:singleLine="true" - android:background="@null" /> - -</merge> + <!-- Specifies time picker mode to be 'spinner' --> + <integer name="time_picker_mode_material">1</integer> +</resources> diff --git a/core/res/res/values-watch/styles_material.xml b/core/res/res/values-watch/styles_material.xml index f5735e69347a..d09119fc7d6b 100644 --- a/core/res/res/values-watch/styles_material.xml +++ b/core/res/res/values-watch/styles_material.xml @@ -61,12 +61,19 @@ please see styles_device_defaults.xml. <item name="divider">@empty</item> </style> + <style name="TextAppearance.Material.ListItem" parent="TextAppearance.Material.Body1" /> + <style name="TextAppearance.Material.ListItemSecondary" parent="TextAppearance.Material.Caption" /> + <style name="Widget.Material.TextView" parent="Widget.TextView"> <item name="breakStrategy">balanced</item> </style> <style name="Widget.Material.ButtonBar" parent="Widget.Material.BaseButtonBar" /> + <style name="TextAppearance.Material.NumberPicker" parent="TextAppearance.Material.Body1"> + <item name="textSize">@dimen/text_size_medium_material</item> + </style> + <!-- Alert dialog button bar button --> <style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Small"> <item name="paddingStart">@dimen/list_item_padding_start_material</item> @@ -82,13 +89,21 @@ please see styles_device_defaults.xml. <item name="solidColor">@color/transparent</item> <item name="selectionDivider">@drawable/numberpicker_selection_divider</item> <item name="selectionDividerHeight">2dp</item> - <item name="selectionDividersDistance">48dp</item> - <item name="internalMinWidth">64dp</item> - <item name="internalMaxHeight">180dp</item> + <item name="selectionDividersDistance">24dp</item> + <item name="internalMinWidth">32dp</item> + <item name="internalMaxHeight">90dp</item> <item name="virtualButtonPressedDrawable">?selectableItemBackground</item> <item name="descendantFocusability">blocksDescendants</item> </style> + <style name="DialogWindowTitle.Material"> + <item name="maxLines">3</item> + <item name="scrollHorizontally">false</item> + <item name="textAppearance">@style/TextAppearance.Material.DialogWindowTitle</item> + <item name="gravity">@integer/config_dialogTextGravity</item> + <item name="ellipsize">end</item> + </style> + <!-- DO NOTE TRANSLATE Spans within this text are applied to style composing regions within an EditText widget. The text content is ignored and not used. Note: This is @color/material_deep_teal_200, cannot use @color references here. --> diff --git a/core/res/res/values-watch/themes_material.xml b/core/res/res/values-watch/themes_material.xml index 4ae4367e8bc7..84bc25f26db4 100644 --- a/core/res/res/values-watch/themes_material.xml +++ b/core/res/res/values-watch/themes_material.xml @@ -59,4 +59,17 @@ please see styles_device_defaults.xml. <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_material_light</item> <item name="windowIsFloating">false</item> </style> + + <!-- Force all settings themes to use normal Material theme. --> + <style name="Theme.Material.Settings" parent="Theme.Material"/> + <style name="Theme.Material.Settings.NoActionBar" parent="Theme.Material"/> + <style name="Theme.Material.Settings.BaseDialog" parent="Theme.Material.Dialog"/> + <style name="Theme.Material.Settings.Dialog" parent="Theme.Material.Settings.BaseDialog"/> + <style name="Theme.Material.Settings.Dialog.BaseAlert" parent="Theme.Material.Dialog.BaseAlert"/> + <style name="Theme.Material.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.BaseAlert"/> + <style name="Theme.Material.Settings.DialogWhenLarge" parent="Theme.Material.DialogWhenLarge"/> + <style name="Theme.Material.Settings.DialogWhenLarge.NoActionBar" parent="Theme.Material.DialogWhenLarge.NoActionBar"/> + <style name="Theme.Material.Settings.Dialog.Presentation" parent="Theme.Material.Dialog.Presentation"/> + <style name="Theme.Material.Settings.SearchBar" parent="Theme.Material.SearchBar"/> + <style name="Theme.Material.Settings.CompactMenu" parent="Theme.Material.CompactMenu"/> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index e21925bb3fb6..231dcdacaeeb 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -539,9 +539,12 @@ Software implementation will be used if config_hardware_auto_brightness_available is not set --> <bool name="config_automatic_brightness_available">false</bool> - <!-- Fast brightness animation ramp rate --> + <!-- Fast brightness animation ramp rate in brightness units per second--> <integer translatable="false" name="config_brightness_ramp_rate_fast">200</integer> + <!-- Slow brightness animation ramp rate in brightness units per second--> + <integer translatable="false" name="config_brightness_ramp_rate_slow">40</integer> + <!-- Don't name config resources like this. It should look like config_annoyDianne --> <bool name="config_annoy_dianne">true</bool> @@ -796,6 +799,12 @@ --> <integer name="config_longPressOnBackBehavior">0</integer> + <!-- Control the behavior when the user panic presses the back button. + 0 - Nothing + 1 - Go to home + --> + <integer name="config_backPanicBehavior">0</integer> + <!-- Control the behavior when the user short presses the power button. 0 - Nothing 1 - Go to sleep (doze) @@ -2519,4 +2528,7 @@ Note: Also update appropriate overlay files. --> <string-array translatable="false" name="config_defaultFirstUserRestrictions"> </string-array> + + <string name="config_networkOverLimitComponent" translatable="false">com.android.systemui/com.android.systemui.net.NetworkOverLimitActivity</string> + <string name="config_dataUsageSummaryComponent" translatable="false">com.android.settings/com.android.settings.Settings$DataUsageSummaryActivity</string> </resources> diff --git a/core/res/res/values/config_material.xml b/core/res/res/values/config_material.xml index a37be837d9f1..397635f402b1 100644 --- a/core/res/res/values/config_material.xml +++ b/core/res/res/values/config_material.xml @@ -32,9 +32,6 @@ <!-- True if windowOverscan should be on by default. --> <bool name="config_windowOverscanByDefault">false</bool> - <!-- Max number of lines for the dialog title. --> - <integer name="config_dialogWindowTitleMaxLines">1</integer> - <!-- True if preference fragment should clip to padding. --> <bool name="config_preferenceFragmentClipToPadding">true</bool> </resources> diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml index f96cef9ad1c5..ae3116584e5d 100644 --- a/core/res/res/values/dimens_material.xml +++ b/core/res/res/values/dimens_material.xml @@ -189,4 +189,8 @@ <dimen name="day_picker_button_margin_top">0dp</dimen> <dimen name="datepicker_view_animator_height">226dp</dimen> + + <!-- Date and time picker legacy dimens --> + <dimen name="picker_top_margin">16dip</dimen> + <dimen name="picker_bottom_margin">16dip</dimen> </resources> diff --git a/core/res/res/values/integers.xml b/core/res/res/values/integers.xml index 71ac2f49ff71..2b69c75b7d9c 100644 --- a/core/res/res/values/integers.xml +++ b/core/res/res/values/integers.xml @@ -26,5 +26,12 @@ <integer name="date_picker_mode">1</integer> <integer name="time_picker_mode">1</integer> + + <!-- Specifies date picker mode to be 'calendar' --> + <integer name="date_picker_mode_material">2</integer> + + <!-- Specifies time picker mode to be 'clock' --> + <integer name="time_picker_mode_material">2</integer> + <integer name="date_picker_header_max_lines_material">2</integer> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 6c26165d4a3a..d66a7f725c20 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1957,7 +1957,7 @@ <string name="lockscreen_access_pattern_cleared">Pattern cleared</string> <!-- Accessibility description sent when user adds a dot to the pattern. [CHAR LIMIT=NONE] --> <string name="lockscreen_access_pattern_cell_added">Cell added</string> - <!-- Accessibility description sent when user adds a dot to the pattern. Announces the + <!-- Accessibility description sent when user adds a dot to the pattern. Announces the actual cell when headphones are connected [CHAR LIMIT=NONE] --> <string name="lockscreen_access_pattern_cell_added_verbose"> Cell <xliff:g id="cell_index" example="3">%1$s</xliff:g> added</string> @@ -2037,6 +2037,12 @@ <!-- Button to restart the device after the factory test. --> <string name="factorytest_reboot">Reboot</string> + <!-- Do not translate. timepicker mode, overridden for watch --> + <string name="time_picker_mode" translatable="false">"clock"</string> + + <!-- Do not translate. datepicker mode, overridden for watch --> + <string name="date_picker_mode" translatable="false">"calendar"</string> + <!-- Do not translate. WebView User Agent string --> <string name="web_user_agent" translatable="false">Mozilla/5.0 (Linux; U; <xliff:g id="x">Android %s</xliff:g>) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.30</string> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index 443553754193..90746e5b5e75 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -255,6 +255,8 @@ please see styles_device_defaults.xml. <item name="textColor">?attr/textColorPrimary</item> </style> + <style name="TextAppearance.Material.NumberPicker" parent="TextAppearance.Material.Body1"/> + <!-- Deprecated text styles --> <style name="TextAppearance.Material.Inverse"> @@ -475,6 +477,9 @@ please see styles_device_defaults.xml. <item name="textColor">#66000000</item> </style> + <style name="TextAppearance.Material.ListItem" parent="TextAppearance.Material.Subhead" /> + <style name="TextAppearance.Material.ListItemSecondary" parent="TextAppearance.Material.Body1" /> + <style name="Widget.Material.Notification.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal" /> <style name="Widget.Material.Notification.MessagingText" parent="Widget.Material.Light.TextView"> @@ -684,7 +689,7 @@ please see styles_device_defaults.xml. </style> <style name="Widget.Material.TimePicker"> - <item name="timePickerMode">clock</item> + <item name="timePickerMode">@integer/time_picker_mode_material</item> <item name="legacyLayout">@layout/time_picker_legacy_material</item> <!-- Attributes for new-style TimePicker. --> <item name="internalLayout">@layout/time_picker_material</item> @@ -698,7 +703,7 @@ please see styles_device_defaults.xml. </style> <style name="Widget.Material.DatePicker"> - <item name="datePickerMode">calendar</item> + <item name="datePickerMode">@integer/date_picker_mode_material</item> <item name="legacyLayout">@layout/date_picker_legacy_holo</item> <item name="calendarViewShown">true</item> <!-- Attributes for new-style DatePicker. --> @@ -1246,7 +1251,7 @@ please see styles_device_defaults.xml. <style name="DialogWindowTitleBackground.Material.Light" /> <style name="DialogWindowTitle.Material"> - <item name="maxLines">@integer/config_dialogWindowTitleMaxLines</item> + <item name="maxLines">1</item> <item name="scrollHorizontally">true</item> <item name="textAppearance">@style/TextAppearance.Material.DialogWindowTitle</item> </style> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index c9ed497679d0..db118ed591ea 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -375,6 +375,7 @@ <java-symbol type="integer" name="config_immersive_mode_confirmation_panic" /> <java-symbol type="integer" name="config_longPressOnPowerBehavior" /> <java-symbol type="integer" name="config_longPressOnBackBehavior" /> + <java-symbol type="integer" name="config_backPanicBehavior" /> <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" /> <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" /> <java-symbol type="integer" name="config_max_pan_devices" /> @@ -1757,6 +1758,7 @@ <java-symbol type="integer" name="config_undockedHdmiRotation" /> <java-symbol type="integer" name="config_virtualKeyQuietTimeMillis" /> <java-symbol type="integer" name="config_brightness_ramp_rate_fast" /> + <java-symbol type="integer" name="config_brightness_ramp_rate_slow" /> <java-symbol type="layout" name="am_compat_mode_dialog" /> <java-symbol type="layout" name="launch_warning" /> <java-symbol type="layout" name="safe_mode" /> @@ -2647,6 +2649,10 @@ <!-- Colon separated list of package names that should be granted DND access --> <java-symbol type="string" name="config_defaultDndAccessPackages" /> + <!-- For NetworkPolicyManagerService --> + <java-symbol type="string" name="config_networkOverLimitComponent" /> + <java-symbol type="string" name="config_dataUsageSummaryComponent" /> + <java-symbol type="string" name="lockscreen_storage_locked" /> <!-- Used for MimeIconUtils. --> diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml index 7e2867de1d7a..0eb4c8d86928 100644 --- a/core/res/res/values/themes_material.xml +++ b/core/res/res/values/themes_material.xml @@ -114,9 +114,9 @@ please see themes_device_defaults.xml. <item name="listPreferredItemHeightSmall">48dip</item> <item name="listPreferredItemHeightLarge">80dip</item> <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item> - <item name="textAppearanceListItem">@style/TextAppearance.Material.Subhead</item> - <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.Subhead</item> - <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.Body1</item> + <item name="textAppearanceListItem">@style/TextAppearance.Material.ListItem</item> + <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.ListItem</item> + <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.ListItemSecondary</item> <item name="listPreferredItemPaddingLeft">@dimen/list_item_padding_horizontal_material</item> <item name="listPreferredItemPaddingRight">@dimen/list_item_padding_horizontal_material</item> <item name="listPreferredItemPaddingStart">@dimen/list_item_padding_start_material</item> @@ -475,9 +475,9 @@ please see themes_device_defaults.xml. <item name="listPreferredItemHeightSmall">48dip</item> <item name="listPreferredItemHeightLarge">80dip</item> <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item> - <item name="textAppearanceListItem">@style/TextAppearance.Material.Subhead</item> - <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.Subhead</item> - <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.Body1</item> + <item name="textAppearanceListItem">@style/TextAppearance.Material.ListItem</item> + <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.ListItem</item> + <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.ListItemSecondary</item> <item name="listPreferredItemPaddingLeft">@dimen/list_item_padding_horizontal_material</item> <item name="listPreferredItemPaddingRight">@dimen/list_item_padding_horizontal_material</item> <item name="listPreferredItemPaddingStart">@dimen/list_item_padding_start_material</item> diff --git a/core/res/res/xml-watch/default_zen_mode_config.xml b/core/res/res/xml-watch/default_zen_mode_config.xml index 26af10c1809e..938cc0c3f7c0 100644 --- a/core/res/res/xml-watch/default_zen_mode_config.xml +++ b/core/res/res/xml-watch/default_zen_mode_config.xml @@ -17,8 +17,8 @@ <!-- Default configuration for zen mode. See android.service.notification.ZenModeConfig. --> <zen version="2"> - <!-- Allow starred contacts to go through only. Repeated calls on. - Calls, messages, reminders, events off.--> - <allow from="2" repeatCallers="true" calls="false" messages="false" reminders="false" + <!-- Allow starred contacts to go through only. + Repeated calls, calls, messages, reminders, events off. --> + <allow from="2" repeatCallers="false" calls="false" messages="false" reminders="false" events="false"/> </zen> diff --git a/docs/html/guide/topics/renderscript/advanced.jd b/docs/html/guide/topics/renderscript/advanced.jd index 6a72b979006c..5cc055658cfd 100644 --- a/docs/html/guide/topics/renderscript/advanced.jd +++ b/docs/html/guide/topics/renderscript/advanced.jd @@ -63,7 +63,7 @@ amount of cores available on a processor. <code>llvm</code> compiler that runs as part of an Android build. When your application runs on a device, the bytecode is then compiled (just-in-time) to machine code by another <code>llvm</code> compiler that resides on the device. The machine code is optimized for the - device and also cached, so subsequent uses of the RenderScript enabled application does not + device and also cached, so subsequent uses of the RenderScript enabled application do not recompile the bytecode.</p> <p>Some key features of the RenderScript runtime libraries include:</p> @@ -128,7 +128,7 @@ generated.</p></li> <h3 id="func">Functions</h3> <p>Functions are reflected into the script class itself, located in <code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. For -example, if you declare the following function in your RenderScript code:</p> +example, if you define the following function in your RenderScript code:</p> <pre> void touch(float x, float y, float pressure, int id) { @@ -142,7 +142,7 @@ void touch(float x, float y, float pressure, int id) { } </pre> -<p>then the following code is generated:</p> +<p>then the following Java code is generated:</p> <pre> public void invoke_touch(float x, float y, float pressure, int id) { @@ -155,7 +155,7 @@ public void invoke_touch(float x, float y, float pressure, int id) { } </pre> <p> -Functions cannot have a return value, because the RenderScript system is designed to be +Functions cannot have return values, because the RenderScript system is designed to be asynchronous. When your Android framework code calls into RenderScript, the call is queued and is executed when possible. This restriction allows the RenderScript system to function without constant interruption and increases efficiency. If functions were allowed to have return values, the call @@ -171,11 +171,11 @@ function. <p>Variables of supported types are reflected into the script class itself, located in <code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. A set of accessor -methods are generated for each variable. For example, if you declare the following variable in +methods is generated for each variable. For example, if you define the following variable in your RenderScript code:</p> <pre>uint32_t unsignedInteger = 1;</pre> - <p>then the following code is generated:</p> + <p>then the following Java code is generated:</p> <pre> private long mExportVar_unsignedInteger; @@ -194,7 +194,7 @@ public long get_unsignedInteger(){ <p>Structs are reflected into their own classes, located in <code><project_root>/gen/com/example/renderscript/ScriptField_struct_name</code>. This class represents an array of the <code>struct</code> and allows you to allocate memory for a - specified number of <code>struct</code>s. For example, if you declare the following struct:</p> + specified number of <code>struct</code>s. For example, if you define the following struct:</p> <pre> typedef struct Point { float2 position; @@ -373,7 +373,7 @@ in memory. Each <code>struct</code>'s class defines the following methods and co the array. The RenderScript runtime automatically has access to the newly written memory. <li>Accessor methods to get and set the values of each field in a struct. Each of these - accessor methods have an <code>index</code> parameter to specify the <code>struct</code> in + accessor methods has an <code>index</code> parameter to specify the <code>struct</code> in the array that you want to read or write to. Each setter method also has a <code>copyNow</code> parameter that specifies whether or not to immediately sync this memory to the RenderScript runtime. To sync any memory that has not been synced, call @@ -395,10 +395,10 @@ properties that are not yet synchronized.</li> </ul> <h3 id="pointer">Pointers</h3> - <p>Pointers are reflected into the script class itself, located in + <p>Global pointers are reflected into the script class itself, located in <code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. You can declare pointers to a <code>struct</code> or any of the supported RenderScript types, but a -<code>struct</code> cannot contain pointers or nested arrays. For example, if you declare the +<code>struct</code> cannot contain pointers or nested arrays. For example, if you define the following pointers to a <code>struct</code> and <code>int32_t</code></p> <pre> @@ -410,7 +410,7 @@ typedef struct Point { Point_t *touchPoints; int32_t *intPointer; </pre> - <p>then the following code is generated in:</p> + <p>then the following Java code is generated:</p> <pre> private ScriptField_Point mExportVar_touchPoints; @@ -437,7 +437,7 @@ public Allocation get_intPointer() { </pre> <p>A <code>get</code> method and a special method named <code>bind_<em>pointer_name</em></code> -(instead of a <code>set()</code> method) is generated. This method allows you to bind the memory +(instead of a <code>set()</code> method) are generated. The <code>bind_<em>pointer_name</em></code> method allows you to bind the memory that is allocated in the Android VM to the RenderScript runtime (you cannot allocate memory in your <code>.rs</code> file). For more information, see <a href="#memory">Working with Allocated Memory</a>. @@ -521,7 +521,7 @@ understand how these classes work, it is useful to think of them in relation to describes.</p> <p>A type consists of five dimensions: X, Y, Z, LOD (level of detail), and Faces (of a cube - map). You can assign the X,Y,Z dimensions to any positive integer value within the + map). You can set the X,Y,Z dimensions to any positive integer value within the constraints of available memory. A single dimension allocation has an X dimension of greater than zero while the Y and Z dimensions are zero to indicate not present. For example, an allocation of x=10, y=1 is considered two dimensional and x=10, y=0 is diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd index fe686547fe6c..13880ec6b796 100755 --- a/docs/html/guide/topics/renderscript/compute.jd +++ b/docs/html/guide/topics/renderscript/compute.jd @@ -16,6 +16,13 @@ parent.link=index.html </ol> </li> <li><a href="#using-rs-from-java">Using RenderScript from Java Code</a></li> + <li><a href="#reduction-in-depth">Reduction Kernels in Depth</a> + <ol> + <li><a href="#writing-reduction-kernel">Writing a reduction kernel</a></li> + <li><a href="#calling-reduction-kernel">Calling a reduction kernel from Java code</a></li> + <li><a href="#more-example">More example reduction kernels</a></li> + </ol> + </li> </ol> <h2>Related Samples</h2> @@ -29,16 +36,18 @@ parent.link=index.html <p>RenderScript is a framework for running computationally intensive tasks at high performance on Android. RenderScript is primarily oriented for use with data-parallel computation, although serial -computationally intensive workloads can benefit as well. The RenderScript runtime will parallelize -work across all processors available on a device, such as multi-core CPUs, GPUs, or DSPs, allowing -you to focus on expressing algorithms rather than scheduling work or load balancing. RenderScript is +workloads can benefit as well. The RenderScript runtime parallelizes +work across processors available on a device, such as multi-core CPUs and GPUs. This allows +you to focus on expressing algorithms rather than scheduling work. RenderScript is especially useful for applications performing image processing, computational photography, or computer vision.</p> <p>To begin with RenderScript, there are two main concepts you should understand:</p> <ul> -<li>High-performance compute kernels are written in a C99-derived language.</li> +<li>High-performance compute kernels are written in a C99-derived language. A <i>compute + kernel</i> is a function or collection of functions that you can direct the RenderScript runtime + to execute in parallel across a collection of data.</li> <li>A Java API is used for managing the lifetime of RenderScript resources and controlling kernel execution.</li> @@ -48,7 +57,7 @@ execution.</li> <p>A RenderScript kernel typically resides in a <code>.rs</code> file in the <code><project_root>/src/</code> directory; each <code>.rs</code> file is called a -script. Every script contains its own set of kernels, functions, and variables. A script can +<i>script</i>. Every script contains its own set of kernels, functions, and variables. A script can contain:</p> <ul> @@ -57,23 +66,32 @@ RenderScript kernel language used in this script. Currently, 1 is the only valid <li>A pragma declaration (<code>#pragma rs java_package_name(com.example.app)</code>) that declares the package name of the Java classes reflected from this script. -Note that your .rs file must be part of your application package, and not in a +Note that your <code>.rs</code> file must be part of your application package, and not in a library project.</li> -<li>Some number of invokable functions. An invokable function is a single-threaded RenderScript +<li>Zero or more <strong><i>invokable functions</i></strong>. An invokable function is a single-threaded RenderScript function that you can call from your Java code with arbitrary arguments. These are often useful for initial setup or serial computations within a larger processing pipeline.</li> -<li>Some number of script globals. A script global is equivalent to a global variable in C. You can +<li><p>Zero or more <strong><i>script globals</i></strong>. A script global is equivalent to a global variable in C. You can access script globals from Java code, and these are often used for parameter passing to RenderScript -kernels.</li> +kernels.</p></li> -<li>Some number of compute kernels. A kernel is a parallel function that executes across every -{@link android.renderscript.Element} within an {@link android.renderscript.Allocation}. +<li><p>Zero or more <strong><i>compute kernels</i></strong>. There are two kinds of compute +kernels: <i>mapping</i> kernels (also called <i>foreach</i> kernels) +and <i>reduction</i> kernels.</p> -<p>A simple kernel may look like the following:</p> +<p>A <em>mapping kernel</em> is a parallel function that operates on a collection of {@link + android.renderscript.Allocation Allocations} of the same dimensions. By default, it executes + once for every coordinate in those dimensions. It is typically (but not exclusively) used to + transform a collection of input {@link android.renderscript.Allocation Allocations} to an + output {@link android.renderscript.Allocation} one {@link android.renderscript.Element} at a + time.</p> -<pre>uchar4 __attribute__((kernel)) invert(uchar4 in, uint32_t x, uint32_t y) { +<ul> +<li><p>Here is an example of a simple <strong>mapping kernel</strong>:</p> + +<pre>uchar4 RS_KERNEL invert(uchar4 in, uint32_t x, uint32_t y) { uchar4 out = in; out.r = 255 - in.r; out.g = 255 - in.g; @@ -81,40 +99,113 @@ kernels.</li> return out; }</pre> -<p>In most respects, this is identical to a standard C function. The first notable feature is the -<code>__attribute__((kernel))</code> applied to the function prototype. This denotes that the -function is a RenderScript kernel instead of an invokable function. The next feature is the -<code>in</code> argument and its type. In a RenderScript kernel, this is a special argument that is -automatically filled in based on the input {@link android.renderscript.Allocation} passed to the -kernel launch. By default, the kernel is run across an entire {@link -android.renderscript.Allocation}, with one execution of the kernel body per {@link -android.renderscript.Element} in the {@link android.renderscript.Allocation}. The third notable -feature is the return type of the kernel. The value returned from the kernel is automatically -written to the appropriate location in the output {@link android.renderscript.Allocation}. The -RenderScript runtime checks to ensure that the {@link android.renderscript.Element} types of the -input and output Allocations match the kernel's prototype; if they do not match, an exception is -thrown.</p> - -<p>A kernel may have an input {@link android.renderscript.Allocation}, an output {@link -android.renderscript.Allocation}, or both. A kernel may not have more than one input or one output -{@link android.renderscript.Allocation}. If more than one input or output is required, those objects -should be bound to <code>rs_allocation</code> script globals and accessed from a kernel or invokable -function via <code>rsGetElementAt_<em>type</em>()</code> or -<code>rsSetElementAt_<em>type</em>()</code>.</p> - -<p>A kernel may access the coordinates of the current execution using the <code>x</code>, -<code>y</code>, and <code>z</code> arguments. These arguments are optional, but the type of the -coordinate arguments must be <code>uint32_t</code>.</p></li> +<p>In most respects, this is identical to a standard C + function. The <a href="#RS_KERNEL"><code>RS_KERNEL</code></a> property applied to the + function prototype specifies that the function is a RenderScript mapping kernel instead of an + invokable function. The <code>in</code> argument is automatically filled in based on the + input {@link android.renderscript.Allocation} passed to the kernel launch. The + arguments <code>x</code> and <code>y</code> are + discussed <a href="#special-arguments">below</a>. The value returned from the kernel is + automatically written to the appropriate location in the output {@link + android.renderscript.Allocation}. By default, this kernel is run across its entire input + {@link android.renderscript.Allocation}, with one execution of the kernel function per {@link + android.renderscript.Element} in the {@link android.renderscript.Allocation}.</p> + +<p>A mapping kernel may have one or more input {@link android.renderscript.Allocation + Allocations}, a single output {@link android.renderscript.Allocation}, or both. The + RenderScript runtime checks to ensure that all input and output Allocations have the same + dimensions, and that the {@link android.renderscript.Element} types of the input and output + Allocations match the kernel's prototype; if either of these checks fails, RenderScript + throws an exception.</p> + +<p class="note"><strong>NOTE:</strong> Before Android 6.0 (API level 23), a mapping kernel may + not have more than one input {@link android.renderscript.Allocation}.</p> + +<p>If you need more input or output {@link android.renderscript.Allocation Allocations} than + the kernel has, those objects should be bound to <code>rs_allocation</code> script globals + and accessed from a kernel or invokable function + via <code>rsGetElementAt_<i>type</i>()</code> or <code>rsSetElementAt_<i>type</i>()</code>.</p> + +<p><strong>NOTE:</strong> <a id="RS_KERNEL"><code>RS_KERNEL</code></a> is a macro + defined automatically by RenderScript for your convenience:</p> +<pre> +#define RS_KERNEL __attribute__((kernel)) +</pre> +</li> +</ul> + +<p>A <em>reduction kernel</em> is a family of functions that operates on a collection of input + {@link android.renderscript.Allocation Allocations} of the same dimensions. By default, + its <a href="#accumulator-function">accumulator function</a> executes once for every + coordinate in those dimensions. It is typically (but not exclusively) used to "reduce" a + collection of input {@link android.renderscript.Allocation Allocations} to a single + value.</p> + +<ul> +<li><p>Here is an <a id="example-addint">example</a> of a simple <strong>reduction +kernel</strong> that adds up the {@link android.renderscript.Element Elements} of its +input:</p> + +<pre>#pragma rs reduce(addint) accumulator(addintAccum) + +static void addintAccum(int *accum, int val) { + *accum += val; +}</pre> + +<p>A reduction kernel consists of one or more user-written functions. +<code>#pragma rs reduce</code> is used to define the kernel by specifying its name +(<code>addint</code>, in this example) and the names and roles of the functions that make +up the kernel (an <code>accumulator</code> function <code>addintAccum</code>, in this +example). All such functions must be <code>static</code>. A reduction kernel always +requires an <code>accumulator</code> function; it may also have other functions, depending +on what you want the kernel to do.</p> + +<p>A reduction kernel accumulator function must return <code>void</code> and must have at least +two arguments. The first argument (<code>accum</code>, in this example) is a pointer to +an <i>accumulator data item</i> and the second (<code>val</code>, in this example) is +automatically filled in based on the input {@link android.renderscript.Allocation} passed to +the kernel launch. The accumulator data item is created by the RenderScript runtime; by +default, it is initialized to zero. By default, this kernel is run across its entire input +{@link android.renderscript.Allocation}, with one execution of the accumulator function per +{@link android.renderscript.Element} in the {@link android.renderscript.Allocation}. By +default, the final value of the accumulator data item is treated as the result of the +reduction, and is returned to Java. The RenderScript runtime checks to ensure that the {@link +android.renderscript.Element} type of the input Allocation matches the accumulator function's +prototype; if it does not match, RenderScript throws an exception.</p> + +<p>A reduction kernel has one or more input {@link android.renderscript.Allocation +Allocations} but no output {@link android.renderscript.Allocation Allocations}.</p></li> + +<p>Reduction kernels are explained in more detail <a href="#reduction-in-depth">here</a>.</p> + +<p>Reduction kernels are supported in Android 7.0 (API level 24) and later.</p> +</li> +</ul> + +<p>A mapping kernel function or a reduction kernel accumulator function may access the coordinates +of the current execution using the <a id="special-arguments">special arguments</a> <code>x</code>, +<code>y</code>, and <code>z</code>, which must be of type <code>int</code> or <code>uint32_t</code>. +These arguments are optional.</p> + +<p>A mapping kernel function or a reduction kernel accumulator +function may also take the optional special argument +<code>context</code> of type <a +href='reference/rs_for_each.html#android_rs:rs_kernel_context'>rs_kernel_context</a>. +It is needed by a family of runtime APIs that are used to query +certain properties of the current execution -- for example, <a +href='reference/rs_for_each.html#android_rs:rsGetDimX'>rsGetDimX</a>. +(The <code>context</code> argument is available in Android 6.0 (API level 23) and later.)</p> +</li> <li>An optional <code>init()</code> function. An <code>init()</code> function is a special type of -invokable function that is run when the script is first instantiated. This allows for some +invokable function that RenderScript runs when the script is first instantiated. This allows for some computation to occur automatically at script creation.</li> -<li>Some number of static script globals and functions. A static script global is equivalent to a -script global except that it cannot be set from Java code. A static function is a standard C +<li>Zero or more <strong><i>static script globals and functions</i></strong>. A static script global is equivalent to a +script global except that it cannot be accessed from Java code. A static function is a standard C function that can be called from any kernel or invokable function in the script but is not exposed to the Java API. If a script global or function does not need to be called from Java code, it is -highly recommended that those be declared <code>static</code>.</li> </ul> +highly recommended that it be declared <code>static</code>.</li> </ul> <h4>Setting floating point precision</h4> @@ -129,13 +220,13 @@ different level of floating point precision:</p> </li> - <li><code>#pragma rs_fp_relaxed</code> - For apps that don’t require strict IEEE 754-2008 + <li><code>#pragma rs_fp_relaxed</code>: For apps that don’t require strict IEEE 754-2008 compliance and can tolerate less precision. This mode enables flush-to-zero for denorms and round-towards-zero. </li> - <li><code>#pragma rs_fp_imprecise</code> - For apps that don’t have stringent precision + <li><code>#pragma rs_fp_imprecise</code>: For apps that don’t have stringent precision requirements. This mode enables everything in <code>rs_fp_relaxed</code> along with the following: @@ -162,14 +253,21 @@ precision (such as SIMD CPU instructions).</p> available on devices running Android 3.0 (API level 11) and higher. </li> <li><strong>{@link android.support.v8.renderscript}</strong> - The APIs in this package are available through a <a href="{@docRoot}tools/support-library/features.html#v8">Support - Library</a>, which allows you to use them on devices running Android 2.2 (API level 8) and + Library</a>, which allows you to use them on devices running Android 2.3 (API level 9) and higher.</li> </ul> -<p>We strongly recommend using the Support Library APIs for accessing RenderScript because they - provide a wider range of device compatibility. Developers targeting specific versions of - Android can use {@link android.renderscript} if necessary.</p> +<p>Here are the tradeoffs:</p> +<ul> +<li>If you use the Support Library APIs, the RenderScript portion of your application will be + compatible with devices running Android 2.3 (API level 9) and higher, regardless of which RenderScript + features you use. This allows your application to work on more devices than if you use the + native (<strong>{@link android.renderscript}</strong>) APIs.</li> +<li>Certain RenderScript features are not available through the Support Library APIs.</li> +<li>If you use the Support Library APIs, you will get (possibly significantly) larger APKs than +if you use the native (<strong>{@link android.renderscript}</strong>) APIs.</li> +</ul> <h3 id="ide-setup">Using the RenderScript Support Library APIs</h3> @@ -202,7 +300,7 @@ android { buildToolsVersion "23.0.3" defaultConfig { - minSdkVersion 8 + minSdkVersion 9 targetSdkVersion 19 <strong> renderscriptTargetApi 18 @@ -250,7 +348,7 @@ import android.support.v8.renderscript.*; <p>Using RenderScript from Java code relies on the API classes located in the {@link android.renderscript} or the {@link android.support.v8.renderscript} package. Most -applications follow the same basic usage patterns:</p> +applications follow the same basic usage pattern:</p> <ol> @@ -266,12 +364,12 @@ possible. Typically, an application will have only a single RenderScript context script.</strong> An {@link android.renderscript.Allocation} is a RenderScript object that provides storage for a fixed amount of data. Kernels in scripts take {@link android.renderscript.Allocation} objects as their input and output, and {@link android.renderscript.Allocation} objects can be -accessed in kernels using <code>rsGetElementAt_<em>type</em>()</code> and -<code>rsSetElementAt_<em>type</em>()</code> when bound as script globals. {@link +accessed in kernels using <code>rsGetElementAt_<i>type</i>()</code> and +<code>rsSetElementAt_<i>type</i>()</code> when bound as script globals. {@link android.renderscript.Allocation} objects allow arrays to be passed from Java code to RenderScript code and vice-versa. {@link android.renderscript.Allocation} objects are typically created using -{@link android.renderscript.Allocation#createTyped} or {@link -android.renderscript.Allocation#createFromBitmap}.</li> +{@link android.renderscript.Allocation#createTyped createTyped()} or {@link +android.renderscript.Allocation#createFromBitmap createFromBitmap()}.</li> <li><strong>Create whatever scripts are necessary.</strong> There are two types of scripts available to you when using RenderScript: @@ -281,9 +379,9 @@ to you when using RenderScript: <li><strong>ScriptC</strong>: These are the user-defined scripts as described in <a href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a> above. Every script has a Java class reflected by the RenderScript compiler in order to make it easy to access the script from Java code; -this class will have the name <code>ScriptC_<em>filename</em></code>. For example, if the kernel -above was located in <code>invert.rs</code> and a RenderScript context was already located in -<code>mRS</code>, the Java code to instantiate the script would be: +this class has the name <code>ScriptC_<i>filename</i></code>. For example, if the mapping kernel +above were located in <code>invert.rs</code> and a RenderScript context were already located in +<code>mRenderScript</code>, the Java code to instantiate the script would be: <pre>ScriptC_invert invert = new ScriptC_invert(mRenderScript);</pre></li> @@ -294,35 +392,926 @@ such as Gaussian blur, convolution, and image blending. For more information, se </ul></li> <li><strong>Populate Allocations with data.</strong> Except for Allocations created with {@link -android.renderscript.Allocation#createFromBitmap}, an Allocation will be populated with empty data when it is -first created. To populate an Allocation, use one of the <code>copy</code> methods in {@link -android.renderscript.Allocation}.</li> - -<li><strong>Set any necessary script globals.</strong> Globals may be set using methods in the same -<code>ScriptC_<em>filename</em></code> class with methods named -<code>set_<em>globalname</em></code>. For example, in order to set an <code>int</code> named -<code>elements</code>, use the Java method <code>set_elements(int)</code>. RenderScript objects can -also be set in kernels; for example, the <code>rs_allocation</code> variable named -<code>lookup</code> can be set with the method <code>set_lookup(Allocation)</code>.</li> - -<li><strong>Launch the appropriate kernels.</strong> Methods to launch a given kernel will be -reflected in the same <code>ScriptC_<em>filename</em></code> class with methods named -<code>forEach_<em>kernelname</em>()</code>. These launches are asynchronous, and launches will be -serialized in the order in which they are launched. Depending on the arguments to the kernel, the -method will take either one or two Allocations. By default, a kernel will execute over the entire -input or output Allocation; to execute over a subset of that Allocation, pass an appropriate {@link -android.renderscript.Script.LaunchOptions} as the last argument to the <code>forEach</code> method. - -<p>Invoked functions can be launched using the <code>invoke_<em>functionname</em></code> methods -reflected in the same <code>ScriptC_<em>filename</em></code> class.</p></li> - -<li><strong>Copy data out of {@link android.renderscript.Allocation} objects.</strong> In order to -access data from an {@link android.renderscript.Allocation} from Java code, that data must be copied -back to Java buffers using one of the <code>copy</code> methods in {@link -android.renderscript.Allocation}. These functions will synchronize with asynchronous kernel and -function launches as necessary.</li> - -<li><strong>Tear down the RenderScript context.</strong> The RenderScript context can be destroyed +android.renderscript.Allocation#createFromBitmap createFromBitmap()}, an Allocation is populated with empty data when it is +first created. To populate an Allocation, use one of the "copy" methods in {@link +android.renderscript.Allocation}. The "copy" methods are <a href="#asynchronous-model">synchronous</a>.</li> + +<li><strong>Set any necessary script globals.</strong> You may set globals using methods in the + same <code>ScriptC_<i>filename</i></code> class named <code>set_<i>globalname</i></code>. For + example, in order to set an <code>int</code> variable named <code>threshold</code>, use the + Java method <code>set_threshold(int)</code>; and in order to set + an <code>rs_allocation</code> variable named <code>lookup</code>, use the Java + method <code>set_lookup(Allocation)</code>. The <code>set</code> methods + are <a href="#asynchronous-model">asynchronous</a>.</li> + +<li><strong>Launch the appropriate kernels and invokable functions.</strong> +<p>Methods to launch a given kernel are +reflected in the same <code>ScriptC_<i>filename</i></code> class with methods named +<code>forEach_<i>mappingKernelName</i>()</code> +or <code>reduce_<i>reductionKernelName</i>()</code>. +These launches are <a href="#asynchronous-model">asynchronous</a>. +Depending on the arguments to the kernel, the +method takes one or more Allocations, all of which must have the same dimensions. By default, a +kernel executes over every coordinate in those dimensions; to execute a kernel over a subset of those coordinates, +pass an appropriate {@link +android.renderscript.Script.LaunchOptions} as the last argument to the <code>forEach</code> or <code>reduce</code> method.</p> + +<p>Launch invokable functions using the <code>invoke_<i>functionName</i></code> methods +reflected in the same <code>ScriptC_<i>filename</i></code> class. +These launches are <a href="#asynchronous-model">asynchronous</a>.</p></li> + +<li><strong>Retrieve data from {@link android.renderscript.Allocation} objects +and <i><a href="#javaFutureType">javaFutureType</a></i> objects.</strong> +In order to +access data from an {@link android.renderscript.Allocation} from Java code, you must copy that data +back to Java using one of the "copy" methods in {@link +android.renderscript.Allocation}. +In order to obtain the result of a reduction kernel, you must use the <code><i>javaFutureType</i>.get()</code> method. +The "copy" and <code>get()</code> methods are <a href="#asynchronous-model">synchronous</a>.</li> + +<li><strong>Tear down the RenderScript context.</strong> You can destroy the RenderScript context with {@link android.renderscript.RenderScript#destroy} or by allowing the RenderScript context -object to be garbage collected. This will cause any further use of any object belonging to that +object to be garbage collected. This causes any further use of any object belonging to that context to throw an exception.</li> </ol> + +<h3 id="asynchronous-model">Asynchronous execution model</h3> + +<p>The reflected <code>forEach</code>, <code>invoke</code>, <code>reduce</code>, + and <code>set</code> methods are asynchronous -- each may return to Java before completing the + requested action. However, the individual actions are serialized in the order in which they are launched.</p> + +<p>The {@link android.renderscript.Allocation} class provides "copy" methods to copy data to + and from Allocations. A "copy" method is synchronous, and is serialized with respect to any + of the asynchronous actions above that touch the same Allocation.</p> + +<p>The reflected <i><a href="#javaFutureType">javaFutureType</a></i> classes provide + a <code>get()</code> method to obtain the result of a reduction. <code>get()</code> is + synchronous, and is serialized with respect to the reduction (which is asynchronous).</p> + +<h2 id="reduction-in-depth">Reduction Kernels in Depth</h2> + +<p><i>Reduction</i> is the process of combining a collection of data into a single +value. This is a useful primitive in parallel programming, with applications such as the +following:</p> +<ul> + <li>computing the sum or product over all the data</li> + <li>computing logical operations (<code>and</code>, <code>or</code>, <code>xor</code>) + over all the data</li> + <li>finding the minimum or maximum value within the data</li> + <li>searching for a specific value or for the coordinate of a specific value within the data</li> +</ul> + +<p>In Android 7.0 (API level 24) and later, RenderScript supports <i>reduction kernels</i> to allow +efficient user-written reduction algorithms. You may launch reduction kernels on inputs with +1, 2, or 3 dimensions.<p> + +<p>An example above shows a simple <a href="#example-addint">addint</a> reduction kernel. +Here is a more complicated <a id="example-findMinAndMax">findMinAndMax</a> reduction kernel +that finds the locations of the minimum and maximum <code>long</code> values in a +1-dimensional {@link android.renderscript.Allocation}:</p> + +<pre> +#define LONG_MAX (long)((1UL << 63) - 1) +#define LONG_MIN (long)(1UL << 63) + +#pragma rs reduce(findMinAndMax) \ + initializer(fMMInit) accumulator(fMMAccumulator) \ + combiner(fMMCombiner) outconverter(fMMOutConverter) + +// Either a value and the location where it was found, or <a href="#INITVAL">INITVAL</a>. +typedef struct { + long val; + int idx; // -1 indicates <a href="#INITVAL">INITVAL</a> +} IndexedVal; + +typedef struct { + IndexedVal min, max; +} MinAndMax; + +// In discussion below, this initial value { { LONG_MAX, -1 }, { LONG_MIN, -1 } } +// is called <a id="INITVAL">INITVAL</a>. +static void fMMInit(MinAndMax *accum) { + accum->min.val = LONG_MAX; + accum->min.idx = -1; + accum->max.val = LONG_MIN; + accum->max.idx = -1; +} + +//---------------------------------------------------------------------- +// In describing the behavior of the accumulator and combiner functions, +// it is helpful to describe hypothetical functions +// IndexedVal min(IndexedVal a, IndexedVal b) +// IndexedVal max(IndexedVal a, IndexedVal b) +// MinAndMax minmax(MinAndMax a, MinAndMax b) +// MinAndMax minmax(MinAndMax accum, IndexedVal val) +// +// The effect of +// IndexedVal min(IndexedVal a, IndexedVal b) +// is to return the IndexedVal from among the two arguments +// whose val is lesser, except that when an IndexedVal +// has a negative index, that IndexedVal is never less than +// any other IndexedVal; therefore, if exactly one of the +// two arguments has a negative index, the min is the other +// argument. Like ordinary arithmetic min and max, this function +// is commutative and associative; that is, +// +// min(A, B) == min(B, A) // commutative +// min(A, min(B, C)) == min((A, B), C) // associative +// +// The effect of +// IndexedVal max(IndexedVal a, IndexedVal b) +// is analogous (greater . . . never greater than). +// +// Then there is +// +// MinAndMax minmax(MinAndMax a, MinAndMax b) { +// return MinAndMax(min(a.min, b.min), max(a.max, b.max)); +// } +// +// Like ordinary arithmetic min and max, the above function +// is commutative and associative; that is: +// +// minmax(A, B) == minmax(B, A) // commutative +// minmax(A, minmax(B, C)) == minmax((A, B), C) // associative +// +// Finally define +// +// MinAndMax minmax(MinAndMax accum, IndexedVal val) { +// return minmax(accum, MinAndMax(val, val)); +// } +//---------------------------------------------------------------------- + +// This function can be explained as doing: +// *accum = minmax(*accum, IndexedVal(in, x)) +// +// This function simply computes minimum and maximum values as if +// INITVAL.min were greater than any other minimum value and +// INITVAL.max were less than any other maximum value. Note that if +// *accum is INITVAL, then this function sets +// *accum = IndexedVal(in, x) +// +// After this function is called, both accum->min.idx and accum->max.idx +// will have nonnegative values: +// - x is always nonnegative, so if this function ever sets one of the +// idx fields, it will set it to a nonnegative value +// - if one of the idx fields is negative, then the corresponding +// val field must be LONG_MAX or LONG_MIN, so the function will always +// set both the val and idx fields +static void fMMAccumulator(MinAndMax *accum, long in, int x) { + IndexedVal me; + me.val = in; + me.idx = x; + + if (me.val <= accum->min.val) + accum->min = me; + if (me.val >= accum->max.val) + accum->max = me; +} + +// This function can be explained as doing: +// *accum = minmax(*accum, *val) +// +// This function simply computes minimum and maximum values as if +// INITVAL.min were greater than any other minimum value and +// INITVAL.max were less than any other maximum value. Note that if +// one of the two accumulator data items is INITVAL, then this +// function sets *accum to the other one. +static void fMMCombiner(MinAndMax *accum, + const MinAndMax *val) { + if ((accum->min.idx < 0) || (val->min.val < accum->min.val)) + accum->min = val->min; + if ((accum->max.idx < 0) || (val->max.val > accum->max.val)) + accum->max = val->max; +} + +static void fMMOutConverter(int2 *result, + const MinAndMax *val) { + result->x = val->min.idx; + result->y = val->max.idx; +} +</pre> + +<p class="note"><strong>NOTE:</strong> There are more example reduction + kernels <a href="#more-example">here</a>.</p> + +<p>In order to run a reduction kernel, the RenderScript runtime creates <em>one or more</em> +variables called <a id="accumulator-data-items"><strong><i>accumulator data +items</i></strong></a> to hold the state of the reduction process. The RenderScript runtime +picks the number of accumulator data items in such a way as to maximize performance. The type +of the accumulator data items (<i>accumType</i>) is determined by the kernel's <i>accumulator +function</i> -- the first argument to that function is a pointer to an accumulator data +item. By default, every accumulator data item is initialized to zero (as if +by <code>memset</code>); however, you may write an <i>initializer function</i> to do something +different.</p> + +<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a> +kernel, the accumulator data items (of type <code>int</code>) are used to add up input +values. There is no initializer function, so each accumulator data item is initialized to +zero.</p> + +<p class="note"><strong>Example:</strong> In +the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the accumulator data items +(of type <code>MinAndMax</code>) are used to keep track of the minimum and maximum values +found so far. There is an initializer function to set these to <code>LONG_MAX</code> and +<code>LONG_MIN</code>, respectively; and to set the locations of these values to -1, indicating that +the values are not actually present in the (empty) portion of the input that has been +processed.</p> + +<p>RenderScript calls your accumulator function once for every coordinate in the +input(s). Typically, your function should update the accumulator data item in some way +according to the input.</p> + +<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a> +kernel, the accumulator function adds the value of an input Element to the accumulator +data item.</p> + +<p class="note"><strong>Example:</strong> In +the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the accumulator function +checks to see whether the value of an input Element is less than or equal to the minimum +value recorded in the accumulator data item and/or greater than or equal to the maximum +value recorded in the accumulator data item, and updates the accumulator data item +accordingly.</p> + +<p>After the accumulator function has been called once for every coordinate in the input(s), +RenderScript must <strong>combine</strong> the <a href="#accumulator-data-items">accumulator +data items</a> together into a single accumulator data item. You may write a <i>combiner +function</i> to do this. If the accumulator function has a single input and +no <a href="#special-arguments">special arguments</a>, then you do not need to write a combiner +function; RenderScript will use the accumulator function to combine the accumulator data +items. (You may still write a combiner function if this default behavior is not what you +want.)</p> + +<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a> +kernel, there is no combiner function, so the accumulator function will be used. This is +the correct behavior, because if we split a collection of values into two pieces, and we +add up the values in those two pieces separately, adding up those two sums is the same as +adding up the entire collection.</p> + +<p class="note"><strong>Example:</strong> In +the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the combiner function +checks to see whether the minimum value recorded in the "source" accumulator data +item <code>*val</code> is less then the minimum value recorded in the "destination" +accumulator data item <code>*accum</code>, and updates <code>*accum</code> +accordingly. It does similar work for the maximum value. This updates <code>*accum</code> +to the state it would have had if all of the input values had been accumulated into +<code>*accum</code> rather than some into <code>*accum</code> and some into +<code>*val</code>.</p> + +<p>After all of the accumulator data items have been combined, RenderScript determines +the result of the reduction to return to Java. You may write an <i>outconverter +function</i> to do this. You do not need to write an outconverter function if you want +the final value of the combined accumulator data items to be the result of the reduction.</p> + +<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a> kernel, +there is no outconverter function. The final value of the combined data items is the sum of +all Elements of the input, which is the value we want to return.</p> + +<p class="note"><strong>Example:</strong> In +the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the outconverter function +initializes an <code>int2</code> result value to hold the locations of the minimum and +maximum values resulting from the combination of all of the accumulator data items.</p> + +<h3 id="writing-reduction-kernel">Writing a reduction kernel</h3> + +<p><code>#pragma rs reduce</code> defines a reduction kernel by +specifying its name and the names and roles of the functions that make +up the kernel. All such functions must be +<code>static</code>. A reduction kernel always requires an <code>accumulator</code> +function; you can omit some or all of the other functions, depending on what you want the +kernel to do.</p> + +<pre>#pragma rs reduce(<i>kernelName</i>) \ + initializer(<i>initializerName</i>) \ + accumulator(<i>accumulatorName</i>) \ + combiner(<i>combinerName</i>) \ + outconverter(<i>outconverterName</i>) +</pre> + +<p>The meaning of the items in the <code>#pragma</code> is as follows:</p> +<ul> + +<li><code>reduce(<i>kernelName</i>)</code> (mandatory): Specifies that a reduction kernel is +being defined. A reflected Java method <code>reduce_<i>kernelName</i></code> will launch the +kernel.</li> + +<li><p><code>initializer(<i>initializerName</i>)</code> (optional): Specifies the name of the +initializer function for this reduction kernel. When you launch the kernel, RenderScript calls +this function once for each <a href="#accumulator-data-items">accumulator data item</a>. The +function must be defined like this:</p> + +<pre>static void <i>initializerName</i>(<i>accumType</i> *accum) { … }</pre> + +<p><code>accum</code> is a pointer to an accumulator data item for this function to +initialize.</p> + +<p>If you do not provide an initializer function, RenderScript initializes every accumulator +data item to zero (as if by <code>memset</code>), behaving as if there were an initializer +function that looks like this:</p> +<pre>static void <i>initializerName</i>(<i>accumType</i> *accum) { + memset(accum, 0, sizeof(*accum)); +}</pre> +</li> + +<li><p><code><a id="accumulator-function">accumulator(<i>accumulatorName</i>)</a></code> +(mandatory): Specifies the name of the accumulator function for this +reduction kernel. When you launch the kernel, RenderScript calls +this function once for every coordinate in the input(s), to update an +accumulator data item in some way according to the input(s). The function +must be defined like this:</p> + +<pre> +static void <i>accumulatorName</i>(<i>accumType</i> *accum, + <i>in1Type</i> in1, <i>…,</i> <i>inNType</i> in<i>N</i> + <i>[, specialArguments]</i>) { … } +</pre> + +<p><code>accum</code> is a pointer to an accumulator data item for this function to +modify. <code>in1</code> through <code>in<i>N</i></code> are one <em>or more</em> arguments that +are automatically filled in based on the inputs passed to the kernel launch, one argument +per input. The accumulator function may optionally take any of the <a +href="#special-arguments">special arguments</a>.</p> + +<p>An example kernel with multiple inputs is <a href="#dot-product"><code>dotProduct</code></a>.</p> +</li> + +<li><code><a id="combiner-function">combiner(<i>combinerName</i>)</a></code> +(optional): Specifies the name of the combiner function for this +reduction kernel. After RenderScript calls the accumulator function +once for every coordinate in the input(s), it calls this function as many +times as necessary to combine all accumulator data items into a single +accumulator data item. The function must be defined like this:</p> + +<pre>static void <i>combinerName</i>(<i>accumType</i> *accum, const <i>accumType</i> *other) { … }</pre> + +<p><code>accum</code> is a pointer to a "destination" accumulator data item for this +function to modify. <code>other</code> is a pointer to a "source" accumulator data item +for this function to "combine" into <code>*accum</code>.</p> + +<p class="note"><strong>NOTE:</strong> It is possible + that <code>*accum</code>, <code>*other</code>, or both have been initialized but have never + been passed to the accumulator function; that is, one or both have never been updated + according to any input data. For example, in + the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the combiner + function <code>fMMCombiner</code> explicitly checks for <code>idx < 0</code> because that + indicates such an accumulator data item, whose value is <a href="#INITVAL">INITVAL</a>.</p> + +<p>If you do not provide a combiner function, RenderScript uses the accumulator function in its +place, behaving as if there were a combiner function that looks like this:</p> + +<pre>static void <i>combinerName</i>(<i>accumType</i> *accum, const <i>accumType</i> *other) { + <i>accumulatorName</i>(accum, *other); +}</pre> + +<p>A combiner function is mandatory if the kernel has more than one input, if the input data + type is not the same as the accumulator data type, or if the accumulator function takes one + or more <a href="#special-arguments">special arguments</a>.</p> +</li> + +<li><p><code><a id="outconverter-function">outconverter(<i>outconverterName</i>)</a></code> +(optional): Specifies the name of the outconverter function for this +reduction kernel. After RenderScript combines all of the accumulator +data items, it calls this function to determine the result of the +reduction to return to Java. The function must be defined like +this:</p> + +<pre>static void <i>outconverterName</i>(<i>resultType</i> *result, const <i>accumType</i> *accum) { … }</pre> + +<p><code>result</code> is a pointer to a result data item (allocated but not initialized +by the RenderScript runtime) for this function to initialize with the result of the +reduction. <i>resultType</i> is the type of that data item, which need not be the same +as <i>accumType</i>. <code>accum</code> is a pointer to the final accumulator data item +computed by the <a href="#combiner-function">combiner function</a>.</p> + +<p>If you do not provide an outconverter function, RenderScript copies the final accumulator +data item to the result data item, behaving as if there were an outconverter function that +looks like this:</p> + +<pre>static void <i>outconverterName</i>(<i>accumType</i> *result, const <i>accumType</i> *accum) { + *result = *accum; +}</pre> + +<p>If you want a different result type than the accumulator data type, then the outconverter function is mandatory.</p> +</li> + +</ul> + +<p>Note that a kernel has input types, an accumulator data item type, and a result type, + none of which need to be the same. For example, in + the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the input + type <code>long</code>, accumulator data item type <code>MinAndMax</code>, and result + type <code>int2</code> are all different.</p> + +<h4 id="assume">What can't you assume?</h4> + +<p>You must not rely on the number of accumulator data items created by RenderScript for a + given kernel launch. There is no guarantee that two launches of the same kernel with the + same input(s) will create the same number of accumulator data items.</p> + +<p>You must not rely on the order in which RenderScript calls the initializer, accumulator, and + combiner functions; it may even call some of them in parallel. There is no guarantee that + two launches of the same kernel with the same input will follow the same order. The only + guarantee is that only the initializer function will ever see an uninitialized accumulator + data item. For example:</p> +<ul> +<li>There is no guarantee that all accumulator data items will be initialized before the + accumulator function is called, although it will only be called on an initialized accumulator + data item.</li> +<li>There is no guarantee on the order in which input Elements are passed to the accumulator + function.</li> +<li>There is no guarantee that the accumulator function has been called for all input Elements + before the combiner function is called.</li> +</ul> + +<p>One consequence of this is that the <a href="#example-findMinAndMax">findMinAndMax</a> + kernel is not deterministic: If the input contains more than one occurrence of the same + minimum or maximum value, you have no way of knowing which occurrence the kernel will + find.</p> + +<h4 id="guarantee">What must you guarantee?</h4> + +<p>Because the RenderScript system can choose to execute a kernel <a href="#assume">in many + different ways</a>, you must follow certain rules to ensure that your kernel behaves the + way you want. If you do not follow these rules, you may get incorrect results, + nondeterministic behavior, or runtime errors.</p> + +<p>The rules below often say that two accumulator data items must have "<a id="the-same">the + same value"</a>. What does this mean? That depends on what you want the kernel to do. For + a mathematical reduction such as <a href="#example-addint">addint</a>, it usually makes sense + for "the same" to mean mathematical equality. For a "pick any" search such + as <a href="#example-findMinAndMax">findMinAndMax</a> ("find the location of minimum and + maximum input values") where there might be more than one occurrence of identical input + values, all locations of a given input value must be considered "the same". You could write + a similar kernel to "find the location of <em>leftmost</em> minimum and maximum input values" + where (say) a minimum value at location 100 is preferred over an identical minimum value at location + 200; for this kernel, "the same" would mean identical <em>location</em>, not merely + identical <em>value</em>, and the accumulator and combiner functions would have to be + different than those for <a href="#example-findMinAndMax">findMinAndMax</a>.</p> + +<strong>The initializer function must create an <i>identity value</i>.</strong> That is, + if <code><i>I</i></code> and <code><i>A</i></code> are accumulator data items initialized + by the initializer function, and <code><i>I</i></code> has never been passed to the + accumulator function (but <code><i>A</i></code> may have been), then +<ul> +<li><code><i>combinerName</i>(&<i>A</i>, &<i>I</i>)</code> must + leave <code><i>A</i></code> <a href="#the-same">the same</a></li> +<li><code><i>combinerName</i>(&<i>I</i>, &<i>A</i>)</code> must + leave <code><i>I</i></code> <a href="#the-same">the same</a> as <code><i>A</i></code></li> +</ul> +<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a> + kernel, an accumulator data item is initialized to zero. The combiner function for this + kernel performs addition; zero is the identity value for addition.</p> +<div class="note"> +<p><strong>Example:</strong> In the <a href="#example-findMinAndMax">findMinAndMax</a> + kernel, an accumulator data item is initialized + to <a href="#INITVAL"><code>INITVAL</code></a>. +<ul> +<li><code>fMMCombiner(&<i>A</i>, &<i>I</i>)</code> leaves <code><i>A</i></code> the same, + because <code><i>I</i></code> is <code>INITVAL</code>.</li> +<li><code>fMMCombiner(&<i>I</i>, &<i>A</i>)</code> sets <code><i>I</i></code> + to <code><i>A</i></code>, because <code><i>I</i></code> is <code>INITVAL</code>.</li> +</ul> +Therefore, <code>INITVAL</code> is indeed an identity value. +</p></div> + +<p><strong>The combiner function must be <i>commutative</i>.</strong> That is, + if <code><i>A</i></code> and <code><i>B</i></code> are accumulator data items initialized + by the initializer function, and that may have been passed to the accumulator function zero + or more times, then <code><i>combinerName</i>(&<i>A</i>, &<i>B</i>)</code> must + set <code><i>A</i></code> to <a href="#the-same">the same value</a> + that <code><i>combinerName</i>(&<i>B</i>, &<i>A</i>)</code> + sets <code><i>B</i></code>.</p> +<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a> + kernel, the combiner function adds the two accumulator data item values; addition is + commutative.</p> +<div class="note"> +<p><strong>Example:</strong> In the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, +<pre> +fMMCombiner(&<i>A</i>, &<i>B</i>) +</pre> +is the same as +<pre> +<i>A</i> = minmax(<i>A</i>, <i>B</i>) +</pre> +and <code>minmax</code> is commutative, so <code>fMMCombiner</code> is also. +</p> +</div> + +<p><strong>The combiner function must be <i>associative</i>.</strong> That is, + if <code><i>A</i></code>, <code><i>B</i></code>, and <code><i>C</i></code> are + accumulator data items initialized by the initializer function, and that may have been passed + to the accumulator function zero or more times, then the following two code sequences must + set <code><i>A</i></code> to <a href="#the-same">the same value</a>:</p> +<ul> +<li><pre> +<i>combinerName</i>(&<i>A</i>, &<i>B</i>); +<i>combinerName</i>(&<i>A</i>, &<i>C</i>); +</pre></li> +<li><pre> +<i>combinerName</i>(&<i>B</i>, &<i>C</i>); +<i>combinerName</i>(&<i>A</i>, &<i>B</i>); +</pre></li> +</ul> +<div class="note"> +<p><strong>Example:</strong> In the <a href="#example-addint">addint</a> kernel, the + combiner function adds the two accumulator data item values: +<ul> +<li><pre> +<i>A</i> = <i>A</i> + <i>B</i> +<i>A</i> = <i>A</i> + <i>C</i> +// Same as +// <i>A</i> = (<i>A</i> + <i>B</i>) + <i>C</i> +</pre></li> +<li><pre> +<i>B</i> = <i>B</i> + <i>C</i> +<i>A</i> = <i>A</i> + <i>B</i> +// Same as +// <i>A</i> = <i>A</i> + (<i>B</i> + <i>C</i>) +// <i>B</i> = <i>B</i> + <i>C</i> +</li> +</ul> +Addition is associative, and so the combiner function is also. +</p> +</div> +<div class="note"> +<p><strong>Example:</strong> In the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, +<pre> +fMMCombiner(&<i>A</i>, &<i>B</i>) +</pre> +is the same as +<pre> +<i>A</i> = minmax(<i>A</i>, <i>B</i>) +</pre> +So the two sequences are +<ul> +<li><pre> +<i>A</i> = minmax(<i>A</i>, <i>B</i>) +<i>A</i> = minmax(<i>A</i>, <i>C</i>) +// Same as +// <i>A</i> = minmax(minmax(<i>A</i>, <i>B</i>), <i>C</i>) +</pre></li> +<li><pre> +<i>B</i> = minmax(<i>B</i>, <i>C</i>) +<i>A</i> = minmax(<i>A</i>, <i>B</i>) +// Same as +// <i>A</i> = minmax(<i>A</i>, minmax(<i>B</i>, <i>C</i>)) +// <i>B</i> = minmax(<i>B</i>, <i>C</i>) +</pre></li> +<code>minmax</code> is associative, and so <code>fMMCombiner</code> is also. +</p> +</div> + +<p><strong>The accumulator function and combiner function together must obey the <i>basic + folding rule</i>.</strong> That is, if <code><i>A</i></code> + and <code><i>B</i></code> are accumulator data items, <code><i>A</i></code> has been + initialized by the initializer function and may have been passed to the accumulator function + zero or more times, <code><i>B</i></code> has not been initialized, and <i>args</i> is + the list of input arguments and special arguments for a particular call to the accumulator + function, then the following two code sequences must set <code><i>A</i></code> + to <a href="#the-same">the same value</a>:</p> +<ul> +<li><pre> +<i>accumulatorName</i>(&<i>A</i>, <i>args</i>); // statement 1 +</pre></li> +<li><pre> +<i>initializerName</i>(&<i>B</i>); // statement 2 +<i>accumulatorName</i>(&<i>B</i>, <i>args</i>); // statement 3 +<i>combinerName</i>(&<i>A</i>, &<i>B</i>); // statement 4 +</pre></li> +</ul> +<div class="note"> +<p><strong>Example:</strong> In the <a href="#example-addint">addint</a> kernel, for an input value <i>V</i>: +<ul> +<li>Statement 1 is the same as <code>A += <i>V</i></code></li> +<li>Statement 2 is the same as <code>B = 0</code></li> +<li>Statement 3 is the same as <code>B += <i>V</i></code>, which is the same as <code>B = <i>V</i></code></li> +<li>Statement 4 is the same as <code>A += B</code>, which is the same as <code>A += <i>V</i></code></li> +</ul> +Statements 1 and 4 set <code><i>A</i></code> to the same value, and so this kernel obeys the +basic folding rule. +</p> +</div> +<div class="note"> +<p><strong>Example:</strong> In the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, for an input + value <i>V</i> at coordinate <i>X</i>: +<ul> +<li>Statement 1 is the same as <code>A = minmax(A, IndexedVal(<i>V</i>, <i>X</i>))</code></li> +<li>Statement 2 is the same as <code>B = <a href="#INITVAL">INITVAL</a></code></li> +<li>Statement 3 is the same as +<pre> +B = minmax(B, IndexedVal(<i>V</i>, <i>X</i>)) +</pre> +which, because <i>B</i> is the initial value, is the same as +<pre> +B = IndexedVal(<i>V</i>, <i>X</i>) +</pre> +</li> +<li>Statement 4 is the same as +<pre> +A = minmax(A, B) +</pre> +which is the same as +<pre> +A = minmax(A, IndexedVal(<i>V</i>, <i>X</i>)) +</pre> +</ul> +Statements 1 and 4 set <code><i>A</i></code> to the same value, and so this kernel obeys the +basic folding rule. +</p> +</div> + +<h3 id="calling-reduction-kernel">Calling a reduction kernel from Java code</h3> + +<p>For a reduction kernel named <i>kernelName</i> defined in the +file <code><i>filename</i>.rs</code>, there are three methods reflected in the +class <code>ScriptC_<i>filename</i></code>:</p> + +<pre> +// Method 1 +public <i>javaFutureType</i> reduce_<i>kernelName</i>(Allocation ain1, <i>…,</i> + Allocation ain<i>N</i>); + +// Method 2 +public <i>javaFutureType</i> reduce_<i>kernelName</i>(Allocation ain1, <i>…,</i> + Allocation ain<i>N</i>, + Script.LaunchOptions sc); + +// Method 3 +public <i>javaFutureType</i> reduce_<i>kernelName</i>(<i><a href="#devec">devecSiIn1Type</a></i>[] in1, …, + <i><a href="#devec">devecSiInNType</a></i>[] in<i>N</i>); +</pre> + +<p>Here are some examples of calling the <a href="#example-addint">addint</a> kernel:</p> +<pre> +ScriptC_example script = new ScriptC_example(mRenderScript); + +// 1D array +// and obtain answer immediately +int input1[] = <i>…</i>; +int sum1 = script.reduce_addint(input1).get(); // Method 3 + +// 2D allocation +// and do some additional work before obtaining answer +Type.Builder typeBuilder = + new Type.Builder(RS, Element.I32(RS)); +typeBuilder.setX(<i>…</i>); +typeBuilder.setY(<i>…</i>); +Allocation input2 = createTyped(RS, typeBuilder.create()); +<i>populateSomehow</i>(input2); // fill in input Allocation with data +script.result_int result2 = script.reduce_addint(input2); // Method 1 +<i>doSomeAdditionalWork</i>(); // might run at same time as reduction +int sum2 = result2.get(); +</pre> + +<p><strong>Method 1</strong> has one input {@link android.renderscript.Allocation} argument for + every input argument in the kernel's <a href="#accumulator-function">accumulator + function</a>. The RenderScript runtime checks to ensure that all of the input Allocations + have the same dimensions and that the {@link android.renderscript.Element} type of each of + the input Allocations matches that of the corresponding input argument of the accumulator + function's prototype. If any of these checks fail, RenderScript throws an exception. The + kernel executes over every coordinate in those dimensions.</p> + +<p><strong>Method 2</strong> is the same as Method 1 except that Method 2 takes an additional + argument <code>sc</code> that can be used to limit the kernel execution to a subset of the + coordinates.</p> + +<p><strong><a id="reduce-method-3">Method 3</a></strong> is the same as Method 1 except that + instead of taking Allocation inputs it takes Java array inputs. This is a convenience that + saves you from having to write code to explicitly create an Allocation and copy data to it + from a Java array. <em>However, using Method 3 instead of Method 1 does not increase the + performance of the code</em>. For each input array, Method 3 creates a temporary + 1-dimensional Allocation with the appropriate {@link android.renderscript.Element} type and + {@link android.renderscript.Allocation#setAutoPadding} enabled, and copies the array to the + Allocation as if by the appropriate <code>copyFrom()</code> method of {@link + android.renderscript.Allocation}. It then calls Method 1, passing those temporary + Allocations.</p> +<p class="note"><strong>NOTE:</strong> If your application will make multiple kernel calls with + the same array, or with different arrays of the same dimensions and Element type, you may improve + performance by explicitly creating, populating, and reusing Allocations yourself, instead of + by using Method 3.</p> +<p><strong><i><a id="javaFutureType">javaFutureType</a></i></strong>, + the return type of the reflected reduction methods, is a reflected + static nested class within the <code>ScriptC_<i>filename</i></code> + class. It represents the future result of a reduction + kernel run. To obtain the actual result of the run, call + the <code>get()</code> method of that class, which returns a value + of type <i>javaResultType</i>. <code>get()</code> is <a href="#asynchronous-model">synchronous</a>.</p> + +<pre> +public class ScriptC_<i>filename</i> extends ScriptC { + public static class <i>javaFutureType</i> { + public <i>javaResultType</i> get() { … } + } +} +</pre> + +<p><strong><i>javaResultType</i></strong> is determined from the <i>resultType</i> of the + <a href="#outconverter-function">outconverter function</a>. Unless <i>resultType</i> is an + unsigned type (scalar, vector, or array), <i>javaResultType</i> is the directly corresponding + Java type. If <i>resultType</i> is an unsigned type and there is a larger Java signed type, + then <i>javaResultType</i> is that larger Java signed type; otherwise, it is the directly + corresponding Java type. For example:</p> +<ul> +<li>If <i>resultType</i> is <code>int</code>, <code>int2</code>, or <code>int[15]</code>, + then <i>javaResultType</i> is <code>int</code>, <code>Int2</code>, + or <code>int[]</code>. All values of <i>resultType</i> can be represented + by <i>javaResultType</i>.</li> +<li>If <i>resultType</i> is <code>uint</code>, <code>uint2</code>, or <code>uint[15]</code>, + then <i>javaResultType</i> is <code>long</code>, <code>Long2</code>, + or <code>long[]</code>. All values of <i>resultType</i> can be represented + by <i>javaResultType</i>.</li> +<li>If <i>resultType</i> is <code>ulong</code>, <code>ulong2</code>, + or <code>ulong[15]</code>, then <i>javaResultType</i> + is <code>long</code>, <code>Long2</code>, or <code>long[]</code>. There are certain values + of <i>resultType</i> that cannot be represented by <i>javaResultType</i>.</li> +</ul> + +<p><strong><i>javaFutureType</i></strong> is the future result type corresponding + to the <i>resultType</i> of the <a href="#outconverter-function">outconverter + function</a>.</p> +<ul> +<li>If <i>resultType</i> is not an array type, then <i>javaFutureType</i> + is <code>result_<i>resultType</i></code>.</li> +<li>If <i>resultType</i> is an array of length <i>Count</i> with members of type <i>memberType</i>, + then <i>javaFutureType</i> is <code>resultArray<i>Count</i>_<i>memberType</i></code>.</li> +</ul> + +<p>For example:</p> + +<pre> +public class ScriptC_<i>filename</i> extends ScriptC { + // for kernels with int result + public static class result_int { + public int get() { … } + } + + // for kernels with int[10] result + public static class resultArray10_int { + public int[] get() { … } + } + + // for kernels with int2 result + // note that the Java type name "Int2" is not the same as the script type name "int2" + public static class result_int2 { + public Int2 get() { … } + } + + // for kernels with int2[10] result + // note that the Java type name "Int2" is not the same as the script type name "int2" + public static class resultArray10_int2 { + public Int2[] get() { … } + } + + // for kernels with uint result + // note that the Java type "long" is a wider signed type than the unsigned script type "uint" + public static class result_uint { + public long get() { … } + } + + // for kernels with uint[10] result + // note that the Java type "long" is a wider signed type than the unsigned script type "uint" + public static class resultArray10_uint { + public long[] get() { … } + } + + // for kernels with uint2 result + // note that the Java type "Long2" is a wider signed type than the unsigned script type "uint2" + public static class result_uint2 { + public Long2 get() { … } + } + + // for kernels with uint2[10] result + // note that the Java type "Long2" is a wider signed type than the unsigned script type "uint2" + public static class resultArray10_uint2 { + public Long2[] get() { … } + } +} +</pre> + +<p>If <i>javaResultType</i> is an object type (including an array type), each call + to <code><i>javaFutureType</i>.get()</code> on the same instance will return the same + object.</p> + +<p>If <i>javaResultType</i> cannot represent all values of type <i>resultType</i>, and a + reduction kernel produces an unrepresentible value, + then <code><i>javaFutureType</i>.get()</code> throws an exception.</p> + +<h4 id="devec">Method 3 and <i>devecSiInXType</i></h4> + +<p><strong><i>devecSiInXType</i></strong> is the Java type corresponding to + the <i>inXType</i> of the corresponding argument of + the <a href="#accumulator-function">accumulator function</a>. Unless <i>inXType</i> is an + unsigned type or a vector type, <i>devecSiInXType</i> is the directly corresponding Java + type. If <i>inXType</i> is an unsigned scalar type, then <i>devecSiInXType</i> is the + Java type directly corresponding to the signed scalar type of the same + size. If <i>inXType</i> is a signed vector type, then <i>devecSiInXType</i> is the Java + type directly corresponding to the vector component type. If <i>inXType</i> is an unsigned + vector type, then <i>devecSiInXType</i> is the Java type directly corresponding to the + signed scalar type of the same size as the vector component type. For example:</p> +<ul> +<li>If <i>inXType</i> is <code>int</code>, then <i>devecSiInXType</i> + is <code>int</code>.</li> +<li>If <i>inXType</i> is <code>int2</code>, then <i>devecSiInXType</i> + is <code>int</code>. The array is a <em>flattened</em> representation: It has twice as + many <em>scalar</em> Elements as the Allocation has 2-component <em>vector</em> + Elements. This is the same way that the <code>copyFrom()</code> methods of {@link + android.renderscript.Allocation} work.</li> +<li>If <i>inXType</i> is <code>uint</code>, then <i>deviceSiInXType</i> + is <code>int</code>. A signed value in the Java array is interpreted as an unsigned value of + the same bitpattern in the Allocation. This is the same way that the <code>copyFrom()</code> + methods of {@link android.renderscript.Allocation} work.</li> +<li>If <i>inXType</i> is <code>uint2</code>, then <i>deviceSiInXType</i> + is <code>int</code>. This is a combination of the way <code>int2</code> and <code>uint</code> + are handled: The array is a flattened representation, and Java array signed values are + interpreted as RenderScript unsigned Element values.</li> +</ul> + +<p>Note that for <a href="#reduce-method-3">Method 3</a>, input types are handled differently +than result types:</p> + +<ul> +<li>A script's vector input is flattened on the Java side, whereas a script's vector result is not.</li> +<li>A script's unsigned input is represented as a signed input of the same size on the Java + side, whereas a script's unsigned result is represented as a widened signed type on the Java + side (except in the case of <code>ulong</code>).</li> +</ul> + +<h3 id="more-example">More example reduction kernels</h3> + +<pre id="dot-product"> +#pragma rs reduce(dotProduct) \ + accumulator(dotProductAccum) combiner(dotProductSum) + +// Note: No initializer function -- therefore, +// each accumulator data item is implicitly initialized to 0.0f. + +static void dotProductAccum(float *accum, float in1, float in2) { + *accum += in1*in2; +} + +// combiner function +static void dotProductSum(float *accum, const float *val) { + *accum += *val; +} +</pre> + +<pre> +// Find a zero Element in a 2D allocation; return (-1, -1) if none +#pragma rs reduce(fz2) \ + initializer(fz2Init) \ + accumulator(fz2Accum) combiner(fz2Combine) + +static void fz2Init(int2 *accum) { accum->x = accum->y = -1; } + +static void fz2Accum(int2 *accum, + int inVal, + int x /* special arg */, + int y /* special arg */) { + if (inVal==0) { + accum->x = x; + accum->y = y; + } +} + +static void fz2Combine(int2 *accum, const int2 *accum2) { + if (accum2->x >= 0) *accum = *accum2; +} +</pre> + +<pre> +// Note that this kernel returns an array to Java +#pragma rs reduce(histogram) \ + accumulator(hsgAccum) combiner(hsgCombine) + +#define BUCKETS 256 +typedef uint32_t Histogram[BUCKETS]; + +// Note: No initializer function -- +// therefore, each bucket is implicitly initialized to 0. + +static void hsgAccum(Histogram *h, uchar in) { ++(*h)[in]; } + +static void hsgCombine(Histogram *accum, + const Histogram *addend) { + for (int i = 0; i < BUCKETS; ++i) + (*accum)[i] += (*addend)[i]; +} + +// Determines the mode (most frequently occurring value), and returns +// the value and the frequency. +// +// If multiple values have the same highest frequency, returns the lowest +// of those values. +// +// Shares functions with the histogram reduction kernel. +#pragma rs reduce(mode) \ + accumulator(hsgAccum) combiner(hsgCombine) \ + outconverter(modeOutConvert) + +static void modeOutConvert(int2 *result, const Histogram *h) { + uint32_t mode = 0; + for (int i = 1; i < BUCKETS; ++i) + if ((*h)[i] > (*h)[mode]) mode = i; + result->x = mode; + result->y = (*h)[mode]; +} +</pre> diff --git a/docs/html/topic/libraries/support-library/features.jd b/docs/html/topic/libraries/support-library/features.jd index 0f63bf669687..614392e00d44 100755 --- a/docs/html/topic/libraries/support-library/features.jd +++ b/docs/html/topic/libraries/support-library/features.jd @@ -7,7 +7,15 @@ page.title=Support Library Features <h2>In this document</h2> <ol> - <li><a href="#v4">v4 Support Library</a></li> + <li><a href="#v4">v4 Support Libraries</a> + <ol> + <li><a href="#v4-compat">v4 compat library</a></li> + <li><a href="#v4-core-utils">v4 core-utils library</a></li> + <li><a href="#v4-core-ui">v4 core-ui library</a></li> + <li><a href="#v4-media-compat">v4 media-compat library</a></li> + <li><a href="#v4-fragment">v4 fragment library</a></li> + </ol> + </li> <li><a href="#multidex">Multidex Support Library</a></li> <li><a href="#v7">v7 Support Libraries</a> <ol> @@ -63,94 +71,115 @@ page.title=Support Library Features include the library in your application.</p> -<h2 id="v4">v4 Support Library</h2> - -<p>This library is designed to be used with Android 1.6 (API level 4) and higher. It includes the - largest set of APIs compared to the other libraries, including support for application components, - user interface features, accessibility, data handling, network connectivity, and programming - utilities. Here are a few of the key classes included in the v4 library:</p> +<h2 id="v4">v4 Support Libraries</h2> -<ul> - <li>App Components - <ul> - <li>{@link android.support.v4.app.Fragment} - - Adds support for encapsulation of user interface and functionality - with Fragments, enabling - applications to provide layouts that adjust between small and - large-screen devices. - </li> - - <li>{@link android.support.v4.app.NotificationCompat} - Adds support for rich notification - features.</li> - <li>{@link android.support.v4.content.LocalBroadcastManager} - Allows applications to easily - register for and receive intents within a single application without broadcasting them - globally.</li> - </ul> - </li> - <li>User Interface - <ul> - <li>{@link android.support.v4.view.ViewPager} - Adds a - {@link android.view.ViewGroup} that manages the layout for the - child views, which the user can swipe between.</li> - <li>{@link android.support.v4.view.PagerTitleStrip} - - Adds a non-interactive title strip, that can be added as a child of - {@link android.support.v4.view.ViewPager}.</li> - <li>{@link android.support.v4.view.PagerTabStrip} - Adds a - navigation widget for switching between paged views, that can also be used with - {@link android.support.v4.view.ViewPager}.</li> - <li>{@link android.support.v4.widget.DrawerLayout} - Adds - support for creating a <a href="{@docRoot}training/implementing-navigation/nav-drawer.html" - >Navigation Drawer</a> that can be pulled in from the edge of a window.</li> - <li>{@link android.support.v4.widget.SlidingPaneLayout} - - Adds widget for creating linked summary and detail views that - appropriately adapt to various screen sizes.</li> - </ul> - </li> - <li>Accessibility - <ul> - <li>{@link android.support.v4.widget.ExploreByTouchHelper} - - Adds a helper class for implementing accessibility support for custom views.</li> - <li>{@link android.support.v4.view.accessibility.AccessibilityEventCompat} - Adds support for - {@link android.view.accessibility.AccessibilityEvent}. For more information about implementing - accessibility, see <a href="{@docRoot}guide/topics/ui/accessibility/index.html" - >Accessibility</a>.</li> - - <li>{@link android.support.v4.view.accessibility.AccessibilityNodeInfoCompat} - Adds support - for {@link android.view.accessibility.AccessibilityNodeInfo}.</li> - <li>{@link android.support.v4.view.accessibility.AccessibilityNodeProviderCompat} - Adds - support for {@link android.view.accessibility.AccessibilityNodeProvider}.</li> - <li>{@link android.support.v4.view.AccessibilityDelegateCompat} - Adds support for - {@link android.view.View.AccessibilityDelegate}.</li> - </ul> - </li> - <li>Content - <ul> - <li>{@link android.support.v4.content.Loader} - Adds support for asynchronous loading of data. - The library also provides concrete implementations of this class, including - {@link android.support.v4.content.CursorLoader} and - {@link android.support.v4.content.AsyncTaskLoader}.</li> - <li>{@link android.support.v4.content.FileProvider} - Adds support for sharing of private - files between applications.</li> - </ul> - </li> -</ul> +<p> + These libraries are designed to be used with Android 2.3 (API level 9) and + higher. They include the largest set of APIs compared to the other libraries, + including support for application components, user interface features, + accessibility, data handling, network connectivity, and programming + utilities. +</p> <p> - There are many other APIs included in this library. For complete, detailed information about the - v4 Support Library APIs, see the {@link android.support.v4.app android.support.v4} package in the - API reference. + For complete, detailed information about the classes and methods provided by + the v4 support libraries, see the {@link android.support.v4.app + android.support.v4} package in the API reference. +</p> + + +<p class="note"> + <strong>Note:</strong> Prior to Support Library revision 24.2.0, there was a + single v4 support library. That library was divided into multiple modules to + improve efficiency. For backwards compatibility, if you list + <code>support-v4</code> in your Gradle script, your APK will include all of + the v4 modules. However, to reduce APK size, we recommend that you just list + the specific modules your app needs. </p> -<p class="caution"><strong>Caution:</strong> Using dynamic dependencies, especially for higher version -numbers, can cause unexpected version updates and regression incompatibilities.</p> +<h3 id="v4-compat">v4 compat library</h3> + +<p> + Provides compatibility wrappers for a number of framework APIs, such as + <code>Context.obtainDrawable()</code> and + <code>View.performAccessibilityAction()</code>. +</p> <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:support-v4:24.1.1 +com.android.support:support-compat:24.2.0 </pre> +<h3 id="v4-core-utils">v4 core-utils library</h3> + +<p> + Provides a number of utility classes, such as {@link + android.support.v4.content.AsyncTaskLoader} and {@link + android.support.v4.content.PermissionChecker}. +</p> +<p> + The Gradle build script dependency identifier for this library is as follows: +</p> + +<pre> +com.android.support:support-core-utils:24.2.0 +</pre> + +<h3 id="v4-core-ui">v4 core-ui library</h3> + +<p> + Implements a variety of UI-related components, such as {@link + android.support.v4.view.ViewPager}, {@link + android.support.v4.widget.NestedScrollView}, and {@link + android.support.v4.widget.ExploreByTouchHelper}. +</p> + +<p> + The Gradle build script dependency identifier for this library is as follows: +</p> + +<pre> +com.android.support:support-core-ui:24.2.0 +</pre> + +<h3 id="v4-media-compat">v4 media-compat library</h3> + +<p> + Backports portions of the <a href= + "/reference/android/media/package-summary.html">media</a> framework, + including {@link android.media.browse.MediaBrowser} and {@link + android.media.session.MediaSession}. +</p> + +<p> + The Gradle build script dependency identifier for this library is as follows: +</p> + +<pre> +com.android.support:support-media-compat:24.2.0 +</pre> + +<h3 id="v4-fragment">v4 fragment library</h3> + +<p> + Adds support for encapsulation of user interface and functionality with + <a href= + "/guide/components/fragments.html">fragments</a>, + enabling applications to provide layouts that adjust between small and + large-screen devices. This module has dependencies on <a href= + "#v4-compat">compat</a>, <a href="#v4-core-utils">core-utils</a>, <a href= + "#v4-core-ui">core-ui</a>, and <a href="#v4-media-compat">media-compat</a>. +</p> + +<p> + The Gradle build script dependency identifier for this library is as follows: +</p> + +<pre> +com.android.support:support-fragment:24.2.0 +</pre> <h2 id="multidex">Multidex Support Library</h2> @@ -173,7 +202,7 @@ com.android.support:multidex:1.0.0 <h2 id="v7">v7 Support Libraries</h2> -<p>There are several libraries designed to be used with Android 2.1 (API level 7) and higher. +<p>There are several libraries designed to be used with Android 2.3 (API level 9) and higher. These libraries provide specific feature sets and can be included in your application independently from each other.</p> @@ -216,7 +245,7 @@ com.android.support:multidex:1.0.0 <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:appcompat-v7:24.1.1 +com.android.support:appcompat-v7:24.2.0 </pre> @@ -231,7 +260,7 @@ implementations, and are used extensively in layouts for TV apps.</p> <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:cardview-v7:24.1.1 +com.android.support:cardview-v7:24.2.0 </pre> @@ -247,7 +276,7 @@ For detailed information about the v7 gridlayout library APIs, see the <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:gridlayout-v7:24.1.1 +com.android.support:gridlayout-v7:24.2.0 </pre> @@ -270,7 +299,7 @@ reference.</p> <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:mediarouter-v7:24.1.1 +com.android.support:mediarouter-v7:24.2.0 </pre> <p class="caution">The v7 mediarouter library APIs introduced in Support Library @@ -290,7 +319,7 @@ title card.</p> <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:palette-v7:24.1.1 +com.android.support:palette-v7:24.2.0 </pre> @@ -306,7 +335,7 @@ limited window of data items.</p> <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:recyclerview-v7:24.1.1 +com.android.support:recyclerview-v7:24.2.0 </pre> @@ -329,18 +358,18 @@ such as {@link android.support.v7.preference.CheckBoxPreference} and <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:preference-v7:24.1.1 +com.android.support:preference-v7:24.2.0 </pre> <h2 id="v8">v8 Support Library</h2> -<p>This library is designed to be used with Android 2.2 (API level 8) and higher. +<p>This library is designed to be used with Android 2.3 (API level 9) and higher. This library provides specific feature sets and can be included in your application independently from other libraries.</p> <h3 id="v8-renderscript">v8 renderscript library</h3> -<p>This library is designed to be used with Android (API level 8) and higher. It adds support for +<p>This library is designed to be used with Android 2.3 (API level 9) and higher. It adds support for the <a href="{@docRoot}guide/topics/renderscript/compute.html">RenderScript</a> computation framework. These APIs are included in the {@link android.support.v8.renderscript} package. You should be aware that the steps for including these APIs in your application is <em>very @@ -380,7 +409,7 @@ defaultConfig { <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:support-v13:24.1.1 +com.android.support:support-v13:24.2.0 </pre> @@ -406,7 +435,7 @@ for preference interfaces such as <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:preference-v14:24.1.1 +com.android.support:preference-v14:24.2.0 </pre> @@ -429,7 +458,7 @@ interface and classes, such as <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:preference-leanback-v17:24.1.1 +com.android.support:preference-leanback-v17:24.2.0 </pre> @@ -465,7 +494,7 @@ com.android.support:preference-leanback-v17:24.1.1 <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:leanback-v17:24.1.1 +com.android.support:leanback-v17:24.2.0 </pre> @@ -480,7 +509,7 @@ package provides APIs to support adding annotation metadata to your apps. </p> <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:support-annotations:24.1.1 +com.android.support:support-annotations:24.2.0 </pre> @@ -498,7 +527,7 @@ snackbars, and <a href="{@docRoot}design/building-blocks/tabs.html">tabs</a>. < <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:design:24.1.1 +com.android.support:design:24.2.0 </pre> @@ -519,7 +548,7 @@ Callback</a>. </p> <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:customtabs:24.1.1 +com.android.support:customtabs:24.2.0 </pre> @@ -543,7 +572,7 @@ PercentRelativeLayout</a>. </p> <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:percent:24.1.1 +com.android.support:percent:24.2.0 </pre> @@ -566,5 +595,5 @@ RecommendationExtender</a>. </p> <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:recommendation:24.1.1 +com.android.support:recommendation:24.2.0 </pre> diff --git a/docs/html/topic/libraries/support-library/revisions.jd b/docs/html/topic/libraries/support-library/revisions.jd index 3b25fb020767..4e14c7054bbd 100644 --- a/docs/html/topic/libraries/support-library/revisions.jd +++ b/docs/html/topic/libraries/support-library/revisions.jd @@ -6,9 +6,324 @@ page.metaDescription=This page provides details about the Support Library packag <p>This page provides details about the Support Library package releases.</p> <div class="toggle-content opened"> - <p id="rev24-1-1"> + <p id="rev24-2-0"> <a href="#" onclick="return toggleContent(this)"><img src= "{@docRoot}assets/images/styles/disclosure_up.png" class= + "toggle-content-img" alt="">Android Support Library, revision 24.2.0</a> + <em>(August 2016)</em> + </p> + + <div class="toggle-content-toggleme"> + +<p>Release 24.2.0 contains the following changes:</p> + +<ul> + <li><a href="#24-2-0-v4-refactor">v4 Support Library split</a></li> + <li><a href="#24-2-0-api-updates">API updates</a></li> + <li><a href="#24-2-0-behavior">Behavior changes</a></li> + <li><a href="#24-2-0-deprecations">Deprecations</a></li> + <li><a href="#24-2-0-bugfixes">Bug fixes</a></li> +</ul> + +<p class="note"><strong>Note:</strong> Release 24.2.0 removes support for + Android 2.2 (API level 8) and lower. Classes and methods that exist only to + serve those system versions are now marked as deprecated and should no longer + be used. These deprecated classes and methods may be removed in a future + release. +</p> + +<h3 id="24-2-0-v4-refactor">v4 Support Library split</h3> + +<p>With this release, the <a href="features.html#v4">v4 Support Library</a> has + been split into several smaller modules:</p> + +<dl> + <dt> + <code>support-compat</code> + </dt> + + <dd> + Provides compatibility wrappers for new framework APIs, such as + <code>Context.getDrawable()</code> and + <code>View.performAccessibilityAction()</code>. + </dd> + + <dt> + <code>support-core-utils</code> + </dt> + + <dd> + Provides a number of utility classes, such as {@link + android.support.v4.content.AsyncTaskLoader} and {@link + android.support.v4.content.PermissionChecker}. + </dd> + + <dt> + <code>support-core-ui</code> + </dt> + + <dd> + Implements a variety of UI-related components, such as {@link + android.support.v4.view.ViewPager}, {@link + android.support.v4.widget.NestedScrollView}, and {@link + android.support.v4.widget.ExploreByTouchHelper}. + </dd> + + <dt> + <code>support-media-compat</code> + </dt> + + <dd> + Backports portions of the <a href= + "/reference/android/media/package-summary.html">media</a> framework, + including {@link android.media.browse.MediaBrowser} and {@link + android.media.session.MediaSession}. + </dd> + + <dt> + <code>support-fragment</code> + </dt> + + <dd> + Backports the <a href= + "/guide/components/fragments.html">fragment</a> + framework. This module has dependencies on <code>support-compat</code>, + <code>support-core-utils</code>, <code>support-core-ui</code>, and + <code>support-media-compat</code>. + </dd> +</dl> + +<p>For backwards compatibility, if you list <code>support-v4</code> in your +Gradle script, your APK will include all of these modules. However, to reduce +APK size, we recommend that you just list the specific modules your app needs. +</p> + +<h3 id="24-2-0-api-updates">API updates</h3> + +<ul> + <li>Clients using <a href="features.html#custom-tabs">Custom Tabs</a> can + control whether Instant Apps should open. (Note that Instant Apps are not yet + generally available.) To enable or disable Instant Apps, call <a href= + "/reference/android/support/customtabs/CustomTabsIntent.Builder.html#setInstantAppsEnabled(boolean)"> + <code>CustomTabsIntent.Builder.setInstantAppsEnabled()</code></a> or + specify <a href= + "/reference/android/support/customtabs/CustomTabsIntent.html#EXTRA_ENABLE_INSTANT_APPS"> + <code>EXTRA_ENABLE_INSTANT_APPS</code></a>. By default, Custom Tabs will + default to enabling Instant Apps, when that feature becomes available. + </li> + + <li>{@link android.support.design.widget.TextInputLayout} adds support for + the <a href= + "https://material.google.com/components/text-fields.html#text-fields-password-input"> + password visibility toggle</a> from the material design specification. + </li> + + <li>The new <a href= + "/reference/android/support/transition/package-summary.html" + ><code>android.support.transition</code></a> + package backports the <a href= + "/training/transitions/index.html">Transitions</a> framework to API levels 14 + and higher. For more information, see the <a href= + "/reference/android/support/transition/package-summary.html" + ><code>android.support.transition</code></a> reference. + </li> + + <li>The <a href="features.html#custom-tabs">Custom Tabs support library</a> + adds support for using {@link android.widget.RemoteViews} in the secondary + toolbar. The existing {@link + android.support.customtabs.CustomTabsSession#setToolbarItem setToolbarItem()} + method is now deprecated. + </li> + + <li>{@link android.support.v7.content.res.AppCompatResources} adds the + ability to load a <code><vector></code> (on API level 9 and higher) or + <code><animated-vector></code> (on API level 11 and higher) from a + resource ID, by using the new <a href= + "/reference/android/support/v7/content/res/AppCompatResources.html#getDrawable(android.content.Context,%20int)" + ><code>getDrawable()</code></a> method. + </li> + + <li>{@link android.support.design.widget.CoordinatorLayout} now supports + defining inset views, and specifying that other views should dodge the inset + views. This allows apps to replicate behavior patterns similar to the way + {@link android.support.design.widget.FloatingActionButton} moves out of the + way of a {@link android.support.design.widget.Snackbar}, but for any + arbitrary view children. For more information, see the <a href= + "/reference/android/support/design/widget/CoordinatorLayout.LayoutParams.html#insetEdge"> + <code>LayoutParams.insetEdge</code></a> and <a href= + "/reference/android/support/design/widget/CoordinatorLayout.LayoutParams.html#dodgeInsetEdges"> + <code>LayoutParams.dodgeInsetEdges</code></a> reference documentation. + </li> + + <li>The new <a href="/reference/android/support/v7/util/DiffUtil.html"><code> + DiffUtil</code></a> class can calculate the difference between two + collections, and can dispatch a list of update operations that are suitable + to be consumed by a {@link android.support.v7.widget.RecyclerView.Adapter}. + </li> + + <li> + <a href= + "/reference/android/support/v7/widget/RecyclerView.OnFlingListener.html"><code> + RecyclerView.OnFlingListener</code></a> has been added to support custom + behavior in response to flings. The <a href= + "/reference/android/support/v7/widget/SnapHelper.html"><code>SnapHelper</code></a> + class provides an implementation specifically for snapping child views, and + the <a href= + "/reference/android/support/v7/widget/LinearSnapHelper.html"><code>LinearSnapHelper</code></a> + class extends this implementation to provide center-aligned snapping + behavior similar to {@link android.support.v4.view.ViewPager}. + </li> + +</ul> + +<h3 id="24-2-0-behavior">Behavior changes</h3> + +<ul> + <li>If you use the appcompat library's day/night functionality, the system + now automatically recreates your activity whenever the day/night mode changes + (either because of the time of day, or because of a call to {@link + android.support.v7.app.AppCompatDelegate#setLocalNightMode + AppCompatDelegate.setLocalNightMode()}). + </li> + + <li>{@link android.support.design.widget.Snackbar} now draws behind the + navigation bar if the status bar is translucent. + </li> +</ul> + +<h3 id="24-2-0-deprecations">Deprecations</h3> + +<p>Deprecated classes and methods are subject to removal in a future release. You should migrate away from these APIs as soon as possible.</p> + +<ul> + <li>Several methods on the following classes were only required for API 8 and + lower, and should no longer be used. Instead, use the framework + implementations. + <ul> + <li>{@link android.support.v4.view.KeyEventCompat}: Replace with {@link + android.view.KeyEvent} + </li> + + <li>{@link android.support.v4.view.MotionEventCompat}: Use {@link + android.view.MotionEvent} + </li> + + <li>{@link android.support.v4.view.ViewCompat}: Use {@link + android.view.View} + </li> + + <li>{@link android.support.v4.view.ViewConfigurationCompat}: Use {@link + android.view.ViewConfiguration} + </li> + </ul> + </li> + + <li> + {@link android.support.v4.accessibilityservice.AccessibilityServiceInfoCompat#getDescription + AccessibilityServiceInfoCompat.getDescription()} + has been deprecated in favor of + <a href="/reference/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.html#loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager)"><code>loadDescription()</code></a> + which returns a correctly localized description. + </li> + + <li>You should not instantiate the <code>ActivityCompat</code> class + directly. The non-static <code>getReferrer(Activity)</code> method will be + made static in an upcoming release. + </li> + + <li>{@link android.support.design.widget.CoordinatorLayout.Behavior#isDirty + CoordinatorLayout.Behavior.isDirty()} has been deprecated and is no longer + called by {@link android.support.design.widget.CoordinatorLayout}. Any + implementations, as well as any calls to this method, should be removed. + </li> + + <li>{@link android.support.v4.media.session.MediaSessionCompat#obtain + MediaSessionCompat.obtain()} has been deprecated and replaced with the more + appropriately-named method + <a href="/reference/android/support/v4/media/session/MediaSessionCompat.html#fromMediaSession"><code>fromMediaSession()</code></a>. + </li> + + <li>{@link + android.support.v4.media.session.MediaSessionCompat.QueueItem#obtain + MediaSessionCompat.QueueItem.obtain()} has been deprecated and replaced with + the more appropriately-named method + <a href="/reference/android/support/v4/media/session/MediaSessionCompat.QueueItem.html#fromQueueItem"><code>fromQueueItem()</code></a>. + </li> + + <li>Several abstract classes have been deprecated and replaced with + interfaces that more closely reflect their framework equivalents. + <ul> + <li>{@link + android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat} + has been replaced by the <a href= + "/reference/android/support/v4/view/accessibility/AccessibilityManagerCompat.AccessibilityStateChangeListener.html"> + <code>AccessibilityManagerCompat.AccessibilityStateChangeListener</code></a> + interface. + </li> + + <li>{@link + android.support.v4.widget.SearchViewCompat.OnCloseListenerCompat} has + been replaced by the <a + href="/reference/android/support/v4/widget/SearchViewCompat.OnCloseListener.html" + ><code>SearchViewCompat.OnCloseListener</code></a> interface. + </li> + + <li>{@link + android.support.v4.widget.SearchViewCompat.OnQueryTextListenerCompat } + has been replaced by the <a + href="/reference/android/support/v4/widget/SearchViewCompat.OnQueryTextListener.html" + ><code>SearchViewCompat.OnQueryTextListener</code></a> + interface. + </li> + </ul> + </li> + + <li>{@link android.support.customtabs.CustomTabsSession#setToolbarItem + CustomTabsSession.setToolbarItem()} has been deprecated and replaced by the + RemoteViews-based <a href= + "/reference/android/support/customtabs/CustomTabsSession.html#setSecondaryToolbarViews"> + <code>setSecondaryToolbarViews()</code></a>. + </li> +</ul> + +<h3 id="24-2-0-bugfixes">Bug fixes</h3> + +<p>The following known issues have been fixed with release 24.2.0:</p> + +<ul> + <li>Ensure <code>SwipeRefreshLayout</code> indicator is shown when + <code>setRefreshing(true)</code> is called before the first measurement pass + (<a href="https://code.google.com/p/android/issues/detail?id=77712">AOSP + issue 77712</a>) + </li> + + <li>Prevent <code>TabLayout</code> from flickering when changing pages + (<a href="https://code.google.com/p/android/issues/detail?id=180454">AOSP + issue 180454</a>) + </li> + + <li>Avoid <code>ClassNotFoundException</code> when unmarshalling + <code>SavedState</code> on API level 11 and lower (<a href= + "https://code.google.com/p/android/issues/detail?id=196430">AOSP issue + 196430</a>) + </li> +</ul> + +<p> + A complete list of public bug fixes is available on the <a href= + "https://code.google.com/p/android/issues/list?can=1&q=Component%3DSupport-Libraries+Target%3DSupport-24.2.0"> + AOSP Issue Tracker</a>. +</p> + + </div> +</div> + +<!-- end of collapsible section: 24.2.0 --> + +<div class="toggle-content closed"> + <p id="rev24-1-1"> + <a href="#" onclick="return toggleContent(this)"><img src= + "{@docRoot}assets/images/styles/disclosure_down.png" class= "toggle-content-img" alt="">Android Support Library, revision 24.1.1</a> <em>(July 2016)</em> </p> @@ -76,7 +391,7 @@ page.metaDescription=This page provides details about the Support Library packag <ul> <li>TabLayout.setCustomView(null) results in NullPointerException (<a href="https://code.google.com/p/android/issues/detail?id=214753">AOSP - issue</a>) + issue 214753</a>) </li> <li>TabLayout incorrectly highlights custom tabs (<a href= diff --git a/docs/html/topic/libraries/support-library/setup.jd b/docs/html/topic/libraries/support-library/setup.jd index 0cb9389ff508..adb263cbcd9a 100755 --- a/docs/html/topic/libraries/support-library/setup.jd +++ b/docs/html/topic/libraries/support-library/setup.jd @@ -85,17 +85,24 @@ Android Support Repository selected.</p> <li>Make sure you have downloaded the <strong>Android Support Repository</strong> using the <a href="#download">SDK Manager</a>.</li> <li>Open the {@code build.gradle} file for your application.</li> - <li>Add the support library to the {@code dependencies} section. For example, to add the v4 - support library, add the following lines: + <li>Add the support library to the {@code dependencies} section. For + example, to add the v4 core-utils library, add the following lines: <pre> dependencies { ... - <b>compile "com.android.support:support-v4:24.1.1"</b> + <b>compile "com.android.support:support-core-utils:24.2.0"</b> } </pre> </li> </ol> +<p class="caution"> + <strong>Caution:</strong> Using dynamic dependencies (for example, + <code>palette-v7:23.0.+</code>) can cause unexpected version updates and + regression incompatibilities. We recommend that you explicitly specify a + library version (for example, <code>palette-v7:24.2.0</code>). +</p> + <h2 id="using-apis">Using Support Library APIs</h2> <p>Support Library classes that provide support for existing framework APIs typically have the @@ -141,12 +148,12 @@ dependencies { <pre> <uses-sdk - android:minSdkVersion="<b>7</b>" - android:targetSdkVersion="17" /> + android:minSdkVersion="<b>14</b>" + android:targetSdkVersion="23" /> </pre> <p>The manifest setting tells Google Play that your application can be installed on devices with Android - 2.1 (API level 7) and higher. </p> + 4.0 (API level 14) and higher. </p> <p>If you are using Gradle build files, the <code>minSdkVersion</code> setting in the build file overrides the manifest settings. </p> @@ -158,7 +165,7 @@ android { ... defaultConfig { - minSdkVersion 8 + minSdkVersion 16 ... } ... @@ -166,13 +173,15 @@ android { </pre> <p>In this case, the build file setting tells Google Play that the default build variant of your - application can be installed on devices with Android 2.2 (API level 8) and higher. For more + application can be installed on devices with Android 4.1 (API level 16) and higher. For more information about build variants, see <a href="{@docRoot}studio/build/index.html">Build System Overview</a>. </p> <p class="note"> - <strong>Note:</strong> If you are including the v4 support and v7 appcompat libraries in your - application, you should specify a minimum SDK version of <code>"7"</code> (and not - <code>"4"</code>). The highest support library level you include in your application determines - the lowest API version in which it can operate. + <strong>Note:</strong> If you are including several support libraries, the + minimum SDK version must be the <em>highest</em> version required by any of + the specified libraries. For example, if your app includes both the <a href= + "features.html#v14-preference">v14 Preference Support library</a> and the + <a href="features.html#v17-leanback">v17 Leanback library</a>, your minimum + SDK version must be 17 or higher. </p> diff --git a/docs/html/training/implementing-navigation/nav-drawer.jd b/docs/html/training/implementing-navigation/nav-drawer.jd index d359a47e6413..abc79b649926 100644 --- a/docs/html/training/implementing-navigation/nav-drawer.jd +++ b/docs/html/training/implementing-navigation/nav-drawer.jd @@ -173,7 +173,7 @@ android.app.Fragment} into the main content view (the <pre> private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { selectItem(position); } } diff --git a/docs/html/training/notify-user/navigation.jd b/docs/html/training/notify-user/navigation.jd index 65f8d48ba375..d0ec1cddc35c 100644 --- a/docs/html/training/notify-user/navigation.jd +++ b/docs/html/training/notify-user/navigation.jd @@ -205,7 +205,7 @@ Intent notifyIntent = notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // Creates the PendingIntent -PendingIntent notifyIntent = +PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, @@ -214,7 +214,7 @@ PendingIntent notifyIntent = ); // Puts the PendingIntent into the notification builder -builder.setContentIntent(notifyIntent); +builder.setContentIntent(pendingIntent); // Notifications are issued by sending them to the // NotificationManager system service. NotificationManager mNotificationManager = diff --git a/docs/html/training/transitions/index.jd b/docs/html/training/transitions/index.jd index 53faa01aad8b..b8f99c84fc93 100644 --- a/docs/html/training/transitions/index.jd +++ b/docs/html/training/transitions/index.jd @@ -48,11 +48,9 @@ animate changes between view hierarchies. This class also covers how to create c animations.</p> <p class="note"><strong>Note:</strong> For Android versions earlier than 4.4.2 (API level 19) -but greater than or equal to Android 4.0 (API level 14), use the <code>animateLayoutChanges</code> -attribute to animate layouts. To learn more, see -<a href="{@docRoot}guide/topics/graphics/prop-animation.html">Property Animation</a> and -<a href="{@docRoot}training/animation/layout.html">Animating Layout Changes</a>.</p> - +but greater than or equal to Android 4.0 (API level 14), use the Android Support +Library's <a href="/reference/android/support/transitions/package-summary.html" +><code>android.support.transition</code></a> package.</p> <h2>Lessons</h2> diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index c6a45c1a677f..c836204486b0 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -244,10 +244,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { // to UI thread animation for AVD. if (!mAnimatorSet.isRunning() && ((VectorDrawableAnimatorRT) mAnimatorSet).mPendingAnimationActions.size() > 0) { - VectorDrawableAnimatorRT oldAnim = (VectorDrawableAnimatorRT) mAnimatorSet; - mAnimatorSet = new VectorDrawableAnimatorUI(this); - mAnimatorSet.init(mAnimatorSetFromXml); - oldAnim.transferPendingActions(mAnimatorSet); + fallbackOntoUI(); } } mAnimatorSet.onDraw(canvas); @@ -490,10 +487,22 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { throw new UnsupportedOperationException("Cannot force Animated Vector Drawable to" + " run on UI thread when the animation has started on RenderThread."); } + fallbackOntoUI(); + } + } + + private void fallbackOntoUI() { + if (mAnimatorSet instanceof VectorDrawableAnimatorRT) { + VectorDrawableAnimatorRT oldAnim = (VectorDrawableAnimatorRT) mAnimatorSet; mAnimatorSet = new VectorDrawableAnimatorUI(this); if (mAnimatorSetFromXml != null) { mAnimatorSet.init(mAnimatorSetFromXml); } + // Transfer the listener from RT animator to UI animator + if (oldAnim.mListener != null) { + mAnimatorSet.setListener(oldAnim.mListener); + } + oldAnim.transferPendingActions(mAnimatorSet); } } diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index f19a2624457e..33c1c3f6acc0 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -3289,7 +3289,10 @@ public class AudioManager { /** * Used as a key for {@link #getProperty} to request the native or optimal output sample rate - * for this device's primary output stream, in decimal Hz. + * for this device's low latency output stream, in decimal Hz. Latency-sensitive apps + * should use this value as a default, and offer the user the option to override it. + * The low latency output stream is typically either the device's primary output stream, + * or another output stream with smaller buffers. */ // FIXME Deprecate public static final String PROPERTY_OUTPUT_SAMPLE_RATE = @@ -3297,7 +3300,10 @@ public class AudioManager { /** * Used as a key for {@link #getProperty} to request the native or optimal output buffer size - * for this device's primary output stream, in decimal PCM frames. + * for this device's low latency output stream, in decimal PCM frames. Latency-sensitive apps + * should use this value as a minimum, and offer the user the option to override it. + * The low latency output stream is typically either the device's primary output stream, + * or another output stream with smaller buffers. */ // FIXME Deprecate public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = diff --git a/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml b/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml index 20173b0dc3bf..24cbfbd6430e 100644 --- a/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml +++ b/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml @@ -4,7 +4,7 @@ <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string> <string name="action_use_network" msgid="6076184727448466030">"যেভাবে আছে সেভাবেই এই নেটওয়ার্ক ব্যবহার করুন"</string> <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটওয়ার্ক ব্যবহার করবেন না"</string> - <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে প্রবেশ করুন করুন"</string> + <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে প্রবেশ করুন"</string> <string name="ssl_error_warning" msgid="6653188881418638872">"আপনি যে নেটওয়ার্কে যোগ দেওয়ার চেষ্টা করছেন তাতে নিরাপত্তার সমস্যা আছে।"</string> <string name="ssl_error_example" msgid="647898534624078900">"উদাহরণস্বরূপ, লগইন পৃষ্ঠাটি প্রদর্শিত প্রতিষ্ঠানের অন্তর্গত নাও হতে পারে৷"</string> <string name="ssl_error_continue" msgid="6492718244923937110">"যাই হোক না কেন ব্রাউজারের মাধ্যমে অবিরত রাখুন"</string> diff --git a/packages/SettingsLib/res/values-bs-rBA/strings.xml b/packages/SettingsLib/res/values-bs-rBA/strings.xml index 40a3630a4e55..a11bf3212836 100644 --- a/packages/SettingsLib/res/values-bs-rBA/strings.xml +++ b/packages/SettingsLib/res/values-bs-rBA/strings.xml @@ -146,9 +146,9 @@ <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN postavke nisu dostupne za ovog korisnika"</string> <string name="tethering_settings_not_available" msgid="6765770438438291012">"Postavke za privezivanje nisu dostupne za ovog korisnika"</string> <string name="apn_settings_not_available" msgid="7873729032165324000">"Postavke za naziv pristupne tačke nisu dostupne za ovog korisnika"</string> - <string name="enable_adb" msgid="7982306934419797485">"Otklanjanje grešaka putem uređaja spojenog na USB"</string> + <string name="enable_adb" msgid="7982306934419797485">"USB otklanjanje grešaka"</string> <string name="enable_adb_summary" msgid="4881186971746056635">"Način rada za uklanjanje grešaka kada je povezan USB"</string> - <string name="clear_adb_keys" msgid="4038889221503122743">"Ukini odobrenja otklanjanja grešaka putem uređaja spojenog na USB"</string> + <string name="clear_adb_keys" msgid="4038889221503122743">"Ukini odobrenja otklanjanja grešaka USB-om"</string> <string name="bugreport_in_power" msgid="7923901846375587241">"Prečica za izvještaj o greškama"</string> <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Prikaži tipku za prijavu grešaka u izborniku za potrošnju energije"</string> <string name="keep_screen_on" msgid="1146389631208760344">"Ostani aktivan"</string> @@ -185,9 +185,9 @@ <string name="allow_mock_location_summary" msgid="317615105156345626">"Dozvoli lažne lokacije"</string> <string name="debug_view_attributes" msgid="6485448367803310384">"Omogući pregled atributa prikaza"</string> <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Uvijek drži mobilne podatke aktivnim, čak i kada je Wi-Fi je aktivan (za brzo prebacivanje između mreža)."</string> - <string name="adb_warning_title" msgid="6234463310896563253">"Omogućiti otklanjanje grešaka putem uređaja spojenog na USB?"</string> - <string name="adb_warning_message" msgid="7316799925425402244">"Otklanjanje grešaka putem uređaja spojenog na USB je namijenjeno samo u svrhe razvoja aplikacija. Koristite ga za kopiranje podataka između računara i uređaja, instaliranje aplikacija na uređaj bez obavještenja te čitanje podataka iz zapisnika."</string> - <string name="adb_keys_warning_message" msgid="5659849457135841625">"Opozvati pristup otklanjanju grešaka putem uređaja spojenog na USB za sve računare koje ste prethodno ovlastili?"</string> + <string name="adb_warning_title" msgid="6234463310896563253">"Omogućiti USB otklanjanje grešaka?"</string> + <string name="adb_warning_message" msgid="7316799925425402244">"USB otklanjanje grešaka je namijenjeno samo u svrhe razvoja aplikacija. Koristite ga za kopiranje podataka između računara i uređaja, instaliranje aplikacija na uređaj bez obavještenja te čitanje podataka iz zapisnika."</string> + <string name="adb_keys_warning_message" msgid="5659849457135841625">"Opozvati pristup otklanjanju grešaka USB-om za sve računare koje ste prethodno ovlastili?"</string> <string name="dev_settings_warning_title" msgid="7244607768088540165">"Dopustiti postavke za razvoj?"</string> <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ove postavke su namijenjene samo za svrhe razvoja. Mogu izazvati pogrešno ponašanje uređaja i aplikacija na njemu."</string> <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifikuj aplikacije putem USB-a"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 99850a5d5cd4..fb7180a0a3b8 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -111,7 +111,7 @@ <string name="tts_play_example_summary" msgid="8029071615047894486">"Reprodueix una breu demostració de síntesi de veu"</string> <string name="tts_install_data_title" msgid="4264378440508149986">"Instal·la dades de veu"</string> <string name="tts_install_data_summary" msgid="5742135732511822589">"Instal·la les dades de veu necessàries per a la síntesi de veu"</string> - <string name="tts_engine_security_warning" msgid="8786238102020223650">"Pot ser que aquest motor de síntesi de la parla pugui recopilar tot el text que es dirà en veu alta, incloses les dades personals, com ara les contrasenyes i els números de les targetes de crèdit. Ve del motor <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Vols activar l\'ús d\'aquest motor de síntesi de la parla?"</string> + <string name="tts_engine_security_warning" msgid="8786238102020223650">"Pot ser que aquest motor de síntesi de la parla pugui recopilar tot el text que es dirà en veu alta, incloses les dades personals, com ara les contrasenyes i els números de les targetes de crèdit. Ve del motor <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Voleu activar l\'ús d\'aquest motor de síntesi de la parla?"</string> <string name="tts_engine_network_required" msgid="1190837151485314743">"Aquest idioma requereix una connexió de xarxa activa per a la sortida de síntesi de veu."</string> <string name="tts_default_sample_string" msgid="4040835213373086322">"Això és un exemple de síntesi de veu"</string> <string name="tts_status_title" msgid="7268566550242584413">"Estat de l\'idioma predeterminat"</string> diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml index 643875fa6ea0..8578810daa2d 100644 --- a/packages/SettingsLib/res/values-kn-rIN/strings.xml +++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml @@ -340,5 +340,5 @@ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ಸ್ವಲ್ಪ ದೊಡ್ಡ"</string> <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ದೊಡ್ಡ"</string> <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ಕಸ್ಟಮ್ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> - <string name="help_feedback_label" msgid="6815040660801785649">"ಸಹಾಯ ಮತ್ತು ಪ್ರತಿಕ್ರಿಯೆ"</string> + <string name="help_feedback_label" msgid="6815040660801785649">"ಸಹಾಯ & ಪ್ರತಿಕ್ರಿಯೆ"</string> </resources> diff --git a/packages/SettingsLib/res/values/config.xml b/packages/SettingsLib/res/values/config.xml index 299a5b74689c..d9473fa0b8b3 100755 --- a/packages/SettingsLib/res/values/config.xml +++ b/packages/SettingsLib/res/values/config.xml @@ -19,4 +19,7 @@ <resources> <!-- Configuration for automotive --> <bool name="enable_pbap_pce_profile">false</bool> + + <!-- Default data warning level in mb --> + <integer name="default_data_warning_level_mb">2048</integer> </resources> diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java index e53dd2f42c75..994ea88a80dd 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java @@ -32,6 +32,8 @@ import android.text.format.DateUtils; import android.text.format.Time; import android.util.Log; +import com.android.settingslib.R; + import java.util.Date; import java.util.Locale; @@ -41,12 +43,12 @@ import static android.net.NetworkStatsHistory.FIELD_TX_BYTES; import static android.telephony.TelephonyManager.SIM_STATE_READY; import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH; import static android.text.format.DateUtils.FORMAT_SHOW_DATE; +import static android.net.TrafficStats.MB_IN_BYTES; public class DataUsageController { + private static final String TAG = "DataUsageController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - public static final long DEFAULT_WARNING_LEVEL = 2L * 1024 * 1024 * 1024; private static final int FIELDS = FIELD_RX_BYTES | FIELD_TX_BYTES; private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50); private static final java.util.Formatter PERIOD_FORMATTER = new java.util.Formatter( @@ -75,6 +77,14 @@ public class DataUsageController { mNetworkController = networkController; } + /** + * Returns the default warning level in bytes. + */ + public long getDefaultWarningLevel() { + return MB_IN_BYTES + * mContext.getResources().getInteger(R.integer.default_data_warning_level_mb); + } + private INetworkStatsSession getSession() { if (mSession == null) { try { @@ -169,7 +179,7 @@ public class DataUsageController { usage.limitLevel = policy.limitBytes > 0 ? policy.limitBytes : 0; usage.warningLevel = policy.warningBytes > 0 ? policy.warningBytes : 0; } else { - usage.warningLevel = DEFAULT_WARNING_LEVEL; + usage.warningLevel = getDefaultWarningLevel(); } if (usage != null && mNetworkController != null) { usage.carrier = mNetworkController.getMobileDataNetworkName(); diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index f7e9541b0d33..fad102f6e6f8 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -155,6 +155,9 @@ <!-- Default for Settings.Secure.LONG_PRESS_TIMEOUT_MILLIS --> <integer name="def_long_press_timeout_millis">400</integer> + <!-- Default for Settings.Secure.MULTI_PRESS_TIMEOUT --> + <integer name="def_multi_press_timeout_millis">300</integer> + <!-- Default for Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD --> <bool name="def_show_ime_with_hard_keyboard">false</bool> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 0f7fe6fc5124..0f3a7fbe9daa 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -2102,7 +2102,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 130; + private static final int SETTINGS_VERSION = 131; private final int mUserId; @@ -2410,6 +2410,22 @@ public class SettingsProvider extends ContentProvider { currentVersion = 130; } + if (currentVersion == 130) { + // Initialize new multi-press timeout to default value + final SettingsState systemSecureSettings = getSecureSettingsLocked(userId); + final String oldValue = systemSecureSettings.getSettingLocked( + Settings.Secure.MULTI_PRESS_TIMEOUT).getValue(); + if (TextUtils.equals(null, oldValue)) { + systemSecureSettings.insertSettingLocked( + Settings.Secure.MULTI_PRESS_TIMEOUT, + String.valueOf(getContext().getResources().getInteger( + R.integer.def_multi_press_timeout_millis)), + SettingsState.SYSTEM_PACKAGE_NAME); + } + + currentVersion = 131; + } + if (currentVersion != newVersion) { Slog.w("SettingsProvider", "warning: upgrading settings database to version " + newVersion + " left it at " diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_carmode.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_carmode.png Binary files differindex 6242084ea175..95e5778448b2 100644 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_carmode.png +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_carmode.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_carmode.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_carmode.png Binary files differindex 1b37a47338aa..6421146caae3 100644 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_carmode.png +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_carmode.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_carmode.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_carmode.png Binary files differindex 9e0575883a06..151d5feee7eb 100644 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_carmode.png +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_carmode.png diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_carmode.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_carmode.png Binary files differindex 2fcfdde08164..b954aa7adc0c 100644 --- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_carmode.png +++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_carmode.png diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_carmode.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_carmode.png Binary files differindex 48708a5099a8..61d5db659850 100644 --- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_carmode.png +++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_carmode.png diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_carmode.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_carmode.png Binary files differindex 3d731840a93f..7b98c1fa7504 100644 --- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_carmode.png +++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_carmode.png diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_carmode.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_carmode.png Binary files differindex 786935d5d185..aad13204b048 100644 --- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_carmode.png +++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_carmode.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_carmode.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_carmode.png Binary files differindex e4bd4bc3e39d..754b2d99ec29 100644 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_carmode.png +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_carmode.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_carmode.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_carmode.png Binary files differindex 94ccf7912e8f..873ed7f9e744 100644 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_carmode.png +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_carmode.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_carmode.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_carmode.png Binary files differindex 980bbbcb4ceb..7696d872fe21 100644 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_carmode.png +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_carmode.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_carmode.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_carmode.png Binary files differindex 201be3b3c8b5..c98f55e071d8 100644 --- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_carmode.png +++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_carmode.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_carmode.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_carmode.png Binary files differindex 2770d6264da0..187a5661a38b 100644 --- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_carmode.png +++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_carmode.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_carmode.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_carmode.png Binary files differindex 8ac64937007b..c66f8be323d6 100644 --- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_carmode.png +++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_carmode.png diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_carmode.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_carmode.png Binary files differindex 8e3678b292b8..3a3a119041bd 100644 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_carmode.png +++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_carmode.png diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_carmode.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_carmode.png Binary files differindex 6c7cb0582733..7198c825322f 100644 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_carmode.png +++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_carmode.png diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_carmode.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_carmode.png Binary files differindex ea2b108e1e4c..b1fc02e51502 100644 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_carmode.png +++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_carmode.png diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_carmode.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_carmode.png Binary files differindex 3e11023ef7e1..c06bfdab0abd 100644 --- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_carmode.png +++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_carmode.png diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_carmode.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_carmode.png Binary files differindex fe8213d6390e..a8c76bfc664c 100644 --- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_carmode.png +++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_carmode.png diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_carmode.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_carmode.png Binary files differindex c117efd1e654..b798e3d6ea06 100644 --- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_carmode.png +++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_carmode.png diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml index 0c8cc9bb5f02..f0c4e595106a 100644 --- a/packages/SystemUI/res/layout/remote_input.xml +++ b/packages/SystemUI/res/layout/remote_input.xml @@ -42,7 +42,6 @@ android:singleLine="true" android:ellipsize="start" android:inputType="textShortMessage|textAutoCorrect|textCapSentences" - android:textIsSelectable="true" android:imeOptions="actionNone|flagNoExtractUi" /> <FrameLayout diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index a60371b49197..7eb227eb84b5 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -345,7 +345,7 @@ <string name="description_target_search" msgid="3091587249776033139">"ค้นหา"</string> <string name="description_direction_up" msgid="7169032478259485180">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string> <string name="description_direction_left" msgid="7207478719805562165">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string> - <string name="zen_priority_introduction" msgid="3070506961866919502">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นการปลุก การเตือนความจำ กิจกรรม และผู้โทรที่คุณระบุ"</string> + <string name="zen_priority_introduction" msgid="3070506961866919502">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นการปลุก การช่วยเตือน กิจกรรม และผู้โทรที่คุณระบุ"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"กำหนดค่า"</string> <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"การใช้โหมดนี้จะบล็อกเสียงและการสั่นทั้งหมด ซึ่งรวมถึงเสียงปลุก เพลง วิดีโอ และเกม คุณจะยังโทรออกได้อยู่"</string> <string name="zen_silence_introduction" msgid="3137882381093271568">"การใช้โหมดนี้จะบล็อกเสียงและการสั่นทั้งหมด ซึ่งรวมถึงเสียงปลุก เพลง วิดีโอ และเกม"</string> diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java index 65d680509be2..15ae4ad6dac0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java @@ -126,8 +126,8 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene ? R.drawable.ic_qs_branded_vpn : R.drawable.ic_qs_vpn); if (mFooterIconId != footerIconId) { - mFooterIcon.setImageResource(footerIconId); mFooterIconId = footerIconId; + mMainHandler.post(mUpdateIcon); } mIsVisible = mIsIconVisible; } @@ -207,6 +207,13 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene } } + private final Runnable mUpdateIcon = new Runnable() { + @Override + public void run() { + mFooterIcon.setImageResource(mFooterIconId); + } + }; + private final Runnable mUpdateDisplayState = new Runnable() { @Override public void run() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index c575417e873e..a1854fa06562 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -2517,8 +2517,7 @@ public abstract class BaseStatusBar extends SystemUI implements boolean inUse = mPowerManager.isScreenOn() && (!mStatusBarKeyguardViewManager.isShowing() - || mStatusBarKeyguardViewManager.isOccluded()) - && !mStatusBarKeyguardViewManager.isInputRestricted(); + || mStatusBarKeyguardViewManager.isOccluded()); try { inUse = inUse && !mDreamManager.isDreaming(); } catch (RemoteException e) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 048c4bd4a770..8cabfb93bf32 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -461,7 +461,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL // happens to occur during the launch. ActivityOptions o = ActivityOptions.makeBasic(); o.setRotationAnimationHint( - WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE); + WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS); try { result = ActivityManagerNative.getDefault().startActivityAsUser( null, getContext().getBasePackageName(), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 51ff29e10964..45d51b01210e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -54,7 +54,7 @@ import java.io.PrintWriter; public class NavigationBarView extends LinearLayout { final static boolean DEBUG = false; - final static String TAG = "PhoneStatusBar/NavigationBarView"; + final static String TAG = "StatusBar/NavBarView"; // slippery nav bar when everything is disabled, e.g. during setup final static boolean SLIPPERY_WHEN_DISABLED = true; @@ -527,8 +527,8 @@ public class NavigationBarView extends LinearLayout { updateCurrentView(); } - public boolean needsReorient() { - return mCurrentRotation != mDisplay.getRotation(); + public boolean needsReorient(int rotation) { + return mCurrentRotation != rotation; } private void updateCurrentView() { @@ -567,7 +567,7 @@ public class NavigationBarView extends LinearLayout { setMenuVisibility(mShowMenu, true /* force */); if (DEBUG) { - Log.d(TAG, "reorient(): rot=" + mDisplay.getRotation()); + Log.d(TAG, "reorient(): rot=" + mCurrentRotation); } updateTaskSwitchHelper(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java index 1755cc68bee2..2c8339a1dc22 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java @@ -42,7 +42,7 @@ public class NotificationGroupManager implements HeadsUpManager.OnHeadsUpChanged private int mBarState = -1; private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>(); private HeadsUpManager mHeadsUpManager; - private boolean mUpdatingSuppressionBlocked; + private boolean mIsUpdatingUnchangedGroup; public void setOnGroupChangeListener(OnGroupChangeListener listener) { mListener = listener; @@ -141,7 +141,7 @@ public class NotificationGroupManager implements HeadsUpManager.OnHeadsUpChanged } private void updateSuppression(NotificationGroup group) { - if (group == null || mUpdatingSuppressionBlocked) { + if (group == null) { return; } boolean prevSuppressed = group.suppressed; @@ -154,7 +154,9 @@ public class NotificationGroupManager implements HeadsUpManager.OnHeadsUpChanged if (group.suppressed) { handleSuppressedSummaryHeadsUpped(group.summary); } - mListener.onGroupsChanged(); + if (!mIsUpdatingUnchangedGroup) { + mListener.onGroupsChanged(); + } } } @@ -188,12 +190,12 @@ public class NotificationGroupManager implements HeadsUpManager.OnHeadsUpChanged boolean groupKeysChanged = !oldKey.equals(newKey); boolean wasGroupChild = isGroupChild(oldNotification); boolean isGroupChild = isGroupChild(entry.notification); - mUpdatingSuppressionBlocked = !groupKeysChanged && wasGroupChild == isGroupChild; + mIsUpdatingUnchangedGroup = !groupKeysChanged && wasGroupChild == isGroupChild; if (mGroupMap.get(getGroupKey(oldNotification)) != null) { onEntryRemovedInternal(entry, oldNotification); } onEntryAdded(entry); - mUpdatingSuppressionBlocked = false; + mIsUpdatingUnchangedGroup = false; if (isIsolated(entry.notification)) { mIsolatedEntries.put(entry.key, entry.notification); if (groupKeysChanged) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index b4368d69343d..64c082b580eb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -65,7 +65,6 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; -import android.hardware.display.DisplayManager; import android.inputmethodservice.InputMethodService; import android.media.AudioAttributes; import android.media.MediaMetadata; @@ -100,6 +99,7 @@ import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; import android.view.Display; +import android.view.IRotationWatcher; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -207,7 +207,7 @@ import java.util.Map; public class PhoneStatusBar extends BaseStatusBar implements DemoMode, DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener, - HeadsUpManager.OnHeadsUpChangedListener, DisplayManager.DisplayListener { + HeadsUpManager.OnHeadsUpChangedListener { static final String TAG = "PhoneStatusBar"; public static final boolean DEBUG = BaseStatusBar.DEBUG; public static final boolean SPEW = false; @@ -693,8 +693,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mUnlockMethodCache.addListener(this); startKeyguard(); - mContext.getSystemService(DisplayManager.class).registerDisplayListener(this, null); - mDozeServiceHost = new DozeServiceHost(); KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mDozeServiceHost); putComponent(DozeHost.class, mDozeServiceHost); @@ -1411,6 +1409,27 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView); if (mNavigationBarView == null) return; + try { + WindowManagerGlobal.getWindowManagerService() + .watchRotation(new IRotationWatcher.Stub() { + @Override + public void onRotationChanged(int rotation) throws RemoteException { + // We need this to be scheduled as early as possible to beat the redrawing of + // window in response to the orientation change. + Message msg = Message.obtain(mHandler, () -> { + if (mNavigationBarView != null + && mNavigationBarView.needsReorient(rotation)) { + repositionNavigationBar(); + } + }); + msg.setAsynchronous(true); + mHandler.sendMessageAtFrontOfQueue(msg); + } + }); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + prepareNavigationBarView(); mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams()); @@ -3419,7 +3438,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // force the crossfade animation if an orientation change // happens to occur during the launch. options.setRotationAnimationHint( - WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE); + WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS); } try { result = ActivityManagerNative.getDefault().startActivityAsUser( @@ -3587,22 +3606,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void onDisplayAdded(int displayId) { - } - - @Override - public void onDisplayRemoved(int displayId) { - } - - @Override - public void onDisplayChanged(int displayId) { - if (displayId == Display.DEFAULT_DISPLAY - && mNavigationBarView != null && mNavigationBarView.needsReorient()) { - repositionNavigationBar(); - } - } - - @Override public void userSwitched(int newUserId) { super.userSwitched(newUserId); if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index f72e50beec10..c8c43101c90f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -412,7 +412,10 @@ public class NotificationStackScrollLayout extends ViewGroup @Override protected void onDraw(Canvas canvas) { - canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom, mBackgroundPaint); + if (mCurrentBounds.top < mCurrentBounds.bottom) { + canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom, + mBackgroundPaint); + } if (DEBUG) { int y = mTopPadding; canvas.drawLine(0, y, getWidth(), y, mDebugPaint); @@ -2013,11 +2016,12 @@ public class NotificationStackScrollLayout extends ViewGroup bottom = top; } if (mPhoneStatusBar.getBarState() != StatusBarState.KEYGUARD) { - mBackgroundBounds.top = (int) Math.max(mTopPadding + mStackTranslation, top); + top = (int) Math.max(mTopPadding + mStackTranslation, top); } else { // otherwise the animation from the shade to the keyguard will jump as it's maxed - mBackgroundBounds.top = Math.max(0, top); + top = Math.max(0, top); } + mBackgroundBounds.top = top; mBackgroundBounds.bottom = Math.min(getHeight(), Math.max(bottom, top)); } @@ -3451,7 +3455,7 @@ public class NotificationStackScrollLayout extends ViewGroup notifyHeightChangeListener(mEmptyShadeView); } }; - if (mAnimationsEnabled) { + if (mAnimationsEnabled && mIsExpanded) { mEmptyShadeView.setWillBeGone(true); mEmptyShadeView.performVisibilityAnimation(false, onFinishedRunnable); } else { diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 99f14d7c4c00..65af958b0181 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -3568,6 +3568,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL: case WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL: case WindowManager.LayoutParams.TYPE_BASE_APPLICATION: + case WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION: case WindowManager.LayoutParams.TYPE_PHONE: case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE: case WindowManager.LayoutParams.TYPE_TOAST: diff --git a/services/accessibility/java/com/android/server/accessibility/KeyEventDispatcher.java b/services/accessibility/java/com/android/server/accessibility/KeyEventDispatcher.java index e03c16e25fc2..e8f93b89bc0c 100644 --- a/services/accessibility/java/com/android/server/accessibility/KeyEventDispatcher.java +++ b/services/accessibility/java/com/android/server/accessibility/KeyEventDispatcher.java @@ -121,7 +121,7 @@ public class KeyEventDispatcher { Service service = boundServices.get(i); // Key events are handled only by services that declared // this capability and requested to filter key events. - if (!service.mRequestFilterKeyEvents) { + if (!service.mRequestFilterKeyEvents || (service.mServiceInterface == null)) { continue; } int filterKeyEventBit = service.mAccessibilityServiceInfo.getCapabilities() diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index ec53c16b312e..bdbd06640e49 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -1310,8 +1310,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub mConnector.execute("tether", "interface", "remove", iface); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); + } finally { + removeInterfaceFromLocalNetwork(iface); } - removeInterfaceFromLocalNetwork(iface); } @Override diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index f78f29c4ac6d..d3826acb7918 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -226,11 +226,12 @@ public final class BroadcastQueue { } public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) { + final Intent intent = r.intent; for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) { - if (r.intent.filterEquals(mParallelBroadcasts.get(i).intent)) { + if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "***** DROPPING PARALLEL [" - + mQueueName + "]: " + r.intent); + + mQueueName + "]: " + intent); mParallelBroadcasts.set(i, r); return true; } @@ -239,11 +240,12 @@ public final class BroadcastQueue { } public final boolean replaceOrderedBroadcastLocked(BroadcastRecord r) { + final Intent intent = r.intent; for (int i = mOrderedBroadcasts.size() - 1; i > 0; i--) { - if (r.intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { + if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "***** DROPPING ORDERED [" - + mQueueName + "]: " + r.intent); + + mQueueName + "]: " + intent); mOrderedBroadcasts.set(i, r); return true; } diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java index 9dd07a9a9f90..73a17c613c4d 100644 --- a/services/core/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java @@ -42,6 +42,7 @@ final class CoreSettingsObserver extends ContentObserver { String, Class<?>>(); static { sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class); + sSecureSettingToTypeMap.put(Settings.Secure.MULTI_PRESS_TIMEOUT, int.class); // add other secure settings here... sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class); diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index e0d8373fc445..927f8f98284f 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -1616,6 +1616,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); if (mNotifyList.indexOf(who) < 0) { mNotifyList.add(who); + mIPv6TetheringCoordinator.addActiveDownstream(who); } transitionTo(mTetherModeAliveState); break; @@ -1623,6 +1624,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering who = (TetherInterfaceStateMachine)message.obj; if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); mNotifyList.remove(who); + mIPv6TetheringCoordinator.removeActiveDownstream(who); break; default: retValue = false; @@ -1661,17 +1663,19 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering maybeLogMessage(this, message.what); boolean retValue = true; switch (message.what) { - case CMD_TETHER_MODE_REQUESTED: + case CMD_TETHER_MODE_REQUESTED: { TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj; if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); if (mNotifyList.indexOf(who) < 0) { mNotifyList.add(who); + mIPv6TetheringCoordinator.addActiveDownstream(who); } who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED, mCurrentUpstreamIface); break; - case CMD_TETHER_MODE_UNREQUESTED: - who = (TetherInterfaceStateMachine)message.obj; + } + case CMD_TETHER_MODE_UNREQUESTED: { + TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj; if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); if (mNotifyList.remove(who)) { if (DBG) Log.d(TAG, "TetherModeAlive removing notifyee " + who); @@ -1689,7 +1693,9 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } else { Log.e(TAG, "TetherModeAliveState UNREQUESTED has unknown who: " + who); } + mIPv6TetheringCoordinator.removeActiveDownstream(who); break; + } case CMD_UPSTREAM_CHANGED: // need to try DUN immediately if Wifi goes down mTryCell = true; diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java index e94b584ac48a..9173febd0ef3 100644 --- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java +++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java @@ -29,6 +29,7 @@ import android.util.Log; import java.net.Inet6Address; import java.net.InetAddress; import java.util.ArrayList; +import java.util.LinkedList; /** @@ -45,10 +46,28 @@ public class IPv6TetheringCoordinator { private static final boolean VDBG = false; private final ArrayList<TetherInterfaceStateMachine> mNotifyList; + private final LinkedList<TetherInterfaceStateMachine> mActiveDownstreams; private NetworkState mUpstreamNetworkState; public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList) { mNotifyList = notifyList; + mActiveDownstreams = new LinkedList<>(); + } + + public void addActiveDownstream(TetherInterfaceStateMachine downstream) { + if (mActiveDownstreams.indexOf(downstream) == -1) { + // Adding a new downstream appends it to the list. Adding a + // downstream a second time without first removing it has no effect. + mActiveDownstreams.offer(downstream); + updateIPv6TetheringInterfaces(); + } + } + + public void removeActiveDownstream(TetherInterfaceStateMachine downstream) { + stopIPv6TetheringOn(downstream); + if (mActiveDownstreams.remove(downstream)) { + updateIPv6TetheringInterfaces(); + } } public void updateUpstreamNetworkState(NetworkState ns) { @@ -72,8 +91,7 @@ public class IPv6TetheringCoordinator { private void stopIPv6TetheringOnAllInterfaces() { for (TetherInterfaceStateMachine sm : mNotifyList) { - sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, - 0, 0, null); + stopIPv6TetheringOn(sm); } } @@ -98,28 +116,32 @@ public class IPv6TetheringCoordinator { private void updateIPv6TetheringInterfaces() { for (TetherInterfaceStateMachine sm : mNotifyList) { - final LinkProperties lp = getInterfaceIPv6LinkProperties(sm.interfaceType()); + final LinkProperties lp = getInterfaceIPv6LinkProperties(sm); sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp); break; } } - private LinkProperties getInterfaceIPv6LinkProperties(int interfaceType) { + private LinkProperties getInterfaceIPv6LinkProperties(TetherInterfaceStateMachine sm) { if (mUpstreamNetworkState == null) return null; + if (sm.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) { + // TODO: Figure out IPv6 support on PAN interfaces. + return null; + } + // NOTE: Here, in future, we would have policies to decide how to divvy // up the available dedicated prefixes among downstream interfaces. // At this time we have no such mechanism--we only support tethering - // IPv6 toward Wi-Fi interfaces. - - switch (interfaceType) { - case ConnectivityManager.TETHERING_WIFI: - final LinkProperties lp = getIPv6OnlyLinkProperties( - mUpstreamNetworkState.linkProperties); - if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) { - return lp; - } - break; + // IPv6 toward the oldest (first requested) active downstream. + + final TetherInterfaceStateMachine currentActive = mActiveDownstreams.peek(); + if (currentActive != null && currentActive == sm) { + final LinkProperties lp = getIPv6OnlyLinkProperties( + mUpstreamNetworkState.linkProperties); + if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) { + return lp; + } } return null; @@ -250,4 +272,8 @@ public class IPv6TetheringCoordinator { ns.networkCapabilities, ns.linkProperties); } + + private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) { + sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null); + } } diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java index edb4347f56a3..7525f302c141 100644 --- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java +++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java @@ -26,6 +26,7 @@ import android.net.RouteInfo; import android.net.ip.RouterAdvertisementDaemon; import android.net.ip.RouterAdvertisementDaemon.RaParams; import android.os.INetworkManagementService; +import android.os.ServiceSpecificException; import android.os.RemoteException; import android.util.Log; import android.util.Slog; @@ -205,7 +206,7 @@ class IPv6TetheringInterfaceServices { final String dnsString = dns.getHostAddress(); try { netd.interfaceDelAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH); - } catch (RemoteException e) { + } catch (ServiceSpecificException | RemoteException e) { Log.e(TAG, "Failed to remove local dns IP: " + dnsString, e); } } @@ -222,7 +223,7 @@ class IPv6TetheringInterfaceServices { final String dnsString = dns.getHostAddress(); try { netd.interfaceAddAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH); - } catch (RemoteException e) { + } catch (ServiceSpecificException | RemoteException e) { Log.e(TAG, "Failed to add local dns IP: " + dnsString, e); newDnses.remove(dns); } @@ -231,7 +232,7 @@ class IPv6TetheringInterfaceServices { try { netd.tetherApplyDnsInterfaces(); - } catch (RemoteException e) { + } catch (ServiceSpecificException | RemoteException e) { Log.e(TAG, "Failed to update local DNS caching server"); if (newDnses != null) newDnses.clear(); } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 61af8edebb83..d6cc9fc6a85c 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -102,9 +102,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // Trigger proximity if distance is less than 5 cm. private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f; - // Brightness animation ramp rate in brightness units per second. - private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40; - private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0; private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1; private static final int REPORTED_TO_POLICY_SCREEN_ON = 2; @@ -243,8 +240,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private boolean mAppliedDimming; private boolean mAppliedLowPower; - // Brightness ramp rate fast. + // Brightness animation ramp rates in brightness units per second private final int mBrightnessRampRateFast; + private final int mBrightnessRampRateSlow; // The controller for the automatic brightness level. private AutomaticBrightnessController mAutomaticBrightnessController; @@ -307,6 +305,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessRampRateFast = resources.getInteger( com.android.internal.R.integer.config_brightness_ramp_rate_fast); + mBrightnessRampRateSlow = resources.getInteger( + com.android.internal.R.integer.config_brightness_ramp_rate_slow); int lightSensorRate = resources.getInteger( com.android.internal.R.integer.config_autoBrightnessLightSensorRate); @@ -703,7 +703,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (!mPendingScreenOff) { if (state == Display.STATE_ON || state == Display.STATE_DOZE) { animateScreenBrightness(brightness, - slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : mBrightnessRampRateFast); + slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast); } else { animateScreenBrightness(brightness, 0); } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index da615ec21720..817efdf0c823 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -1035,7 +1035,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { */ private void notifyOverLimitNL(NetworkTemplate template) { if (!mOverLimitNotified.contains(template)) { - mContext.startActivity(buildNetworkOverLimitIntent(template)); + mContext.startActivity(buildNetworkOverLimitIntent(mContext.getResources(), template)); mOverLimitNotified.add(template); } } @@ -1081,7 +1081,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { builder.setDeleteIntent(PendingIntent.getBroadcast( mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT)); - final Intent viewIntent = buildViewDataUsageIntent(policy.template); + final Intent viewIntent = buildViewDataUsageIntent(res, policy.template); builder.setContentIntent(PendingIntent.getActivity( mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT)); @@ -1117,7 +1117,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { builder.setContentTitle(title); builder.setContentText(body); - final Intent intent = buildNetworkOverLimitIntent(policy.template); + final Intent intent = buildNetworkOverLimitIntent(res, policy.template); builder.setContentIntent(PendingIntent.getActivity( mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); break; @@ -1152,7 +1152,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { builder.setContentTitle(title); builder.setContentText(body); - final Intent intent = buildViewDataUsageIntent(policy.template); + final Intent intent = buildViewDataUsageIntent(res, policy.template); builder.setContentIntent(PendingIntent.getActivity( mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); break; @@ -3520,19 +3520,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return intent; } - private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { + private static Intent buildNetworkOverLimitIntent(Resources res, NetworkTemplate template) { final Intent intent = new Intent(); - intent.setComponent(new ComponentName( - "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity")); + intent.setComponent(ComponentName.unflattenFromString( + res.getString(R.string.config_networkOverLimitComponent))); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); return intent; } - private static Intent buildViewDataUsageIntent(NetworkTemplate template) { + private static Intent buildViewDataUsageIntent(Resources res, NetworkTemplate template) { final Intent intent = new Intent(); - intent.setComponent(new ComponentName( - "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); + intent.setComponent(ComponentName.unflattenFromString( + res.getString(R.string.config_dataUsageSummaryComponent))); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); return intent; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 9191098e3a6e..1c303dc9b62b 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -200,6 +200,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int MULTI_PRESS_POWER_THEATER_MODE = 1; static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2; + // Number of presses needed before we induce panic press behavior on the back button + static final int PANIC_PRESS_BACK_COUNT = 4; + static final int PANIC_PRESS_BACK_NOTHING = 0; + static final int PANIC_PRESS_BACK_HOME = 1; + // These need to match the documentation/constant in // core/res/res/values/config.xml static final int LONG_PRESS_HOME_NOTHING = 0; @@ -406,6 +411,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { volatile boolean mBackKeyHandled; volatile boolean mBeganFromNonInteractive; volatile int mPowerKeyPressCounter; + volatile int mBackKeyPressCounter; volatile boolean mEndCallKeyHandled; volatile boolean mCameraGestureTriggeredDuringGoingToSleep; volatile boolean mGoingToSleep; @@ -464,6 +470,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mDoublePressOnPowerBehavior; int mTriplePressOnPowerBehavior; int mLongPressOnBackBehavior; + int mPanicPressOnBackBehavior; int mShortPressOnSleepBehavior; int mShortPressWindowBehavior; boolean mAwake; @@ -726,6 +733,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private static final int MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU = 17; private static final int MSG_BACK_LONG_PRESS = 18; private static final int MSG_DISPOSE_INPUT_CONSUMER = 19; + private static final int MSG_BACK_DELAYED_PRESS = 20; private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0; private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1; @@ -792,10 +800,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { break; case MSG_BACK_LONG_PRESS: backLongPress(); + finishBackKeyPress(); break; case MSG_DISPOSE_INPUT_CONSUMER: disposeInputConsumer((InputConsumer) msg.obj); break; + case MSG_BACK_DELAYED_PRESS: + backMultiPressAction((Long) msg.obj, msg.arg1); + finishBackKeyPress(); + break; } } } @@ -1010,6 +1023,52 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + private void interceptBackKeyDown() { + // Reset back key state for long press + mBackKeyHandled = false; + + // Cancel multi-press detection timeout. + if (hasPanicPressOnBackBehavior()) { + if (mBackKeyPressCounter != 0 + && mBackKeyPressCounter < PANIC_PRESS_BACK_COUNT) { + mHandler.removeMessages(MSG_BACK_DELAYED_PRESS); + } + } + + if (hasLongPressOnBackBehavior()) { + Message msg = mHandler.obtainMessage(MSG_BACK_LONG_PRESS); + msg.setAsynchronous(true); + mHandler.sendMessageDelayed(msg, + ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); + } + } + + // returns true if the key was handled and should not be passed to the user + private boolean interceptBackKeyUp(KeyEvent event) { + // Cache handled state + boolean handled = mBackKeyHandled; + + if (hasPanicPressOnBackBehavior()) { + // Check for back key panic press + ++mBackKeyPressCounter; + + final long eventTime = event.getDownTime(); + + if (mBackKeyPressCounter <= PANIC_PRESS_BACK_COUNT) { + // This could be a multi-press. Wait a little bit longer to confirm. + Message msg = mHandler.obtainMessage(MSG_BACK_DELAYED_PRESS, + mBackKeyPressCounter, 0, eventTime); + msg.setAsynchronous(true); + mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout()); + } + } + + // Reset back long press state + cancelPendingBackKeyAction(); + + return handled; + } + private void interceptPowerKeyDown(KeyEvent event, boolean interactive) { // Hold a wake lock until the power key is released. if (!mPowerKeyWakeLock.isHeld()) { @@ -1140,6 +1199,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + private void finishBackKeyPress() { + mBackKeyPressCounter = 0; + } + private void cancelPendingPowerKeyAction() { if (!mPowerKeyHandled) { mPowerKeyHandled = true; @@ -1154,6 +1217,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + private void backMultiPressAction(long eventTime, int count) { + if (count >= PANIC_PRESS_BACK_COUNT) { + switch (mPanicPressOnBackBehavior) { + case PANIC_PRESS_BACK_NOTHING: + break; + case PANIC_PRESS_BACK_HOME: + launchHomeFromHotKey(); + break; + } + } + } + private void powerPress(long eventTime, boolean interactive, int count) { if (mScreenOnEarly && !mScreenOnFully) { Slog.i(TAG, "Suppressed redundant power key press while " @@ -1312,6 +1387,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { return mLongPressOnBackBehavior != LONG_PRESS_BACK_NOTHING; } + private boolean hasPanicPressOnBackBehavior() { + return mPanicPressOnBackBehavior != PANIC_PRESS_BACK_NOTHING; + } + private void interceptScreenshotChord() { if (mScreenshotChordEnabled && mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered @@ -1639,6 +1718,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { mLongPressOnBackBehavior = mContext.getResources().getInteger( com.android.internal.R.integer.config_longPressOnBackBehavior); + mPanicPressOnBackBehavior = mContext.getResources().getInteger( + com.android.internal.R.integer.config_backPanicBehavior); mShortPressOnPowerBehavior = mContext.getResources().getInteger( com.android.internal.R.integer.config_shortPressOnPowerBehavior); @@ -2891,6 +2972,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } switch (animationHint) { case ROTATION_ANIMATION_CROSSFADE: + case ROTATION_ANIMATION_SEAMLESS: // Crossfade is fallback for seamless. anim[0] = R.anim.rotation_animation_xfade_exit; anim[1] = R.anim.rotation_animation_enter; break; @@ -5624,20 +5706,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { switch (keyCode) { case KeyEvent.KEYCODE_BACK: { if (down) { - mBackKeyHandled = false; - if (hasLongPressOnBackBehavior()) { - Message msg = mHandler.obtainMessage(MSG_BACK_LONG_PRESS); - msg.setAsynchronous(true); - mHandler.sendMessageDelayed(msg, - ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); - } + interceptBackKeyDown(); } else { - boolean handled = mBackKeyHandled; + boolean handled = interceptBackKeyUp(event); - // Reset back key state - cancelPendingBackKeyAction(); - - // Don't pass back press to app if we've already handled it + // Don't pass back press to app if we've already handled it via long press if (handled) { result &= ~ACTION_PASS_TO_USER; } @@ -7754,14 +7827,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { return false; } + final WindowState w = mTopFullscreenOpaqueWindowState; + // We only enable seamless rotation if the top window has requested // it and is in the fullscreen opaque state. Seamless rotation // requires freezing various Surface states and won't work well // with animations, so we disable it in the animation case for now. - if (mTopFullscreenOpaqueWindowState != null && mTopIsFullscreen && - !mTopFullscreenOpaqueWindowState.isAnimatingLw() && - mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation == - ROTATION_ANIMATION_JUMPCUT) { + if (w != null && !w.isAnimatingLw() && + ((w.getAttrs().rotationAnimation == ROTATION_ANIMATION_JUMPCUT) || + (w.getAttrs().rotationAnimation == ROTATION_ANIMATION_SEAMLESS))) { return true; } return false; diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index d2d5c2878889..e5e2175fb616 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -348,6 +348,7 @@ final class AccessibilityController { } switch (type) { case WindowManager.LayoutParams.TYPE_APPLICATION: + case WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION: case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL: case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA: case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL: diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index a9624cfaba95..b0653921caf1 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -17,7 +17,9 @@ package com.android.server.wm; import static android.app.ActivityManager.StackId; +import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; +import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; @@ -338,6 +340,7 @@ class AppWindowToken extends WindowToken { } void clearAnimatingFlags() { + boolean wallpaperMightChange = false; for (int i = allAppWindows.size() - 1; i >= 0; i--) { final WindowState win = allAppWindows.get(i); // We don't want to clear it out for windows that get replaced, because the @@ -348,7 +351,6 @@ class AppWindowToken extends WindowToken { // by the client. We should let animation proceed and not clear this flag or // they won't eventually be removed by WindowStateAnimator#finishExit. if (!win.mWillReplaceWindow && !win.mRemoveOnExit) { - win.mAnimatingExit = false; // Clear mAnimating flag together with mAnimatingExit. When animation // changes from exiting to entering, we need to clear this flag until the // new animation gets applied, so that isAnimationStarting() becomes true @@ -356,9 +358,24 @@ class AppWindowToken extends WindowToken { // Otherwise applySurfaceChangesTransaction will faill to skip surface // placement for this window during this period, one or more frame will // show up with wrong position or scale. - win.mWinAnimator.mAnimating = false; + if (win.mAnimatingExit) { + win.mAnimatingExit = false; + wallpaperMightChange = true; + } + if (win.mWinAnimator.mAnimating) { + win.mWinAnimator.mAnimating = false; + wallpaperMightChange = true; + } + if (win.mDestroying) { + win.mDestroying = false; + service.mDestroySurface.remove(win); + wallpaperMightChange = true; + } } } + if (wallpaperMightChange) { + requestUpdateWallpaperIfNeeded(); + } } void destroySurfaces() { @@ -406,6 +423,9 @@ class AppWindowToken extends WindowToken { if (displayContent != null && !displayList.contains(displayContent)) { displayList.add(displayContent); } + if (cleanupOnResume) { + win.requestUpdateWallpaperIfNeeded(); + } win.mDestroying = false; } for (int i = 0; i < displayList.size(); i++) { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index b4387b98e6d7..1dcada6729fc 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -624,8 +624,8 @@ class Task implements DimLayer.DimLayerUser { // // As we use this flag as a hint to freeze surface boundary updates, // we'd like to only apply this to TYPE_BASE_APPLICATION, - // windows of TYPE_APPLICATION like dialogs, could appear - // to not be drag resizing while they resize, but we'd + // windows of TYPE_APPLICATION (or TYPE_DRAWN_APPLICATION) like dialogs, + // could appear to not be drag resizing while they resize, but we'd // still like to manipulate their frame to update crop, etc... // // Anyway we don't need to synchronize position and content updates for these diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index a976b3649554..2b66c3af2beb 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -586,27 +586,24 @@ class WallpaperController { if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "New i: " + wallpaperTargetIndex + " old i: " + oldI); if (oldI >= 0) { - if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, - "Animating wallpapers: old#" + oldI + "=" + oldW + "; new#" - + wallpaperTargetIndex + "=" + wallpaperTarget); - - // Set the new target correctly. - if (wallpaperTarget.mAppToken != null - && wallpaperTarget.mAppToken.hiddenRequested) { - if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, - "Old wallpaper still the target."); - mWallpaperTarget = oldW; - wallpaperTarget = oldW; - wallpaperTargetIndex = oldI; - } - // Now set the upper and lower wallpaper targets correctly, + final boolean newTargetHidden = + wallpaperTarget.mAppToken != null && wallpaperTarget.mAppToken.hiddenRequested; + final boolean oldTargetHidden = + oldW.mAppToken != null && oldW.mAppToken.hiddenRequested; + if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:" + + " old#" + oldI + "=" + oldW + " hidden=" + oldTargetHidden + + " new#" + wallpaperTargetIndex + "=" + wallpaperTarget + + " hidden=" + newTargetHidden); + + // Set the upper and lower wallpaper targets correctly, // and make sure that we are positioning the wallpaper below the lower. - else if (wallpaperTargetIndex > oldI) { + if (wallpaperTargetIndex > oldI) { // The new target is on top of the old one. if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Found target above old target."); mUpperWallpaperTarget = wallpaperTarget; mLowerWallpaperTarget = oldW; + wallpaperTarget = oldW; wallpaperTargetIndex = oldI; } else { @@ -616,6 +613,22 @@ class WallpaperController { mUpperWallpaperTarget = oldW; mLowerWallpaperTarget = wallpaperTarget; } + if (newTargetHidden && !oldTargetHidden) { + if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, + "Old wallpaper still the target."); + // Use the old target if new target is hidden but old target + // is not. If they're both hidden, still use the new target. + mWallpaperTarget = oldW; + } else if (newTargetHidden == oldTargetHidden + && !mService.mOpeningApps.contains(wallpaperTarget.mAppToken) + && (mService.mOpeningApps.contains(oldW.mAppToken) + || mService.mClosingApps.contains(oldW.mAppToken))) { + // If they're both hidden (or both not hidden), prefer the one that's + // currently in opening or closing app list, this allows transition + // selection logic to better determine the wallpaper status of + // opening/closing apps. + mWallpaperTarget = oldW; + } } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 6fdfaa25e14e..f2f85bf184cf 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -191,6 +191,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_DREAM; @@ -5886,7 +5887,8 @@ public class WindowManagerService extends IWindowManager.Stub if (w.isDrawnLw()) { if (w.mAttrs.type == TYPE_BOOT_PROGRESS) { haveBootMsg = true; - } else if (w.mAttrs.type == TYPE_APPLICATION) { + } else if (w.mAttrs.type == TYPE_APPLICATION + || w.mAttrs.type == TYPE_DRAWN_APPLICATION) { haveApp = true; } else if (w.mAttrs.type == TYPE_WALLPAPER) { haveWallpaper = true; @@ -6772,6 +6774,20 @@ public class WindowManagerService extends IWindowManager.Stub rotateSeamlessly = false; break; } + // In what can only be called an unfortunate workaround we require + // seamlessly rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE + // flag. Due to limitations in the client API, there is no way for + // the client to set this flag in a race free fashion. If we seamlessly rotate + // a window which does not have this flag, but then gains it, we will get + // an incorrect visual result (rotated viewfinder). This means if we want to + // support seamlessly rotating windows which could gain this flag, we can't + // rotate windows without it. This limits seamless rotation in N to camera framework + // users, windows without children, and native code. This is unfortunate but + // having the camera work is our primary goal. + if (w.isChildWindow() & w.isVisibleNow() && + !w.mWinAnimator.mSurfaceController.getTransformToDisplayInverse()) { + rotateSeamlessly = false; + } } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index a00ac5d5429b..54f60ef6a8a7 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -87,6 +87,7 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; @@ -1289,7 +1290,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { final boolean isViewVisible = (mAppToken == null || !mAppToken.clientHidden) && (mViewVisibility == View.VISIBLE) && !mWindowRemovalAllowed; return (isOnScreenIgnoringKeyguard() && (!visibleOnly || isViewVisible) - || mWinAnimator.mAttrType == TYPE_BASE_APPLICATION) + || mWinAnimator.mAttrType == TYPE_BASE_APPLICATION + || mWinAnimator.mAttrType == TYPE_DRAWN_APPLICATION) && !mAnimatingExit && !mDestroying; } @@ -1334,7 +1336,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden) || mWinAnimator.mAnimation != null || ((atoken != null) && (atoken.mAppAnimator.animation != null) - && !mWinAnimator.isDummyAnimation())); + && !mWinAnimator.isDummyAnimation()) + || isAnimatingWithSavedSurface()); } /** @@ -2924,12 +2927,13 @@ final class WindowState implements WindowManagerPolicy.WindowState { // for only child windows (as the main window is handled by window preservation) // and the big surface. // - // Though windows of TYPE_APPLICATION (as opposed to TYPE_BASE_APPLICATION) - // are not children in the sense of an attached window, we also want to replace - // them at such phases, as they won't be covered by window preservation, - // and in general we expect them to return following relaunch. + // Though windows of TYPE_APPLICATION or TYPE_DRAWN_APPLICATION (as opposed to + // TYPE_BASE_APPLICATION) are not children in the sense of an attached window, + // we also want to replace them at such phases, as they won't be covered by window + // preservation, and in general we expect them to return following relaunch. boolean shouldBeReplacedWithChildren() { - return isChildWindow() || mAttrs.type == TYPE_APPLICATION; + return isChildWindow() || mAttrs.type == TYPE_APPLICATION + || mAttrs.type == TYPE_DRAWN_APPLICATION; } public int getRotationAnimationHint() { diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index eacf44e197a0..fa5e3cabeb44 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -1097,6 +1097,26 @@ class WindowSurfacePlacer { boolean fullscreenAnim = false; boolean voiceInteraction = false; + int i; + for (i = 0; i < appsCount; i++) { + final AppWindowToken wtoken = mService.mOpeningApps.valueAt(i); + // Clearing the mAnimatingExit flag before entering animation. It's set to + // true if app window is removed, or window relayout to invisible. + // This also affects window visibility. We need to clear it *before* + // maybeUpdateTransitToWallpaper() as the transition selection depends on + // wallpaper target visibility. + wtoken.clearAnimatingFlags(); + + } + // Adjust wallpaper before we pull the lower/upper target, since pending changes + // (like the clearAnimatingFlags() above) might affect wallpaper target result. + final DisplayContent displayContent = mService.getDefaultDisplayContentLocked(); + if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 && + mWallpaperControllerLocked.adjustWallpaperWindows()) { + mService.mLayersController.assignLayersLocked(windows); + displayContent.layoutNeeded = true; + } + final WindowState lowerWallpaperTarget = mWallpaperControllerLocked.getLowerWallpaperTarget(); final WindowState upperWallpaperTarget = @@ -1113,7 +1133,6 @@ class WindowSurfacePlacer { upperWallpaperAppToken = upperWallpaperTarget.mAppToken; } - int i; // Do a first pass through the tokens for two // things: // (1) Determine if both the closing and opening @@ -1138,12 +1157,6 @@ class WindowSurfacePlacer { if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) { openingAppHasWallpaper = true; } - // Clearing the mAnimatingExit flag before entering animation. It's set to - // true if app window is removed, or window relayout to invisible. - // This also affects window visibility. We need to clear it *before* - // maybeUpdateTransitToWallpaper() as the transition selection depends on - // wallpaper target visibility. - wtoken.clearAnimatingFlags(); } voiceInteraction |= wtoken.voiceInteraction; @@ -1206,7 +1219,7 @@ class WindowSurfacePlacer { // This has changed the visibility of windows, so perform // a new layout to get them all up-to-date. - mService.getDefaultDisplayContentLocked().layoutNeeded = true; + displayContent.layoutNeeded = true; // TODO(multidisplay): IMEs are only supported on the default display. if (windows == mService.getDefaultWindowListLocked() diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index e828650a3049..6258340c9422 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -5876,8 +5876,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { updateDeviceOwnerLocked(); disableSecurityLoggingIfNotCompliant(); try { - // Reactivate backup service. - mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true); + if (mInjector.getIBackupManager() != null) { + // Reactivate backup service. + mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true); + } } catch (RemoteException e) { throw new IllegalStateException("Failed reactivating backup service.", e); } diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java index daaa4f5c6848..2038c9e35f0c 100644 --- a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java +++ b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java @@ -136,6 +136,10 @@ class PreloadAppsInstaller { mApkToPackageMap.put(apkName, basePackageName); } installExistingPackage(basePackageName, userId, counter); + } else { + Log.e(TAG, "Package " + basePackageName + " cannot be installed from " + + apkName + ": " + msg + " (returnCode " + returnCode + ")"); + counter.appInstallFinished(); } } }.getBinder(), 0, SYSTEM_SERVER_PACKAGE_NAME, userId); diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java index 7525e87c0e12..6b273210263d 100644 --- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java +++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java @@ -89,8 +89,8 @@ public class RetailDemoModeService extends SystemService { private static final long SCREEN_WAKEUP_DELAY = 2500; private static final long USER_INACTIVITY_TIMEOUT_MIN = 10000; - private static final long USER_INACTIVITY_TIMEOUT_DEFAULT = 30000; - private static final long WARNING_DIALOG_TIMEOUT_DEFAULT = 6000; + private static final long USER_INACTIVITY_TIMEOUT_DEFAULT = 90000; + private static final long WARNING_DIALOG_TIMEOUT_DEFAULT = 0; private static final long MILLIS_PER_SECOND = 1000; private static final int[] VOLUME_STREAMS_TO_MUTE = { diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java index 306b3c15fa11..c4739ff13a19 100644 --- a/telecomm/java/android/telecom/RemoteConnectionService.java +++ b/telecomm/java/android/telecom/RemoteConnectionService.java @@ -224,6 +224,7 @@ final class RemoteConnectionService { conference.setState(parcel.getState()); conference.setConnectionCapabilities(parcel.getConnectionCapabilities()); + conference.setConnectionProperties(parcel.getConnectionProperties()); mConferenceById.put(callId, conference); conference.registerCallback(new RemoteConference.Callback() { @Override diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index a171d9d4c40d..69b9fbfb848a 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -246,6 +246,14 @@ public class CarrierConfigManager { public static final String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool"; /** + * Flag specifying whether the carrier supports downgrading a video call (tx, rx or tx/rx) + * directly to an audio call. + * @hide + */ + public static final String KEY_SUPPORT_DOWNGRADE_VT_TO_AUDIO_BOOL = + "support_downgrade_vt_to_audio_bool"; + + /** * Flag specifying whether WFC over IMS should be available for carrier: independent of * carrier provisioning. If false: hard disabled. If true: then depends on carrier * provisioning, availability etc. @@ -913,6 +921,15 @@ public class CarrierConfigManager { public static final String KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL = "notify_vt_handover_to_wifi_failure_bool"; + /** + * A upper case list of CNAP names that are unhelpful to the user for distinguising calls and + * should be filtered out of the CNAP information. This includes CNAP names such as "WIRELESS + * CALLER" or "UNKNOWN NAME". By default, if there are no filtered names for this carrier, null + * is returned. + * @hide + */ + public static final String FILTERED_CNAP_NAMES_STRING_ARRAY = "filtered_cnap_names_string_array"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -927,6 +944,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CARRIER_SETTINGS_ENABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VOLTE_AVAILABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VT_AVAILABLE_BOOL, false); + sDefaults.putBoolean(KEY_SUPPORT_DOWNGRADE_VT_TO_AUDIO_BOOL, true); sDefaults.putBoolean(KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, false); @@ -1079,6 +1097,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY, null); sDefaults.putBoolean(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL, false); sDefaults.putBoolean(KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, false); + sDefaults.putStringArray(FILTERED_CNAP_NAMES_STRING_ARRAY, null); } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 759ea1d2b8ac..013efe7fb21b 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -716,6 +716,28 @@ public class TelephonyManager { "android.telephony.event.EVENT_HANDOVER_TO_WIFI_FAILED"; /** + * {@link android.telecom.Connection} event used to indicate that a video call was downgraded to + * audio because the data limit was reached. + * <p> + * Sent via {@link android.telecom.Connection#sendConnectionEvent(String, Bundle)}. + * The {@link Bundle} parameter is expected to be null when this connection event is used. + * @hide + */ + public static final String EVENT_DOWNGRADE_DATA_LIMIT_REACHED = + "android.telephony.event.EVENT_DOWNGRADE_DATA_LIMIT_REACHED"; + + /** + * {@link android.telecom.Connection} event used to indicate that a video call was downgraded to + * audio because the data was disabled. + * <p> + * Sent via {@link android.telecom.Connection#sendConnectionEvent(String, Bundle)}. + * The {@link Bundle} parameter is expected to be null when this connection event is used. + * @hide + */ + public static final String EVENT_DOWNGRADE_DATA_DISABLED = + "android.telephony.event.EVENT_DOWNGRADE_DATA_DISABLED"; + + /** * Response codes for sim activation. Activation completed successfully. * @hide */ diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index a7878d196c15..5f91f17b05a3 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -1033,7 +1033,6 @@ static ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle) return NO_ERROR; } - ResXMLTree tree; Asset* asset = assets.openNonAsset(cookie, "AndroidManifest.xml", Asset::ACCESS_STREAMING); if (asset == NULL) { fprintf(stderr, "ERROR: Platform AndroidManifest.xml not found\n"); @@ -1041,11 +1040,17 @@ static ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle) } ssize_t result = NO_ERROR; - if (tree.setTo(asset->getBuffer(true), asset->getLength()) != NO_ERROR) { - fprintf(stderr, "ERROR: Platform AndroidManifest.xml is corrupt\n"); - result = UNKNOWN_ERROR; - } else { - result = extractPlatformBuildVersion(tree, bundle); + + // Create a new scope so that ResXMLTree is destroyed before we delete the memory over + // which it iterates (asset). + { + ResXMLTree tree; + if (tree.setTo(asset->getBuffer(true), asset->getLength()) != NO_ERROR) { + fprintf(stderr, "ERROR: Platform AndroidManifest.xml is corrupt\n"); + result = UNKNOWN_ERROR; + } else { + result = extractPlatformBuildVersion(tree, bundle); + } } delete asset; diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 9d0c20ce4c5d..d3d5ea05c1af 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -817,6 +817,7 @@ public class WifiConfiguration implements Parcelable { */ public static final int NETWORK_SELECTION_ENABLE = 0; /** + * @deprecated it is not used any more. * This network is disabled because higher layer (>2) network is bad */ public static final int DISABLED_BAD_LINK = 1; @@ -862,7 +863,7 @@ public class WifiConfiguration implements Parcelable { */ private static final String[] QUALITY_NETWORK_SELECTION_DISABLE_REASON = { "NETWORK_SELECTION_ENABLE", - "NETWORK_SELECTION_DISABLED_BAD_LINK", + "NETWORK_SELECTION_DISABLED_BAD_LINK", // deprecated "NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ", "NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE", "NETWORK_SELECTION_DISABLED_DHCP_FAILURE", |