Merge "Add additional info to AudioPort for enum/selection API."
diff --git a/api/current.txt b/api/current.txt
index 5b64324..ec07456 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28625,8 +28625,65 @@
package android.telecom {
+ public class PhoneAccount implements android.os.Parcelable {
+ method public static android.telecom.PhoneAccount.Builder builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence);
+ method public android.graphics.drawable.Drawable createIconDrawable(android.content.Context);
+ method public int describeContents();
+ method public android.telecom.PhoneAccountHandle getAccountHandle();
+ method public android.net.Uri getAddress();
+ method public int getCapabilities();
+ method public int getHighlightColor();
+ method public android.graphics.Bitmap getIconBitmap();
+ method public java.lang.String getIconPackageName();
+ method public int getIconResId();
+ method public int getIconTint();
+ method public java.lang.CharSequence getLabel();
+ method public java.lang.CharSequence getShortDescription();
+ method public android.net.Uri getSubscriptionAddress();
+ method public java.util.List<java.lang.String> getSupportedUriSchemes();
+ method public boolean hasCapabilities(int);
+ method public boolean supportsUriScheme(java.lang.String);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10
+ field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
+ field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
+ field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0
+ field public static final int NO_ICON_TINT = 0; // 0x0
+ field public static final int NO_RESOURCE_ID = -1; // 0xffffffff
+ field public static final java.lang.String SCHEME_SIP = "sip";
+ field public static final java.lang.String SCHEME_TEL = "tel";
+ field public static final java.lang.String SCHEME_VOICEMAIL = "voicemail";
+ }
+
+ public static class PhoneAccount.Builder {
+ ctor public PhoneAccount.Builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence);
+ ctor public PhoneAccount.Builder(android.telecom.PhoneAccount);
+ method public android.telecom.PhoneAccount build();
+ method public android.telecom.PhoneAccount.Builder setAddress(android.net.Uri);
+ method public android.telecom.PhoneAccount.Builder setCapabilities(int);
+ method public android.telecom.PhoneAccount.Builder setHighlightColor(int);
+ method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int);
+ method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int);
+ method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int, int);
+ method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int, int);
+ method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.Bitmap);
+ method public android.telecom.PhoneAccount.Builder setShortDescription(java.lang.CharSequence);
+ method public android.telecom.PhoneAccount.Builder setSubscriptionAddress(android.net.Uri);
+ method public android.telecom.PhoneAccount.Builder setSupportedUriSchemes(java.util.List<java.lang.String>);
+ }
+
+ public class PhoneAccountHandle implements android.os.Parcelable {
+ ctor public PhoneAccountHandle(android.content.ComponentName, java.lang.String);
+ method public int describeContents();
+ method public android.content.ComponentName getComponentName();
+ method public java.lang.String getId();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccountHandle> CREATOR;
+ }
+
public class TelecomManager {
method public void cancelMissedCallsNotification();
+ method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
method public boolean handleMmi(java.lang.String);
method public boolean isInCall();
method public void showInCallScreen(boolean);
@@ -28635,7 +28692,10 @@
field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
+ field public static final java.lang.String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
+ field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
+ field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
field public static final int PRESENTATION_ALLOWED = 1; // 0x1
@@ -28644,6 +28704,34 @@
field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
}
+ public class VideoProfile implements android.os.Parcelable {
+ ctor public VideoProfile(int);
+ ctor public VideoProfile(int, int);
+ method public int describeContents();
+ method public int getQuality();
+ method public int getVideoState();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telecom.VideoProfile> CREATOR;
+ field public static final int QUALITY_DEFAULT = 4; // 0x4
+ field public static final int QUALITY_HIGH = 1; // 0x1
+ field public static final int QUALITY_LOW = 3; // 0x3
+ field public static final int QUALITY_MEDIUM = 2; // 0x2
+ }
+
+ public static class VideoProfile.VideoState {
+ ctor public VideoProfile.VideoState();
+ method public static boolean isAudioOnly(int);
+ method public static boolean isBidirectional(int);
+ method public static boolean isPaused(int);
+ method public static boolean isReceptionEnabled(int);
+ method public static boolean isTransmissionEnabled(int);
+ field public static final int AUDIO_ONLY = 0; // 0x0
+ field public static final int BIDIRECTIONAL = 3; // 0x3
+ field public static final int PAUSED = 4; // 0x4
+ field public static final int RX_ENABLED = 2; // 0x2
+ field public static final int TX_ENABLED = 1; // 0x1
+ }
+
}
package android.telephony {
diff --git a/api/system-current.txt b/api/system-current.txt
index c62f3bc..2362608 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -30630,10 +30630,14 @@
method public java.util.List<java.lang.String> getSupportedUriSchemes();
method public boolean hasCapabilities(int);
method public boolean supportsUriScheme(java.lang.String);
+ method public android.telecom.PhoneAccount.Builder toBuilder();
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CAPABILITY_CALL_PROVIDER = 2; // 0x2
field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1
+ field public static final int CAPABILITY_MULTI_USER = 32; // 0x20
field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10
field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
+ field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8
field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0
field public static final int NO_ICON_TINT = 0; // 0x0
@@ -30646,7 +30650,9 @@
public static class PhoneAccount.Builder {
ctor public PhoneAccount.Builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence);
ctor public PhoneAccount.Builder(android.telecom.PhoneAccount);
+ method public android.telecom.PhoneAccount.Builder addSupportedUriScheme(java.lang.String);
method public android.telecom.PhoneAccount build();
+ method public android.telecom.PhoneAccount.Builder setAccountHandle(android.telecom.PhoneAccountHandle);
method public android.telecom.PhoneAccount.Builder setAddress(android.net.Uri);
method public android.telecom.PhoneAccount.Builder setCapabilities(int);
method public android.telecom.PhoneAccount.Builder setHighlightColor(int);
@@ -30662,9 +30668,11 @@
public class PhoneAccountHandle implements android.os.Parcelable {
ctor public PhoneAccountHandle(android.content.ComponentName, java.lang.String);
+ ctor public PhoneAccountHandle(android.content.ComponentName, java.lang.String, android.os.UserHandle);
method public int describeContents();
method public android.content.ComponentName getComponentName();
method public java.lang.String getId();
+ method public android.os.UserHandle getUserHandle();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccountHandle> CREATOR;
}
@@ -30800,6 +30808,7 @@
field public static final java.lang.String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
+ field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
field public static final int PRESENTATION_ALLOWED = 1; // 0x1
@@ -30808,6 +30817,34 @@
field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
}
+ public class VideoProfile implements android.os.Parcelable {
+ ctor public VideoProfile(int);
+ ctor public VideoProfile(int, int);
+ method public int describeContents();
+ method public int getQuality();
+ method public int getVideoState();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telecom.VideoProfile> CREATOR;
+ field public static final int QUALITY_DEFAULT = 4; // 0x4
+ field public static final int QUALITY_HIGH = 1; // 0x1
+ field public static final int QUALITY_LOW = 3; // 0x3
+ field public static final int QUALITY_MEDIUM = 2; // 0x2
+ }
+
+ public static class VideoProfile.VideoState {
+ ctor public VideoProfile.VideoState();
+ method public static boolean isAudioOnly(int);
+ method public static boolean isBidirectional(int);
+ method public static boolean isPaused(int);
+ method public static boolean isReceptionEnabled(int);
+ method public static boolean isTransmissionEnabled(int);
+ field public static final int AUDIO_ONLY = 0; // 0x0
+ field public static final int BIDIRECTIONAL = 3; // 0x3
+ field public static final int PAUSED = 4; // 0x4
+ field public static final int RX_ENABLED = 2; // 0x2
+ field public static final int TX_ENABLED = 1; // 0x1
+ }
+
}
package android.telephony {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index b76e8c0..04777ba 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2760,9 +2760,17 @@
}
}
+ addSharedLibrariesForBackwardCompatibility(owner);
+
return true;
}
+ private static void addSharedLibrariesForBackwardCompatibility(Package owner) {
+ if (owner.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
+ owner.usesLibraries = ArrayUtils.add(owner.usesLibraries, "org.apache.http.legacy");
+ }
+ }
+
/**
* Parse the {@code application} XML tree at the current parse location in a
* <em>split APK</em> manifest.
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 16bc6a4..bb45b91 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -391,10 +391,12 @@
* {@link CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION android.control.aeExposureCompensation}, in counts of {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP android.control.aeCompensationStep},
* that are supported by this camera device.</p>
* <p><b>Range of valid values:</b><br></p>
+ * <p>Range [0,0] indicates that exposure compensation is not supported.</p>
+ * <p>For LIMITED and FULL devices, range must follow below requirements if exposure
+ * compensation is supported (<code>range != [0, 0]</code>):</p>
* <p><code>Min.exposure compensation * {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP android.control.aeCompensationStep} <= -2 EV</code></p>
* <p><code>Max.exposure compensation * {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP android.control.aeCompensationStep} >= 2 EV</code></p>
- * <p>LEGACY devices may support a smaller range than this, including the range [0,0], which
- * indicates that changing the exposure compensation is not supported.</p>
+ * <p>LEGACY devices may support a smaller range than this.</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index ac32430..a5225cb 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -16,24 +16,25 @@
package android.view;
-import android.annotation.Nullable;
-import android.graphics.Canvas;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Trace;
-import android.util.TypedValue;
-import android.widget.FrameLayout;
+import com.android.internal.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.graphics.Canvas;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Trace;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.TypedValue;
import android.util.Xml;
+import android.widget.FrameLayout;
import java.io.IOException;
import java.lang.reflect.Constructor;
@@ -925,6 +926,14 @@
inheritContext);
final ViewGroup group = (ViewGroup) parent;
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.Include);
+ final int id = a.getResourceId(R.styleable.Include_id, View.NO_ID);
+ final int visibility = a.getInt(R.styleable.Include_visibility, -1);
+ final boolean hasWidth = a.hasValue(R.styleable.Include_layout_width);
+ final boolean hasHeight = a.hasValue(R.styleable.Include_layout_height);
+ a.recycle();
+
// We try to load the layout params set in the <include /> tag. If
// they don't exist, we will rely on the layout params set in the
// included XML file.
@@ -934,27 +943,21 @@
// successfully loaded layout params from the <include /> tag,
// false means we need to rely on the included layout params.
ViewGroup.LayoutParams params = null;
- try {
- params = group.generateLayoutParams(attrs);
- } catch (RuntimeException e) {
- params = group.generateLayoutParams(childAttrs);
- } finally {
- if (params != null) {
- view.setLayoutParams(params);
+ if (hasWidth && hasHeight) {
+ try {
+ params = group.generateLayoutParams(attrs);
+ } catch (RuntimeException e) {
+ // Ignore, just fail over to child attrs.
}
}
+ if (params == null) {
+ params = group.generateLayoutParams(childAttrs);
+ }
+ view.setLayoutParams(params);
// Inflate all children.
rInflate(childParser, view, childAttrs, true, true);
- final TypedArray a = context.obtainStyledAttributes(
- attrs, com.android.internal.R.styleable.Include);
- final int id = a.getResourceId(
- com.android.internal.R.styleable.Include_id, View.NO_ID);
- final int visibility = a.getInt(
- com.android.internal.R.styleable.Include_visibility, -1);
- a.recycle();
-
if (id != View.NO_ID) {
view.setId(id);
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 3f2f3a5..8704356 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -102,10 +102,12 @@
*/
public static final int FEATURE_SWIPE_TO_DISMISS = 11;
/**
- * Flag for requesting that window content changes should be represented
- * with scenes and transitions.
+ * Flag for requesting that window content changes should be animated using a
+ * TransitionManager.
*
- * TODO Add docs
+ * <p>The TransitionManager is set using
+ * {@link #setTransitionManager(android.transition.TransitionManager)}. If none is set,
+ * a default TransitionManager will be used.</p>
*
* @see #setContentView
*/
@@ -1019,10 +1021,16 @@
* <p>Note that calling this function "locks in" various characteristics
* of the window that can not, from this point forward, be changed: the
* features that have been requested with {@link #requestFeature(int)},
- * and certain window flags as described in {@link #setFlags(int, int)}.
+ * and certain window flags as described in {@link #setFlags(int, int)}.</p>
+ *
+ * <p>If {@link #FEATURE_CONTENT_TRANSITIONS} is set, the window's
+ * TransitionManager will be used to animate content from the current
+ * content View to view.</p>
*
* @param view The desired content to display.
* @param params Layout parameters for the view.
+ * @see #getTransitionManager()
+ * @see #setTransitionManager(android.transition.TransitionManager)
*/
public abstract void setContentView(View view, ViewGroup.LayoutParams params);
@@ -1467,6 +1475,7 @@
* {@link #setContentView}) if {@link #FEATURE_CONTENT_TRANSITIONS} has been granted.</p>
*
* @return This window's content TransitionManager or null if none is set.
+ * @attr ref android.R.styleable#Window_windowContentTransitionManager
*/
public TransitionManager getTransitionManager() {
return null;
@@ -1477,6 +1486,7 @@
* Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
*
* @param tm The TransitionManager to use for scene changes.
+ * @attr ref android.R.styleable#Window_windowContentTransitionManager
*/
public void setTransitionManager(TransitionManager tm) {
throw new UnsupportedOperationException();
diff --git a/core/res/res/drawable-mdpi/ic_clear_mtrl_alpha.png b/core/res/res/drawable-mdpi/ic_clear_mtrl_alpha.png
deleted file mode 100644
index d43e4d1..0000000
--- a/core/res/res/drawable-mdpi/ic_clear_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_clear_mtrl_alpha.png b/core/res/res/drawable-xhdpi/ic_clear_mtrl_alpha.png
deleted file mode 100644
index ddacb59..0000000
--- a/core/res/res/drawable-xhdpi/ic_clear_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_clear_mtrl_alpha.png b/core/res/res/drawable-xxhdpi/ic_clear_mtrl_alpha.png
deleted file mode 100644
index 21ed9144..0000000
--- a/core/res/res/drawable-xxhdpi/ic_clear_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_clear_material.xml b/core/res/res/drawable/ic_clear_material.xml
index 076c0a2..a21f47a 100644
--- a/core/res/res/drawable/ic_clear_material.xml
+++ b/core/res/res/drawable/ic_clear_material.xml
@@ -14,6 +14,13 @@
limitations under the License.
-->
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_clear_mtrl_alpha"
- android:tint="?attr/colorControlNormal" />
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?attr/colorControlNormal">
+<path
+ android:pathData="M19,6.41L17.59,5,12,10.59,6.41,5,5,6.41,10.59,12,5,17.59,6.41,19,12,13.41,17.59,19,19,17.59,13.41,12z"
+ android:fillColor="@color/white"/>
+</vector>
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_material.xml b/core/res/res/drawable/scrubber_progress_horizontal_material.xml
index f2ea30f..89a1787 100644
--- a/core/res/res/drawable/scrubber_progress_horizontal_material.xml
+++ b/core/res/res/drawable/scrubber_progress_horizontal_material.xml
@@ -14,29 +14,35 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false">
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@id/background">
<nine-patch android:src="@drawable/scrubber_track_mtrl_alpha"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item>
- <layer-list>
- <item android:id="@id/background">
- <nine-patch android:src="@drawable/scrubber_track_mtrl_alpha"
android:tint="?attr/colorControlNormal" />
- </item>
- <item android:id="@id/secondaryProgress">
- <scale android:scaleWidth="100%">
- <nine-patch android:src="@drawable/scrubber_primary_mtrl_alpha"
- android:tint="?attr/colorControlNormal" />
- </scale>
- </item>
- <item android:id="@id/progress">
- <scale android:scaleWidth="100%">
- <nine-patch android:src="@drawable/scrubber_primary_mtrl_alpha"
- android:tint="?attr/colorControlActivated" />
- </scale>
- </item>
- </layer-list>
</item>
-</selector>
+ <item android:id="@id/secondaryProgress">
+ <scale android:scaleWidth="100%">
+ <selector>
+ <item android:state_enabled="false">
+ <color android:color="@color/transparent" />
+ </item>
+ <item>
+ <nine-patch android:src="@drawable/scrubber_primary_mtrl_alpha"
+ android:tint="?attr/colorControlNormal" />
+ </item>
+ </selector>
+ </scale>
+ </item>
+ <item android:id="@id/progress">
+ <scale android:scaleWidth="100%">
+ <selector>
+ <item android:state_enabled="false">
+ <color android:color="@color/transparent" />
+ </item>
+ <item>
+ <nine-patch android:src="@drawable/scrubber_primary_mtrl_alpha"
+ android:tint="?attr/colorControlActivated" />
+ </item>
+ </selector>
+ </scale>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 3a15b9d..ceb7b63 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2641,6 +2641,8 @@
<declare-styleable name="Include">
<attr name="id" />
<attr name="visibility" />
+ <attr name="layout_width" />
+ <attr name="layout_height" />
</declare-styleable>
<!-- Attributes that can be used with a {@link android.view.ViewGroup} or any
diff --git a/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java b/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java
new file mode 100644
index 0000000..59f780f
--- /dev/null
+++ b/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
+import android.os.Parcel;
+
+import java.net.InetAddress;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import static org.junit.Assert.*;
+
+
+public class StaticIpConfigurationTest extends TestCase {
+
+ private static final String ADDRSTR = "192.0.2.2/25";
+ private static final LinkAddress ADDR = new LinkAddress(ADDRSTR);
+ private static final InetAddress GATEWAY = IpAddress("192.0.2.1");
+ private static final InetAddress OFFLINKGATEWAY = IpAddress("192.0.2.129");
+ private static final InetAddress DNS1 = IpAddress("8.8.8.8");
+ private static final InetAddress DNS2 = IpAddress("8.8.4.4");
+ private static final InetAddress DNS3 = IpAddress("4.2.2.2");
+ private static final String IFACE = "eth0";
+
+ private static InetAddress IpAddress(String addr) {
+ return InetAddress.parseNumericAddress(addr);
+ }
+
+ private void checkEmpty(StaticIpConfiguration s) {
+ assertNull(s.ipAddress);
+ assertNull(s.gateway);
+ assertNull(s.domains);
+ assertEquals(0, s.dnsServers.size());
+ }
+
+ private boolean isEqual(StaticIpConfiguration s1, StaticIpConfiguration s2) {
+ return s1.equals(s2);
+ }
+
+ private void assertEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) {
+ assertTrue(isEqual(s1, s2));
+ }
+
+ private void assertNotEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) {
+ assertFalse(isEqual(s1, s2));
+ }
+
+ private StaticIpConfiguration makeTestObject() {
+ StaticIpConfiguration s = new StaticIpConfiguration();
+ s.ipAddress = ADDR;
+ s.gateway = GATEWAY;
+ s.dnsServers.add(DNS1);
+ s.dnsServers.add(DNS2);
+ s.dnsServers.add(DNS3);
+ s.domains = "google.com";
+ return s;
+ }
+
+ @SmallTest
+ public void testConstructor() {
+ StaticIpConfiguration s = new StaticIpConfiguration();
+ checkEmpty(s);
+ }
+
+ @SmallTest
+ public void testCopyAndClear() {
+ StaticIpConfiguration empty = new StaticIpConfiguration((StaticIpConfiguration) null);
+ checkEmpty(empty);
+
+ StaticIpConfiguration s1 = makeTestObject();
+ StaticIpConfiguration s2 = new StaticIpConfiguration(s1);
+ assertEquals(s1, s2);
+ s2.clear();
+ assertEquals(empty, s2);
+ }
+
+ @SmallTest
+ public void testHashCodeAndEquals() {
+ HashSet<Integer> hashCodes = new HashSet();
+ hashCodes.add(0);
+
+ StaticIpConfiguration s = new StaticIpConfiguration();
+ // Check that this hash code is nonzero and different from all the ones seen so far.
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.ipAddress = ADDR;
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.gateway = GATEWAY;
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.dnsServers.add(DNS1);
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.dnsServers.add(DNS2);
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.dnsServers.add(DNS3);
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.domains = "example.com";
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ assertFalse(s.equals(null));
+ assertEquals(s, s);
+
+ StaticIpConfiguration s2 = new StaticIpConfiguration(s);
+ assertEquals(s, s2);
+
+ s.ipAddress = new LinkAddress(DNS1, 32);
+ assertNotEquals(s, s2);
+
+ s2 = new StaticIpConfiguration(s);
+ s.domains = "foo";
+ assertNotEquals(s, s2);
+
+ s2 = new StaticIpConfiguration(s);
+ s.gateway = DNS2;
+ assertNotEquals(s, s2);
+
+ s2 = new StaticIpConfiguration(s);
+ s.dnsServers.add(DNS3);
+ assertNotEquals(s, s2);
+ }
+
+ @SmallTest
+ public void testToLinkProperties() {
+ LinkProperties expected = new LinkProperties();
+ expected.setInterfaceName(IFACE);
+
+ StaticIpConfiguration s = new StaticIpConfiguration();
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ final RouteInfo connectedRoute = new RouteInfo(new IpPrefix(ADDRSTR), null, IFACE);
+ s.ipAddress = ADDR;
+ expected.addLinkAddress(ADDR);
+ expected.addRoute(connectedRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.gateway = GATEWAY;
+ RouteInfo defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), GATEWAY, IFACE);
+ expected.addRoute(defaultRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.gateway = OFFLINKGATEWAY;
+ expected.removeRoute(defaultRoute);
+ defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), OFFLINKGATEWAY, IFACE);
+ expected.addRoute(defaultRoute);
+
+ RouteInfo gatewayRoute = new RouteInfo(new IpPrefix("192.0.2.129/32"), null, IFACE);
+ expected.addRoute(gatewayRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.dnsServers.add(DNS1);
+ expected.addDnsServer(DNS1);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.dnsServers.add(DNS2);
+ s.dnsServers.add(DNS3);
+ expected.addDnsServer(DNS2);
+ expected.addDnsServer(DNS3);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.domains = "google.com";
+ expected.setDomains("google.com");
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.gateway = null;
+ expected.removeRoute(defaultRoute);
+ expected.removeRoute(gatewayRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ // Without knowing the IP address, we don't have a directly-connected route, so we can't
+ // tell if the gateway is off-link or not and we don't add a host route. This isn't a real
+ // configuration, but we should at least not crash.
+ s.gateway = OFFLINKGATEWAY;
+ s.ipAddress = null;
+ expected.removeLinkAddress(ADDR);
+ expected.removeRoute(connectedRoute);
+ expected.addRoute(defaultRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+ }
+
+ private StaticIpConfiguration passThroughParcel(StaticIpConfiguration s) {
+ Parcel p = Parcel.obtain();
+ StaticIpConfiguration s2 = null;
+ try {
+ s.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ s2 = StaticIpConfiguration.CREATOR.createFromParcel(p);
+ } finally {
+ p.recycle();
+ }
+ assertNotNull(s2);
+ return s2;
+ }
+
+ @SmallTest
+ public void testParceling() {
+ StaticIpConfiguration s = makeTestObject();
+ StaticIpConfiguration s2 = passThroughParcel(s);
+ assertEquals(s, s2);
+ }
+}
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
index 0002ba7..7bf5f65 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
@@ -33,7 +33,8 @@
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
-D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-ifeq ($(LOCAL_USE_JACK),true)
+
+ifdef LOCAL_USE_JACK
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
endif
@@ -41,10 +42,11 @@
include $(BUILD_PACKAGE)
+ifndef LOCAL_USE_JACK
$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
$(hide) mkdir -p $(dir $@)
$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
echo "com/android/multidexlegacyandexception/Test.class" >> $@
$(built_dex_intermediate): $(mainDexList)
-
+endif
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
index c9dbb57..416c238 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
@@ -33,7 +33,7 @@
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
-D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-ifeq ($(LOCAL_USE_JACK),true)
+ifdef LOCAL_USE_JACK
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
endif
@@ -41,12 +41,14 @@
include $(BUILD_PACKAGE)
+ifndef LOCAL_USE_JACK
$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
$(hide) mkdir -p $(dir $@)
$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
echo "com/android/multidexlegacytestapp/Test.class" >> $@
$(built_dex_intermediate): $(mainDexList)
+endif
## The application with a full main dex
include $(CLEAR_VARS)
@@ -67,7 +69,7 @@
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList2)
LOCAL_JACK_FLAGS := -D jack.dex.output.policy=multidex -D jack.preprocessor=true\
-D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-ifeq ($(LOCAL_USE_JACK),true)
+ifdef LOCAL_USE_JACK
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
endif
@@ -75,9 +77,11 @@
include $(BUILD_PACKAGE)
+ifndef LOCAL_USE_JACK
$(mainDexList2): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
$(hide) mkdir -p $(dir $@)
$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
echo "com/android/multidexlegacytestapp/Test.class" >> $@
$(built_dex_intermediate): $(mainDexList2)
+endif
\ No newline at end of file
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestServices/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyTestServices/Android.mk
index 16e396b..83ead4b 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestServices/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestServices/Android.mk
@@ -36,9 +36,10 @@
include $(BUILD_PACKAGE)
+ifndef LOCAL_USE_JACK
$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
$(hide) mkdir -p $(dir $@)
$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
$(built_dex_intermediate): $(mainDexList)
-
+endif
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
index c62238b..d706ca9 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
@@ -32,7 +32,8 @@
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
-D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-ifeq ($(LOCAL_USE_JACK),true)
+
+ifdef LOCAL_USE_JACK
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
endif
@@ -40,9 +41,11 @@
include $(BUILD_PACKAGE)
+ifndef LOCAL_USE_JACK
$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
$(hide) mkdir -p $(dir $@)
$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
$(built_dex_intermediate): $(mainDexList)
+endif
\ No newline at end of file
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
index 8c0c5d5..99b2a8b 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
@@ -32,7 +32,8 @@
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
-D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-ifeq ($(LOCAL_USE_JACK),true)
+
+ifdef LOCAL_USE_JACK
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
endif
@@ -40,9 +41,11 @@
include $(BUILD_PACKAGE)
+ifndef LOCAL_USE_JACK
$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
$(hide) mkdir -p $(dir $@)
$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
$(built_dex_intermediate): $(mainDexList)
+endif
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
index 002c1cc..3ee1c22 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
@@ -32,7 +32,8 @@
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
-D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
-ifeq ($(LOCAL_USE_JACK),true)
+
+ifdef LOCAL_USE_JACK
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
endif
@@ -40,10 +41,12 @@
include $(BUILD_PACKAGE)
+ifndef LOCAL_USE_JACK
$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
$(hide) mkdir -p $(dir $@)
$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
$(built_dex_intermediate): $(mainDexList)
+endif
diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk
index a05217f..e05dd55 100644
--- a/libs/hwui/Android.common.mk
+++ b/libs/hwui/Android.common.mk
@@ -34,9 +34,9 @@
CanvasState.cpp \
ClipArea.cpp \
DamageAccumulator.cpp \
- DisplayList.cpp \
DeferredDisplayList.cpp \
DeferredLayerUpdater.cpp \
+ DisplayList.cpp \
DisplayListRenderer.cpp \
Dither.cpp \
DrawProfiler.cpp \
@@ -44,6 +44,7 @@
FboCache.cpp \
FontRenderer.cpp \
GammaFontRenderer.cpp \
+ GlopBuilder.cpp \
GradientCache.cpp \
Image.cpp \
Interpolator.cpp \
@@ -70,9 +71,9 @@
Snapshot.cpp \
SpotShadow.cpp \
TessellationCache.cpp \
+ TextDropShadowCache.cpp \
Texture.cpp \
- TextureCache.cpp \
- TextDropShadowCache.cpp
+ TextureCache.cpp
intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 03b8283..af1b1cd 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -199,7 +199,7 @@
fboCache.clear();
programCache.clear();
- setProgram(nullptr);
+ mProgram = nullptr;
patchCache.clear();
diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h
index 730d9df..bbeb19e 100644
--- a/libs/hwui/Glop.h
+++ b/libs/hwui/Glop.h
@@ -23,10 +23,13 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#include <SkXfermode.h>
namespace android {
namespace uirenderer {
+class Program;
+
/*
* Enumerates optional vertex attributes
*
@@ -53,18 +56,16 @@
Rect bounds;
struct Mesh {
- VertexAttribFlags vertexFlags = static_cast<VertexAttribFlags>(0);
+ VertexAttribFlags vertexFlags;
GLuint primitiveMode; // GL_TRIANGLES and GL_TRIANGLE_STRIP supported
- GLuint vertexBufferObject = 0;
- GLuint indexBufferObject = 0;
+ GLuint vertexBufferObject;
+ GLuint indexBufferObject;
int vertexCount;
GLsizei stride;
} mesh;
struct Fill {
Program* program;
- GLuint shaderId;
- GLuint textureId;
struct Color {
float a, r, g, b;
@@ -89,10 +90,8 @@
} transform;
struct Blend {
- static const SkXfermode::Mode kDisable =
- static_cast<SkXfermode::Mode>(SkXfermode::kLastMode + 1);
- SkXfermode::Mode mode;
- bool swapSrcDst;
+ GLenum src;
+ GLenum dst;
} blend;
/**
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
new file mode 100644
index 0000000..dafe087
--- /dev/null
+++ b/libs/hwui/GlopBuilder.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+#include "GlopBuilder.h"
+
+#include "Caches.h"
+#include "Glop.h"
+#include "Matrix.h"
+#include "Texture.h"
+#include "renderstate/MeshState.h"
+#include "renderstate/RenderState.h"
+#include "utils/PaintUtils.h"
+
+#include <GLES2/gl2.h>
+#include <SkPaint.h>
+
+namespace android {
+namespace uirenderer {
+
+GlopBuilder::GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop)
+ : mRenderState(renderState)
+ , mCaches(caches)
+ , mOutGlop(outGlop){
+}
+
+GlopBuilder& GlopBuilder::setMeshUnitQuad() {
+ mOutGlop->mesh.vertexFlags = static_cast<VertexAttribFlags>(0);
+ mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
+ mOutGlop->mesh.vertexBufferObject = mRenderState.meshState().getUnitQuadVBO();
+ mOutGlop->mesh.indexBufferObject = 0;
+ mOutGlop->mesh.vertexCount = 4;
+ mOutGlop->mesh.stride = kTextureVertexStride;
+ return *this;
+}
+
+GlopBuilder& GlopBuilder::setTransformAndRect(ModelViewMode mode,
+ const Matrix4& ortho, const Matrix4& transform,
+ float left, float top, float right, float bottom, bool offset) {
+ mOutGlop->transform.ortho.load(ortho);
+
+ mOutGlop->transform.modelView.loadTranslate(left, top, 0.0f);
+ if (mode == kModelViewMode_TranslateAndScale) {
+ mOutGlop->transform.modelView.scale(right - left, bottom - top, 1.0f);
+ }
+
+ mOutGlop->transform.canvas.load(transform);
+
+ mOutGlop->transform.offset = offset;
+
+ mOutGlop->bounds.set(left, top, right, bottom);
+ mOutGlop->transform.canvas.mapRect(mOutGlop->bounds);
+ return *this;
+}
+
+GlopBuilder& GlopBuilder::setPaint(const SkPaint* paint, float alphaScale) {
+ // TODO: support null paint
+ const SkShader* shader = paint->getShader();
+ const SkColorFilter* colorFilter = paint->getColorFilter();
+
+ SkXfermode::Mode mode = PaintUtils::getXfermode(paint->getXfermode());
+ if (mode != SkXfermode::kClear_Mode) {
+ int color = paint->getColor();
+ float alpha = (SkColorGetA(color) / 255.0f) * alphaScale;
+ if (shader) {
+ // shader discards color channels
+ color |= 0x00FFFFFF;
+ }
+ mOutGlop->fill.color = {
+ alpha,
+ alpha * SkColorGetR(color),
+ alpha * SkColorGetG(color),
+ alpha * SkColorGetB(color)
+ };
+ } else {
+ mOutGlop->fill.color = { 1, 0, 0, 0 };
+ }
+ const bool SWAP_SRC_DST = false;
+ const bool HAS_FRAMEBUFFER_FETCH = false; //mExtensions.hasFramebufferFetch();
+
+ mOutGlop->blend = {GL_ZERO, GL_ZERO};
+ if (mOutGlop->fill.color.a < 1.0f
+ || (shader && !shader->isOpaque())
+ || PaintUtils::isBlendedColorFilter(colorFilter)
+ || mode != SkXfermode::kSrcOver_Mode) {
+ if (CC_LIKELY(mode <= SkXfermode::kScreen_Mode)) {
+ Blend::getFactors(mode, SWAP_SRC_DST,
+ &mOutGlop->blend.src, &mOutGlop->blend.dst);
+ } else {
+ // These blend modes are not supported by OpenGL directly and have
+ // to be implemented using shaders. Since the shader will perform
+ // the blending, don't enable GL blending off here
+ // If the blend mode cannot be implemented using shaders, fall
+ // back to the default SrcOver blend mode instead
+ if (CC_UNLIKELY(HAS_FRAMEBUFFER_FETCH)) {
+ mDescription.framebufferMode = mode;
+ mDescription.swapSrcDst = SWAP_SRC_DST;
+ // blending in shader, don't enable
+ } else {
+ // unsupported
+ Blend::getFactors(SkXfermode::kSrcOver_Mode, SWAP_SRC_DST,
+ &mOutGlop->blend.src, &mOutGlop->blend.dst);
+ }
+ }
+ }
+
+ return *this;
+}
+
+GlopBuilder& GlopBuilder::setTexture(Texture* texture) {
+ LOG_ALWAYS_FATAL("not yet supported");
+ return *this;
+}
+
+void GlopBuilder::build() {
+ mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
+ mOutGlop->fill.program = mCaches.programCache.get(mDescription);
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
+
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
new file mode 100644
index 0000000..d243d76
--- /dev/null
+++ b/libs/hwui/GlopBuilder.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+#ifndef RENDERSTATE_GLOPBUILDER_H
+#define RENDERSTATE_GLOPBUILDER_H
+
+#include "OpenGLRenderer.h"
+#include "Program.h"
+#include "utils/Macros.h"
+
+class SkPaint;
+
+namespace android {
+namespace uirenderer {
+
+class Caches;
+struct Glop;
+class RenderState;
+class Texture;
+class Matrix4;
+
+class GlopBuilder {
+ PREVENT_COPY_AND_ASSIGN(GlopBuilder);
+public:
+ GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop);
+ GlopBuilder& setMeshUnitQuad();
+ GlopBuilder& setTransformAndRect(ModelViewMode mode,
+ const Matrix4& ortho, const Matrix4& transform,
+ float left, float top, float right, float bottom, bool offset);
+ GlopBuilder& setPaint(const SkPaint* paint, float alphaScale);
+ GlopBuilder& setTexture(Texture* texture);
+ void build();
+private:
+ ProgramDescription mDescription;
+ RenderState& mRenderState;
+ Caches& mCaches;
+ Glop* mOutGlop;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif // RENDERSTATE_GLOPBUILDER_H
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index b56ce4f..f4b12b6 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -19,10 +19,13 @@
#include "DeferredDisplayList.h"
#include "DisplayListRenderer.h"
#include "GammaFontRenderer.h"
+#include "Glop.h"
+#include "GlopBuilder.h"
#include "Patch.h"
#include "PathTessellator.h"
#include "Properties.h"
#include "RenderNode.h"
+#include "renderstate/MeshState.h"
#include "renderstate/RenderState.h"
#include "ShadowTessellator.h"
#include "SkiaShader.h"
@@ -100,7 +103,7 @@
memset(&mDrawModifiers, 0, sizeof(mDrawModifiers));
mDrawModifiers.mOverrideLayerAlpha = 1.0f;
- memcpy(mMeshVertices, kMeshVertices, sizeof(kMeshVertices));
+ memcpy(mMeshVertices, kUnitQuadVertices, sizeof(kUnitQuadVertices));
}
OpenGLRenderer::~OpenGLRenderer() {
@@ -1703,9 +1706,9 @@
// When the blending mode is kClear_Mode, we need to use a modulate color
// argb=1,0,0,0
accountForClear(mode);
- blend |= (mColorSet && mColorA < 1.0f) ||
- (getShader(paint) && !getShader(paint)->isOpaque()) ||
- PaintUtils::isBlendedColorFilter(getColorFilter(paint));
+ blend |= (mColorSet && mColorA < 1.0f)
+ || (getShader(paint) && !getShader(paint)->isOpaque())
+ || PaintUtils::isBlendedColorFilter(getColorFilter(paint));
chooseBlending(blend, mode, mDescription, swapSrcDst);
}
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index d6eff85..e2caf8b 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -492,7 +492,9 @@
if (mProcessor == nullptr) {
mProcessor = new PathProcessor(Caches::getInstance());
}
- mProcessor->add(task);
+ if (!mProcessor->add(task)) {
+ mProcessor->process(task);
+ }
}
}
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index a0a5a1c..659ef6c 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -836,7 +836,6 @@
*/
template <class T>
void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
- const int level = handler.level();
if (mDisplayListData->isEmpty()) {
DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, getName());
return;
@@ -860,7 +859,7 @@
#if DEBUG_DISPLAY_LIST
const Rect& clipRect = renderer.getLocalClipBounds();
DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), localClipBounds: %.0f, %.0f, %.0f, %.0f",
- level * 2, "", this, getName(),
+ handler.level() * 2, "", this, getName(),
clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
#endif
@@ -900,7 +899,7 @@
for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) {
DisplayListOp *op = mDisplayListData->displayListOps[opIndex];
#if DEBUG_DISPLAY_LIST
- op->output(level + 1);
+ op->output(handler.level() + 1);
#endif
handler(op, saveCountOffset, properties().getClipToBounds());
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index c6483ac..4333792 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -81,7 +81,7 @@
uint32_t mPixelRefStableID;
friend class ResourceCache;
- friend class android::key_value_pair_t<BitmapKey, SkBitmap*>;
+ friend struct android::key_value_pair_t<BitmapKey, SkBitmap*>;
};
class ANDROID_API ResourceCache: public Singleton<ResourceCache> {
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 49fb4ba..597d95c 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -203,8 +203,8 @@
ALOGD("Snapshot %p, flags %x, prev %p, height %d, ignored %d, hasComplexClip %d",
this, flags, previous.get(), getViewportHeight(), isIgnored(), !mClipArea->isSimple());
const Rect& clipRect(mClipArea->getClipRect());
- ALOGD(" ClipRect (at %p) %.1f %.1f %.1f %.1f",
- clipRect, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
+ ALOGD(" ClipRect %.1f %.1f %.1f %.1f",
+ clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
ALOGD(" Transform (at %p):", transform);
transform->dump();
}
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 4f028d5..66de333 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -385,7 +385,9 @@
if (mShadowProcessor == nullptr) {
mShadowProcessor = new ShadowProcessor(Caches::getInstance());
}
- mShadowProcessor->add(task);
+ if (!mShadowProcessor->add(task)) {
+ mShadowProcessor->process(task);
+ }
task->incStrong(nullptr); // not using sp<>s, so manually ref while in the cache
mShadowCache.put(key, task.get());
@@ -421,7 +423,9 @@
if (mProcessor == nullptr) {
mProcessor = new TessellationProcessor(Caches::getInstance());
}
- mProcessor->add(task);
+ if (!mProcessor->add(task)) {
+ mProcessor->process(task);
+ }
mCache.put(entry, buffer);
}
return buffer;
diff --git a/libs/hwui/renderstate/Blend.cpp b/libs/hwui/renderstate/Blend.cpp
index 3e7b721..93088e4 100644
--- a/libs/hwui/renderstate/Blend.cpp
+++ b/libs/hwui/renderstate/Blend.cpp
@@ -79,21 +79,10 @@
}
void Blend::enable(SkXfermode::Mode mode, bool swapSrcDst) {
- // enable
- if (!mEnabled) {
- glEnable(GL_BLEND);
- mEnabled = true;
- }
-
- // select blend mode
- GLenum sourceMode = swapSrcDst ? kBlendsSwap[mode].src : kBlends[mode].src;
- GLenum destMode = swapSrcDst ? kBlendsSwap[mode].dst : kBlends[mode].dst;
-
- if (sourceMode != mSrcMode || destMode != mSrcMode) {
- glBlendFunc(sourceMode, destMode);
- mSrcMode = sourceMode;
- mDstMode = destMode;
- }
+ GLenum srcMode;
+ GLenum dstMode;
+ getFactors(mode, swapSrcDst, &srcMode, &dstMode);
+ setFactors(srcMode, dstMode);
}
void Blend::disable() {
@@ -116,6 +105,28 @@
}
}
+void Blend::getFactors(SkXfermode::Mode mode, bool swapSrcDst, GLenum* outSrc, GLenum* outDst) {
+ *outSrc = swapSrcDst ? kBlendsSwap[mode].src : kBlends[mode].src;
+ *outDst = swapSrcDst ? kBlendsSwap[mode].dst : kBlends[mode].dst;
+}
+
+void Blend::setFactors(GLenum srcMode, GLenum dstMode) {
+ if (srcMode == GL_ZERO && dstMode == GL_ZERO) {
+ disable();
+ } else {
+ if (!mEnabled) {
+ glEnable(GL_BLEND);
+ mEnabled = true;
+ }
+
+ if (srcMode != mSrcMode || dstMode != mSrcMode) {
+ glBlendFunc(srcMode, dstMode);
+ mSrcMode = srcMode;
+ mDstMode = dstMode;
+ }
+ }
+}
+
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderstate/Blend.h b/libs/hwui/renderstate/Blend.h
index b82b477..31d7dde 100644
--- a/libs/hwui/renderstate/Blend.h
+++ b/libs/hwui/renderstate/Blend.h
@@ -32,6 +32,9 @@
void enable(SkXfermode::Mode mode, bool swapSrcDst);
void disable();
void syncEnabled();
+
+ static void getFactors(SkXfermode::Mode mode, bool swapSrcDst, GLenum* outSrc, GLenum* outDst);
+ void setFactors(GLenum src, GLenum dst);
private:
Blend();
void invalidate();
diff --git a/libs/hwui/renderstate/MeshState.cpp b/libs/hwui/renderstate/MeshState.cpp
index 022faf7d..50c09c8 100644
--- a/libs/hwui/renderstate/MeshState.cpp
+++ b/libs/hwui/renderstate/MeshState.cpp
@@ -29,11 +29,11 @@
, mCurrentTexCoordsStride(0)
, mTexCoordsArrayEnabled(false) {
- glGenBuffers(1, &meshBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
- glBufferData(GL_ARRAY_BUFFER, sizeof(kMeshVertices), kMeshVertices, GL_STATIC_DRAW);
+ glGenBuffers(1, &mUnitQuadBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW);
- mCurrentBuffer = meshBuffer;
+ mCurrentBuffer = mUnitQuadBuffer;
mCurrentIndicesBuffer = 0;
mCurrentPixelBuffer = 0;
@@ -45,7 +45,7 @@
}
MeshState::~MeshState() {
- glDeleteBuffers(1, &meshBuffer);
+ glDeleteBuffers(1, &mUnitQuadBuffer);
mCurrentBuffer = 0;
glDeleteBuffers(1, &mQuadListIndices);
@@ -60,11 +60,11 @@
///////////////////////////////////////////////////////////////////////////////
bool MeshState::bindMeshBuffer() {
- return bindMeshBuffer(meshBuffer);
+ return bindMeshBuffer(mUnitQuadBuffer);
}
bool MeshState::bindMeshBuffer(GLuint buffer) {
- if (!buffer) buffer = meshBuffer;
+ if (!buffer) buffer = mUnitQuadBuffer;
if (mCurrentBuffer != buffer) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
mCurrentBuffer = buffer;
diff --git a/libs/hwui/renderstate/MeshState.h b/libs/hwui/renderstate/MeshState.h
index 9b1021d..5cb1143 100644
--- a/libs/hwui/renderstate/MeshState.h
+++ b/libs/hwui/renderstate/MeshState.h
@@ -32,7 +32,7 @@
// This array is never used directly but used as a memcpy source in the
// OpenGLRenderer constructor
-const TextureVertex kMeshVertices[] = {
+const TextureVertex kUnitQuadVertices[] = {
{ 0, 0, 0, 0 },
{ 1, 0, 1, 0 },
{ 0, 1, 0, 1 },
@@ -110,12 +110,16 @@
bool bindShadowIndicesBuffer();
bool unbindIndicesBuffer();
+ ///////////////////////////////////////////////////////////////////////////////
+ // Getters - for use in Glop building
+ ///////////////////////////////////////////////////////////////////////////////
+ GLuint getUnitQuadVBO() { return mUnitQuadBuffer; }
private:
MeshState();
bool bindIndicesBufferInternal(const GLuint buffer);
// VBO to draw with
- GLuint meshBuffer;
+ GLuint mUnitQuadBuffer;
GLuint mCurrentBuffer;
GLuint mCurrentIndicesBuffer;
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 5e02844..0cb3ddb 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -219,7 +219,7 @@
mCaches->setProgram(shader.program);
Glop::Fill::Color color = shader.color;
- shader.program->setColor(color.a, color.r, color.g, color.b);
+ shader.program->setColor(color.r, color.g, color.b, color.a);
shader.program->set(glop.transform.ortho,
glop.transform.modelView,
@@ -261,14 +261,13 @@
meshState().bindIndicesBufferInternal(mesh.indexBufferObject);
// ---------- GL state setup ----------
+ blend().setFactors(glop.blend.src, glop.blend.dst);
- if (glop.blend.mode != Glop::Blend::kDisable) {
- blend().enable(glop.blend.mode, glop.blend.swapSrcDst);
+ if (mesh.indexBufferObject) {
+ glDrawElements(glop.mesh.primitiveMode, glop.mesh.vertexCount, GL_UNSIGNED_BYTE, nullptr);
} else {
- blend().disable();
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, glop.mesh.vertexCount);
}
-
- glDrawElements(glop.mesh.primitiveMode, glop.mesh.vertexCount, GL_UNSIGNED_BYTE, nullptr);
}
} /* namespace uirenderer */
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index a12dac7..1e7ba23 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -42,7 +42,8 @@
static DisplayListRenderer* startRecording(RenderNode* node) {
DisplayListRenderer* renderer = new DisplayListRenderer();
- renderer->setViewport(node->getWidth(), node->getHeight());
+ renderer->setViewport(node->stagingProperties().getWidth(),
+ node->stagingProperties().getHeight());
renderer->prepare();
return renderer;
}
@@ -53,80 +54,174 @@
delete renderer;
}
-sp<RenderNode> createCard(int x, int y, int width, int height) {
- sp<RenderNode> node = new RenderNode();
- node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
- node->mutateStagingProperties().setElevation(dp(16));
- node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1);
- node->mutateStagingProperties().mutableOutline().setShouldClip(true);
- node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z);
+class TreeContentAnimation {
+public:
+ virtual ~TreeContentAnimation() {}
+ virtual int getFrameCount() { return 150; }
+ virtual void createContent(int width, int height, DisplayListRenderer* renderer) = 0;
+ virtual void doFrame(int frameNr) = 0;
- DisplayListRenderer* renderer = startRecording(node.get());
- renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode);
- endRecording(renderer, node.get());
+ template <class T>
+ static void run() {
+ T animation;
- return node;
-}
+ TestContext testContext;
-int main(int argc, char* argv[]) {
- TestContext testContext;
+ // create the native surface
+ const int width = gDisplay.w;
+ const int height = gDisplay.h;
+ sp<Surface> surface = testContext.surface();
- // create the native surface
- const int width = gDisplay.w;
- const int height = gDisplay.h;
- sp<Surface> surface = testContext.surface();
+ RenderNode* rootNode = new RenderNode();
+ rootNode->incStrong(nullptr);
+ rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height);
+ rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+ rootNode->mutateStagingProperties().setClipToBounds(false);
+ rootNode->setPropertyFieldsDirty(RenderNode::GENERIC);
- RenderNode* rootNode = new RenderNode();
- rootNode->incStrong(nullptr);
- rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height);
- rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
- rootNode->mutateStagingProperties().setClipToBounds(false);
- rootNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+ ContextFactory factory;
+ std::unique_ptr<RenderProxy> proxy(new RenderProxy(false, rootNode, &factory));
+ proxy->loadSystemProperties();
+ proxy->initialize(surface);
+ float lightX = width / 2.0;
+ proxy->setup(width, height, (Vector3){lightX, dp(-200.0f), dp(800.0f)},
+ dp(800.0f), 255 * 0.075, 255 * 0.15);
- ContextFactory factory;
- std::unique_ptr<RenderProxy> proxy(new RenderProxy(false, rootNode, &factory));
- proxy->loadSystemProperties();
- proxy->initialize(surface);
- float lightX = width / 2.0;
- proxy->setup(width, height, (Vector3){lightX, dp(-200.0f), dp(800.0f)},
- dp(800.0f), 255 * 0.075, 255 * 0.15);
+ android::uirenderer::Rect DUMMY;
- android::uirenderer::Rect DUMMY;
+ std::vector< sp<RenderNode> > cards;
- std::vector< sp<RenderNode> > cards;
+ DisplayListRenderer* renderer = startRecording(rootNode);
+ animation.createContent(width, height, renderer);
+ endRecording(renderer, rootNode);
- DisplayListRenderer* renderer = startRecording(rootNode);
- renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
- renderer->insertReorderBarrier(true);
+ for (int i = 0; i < 150; i++) {
+ testContext.waitForVsync();
- for (int x = dp(16); x < (width - dp(116)); x += dp(116)) {
- for (int y = dp(16); y < (height - dp(116)); y += dp(116)) {
- sp<RenderNode> card = createCard(x, y, dp(100), dp(100));
- renderer->drawRenderNode(card.get(), DUMMY, 0);
- cards.push_back(card);
+ ATRACE_NAME("UI-Draw Frame");
+ animation.doFrame(i);
+ nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC);
+ proxy->syncAndDrawFrame(frameTimeNs, 0, gDisplay.density);
}
+
+ sleep(5);
+
+ rootNode->decStrong(nullptr);
}
+};
- renderer->insertReorderBarrier(false);
- endRecording(renderer, rootNode);
+class ShadowGridAnimation : public TreeContentAnimation {
+public:
+ std::vector< sp<RenderNode> > cards;
+ void createContent(int width, int height, DisplayListRenderer* renderer) override {
+ android::uirenderer::Rect DUMMY;
- for (int i = 0; i < 150; i++) {
- testContext.waitForVsync();
+ renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
+ renderer->insertReorderBarrier(true);
- ATRACE_NAME("UI-Draw Frame");
+ for (int x = dp(16); x < (width - dp(116)); x += dp(116)) {
+ for (int y = dp(16); y < (height - dp(116)); y += dp(116)) {
+ sp<RenderNode> card = createCard(x, y, dp(100), dp(100));
+ renderer->drawRenderNode(card.get(), DUMMY, 0);
+ cards.push_back(card);
+ }
+ }
+
+ renderer->insertReorderBarrier(false);
+ }
+ void doFrame(int frameNr) override {
for (size_t ci = 0; ci < cards.size(); ci++) {
- cards[ci]->mutateStagingProperties().setTranslationX(i);
- cards[ci]->mutateStagingProperties().setTranslationY(i);
+ cards[ci]->mutateStagingProperties().setTranslationX(frameNr);
+ cards[ci]->mutateStagingProperties().setTranslationY(frameNr);
cards[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
}
- nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC);
- proxy->syncAndDrawFrame(frameTimeNs, 0, gDisplay.density);
}
+private:
+ sp<RenderNode> createCard(int x, int y, int width, int height) {
+ sp<RenderNode> node = new RenderNode();
+ node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
+ node->mutateStagingProperties().setElevation(dp(16));
+ node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1);
+ node->mutateStagingProperties().mutableOutline().setShouldClip(true);
+ node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z);
- sleep(5);
+ DisplayListRenderer* renderer = startRecording(node.get());
+ renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode);
+ endRecording(renderer, node.get());
+ return node;
+ }
+};
- rootNode->decStrong(nullptr);
+class RectGridAnimation : public TreeContentAnimation {
+public:
+ sp<RenderNode> card;
+ void createContent(int width, int height, DisplayListRenderer* renderer) override {
+ android::uirenderer::Rect DUMMY;
+ renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
+ renderer->insertReorderBarrier(true);
+
+ card = createCard(40, 40, 200, 200);
+ renderer->drawRenderNode(card.get(), DUMMY, 0);
+
+ renderer->insertReorderBarrier(false);
+ }
+ void doFrame(int frameNr) override {
+ card->mutateStagingProperties().setTranslationX(frameNr);
+ card->mutateStagingProperties().setTranslationY(frameNr);
+ card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+ }
+private:
+ sp<RenderNode> createCard(int x, int y, int width, int height) {
+ sp<RenderNode> node = new RenderNode();
+ node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
+ node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+
+ DisplayListRenderer* renderer = startRecording(node.get());
+ renderer->drawColor(0xFFFF00FF, SkXfermode::kSrcOver_Mode);
+
+ float rects[width * height];
+ int index = 0;
+ for (int xOffset = 0; xOffset < width; xOffset+=2) {
+ for (int yOffset = 0; yOffset < height; yOffset+=2) {
+ rects[index++] = xOffset;
+ rects[index++] = yOffset;
+ rects[index++] = xOffset + 1;
+ rects[index++] = yOffset + 1;
+ }
+ }
+ int count = width * height;
+
+ SkPaint paint;
+ paint.setColor(0xff00ffff);
+ renderer->drawRects(rects, count, &paint);
+
+ endRecording(renderer, node.get());
+ return node;
+ }
+};
+
+struct cstr_cmp {
+ bool operator()(const char *a, const char *b) const {
+ return std::strcmp(a, b) < 0;
+ }
+};
+
+typedef void (*testProc)();
+
+std::map<const char*, testProc, cstr_cmp> gTestMap {
+ {"shadowgrid", TreeContentAnimation::run<ShadowGridAnimation>},
+ {"rectgrid", TreeContentAnimation::run<RectGridAnimation> },
+};
+
+int main(int argc, char* argv[]) {
+ const char* testName = argc > 1 ? argv[1] : "shadowgrid";
+ testProc proc = gTestMap[testName];
+ if(!proc) {
+ printf("Error: couldn't find test %s\n", testName);
+ return 1;
+ }
+ proc();
printf("Success!\n");
return 0;
}
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index 3c30aab..c69b2fd 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -105,6 +105,8 @@
bool TaskManager::WorkerThread::addTask(TaskWrapper task) {
if (!isRunning()) {
run(mName.string(), PRIORITY_DEFAULT);
+ } else if (exitPending()) {
+ return false;
}
Mutex::Autolock l(mLock);
@@ -120,10 +122,6 @@
}
void TaskManager::WorkerThread::exit() {
- {
- Mutex::Autolock l(mLock);
- mTasks.clear();
- }
requestExit();
mSignal.signal();
}
diff --git a/libs/hwui/thread/TaskProcessor.h b/libs/hwui/thread/TaskProcessor.h
index eb4ab64..ec6519c 100644
--- a/libs/hwui/thread/TaskProcessor.h
+++ b/libs/hwui/thread/TaskProcessor.h
@@ -30,9 +30,6 @@
TaskProcessorBase() { }
virtual ~TaskProcessorBase() { };
-private:
- friend class TaskManager;
-
virtual void process(const sp<TaskBase>& task) = 0;
};
@@ -44,9 +41,6 @@
bool add(const sp<Task<T> >& task);
- virtual void onProcess(const sp<Task<T> >& task) = 0;
-
-private:
virtual void process(const sp<TaskBase>& task) override {
sp<Task<T> > realTask = static_cast<Task<T>* >(task.get());
// This is the right way to do it but sp<> doesn't play nice
@@ -54,6 +48,8 @@
onProcess(realTask);
}
+ virtual void onProcess(const sp<Task<T> >& task) = 0;
+
TaskManager* mManager;
};
diff --git a/libs/hwui/utils/PaintUtils.h b/libs/hwui/utils/PaintUtils.h
index fa0ae03..2091705 100644
--- a/libs/hwui/utils/PaintUtils.h
+++ b/libs/hwui/utils/PaintUtils.h
@@ -16,6 +16,9 @@
#ifndef PAINT_UTILS_H
#define PAINT_UTILS_H
+#include <SkColorFilter.h>
+#include <SkXfermode.h>
+
namespace android {
namespace uirenderer {
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 7c07fb5..3e91e4c 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -356,6 +356,12 @@
"STREAM_TTS"
};
+ public static final int DEFAULT_MUTE_STREAMS_AFFECTED =
+ (1 << AudioSystem.STREAM_MUSIC) |
+ (1 << AudioSystem.STREAM_RING) |
+ (1 << AudioSystem.STREAM_NOTIFICATION) |
+ (1 << AudioSystem.STREAM_SYSTEM);
+
private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
public void onError(int error) {
switch (error) {
@@ -925,11 +931,8 @@
}
mMuteAffectedStreams = System.getIntForUser(cr,
- System.MUTE_STREAMS_AFFECTED,
- ((1 << AudioSystem.STREAM_MUSIC)|
- (1 << AudioSystem.STREAM_RING)|
- (1 << AudioSystem.STREAM_SYSTEM)),
- UserHandle.USER_CURRENT);
+ System.MUTE_STREAMS_AFFECTED, DEFAULT_MUTE_STREAMS_AFFECTED,
+ UserHandle.USER_CURRENT);
boolean masterMute = System.getIntForUser(cr, System.VOLUME_MASTER_MUTE,
0, UserHandle.USER_CURRENT) == 1;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 175b424..6a05af1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2236,10 +2236,7 @@
ringerModeAffectedStreams);
loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
- ((1 << AudioManager.STREAM_MUSIC) |
- (1 << AudioManager.STREAM_RING) |
- (1 << AudioManager.STREAM_NOTIFICATION) |
- (1 << AudioManager.STREAM_SYSTEM)));
+ AudioService.DEFAULT_MUTE_STREAMS_AFFECTED);
} finally {
if (stmt != null) stmt.close();
}
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index 4e89566..e979a1be 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -1882,4 +1882,15 @@
}
}
+ /**
+ * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
+ *
+ */
+ @Override
+ public void destroy() {
+ if((mUsage & USAGE_IO_OUTPUT) != 0) {
+ setSurface(null);
+ }
+ super.destroy();
+ }
}
diff --git a/rs/java/android/renderscript/FieldPacker.java b/rs/java/android/renderscript/FieldPacker.java
index 20b07e7..0f967fc 100644
--- a/rs/java/android/renderscript/FieldPacker.java
+++ b/rs/java/android/renderscript/FieldPacker.java
@@ -241,8 +241,7 @@
addI64(0);
addI64(0);
addI64(0);
- }
- else {
+ } else {
addI32((int)obj.getID(null));
}
} else {
@@ -619,6 +618,289 @@
return mPos;
}
+ private static void addToPack(FieldPacker fp, Object obj) {
+ if (obj instanceof Boolean) {
+ fp.addBoolean(((Boolean)obj).booleanValue());
+ return;
+ }
+
+ if (obj instanceof Byte) {
+ fp.addI8(((Byte)obj).byteValue());
+ return;
+ }
+
+ if (obj instanceof Short) {
+ fp.addI16(((Short)obj).shortValue());
+ return;
+ }
+
+ if (obj instanceof Integer) {
+ fp.addI32(((Integer)obj).intValue());
+ return;
+ }
+
+ if (obj instanceof Long) {
+ fp.addI64(((Long)obj).longValue());
+ return;
+ }
+
+ if (obj instanceof Float) {
+ fp.addF32(((Float)obj).floatValue());
+ return;
+ }
+
+ if (obj instanceof Double) {
+ fp.addF64(((Double)obj).doubleValue());
+ return;
+ }
+
+ if (obj instanceof Byte2) {
+ fp.addI8((Byte2)obj);
+ return;
+ }
+
+ if (obj instanceof Byte3) {
+ fp.addI8((Byte3)obj);
+ return;
+ }
+
+ if (obj instanceof Byte4) {
+ fp.addI8((Byte4)obj);
+ return;
+ }
+
+ if (obj instanceof Short2) {
+ fp.addI16((Short2)obj);
+ return;
+ }
+
+ if (obj instanceof Short3) {
+ fp.addI16((Short3)obj);
+ return;
+ }
+
+ if (obj instanceof Short4) {
+ fp.addI16((Short4)obj);
+ return;
+ }
+
+ if (obj instanceof Int2) {
+ fp.addI32((Int2)obj);
+ return;
+ }
+
+ if (obj instanceof Int3) {
+ fp.addI32((Int3)obj);
+ return;
+ }
+
+ if (obj instanceof Int4) {
+ fp.addI32((Int4)obj);
+ return;
+ }
+
+ if (obj instanceof Long2) {
+ fp.addI64((Long2)obj);
+ return;
+ }
+
+ if (obj instanceof Long3) {
+ fp.addI64((Long3)obj);
+ return;
+ }
+
+ if (obj instanceof Long4) {
+ fp.addI64((Long4)obj);
+ return;
+ }
+
+ if (obj instanceof Float2) {
+ fp.addF32((Float2)obj);
+ return;
+ }
+
+ if (obj instanceof Float3) {
+ fp.addF32((Float3)obj);
+ return;
+ }
+
+ if (obj instanceof Float4) {
+ fp.addF32((Float4)obj);
+ return;
+ }
+
+ if (obj instanceof Double2) {
+ fp.addF64((Double2)obj);
+ return;
+ }
+
+ if (obj instanceof Double3) {
+ fp.addF64((Double3)obj);
+ return;
+ }
+
+ if (obj instanceof Double4) {
+ fp.addF64((Double4)obj);
+ return;
+ }
+
+ if (obj instanceof Matrix2f) {
+ fp.addMatrix((Matrix2f)obj);
+ return;
+ }
+
+ if (obj instanceof Matrix3f) {
+ fp.addMatrix((Matrix3f)obj);
+ return;
+ }
+
+ if (obj instanceof Matrix4f) {
+ fp.addMatrix((Matrix4f)obj);
+ return;
+ }
+
+ if (obj instanceof BaseObj) {
+ fp.addObj((BaseObj)obj);
+ return;
+ }
+ }
+
+ private static int getPackedSize(Object obj) {
+ if (obj instanceof Boolean) {
+ return 1;
+ }
+
+ if (obj instanceof Byte) {
+ return 1;
+ }
+
+ if (obj instanceof Short) {
+ return 2;
+ }
+
+ if (obj instanceof Integer) {
+ return 4;
+ }
+
+ if (obj instanceof Long) {
+ return 8;
+ }
+
+ if (obj instanceof Float) {
+ return 4;
+ }
+
+ if (obj instanceof Double) {
+ return 8;
+ }
+
+ if (obj instanceof Byte2) {
+ return 2;
+ }
+
+ if (obj instanceof Byte3) {
+ return 3;
+ }
+
+ if (obj instanceof Byte4) {
+ return 4;
+ }
+
+ if (obj instanceof Short2) {
+ return 4;
+ }
+
+ if (obj instanceof Short3) {
+ return 6;
+ }
+
+ if (obj instanceof Short4) {
+ return 8;
+ }
+
+ if (obj instanceof Int2) {
+ return 8;
+ }
+
+ if (obj instanceof Int3) {
+ return 12;
+ }
+
+ if (obj instanceof Int4) {
+ return 16;
+ }
+
+ if (obj instanceof Long2) {
+ return 16;
+ }
+
+ if (obj instanceof Long3) {
+ return 24;
+ }
+
+ if (obj instanceof Long4) {
+ return 32;
+ }
+
+ if (obj instanceof Float2) {
+ return 8;
+ }
+
+ if (obj instanceof Float3) {
+ return 12;
+ }
+
+ if (obj instanceof Float4) {
+ return 16;
+ }
+
+ if (obj instanceof Double2) {
+ return 16;
+ }
+
+ if (obj instanceof Double3) {
+ return 24;
+ }
+
+ if (obj instanceof Double4) {
+ return 32;
+ }
+
+ if (obj instanceof Matrix2f) {
+ return 16;
+ }
+
+ if (obj instanceof Matrix3f) {
+ return 36;
+ }
+
+ if (obj instanceof Matrix4f) {
+ return 64;
+ }
+
+ if (obj instanceof BaseObj) {
+ if (RenderScript.sPointerSize == 8) {
+ return 32;
+ } else {
+ return 4;
+ }
+ }
+
+ return 0;
+ }
+
+ static FieldPacker createFieldPack(Object[] args) {
+ int len = 0;
+ for (Object arg : args) {
+ len += getPackedSize(arg);
+ }
+ FieldPacker fp = new FieldPacker(len);
+ for (Object arg : args) {
+ addToPack(fp, arg);
+ }
+ return fp;
+ }
+
private final byte mData[];
private int mPos;
private int mLen;
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index f37519e..94aa857 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -313,6 +313,15 @@
sizes, depClosures, depFieldIDs);
}
+ native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params,
+ long[] fieldIDs, long[] values, int[] sizes);
+ synchronized long nInvokeClosureCreate(long invokeID, byte[] params,
+ long[] fieldIDs, long[] values, int[] sizes) {
+ validate();
+ return rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs,
+ values, sizes);
+ }
+
native void rsnClosureSetArg(long con, long closureID, int index,
long value, int size);
synchronized void nClosureSetArg(long closureID, int index, long value,
@@ -745,6 +754,12 @@
return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
}
+ native long rsnScriptInvokeIDCreate(long con, long sid, int slot);
+ synchronized long nScriptInvokeIDCreate(long sid, int slot) {
+ validate();
+ return rsnScriptInvokeIDCreate(mContext, sid, slot);
+ }
+
native long rsnScriptFieldIDCreate(long con, long sid, int slot);
synchronized long nScriptFieldIDCreate(long sid, int slot) {
validate();
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index eb1687a..d352130 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -66,6 +66,46 @@
}
/**
+ * @hide Pending API review
+ * InvokeID is an identifier for an invoke function. It is used
+ * as an identifier for ScriptGroup creation.
+ *
+ * This class should not be directly created. Instead use the method in the
+ * reflected or intrinsic code "getInvokeID_funcname()".
+ *
+ */
+ public static final class InvokeID extends BaseObj {
+ Script mScript;
+ int mSlot;
+ InvokeID(long id, RenderScript rs, Script s, int slot) {
+ super(id, rs);
+ mScript = s;
+ mSlot = slot;
+ }
+ }
+
+ private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
+ /**
+ * @hide Pending API review
+ * Only to be used by generated reflected classes.
+ */
+ protected InvokeID createInvokeID(int slot) {
+ InvokeID i = mIIDs.get(slot);
+ if (i != null) {
+ return i;
+ }
+
+ long id = mRS.nScriptInvokeIDCreate(getID(mRS), slot);
+ if (id == 0) {
+ throw new RSDriverException("Failed to create KernelID");
+ }
+
+ i = new InvokeID(id, mRS, this, slot);
+ mIIDs.put(slot, i);
+ return i;
+ }
+
+ /**
* FieldID is an identifier for a Script + exported field pair. It is used
* as an identifier for ScriptGroup creation.
*
diff --git a/rs/java/android/renderscript/ScriptGroup2.java b/rs/java/android/renderscript/ScriptGroup2.java
index 366039e..113b896 100644
--- a/rs/java/android/renderscript/ScriptGroup2.java
+++ b/rs/java/android/renderscript/ScriptGroup2.java
@@ -34,6 +34,8 @@
private Future mReturnFuture;
private Map<Script.FieldID, Future> mGlobalFuture;
+ private FieldPacker mFP;
+
private static final String TAG = "Closure";
public Closure(long id, RenderScript rs) {
@@ -89,6 +91,44 @@
setID(id);
}
+ public Closure(RenderScript rs, Script.InvokeID invokeID,
+ Object[] args, Map<Script.FieldID, Object> globals) {
+ super(0, rs);
+ mFP = FieldPacker.createFieldPack(args);
+
+ mBindings = new HashMap<Script.FieldID, Object>();
+ mGlobalFuture = new HashMap<Script.FieldID, Future>();
+
+ int numValues = globals.size();
+
+ long[] fieldIDs = new long[numValues];
+ long[] values = new long[numValues];
+ int[] sizes = new int[numValues];
+ long[] depClosures = new long[numValues];
+ long[] depFieldIDs = new long[numValues];
+
+ int i = 0;
+ for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
+ Object obj = entry.getValue();
+ Script.FieldID fieldID = entry.getKey();
+ fieldIDs[i] = fieldID.getID(rs);
+ if (obj instanceof UnboundValue) {
+ UnboundValue unbound = (UnboundValue)obj;
+ unbound.addReference(this, fieldID);
+ } else {
+ // TODO(yangni): Verify obj not a future.
+ retrieveValueAndDependenceInfo(rs, i, obj, values,
+ sizes, depClosures, depFieldIDs);
+ }
+ i++;
+ }
+
+ long id = rs.nInvokeClosureCreate(invokeID.getID(rs), mFP.getData(), fieldIDs,
+ values, sizes);
+
+ setID(id);
+ }
+
private static void retrieveValueAndDependenceInfo(RenderScript rs,
int index, Object obj, long[] values, int[] sizes, long[] depClosures,
long[] depFieldIDs) {
@@ -99,6 +139,12 @@
depClosures[index] = f.getClosure().getID(rs);
Script.FieldID fieldID = f.getFieldID();
depFieldIDs[index] = fieldID != null ? fieldID.getID(rs) : 0;
+ if (obj == null) {
+ // Value is originally created by the owner closure
+ values[index] = 0;
+ sizes[index] = 0;
+ return;
+ }
} else {
depClosures[index] = 0;
depFieldIDs[index] = 0;
@@ -121,6 +167,10 @@
Future f = mGlobalFuture.get(field);
if (f == null) {
+ // If the field is not bound to this closure, this will return a future
+ // without an associated value (reference). So this is not working for
+ // cross-module (cross-script) linking in this case where a field not
+ // explicitly bound.
f = new Future(this, field, mBindings.get(field));
mGlobalFuture.put(field, f);
}
@@ -160,7 +210,6 @@
size = 8;
}
}
-
public long value;
public int size;
}
@@ -297,6 +346,13 @@
return c;
}
+ public Closure addInvoke(Script.InvokeID invoke, Object[] args,
+ Map<Script.FieldID, Object> globalBindings) {
+ Closure c = new Closure(mRS, invoke, args, globalBindings);
+ mClosures.add(c);
+ return c;
+ }
+
public UnboundValue addInput() {
UnboundValue unbound = new UnboundValue();
mInputs.add(unbound);
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index cbcba39..7387af0 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -242,6 +242,37 @@
depFieldIDs, (size_t)depFieldIDs_length);
}
+static jlong
+nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID,
+ jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray,
+ jintArray sizeArray) {
+ jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr);
+ jsize jParamLength = _env->GetArrayLength(paramArray);
+
+ jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
+ jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
+ RsScriptFieldID* fieldIDs =
+ (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length);
+ for (int i = 0; i< fieldIDs_length; i++) {
+ fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
+ }
+
+ jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
+ jsize values_length = _env->GetArrayLength(valueArray);
+ uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length);
+ for (int i = 0; i < values_length; i++) {
+ values[i] = (uintptr_t)jValues[i];
+ }
+
+ jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr);
+ jsize sizes_length = _env->GetArrayLength(sizeArray);
+
+ return (jlong)(uintptr_t)rsInvokeClosureCreate(
+ (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength,
+ fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length,
+ (size_t*)sizes, (size_t)sizes_length);
+}
+
static void
nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
jint index, jlong value, jint size) {
@@ -1488,6 +1519,16 @@
}
static jlong
+nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
+{
+ if (kLogApi) {
+ ALOGD("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
+ (void *)sid, slot);
+ }
+ return (jlong)(uintptr_t)rsScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
+}
+
+static jlong
nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
{
if (kLogApi) {
@@ -1935,6 +1976,7 @@
{"rsnContextResume", "(J)V", (void*)nContextResume },
{"rsnContextSendMessage", "(JI[I)V", (void*)nContextSendMessage },
{"rsnClosureCreate", "(JJJ[J[J[I[J[J)J", (void*)nClosureCreate },
+{"rsnInvokeClosureCreate", "(JJ[B[J[J[I)J", (void*)nInvokeClosureCreate },
{"rsnClosureSetArg", "(JJIJI)V", (void*)nClosureSetArg },
{"rsnClosureSetGlobal", "(JJJJI)V", (void*)nClosureSetGlobal },
{"rsnAssignName", "(JJ[B)V", (void*)nAssignName },
@@ -2009,6 +2051,7 @@
{"rsnScriptCCreate", "(JLjava/lang/String;Ljava/lang/String;[BI)J", (void*)nScriptCCreate },
{"rsnScriptIntrinsicCreate", "(JIJ)J", (void*)nScriptIntrinsicCreate },
{"rsnScriptKernelIDCreate", "(JJII)J", (void*)nScriptKernelIDCreate },
+{"rsnScriptInvokeIDCreate", "(JJI)J", (void*)nScriptInvokeIDCreate },
{"rsnScriptFieldIDCreate", "(JJI)J", (void*)nScriptFieldIDCreate },
{"rsnScriptGroupCreate", "(J[J[J[J[J[J)J", (void*)nScriptGroupCreate },
{"rsnScriptGroup2Create", "(JLjava/lang/String;[J)J", (void*)nScriptGroup2Create },
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b989bc6..58104a8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2606,9 +2606,8 @@
}
final ActivityRecord r = stack.topRunningActivityLocked(null);
- final TaskRecord topTask = r.task;
- if (!topTask.mResizeable) {
- Slog.w(TAG, "resizeStack: top task " + topTask + " not resizeable.");
+ if (r != null && !r.task.mResizeable) {
+ Slog.w(TAG, "resizeStack: top task " + r.task + " not resizeable.");
return;
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index fa77a3b..bb95305 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -584,12 +584,13 @@
y = mAttrs.y;
}
+ // Make sure window fits in containing frame required by {@link Gravity#apply} call.
+ w = Math.min(w, pw);
+ h = Math.min(h, ph);
Gravity.apply(mAttrs.gravity, w, h, mContainingFrame,
(int) (x + mAttrs.horizontalMargin * pw),
(int) (y + mAttrs.verticalMargin * ph), mFrame);
- //System.out.println("Out: " + mFrame);
-
// Now make sure the window fits in the overall display.
Gravity.applyDisplay(mAttrs.gravity, df, mFrame);
@@ -1464,7 +1465,11 @@
}
void dump(PrintWriter pw, String prefix, boolean dumpAll) {
+ final TaskStack stack = getStack();
pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());
+ if (stack != null) {
+ pw.print(" stackId="); pw.print(stack.mStackId);
+ }
pw.print(" mSession="); pw.print(mSession);
pw.print(" mClient="); pw.println(mClient.asBinder());
pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid);
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 052a481..a94c2f6 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -40,15 +40,13 @@
/**
* Represents a distinct method to place or receive a phone call. Apps which can place calls and
* want those calls to be integrated into the dialer and in-call UI should build an instance of
- * this class and register it with the system using {@link TelecomManager#registerPhoneAccount}.
+ * this class and register it with the system using {@link TelecomManager}.
* <p>
* {@link TelecomManager} uses registered {@link PhoneAccount}s to present the user with
* alternative options when placing a phone call. When building a {@link PhoneAccount}, the app
- * should supply a valid {@link PhoneAccountHandle} that references the {@link ConnectionService}
+ * should supply a valid {@link PhoneAccountHandle} that references the connection service
* implementation Telecom will use to interact with the app.
- * @hide
*/
-@SystemApi
public class PhoneAccount implements Parcelable {
/**
@@ -62,7 +60,9 @@
* if the user has explicitly selected it to be used as the default connection manager.
* <p>
* See {@link #getCapabilities}
+ * @hide
*/
+ @SystemApi
public static final int CAPABILITY_CONNECTION_MANAGER = 0x1;
/**
@@ -76,6 +76,7 @@
* <p>
* {@hide}
*/
+ @SystemApi
public static final int CAPABILITY_CALL_PROVIDER = 0x2;
/**
@@ -94,6 +95,7 @@
* See {@link #getCapabilities}
* @hide
*/
+ @SystemApi
public static final int CAPABILITY_VIDEO_CALLING = 0x8;
/**
@@ -111,6 +113,7 @@
* See {@link #getCapabilities}
* @hide
*/
+ @SystemApi
public static final int CAPABILITY_MULTI_USER = 0x20;
/**
@@ -203,6 +206,7 @@
}
/** @hide */
+ @SystemApi
public Builder setAccountHandle(PhoneAccountHandle accountHandle) {
mAccountHandle = accountHandle;
return this;
@@ -333,6 +337,7 @@
* @return The builder.
* @hide
*/
+ @SystemApi
public Builder addSupportedUriScheme(String uriScheme) {
if (!TextUtils.isEmpty(uriScheme) && !mSupportedUriSchemes.contains(uriScheme)) {
this.mSupportedUriSchemes.add(uriScheme);
@@ -423,6 +428,7 @@
* @return The builder.
* @hide
*/
+ @SystemApi
public Builder toBuilder() { return new Builder(this); }
/**
diff --git a/telecomm/java/android/telecom/PhoneAccountHandle.java b/telecomm/java/android/telecom/PhoneAccountHandle.java
index 97af41a..570f5fd 100644
--- a/telecomm/java/android/telecom/PhoneAccountHandle.java
+++ b/telecomm/java/android/telecom/PhoneAccountHandle.java
@@ -29,16 +29,13 @@
* The unique identifier for a {@link PhoneAccount}. A {@code PhoneAccountHandle} is made of two
* parts:
* <ul>
- * <li>The component name of the associated {@link ConnectionService}.</li>
+ * <li>The component name of the associated connection service.</li>
* <li>A string identifier that is unique across {@code PhoneAccountHandle}s with the same
* component name.</li>
* </ul>
*
- * See {@link PhoneAccount},
- * {@link TelecomManager#registerPhoneAccount TelecomManager.registerPhoneAccount}.
- * @hide
+ * See {@link PhoneAccount}, {@link TelecomManager}.
*/
-@SystemApi
public class PhoneAccountHandle implements Parcelable {
private final ComponentName mComponentName;
private final String mId;
@@ -51,6 +48,7 @@
}
/** @hide */
+ @SystemApi
public PhoneAccountHandle(
ComponentName componentName,
String id,
@@ -61,8 +59,8 @@
}
/**
- * The {@code ComponentName} of the {@link android.telecom.ConnectionService} which is
- * responsible for making phone calls using this {@code PhoneAccountHandle}.
+ * The {@code ComponentName} of the connection service which is responsible for making phone
+ * calls using this {@code PhoneAccountHandle}.
*
* @return A suitable {@code ComponentName}.
*/
@@ -72,9 +70,9 @@
/**
* A string that uniquely distinguishes this particular {@code PhoneAccountHandle} from all the
- * others supported by the {@link ConnectionService} that created it.
+ * others supported by the connection service that created it.
* <p>
- * A {@code ConnectionService} must select identifiers that are stable for the lifetime of
+ * A connection service must select identifiers that are stable for the lifetime of
* their users' relationship with their service, across many Android devices. For example, a
* good set of identifiers might be the email addresses with which with users registered for
* their accounts with a particular service. Depending on how a service chooses to operate,
@@ -92,6 +90,7 @@
* @return the {@link UserHandle} to use when connecting to this PhoneAccount.
* @hide
*/
+ @SystemApi
public UserHandle getUserHandle() {
return mUserHandle;
}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 1a6b292..6c5f1c6 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -106,7 +106,6 @@
* {@link VideoProfile.VideoState#BIDIRECTIONAL},
* {@link VideoProfile.VideoState#RX_ENABLED},
* {@link VideoProfile.VideoState#TX_ENABLED}.
- * @hide
*/
public static final String EXTRA_START_CALL_WITH_VIDEO_STATE =
"android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
@@ -117,9 +116,7 @@
* {@link PhoneAccountHandle} to use when making the call.
* <p class="note">
* Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
- * @hide
*/
- @SystemApi
public static final String EXTRA_PHONE_ACCOUNT_HANDLE =
"android.telecom.extra.PHONE_ACCOUNT_HANDLE";
@@ -139,10 +136,7 @@
* {@link android.content.Intent#ACTION_DIAL} {@code Intent} containing a {@link Bundle}
* which contains metadata about the call. This {@link Bundle} will be saved into
* {@code Call.Details}.
- *
- * @hide
*/
- @SystemApi
public static final String EXTRA_OUTGOING_CALL_EXTRAS =
"android.telecom.extra.OUTGOING_CALL_EXTRAS";
@@ -554,9 +548,7 @@
*
* @param account The {@link PhoneAccountHandle}.
* @return The {@link PhoneAccount} object.
- * @hide
*/
- @SystemApi
public PhoneAccount getPhoneAccount(PhoneAccountHandle account) {
try {
if (isServiceConnected()) {
diff --git a/telecomm/java/android/telecom/VideoProfile.java b/telecomm/java/android/telecom/VideoProfile.java
index f5cb054..e62e994 100644
--- a/telecomm/java/android/telecom/VideoProfile.java
+++ b/telecomm/java/android/telecom/VideoProfile.java
@@ -21,8 +21,6 @@
/**
* Represents attributes of video calls.
- *
- * {@hide}
*/
public class VideoProfile implements Parcelable {
/**