Merge "Added TaskWindowContainerController"
diff --git a/api/system-current.txt b/api/system-current.txt
index 4c9cada..f2b0eae 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6423,6 +6423,8 @@
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
+ field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI";
+ field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL";
field public static final deprecated java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM";
field public static final java.lang.String EXTRA_PROVISIONING_DISCLAIMERS = "android.app.extra.PROVISIONING_DISCLAIMERS";
@@ -6435,8 +6437,10 @@
field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
field public static final java.lang.String EXTRA_PROVISIONING_LOGO_URI = "android.app.extra.PROVISIONING_LOGO_URI";
field public static final java.lang.String EXTRA_PROVISIONING_MAIN_COLOR = "android.app.extra.PROVISIONING_MAIN_COLOR";
+ field public static final java.lang.String EXTRA_PROVISIONING_ORGANIZATION_NAME = "android.app.extra.PROVISIONING_ORGANIZATION_NAME";
field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
field public static final java.lang.String EXTRA_PROVISIONING_SKIP_USER_CONSENT = "android.app.extra.PROVISIONING_SKIP_USER_CONSENT";
+ field public static final java.lang.String EXTRA_PROVISIONING_SUPPORT_URL = "android.app.extra.PROVISIONING_SUPPORT_URL";
field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PAC_URL = "android.app.extra.PROVISIONING_WIFI_PAC_URL";
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index e454ae1..ef997c9 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -95,4 +95,11 @@
* perform relevant animations before the window disappears.
*/
void onTaskRemovalStarted(int taskId);
+
+ /**
+ * Called when the task has been put in a locked state because one or more of the
+ * activities inside it belong to a managed profile user, and that user has just
+ * been locked.
+ */
+ void onTaskProfileLocked(int taskId, int userId);
}
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 0639552..ad5e69b 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -74,4 +74,8 @@
public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation)
throws RemoteException {
}
+
+ @Override
+ public void onTaskProfileLocked(int taskId, int userId) {
+ }
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index a56ff5e..29633aa 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -279,6 +279,8 @@
* <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_LOCAL_TIME} (convert to String), optional</li>
* <li>{@link #EXTRA_PROVISIONING_TIME_ZONE}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_LOCALE}, optional</li>
@@ -290,6 +292,8 @@
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT} (convert to String), optional</li>
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_SUPPORT_URL}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_ORGANIZATION_NAME}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li></ul>
*
* @hide
@@ -688,6 +692,67 @@
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
/**
+ * A String extra holding the localized name of the organization under management.
+ *
+ * The name is displayed only during provisioning.
+ *
+ * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE}
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_PROVISIONING_ORGANIZATION_NAME =
+ "android.app.extra.PROVISIONING_ORGANIZATION_NAME";
+
+ /**
+ * A String extra holding a url to the website of the device's provider. The website can be
+ * opened in a browser during provisioning.
+ *
+ * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE}
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_PROVISIONING_SUPPORT_URL =
+ "android.app.extra.PROVISIONING_SUPPORT_URL";
+
+ /**
+ * A String extra holding the localized name of the device admin package. It should be the same
+ * as the app label of the package.
+ *
+ * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE}
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL =
+ "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL";
+
+ /**
+ * A {@link Uri} extra pointing to the app icon of device admin package. This image will be
+ * shown during the provisioning.
+ * <h5>The following URI schemes are accepted:</h5>
+ * <ul>
+ * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+ * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
+ * </ul>
+ *
+ * <p> It is the responsibility of the caller to provide an image with a reasonable
+ * pixel density for the device.
+ *
+ * <p> If a content: URI is passed, the intent should have the flag
+ * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and the uri should be added to the
+ * {@link android.content.ClipData} of the intent too.
+ *
+ * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE}
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI =
+ "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI";
+
+ /**
* An int extra holding a minimum required version code for the device admin package. If the
* device admin is already installed on the device, it will only be re-downloaded from
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION} if the version of the
@@ -808,7 +873,7 @@
* </ul>
*
* <p> It is the responsibility of the caller to provide an image with a reasonable
- * pixed density for the device.
+ * pixel density for the device.
*
* <p> If a content: URI is passed, the intent should have the flag
* {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and the uri should be added to the
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 3189681..31e779f 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -1094,8 +1094,9 @@
* <p>Only apps with a foreground activity or a foreground service can call it. Otherwise
* it'll throw {@link IllegalStateException}.
*
- * <p>When an app calls this API when a previous request is still waiting for a response,
- * the previous request will be canceled.
+ * <p>It's up to the launcher how to handle previous pending requests when the same package
+ * calls this API multiple times in a row. It may ignore the previous requests,
+ * for example.
*
* @param provider The {@link ComponentName} for the {@link
* android.content.BroadcastReceiver BroadcastReceiver} provider for your AppWidget.
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 4b5b995..afd7578 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -1200,7 +1200,7 @@
/**
* Return {@code TRUE} if a request is valid -- i.e. {@link #accept(Bundle)} has not been
- * called, and it has not been canceled.
+ * called yet.
*/
public boolean isValid() {
try {
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index c8fb3d1..3853400 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -846,8 +846,9 @@
* <p>Only apps with a foreground activity or a foreground service can call it. Otherwise
* it'll throw {@link IllegalStateException}.
*
- * <p>When an app calls this API when a previous request is still waiting for a response,
- * the previous request will be canceled.
+ * <p>It's up to the launcher how to handle previous pending requests when the same package
+ * calls this API multiple times in a row. It may ignore the previous requests,
+ * for example.
*
* @param shortcut New shortcut to pin. If an app wants to pin an existing (either dynamic
* or manifest) shortcut, then it only needs to have an ID, and other fields don't have to
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index 99f6c2a9..79d16fb 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -59,7 +59,7 @@
private Exception mLastWtf;
// Layout of event log entry received from Android logger.
- // see system/core/include/log/logger.h
+ // see system/core/include/log/log.h
private static final int LENGTH_OFFSET = 0;
private static final int HEADER_SIZE_OFFSET = 2;
private static final int PROCESS_OFFSET = 4;
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index eb0c44c..d7a49e4 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -59,8 +59,8 @@
// visible for WebViewZygoteInit to look up the class by reflection and call preloadInZygote.
/** @hide */
- public static final String CHROMIUM_WEBVIEW_FACTORY =
- "com.android.webview.chromium.WebViewChromiumFactoryProvider";
+ private static final String CHROMIUM_WEBVIEW_FACTORY =
+ "com.android.webview.chromium.WebViewChromiumFactoryProviderForO";
private static final String CHROMIUM_WEBVIEW_FACTORY_METHOD = "create";
@@ -143,6 +143,23 @@
}
/**
+ * @hide
+ */
+ public static Class<WebViewFactoryProvider> getWebViewProviderClass( ClassLoader clazzLoader)
+ throws ClassNotFoundException{
+ try {
+ return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY,
+ true, clazzLoader);
+ } catch (ClassNotFoundException e) {
+ // TODO: This loads the provider which is not built for O, should be removed
+ // before the release.
+ return (Class<WebViewFactoryProvider>) Class.forName(
+ "com.android.webview.chromium.WebViewChromiumFactoryProvider",
+ true, clazzLoader);
+ }
+ }
+
+ /**
* Load the native library for the given package name iff that package
* name is the same as the one providing the webview.
*/
@@ -366,9 +383,9 @@
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()");
try {
- return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY,
- true, clazzLoader);
- } finally {
+ return getWebViewProviderClass(clazzLoader);
+ }
+ finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
}
} catch (ClassNotFoundException e) {
diff --git a/core/java/com/android/internal/logging/LogBuilder.java b/core/java/com/android/internal/logging/LogBuilder.java
index 634d061..8e2e114 100644
--- a/core/java/com/android/internal/logging/LogBuilder.java
+++ b/core/java/com/android/internal/logging/LogBuilder.java
@@ -17,8 +17,9 @@
private SparseArray<Object> entries = new SparseArray();
- public LogBuilder() {}
-
+ public LogBuilder(int mainCategory) {
+ setCategory(mainCategory);
+ }
public LogBuilder setView(View view) {
entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_VIEW, view.getId());
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index 12d699d..d82a211 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -24,6 +24,7 @@
import android.text.TextUtils;
import android.util.Log;
import android.webkit.WebViewFactory;
+import android.webkit.WebViewFactoryProvider;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
@@ -74,8 +75,8 @@
// call preloadInZygote() on it to give it the opportunity to preload the native library
// and perform any other initialisation work that should be shared among the children.
try {
- Class providerClass = Class.forName(WebViewFactory.CHROMIUM_WEBVIEW_FACTORY, true,
- loader);
+ Class<WebViewFactoryProvider> providerClass =
+ WebViewFactory.getWebViewProviderClass(loader);
Object result = providerClass.getMethod("preloadInZygote").invoke(null);
if (!((Boolean)result).booleanValue()) {
Log.e(TAG, "preloadInZygote returned false");
diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
index aa6348e..dcb7874 100644
--- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
+++ b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
@@ -33,7 +33,9 @@
#include "HarfBuzzNGFaceSkia.h"
#include <stdlib.h>
-#include <cutils/log.h>
+
+#include <log/log.h>
+
#include <SkPaint.h>
#include <SkPath.h>
#include <SkPoint.h>
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index aa4570f..14d7e81 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -16,32 +16,32 @@
#define LOG_TAG "android.os.Debug"
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <time.h>
#include <sys/time.h>
-#include <errno.h>
-#include <assert.h>
-#include <ctype.h>
-#include <malloc.h>
+#include <time.h>
+#include <unistd.h>
#include <iomanip>
#include <string>
-#include "jni.h"
+#include <android-base/stringprintf.h>
+#include <cutils/debugger.h>
+#include <log/log.h>
+#include <utils/misc.h>
+#include <utils/String8.h>
-#include "android-base/stringprintf.h"
-#include "cutils/debugger.h"
-#include "cutils/log.h"
#include "JNIHelp.h"
-#include "memtrack/memtrack.h"
-#include "memunreachable/memunreachable.h"
-#include "utils/misc.h"
-#include "utils/String8.h"
+#include "jni.h"
+#include <memtrack/memtrack.h>
+#include <memunreachable/memunreachable.h>
namespace android
{
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index ea893f0..de91f70 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -19,15 +19,14 @@
#include <inttypes.h>
+#include <cutils/trace.h>
+#include <utils/String8.h>
+#include <log/log.h>
+
#include <JNIHelp.h>
#include <ScopedUtfChars.h>
#include <ScopedStringChars.h>
-#include <utils/String8.h>
-
-#include <cutils/trace.h>
-#include <cutils/log.h>
-
namespace android {
static void sanitizeString(String8& utf8Chars) {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 5559d48..abcd1e7 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -29,19 +29,19 @@
#include <sys/types.h>
#include <unistd.h>
-#include <utils/Atomic.h>
#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
-#include <utils/Log.h>
-#include <utils/SystemClock.h>
-#include <utils/List.h>
-#include <utils/KeyedVector.h>
-#include <log/logger.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <utils/threads.h>
+#include <log/log.h>
+#include <utils/Atomic.h>
+#include <utils/KeyedVector.h>
+#include <utils/List.h>
+#include <utils/Log.h>
#include <utils/String8.h>
+#include <utils/SystemClock.h>
+#include <utils/threads.h>
#include <ScopedUtfChars.h>
#include <ScopedLocalRef.h>
diff --git a/core/jni/android_util_Log.cpp b/core/jni/android_util_Log.cpp
index 7719e31..20dfe78 100644
--- a/core/jni/android_util_Log.cpp
+++ b/core/jni/android_util_Log.cpp
@@ -21,7 +21,7 @@
#include <android-base/macros.h>
#include <assert.h>
#include <cutils/properties.h>
-#include <log/logger.h> // For LOGGER_ENTRY_MAX_PAYLOAD.
+#include <log/log.h> // For LOGGER_ENTRY_MAX_PAYLOAD.
#include <utils/Log.h>
#include <utils/String8.h>
diff --git a/core/jni/android_util_jar_StrictJarFile.cpp b/core/jni/android_util_jar_StrictJarFile.cpp
index 2e31c8b..4f1f926 100644
--- a/core/jni/android_util_jar_StrictJarFile.cpp
+++ b/core/jni/android_util_jar_StrictJarFile.cpp
@@ -20,13 +20,14 @@
#include <memory>
#include <string>
+#include <log/log.h>
+
#include "JNIHelp.h"
#include "JniConstants.h"
#include "ScopedLocalRef.h"
#include "ScopedUtfChars.h"
#include "jni.h"
#include "ziparchive/zip_archive.h"
-#include "cutils/log.h"
namespace android {
diff --git a/core/tests/coretests/src/com/android/internal/logging/LogBuilderTest.java b/core/tests/coretests/src/com/android/internal/logging/LogBuilderTest.java
index e7d23a8..e3f754c 100644
--- a/core/tests/coretests/src/com/android/internal/logging/LogBuilderTest.java
+++ b/core/tests/coretests/src/com/android/internal/logging/LogBuilderTest.java
@@ -5,7 +5,7 @@
public class LogBuilderTest extends TestCase {
public void testSerialize() {
- LogBuilder builder = new LogBuilder();
+ LogBuilder builder = new LogBuilder(0);
builder.addTaggedData(1, "one");
builder.addTaggedData(2, "two");
Object[] out = builder.serialize();
@@ -16,7 +16,7 @@
}
public void testInvalidInputThrows() {
- LogBuilder builder = new LogBuilder();
+ LogBuilder builder = new LogBuilder(0);
boolean threw = false;
try {
builder.addTaggedData(0, new Object());
@@ -28,7 +28,7 @@
}
public void testValidInputTypes() {
- LogBuilder builder = new LogBuilder();
+ LogBuilder builder = new LogBuilder(0);
builder.addTaggedData(1, "onetwothree");
builder.addTaggedData(2, 123);
builder.addTaggedData(3, 123L);
diff --git a/libs/androidfw/BackupData.cpp b/libs/androidfw/BackupData.cpp
index ba4a4ff..76a430e 100644
--- a/libs/androidfw/BackupData.cpp
+++ b/libs/androidfw/BackupData.cpp
@@ -16,14 +16,13 @@
#define LOG_TAG "backup_data"
-#include <androidfw/BackupHelpers.h>
-#include <utils/ByteOrder.h>
-
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <cutils/log.h>
+#include <androidfw/BackupHelpers.h>
+#include <log/log.h>
+#include <utils/ByteOrder.h>
namespace android {
diff --git a/libs/androidfw/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp
index 78e9d91..8bfe2b6 100644
--- a/libs/androidfw/BackupHelpers.cpp
+++ b/libs/androidfw/BackupHelpers.cpp
@@ -18,23 +18,22 @@
#include <androidfw/BackupHelpers.h>
-#include <utils/KeyedVector.h>
-#include <utils/ByteOrder.h>
-#include <utils/String8.h>
-
#include <errno.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/stat.h>
-#include <sys/time.h> // for utimes
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h> // for utimes
+#include <sys/uio.h>
#include <unistd.h>
#include <utime.h>
-#include <fcntl.h>
#include <zlib.h>
-#include <cutils/log.h>
+#include <log/log.h>
+#include <utils/ByteOrder.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
namespace android {
diff --git a/libs/androidfw/include/androidfw/CursorWindow.h b/libs/androidfw/include/androidfw/CursorWindow.h
index 8a2979a..f543565 100644
--- a/libs/androidfw/include/androidfw/CursorWindow.h
+++ b/libs/androidfw/include/androidfw/CursorWindow.h
@@ -17,11 +17,11 @@
#ifndef _ANDROID__DATABASE_WINDOW_H
#define _ANDROID__DATABASE_WINDOW_H
-#include <cutils/log.h>
#include <stddef.h>
#include <stdint.h>
#include <binder/Parcel.h>
+#include <log/log.h>
#include <utils/String8.h>
#if LOG_NDEBUG
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 18e59e5..8f7787b 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -75,6 +75,7 @@
FrameInfo.cpp \
FrameInfoVisualizer.cpp \
GammaFontRenderer.cpp \
+ GlLayer.cpp \
GlopBuilder.cpp \
GpuMemoryTracker.cpp \
GradientCache.cpp \
@@ -115,6 +116,7 @@
Texture.cpp \
TextureCache.cpp \
VectorDrawable.cpp \
+ VkLayer.cpp \
protos/hwui.proto
hwui_test_common_src_files := \
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index b463e45..a0366de 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -17,7 +17,7 @@
#include "Caches.h"
#include "GammaFontRenderer.h"
-#include "Layer.h"
+#include "GlLayer.h"
#include "Properties.h"
#include "renderstate/RenderState.h"
#include "ShadowTessellator.h"
@@ -170,9 +170,11 @@
for (std::set<Layer*>::iterator it = mRenderState->mActiveLayers.begin();
it != mRenderState->mActiveLayers.end(); it++) {
const Layer* layer = *it;
- log.appendFormat(" Layer size %dx%d; texid=%u refs=%d\n",
+ LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::OpenGL);
+ const GlLayer* glLayer = static_cast<const GlLayer*>(layer);
+ log.appendFormat(" GlLayer size %dx%d; texid=%u refs=%d\n",
layer->getWidth(), layer->getHeight(),
- layer->getTextureId(),
+ glLayer->getTextureId(),
layer->getStrongCount());
memused += layer->getWidth() * layer->getHeight() * 4;
}
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index 6d5833b..2b4fe17 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -16,7 +16,7 @@
#include "DamageAccumulator.h"
-#include <cutils/log.h>
+#include <log/log.h>
#include "RenderNode.h"
#include "utils/MathUtils.h"
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index a7d5f60..3e8e8a1 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -15,6 +15,8 @@
*/
#include "DeferredLayerUpdater.h"
+#include "GlLayer.h"
+#include "VkLayer.h"
#include "renderthread/EglManager.h"
#include "renderthread/RenderTask.h"
#include "utils/PaintUtils.h"
@@ -55,13 +57,23 @@
mLayer->setAlpha(mAlpha, mMode);
if (mSurfaceTexture.get()) {
- if (mNeedsGLContextAttach) {
- mNeedsGLContextAttach = false;
- mSurfaceTexture->attachToContext(mLayer->getTextureId());
- }
- if (mUpdateTexImage) {
- mUpdateTexImage = false;
- doUpdateTexImage();
+ if (mLayer->getApi() == Layer::Api::Vulkan) {
+ if (mUpdateTexImage) {
+ mUpdateTexImage = false;
+ doUpdateVkTexImage();
+ }
+ } else {
+ LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
+ "apply surfaceTexture with non GL backend %x, GL %x, VK %x",
+ mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
+ if (mNeedsGLContextAttach) {
+ mNeedsGLContextAttach = false;
+ mSurfaceTexture->attachToContext(static_cast<GlLayer*>(mLayer)->getTextureId());
+ }
+ if (mUpdateTexImage) {
+ mUpdateTexImage = false;
+ doUpdateTexImage();
+ }
}
if (mTransform) {
mLayer->getTransform().load(*mTransform);
@@ -71,6 +83,9 @@
}
void DeferredLayerUpdater::doUpdateTexImage() {
+ LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
+ "doUpdateTexImage non GL backend %x, GL %x, VK %x",
+ mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
if (mSurfaceTexture->updateTexImage() == NO_ERROR) {
float transform[16];
@@ -110,30 +125,53 @@
}
}
+void DeferredLayerUpdater::doUpdateVkTexImage() {
+ LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::Vulkan,
+ "updateLayer non Vulkan backend %x, GL %x, VK %x",
+ mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
+
+ static const mat4 identityMatrix;
+ updateLayer(false, identityMatrix.data);
+
+ VkLayer* vkLayer = static_cast<VkLayer*>(mLayer);
+ vkLayer->updateTexture();
+}
+
void DeferredLayerUpdater::updateLayer(bool forceFilter, GLenum renderTarget,
const float* textureTransform) {
+ LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL,
+ "updateLayer non GL backend %x, GL %x, VK %x",
+ mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan);
+
+ updateLayer(forceFilter, textureTransform);
+
+ GlLayer* glLayer = static_cast<GlLayer*>(mLayer);
+ if (renderTarget != glLayer->getRenderTarget()) {
+ glLayer->setRenderTarget(renderTarget);
+ glLayer->bindTexture();
+ glLayer->setFilter(GL_NEAREST, false, true);
+ glLayer->setWrap(GL_CLAMP_TO_EDGE, false, true);
+ }
+}
+
+void DeferredLayerUpdater::updateLayer(bool forceFilter, const float* textureTransform) {
mLayer->setBlend(mBlend);
mLayer->setForceFilter(forceFilter);
mLayer->setSize(mWidth, mHeight);
mLayer->getTexTransform().load(textureTransform);
-
- if (renderTarget != mLayer->getRenderTarget()) {
- mLayer->setRenderTarget(renderTarget);
- mLayer->bindTexture();
- mLayer->setFilter(GL_NEAREST, false, true);
- mLayer->setWrap(GL_CLAMP_TO_EDGE, false, true);
- }
}
void DeferredLayerUpdater::detachSurfaceTexture() {
if (mSurfaceTexture.get()) {
- status_t err = mSurfaceTexture->detachFromContext();
- if (err != 0) {
- // TODO: Elevate to fatal exception
- ALOGE("Failed to detach SurfaceTexture from context %d", err);
+ if (mLayer->getApi() == Layer::Api::OpenGL) {
+ status_t err = mSurfaceTexture->detachFromContext();
+ if (err != 0) {
+ // TODO: Elevate to fatal exception
+ ALOGE("Failed to detach SurfaceTexture from context %d", err);
+ }
+ static_cast<GlLayer*>(mLayer)->clearTexture();
}
mSurfaceTexture = nullptr;
- mLayer->clearTexture();
}
}
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 7335008..ead8314 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -22,6 +22,9 @@
#include <SkMatrix.h>
#include <utils/StrongPointer.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
#include "Layer.h"
#include "Rect.h"
#include "renderthread/RenderThread.h"
@@ -110,6 +113,8 @@
Layer* mLayer;
void doUpdateTexImage();
+ void doUpdateVkTexImage();
+ void updateLayer(bool forceFilter, const float* textureTransform);
};
} /* namespace uirenderer */
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index 700642e..d180ba5 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -13,16 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include <DeviceInfo.h>
#include "Extensions.h"
-#include <GLES2/gl2.h>
-#include <log/log.h>
-
#include <thread>
#include <mutex>
+#include <log/log.h>
+
+#include <GLES2/gl2.h>
+
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/GlLayer.cpp b/libs/hwui/GlLayer.cpp
new file mode 100644
index 0000000..c0ab895
--- /dev/null
+++ b/libs/hwui/GlLayer.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GlLayer.h"
+
+#include "Caches.h"
+#include "RenderNode.h"
+#include "renderstate/RenderState.h"
+#include "utils/TraceUtils.h"
+
+#include <utils/Log.h>
+
+#define ATRACE_LAYER_WORK(label) \
+ ATRACE_FORMAT("%s HW Layer DisplayList %s %ux%u", \
+ label, \
+ (renderNode.get() != NULL) ? renderNode->getName() : "", \
+ getWidth(), getHeight())
+
+namespace android {
+namespace uirenderer {
+
+GlLayer::GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
+ : Layer(renderState, Api::OpenGL)
+ , caches(Caches::getInstance())
+ , texture(caches) {
+ texture.mWidth = layerWidth;
+ texture.mHeight = layerHeight;
+}
+
+GlLayer::~GlLayer() {
+ if (texture.mId) {
+ texture.deleteTexture();
+ }
+}
+
+void GlLayer::onGlContextLost() {
+ texture.deleteTexture();
+}
+
+void GlLayer::bindTexture() const {
+ if (texture.mId) {
+ caches.textureState().bindTexture(texture.target(), texture.mId);
+ }
+}
+
+void GlLayer::generateTexture() {
+ if (!texture.mId) {
+ glGenTextures(1, &texture.mId);
+ }
+}
+
+void GlLayer::clearTexture() {
+ // There's a rare possibility that Caches could have been destroyed already
+ // since this method is queued up as a task.
+ // Since this is a reset method, treat this as non-fatal.
+ if (caches.isInitialized()) {
+ caches.textureState().unbindTexture(texture.mId);
+ }
+ texture.mId = 0;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/GlLayer.h b/libs/hwui/GlLayer.h
new file mode 100644
index 0000000..54bf5ad
--- /dev/null
+++ b/libs/hwui/GlLayer.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Layer.h"
+
+#include "Texture.h"
+
+namespace android {
+namespace uirenderer {
+
+// Forward declarations
+class Caches;
+
+/**
+ * A layer has dimensions and is backed by an OpenGL texture or FBO.
+ */
+class GlLayer : public Layer {
+public:
+ GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
+ virtual ~GlLayer();
+
+ uint32_t getWidth() const override {
+ return texture.mWidth;
+ }
+
+ uint32_t getHeight() const override {
+ return texture.mHeight;
+ }
+
+ void setSize(uint32_t width, uint32_t height) override {
+ texture.updateSize(width, height, texture.internalFormat(), texture.format(),
+ texture.target());
+ }
+
+ void setBlend(bool blend) override {
+ texture.blend = blend;
+ }
+
+ bool isBlend() const override {
+ return texture.blend;
+ }
+
+ inline GLuint getTextureId() const {
+ return texture.id();
+ }
+
+ inline Texture& getTexture() {
+ return texture;
+ }
+
+ inline GLenum getRenderTarget() const {
+ return texture.target();
+ }
+
+ inline void setRenderTarget(GLenum renderTarget) {
+ texture.mTarget = renderTarget;
+ }
+
+ inline bool isRenderable() const {
+ return texture.target() != GL_NONE;
+ }
+
+ void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
+ texture.setWrap(wrap, bindTexture, force);
+ }
+
+ void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
+ texture.setFilter(filter, bindTexture, force);
+ }
+
+ void bindTexture() const;
+ void generateTexture();
+
+ /**
+ * When the caller frees the texture itself, the caller
+ * must call this method to tell this layer that it lost
+ * the texture.
+ */
+ void clearTexture();
+
+ /**
+ * Lost the GL context but the layer is still around, mark it invalid internally
+ * so the dtor knows not to do any GL work
+ */
+ void onGlContextLost();
+
+private:
+ Caches& caches;
+
+ /**
+ * The texture backing this layer.
+ */
+ Texture texture;
+}; // struct GlLayer
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 34e6d39..8a6e038 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -16,6 +16,7 @@
#include "GlopBuilder.h"
#include "Caches.h"
+#include "GlLayer.h"
#include "Glop.h"
#include "Layer.h"
#include "Matrix.h"
@@ -440,7 +441,7 @@
return *this;
}
-GlopBuilder& GlopBuilder::setFillTextureLayer(Layer& layer, float alpha) {
+GlopBuilder& GlopBuilder::setFillTextureLayer(GlLayer& layer, float alpha) {
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index 8a8b652..87b1568 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -28,6 +28,7 @@
namespace uirenderer {
class Caches;
+class GlLayer;
class Matrix4;
class Patch;
class RenderState;
@@ -71,7 +72,7 @@
GlopBuilder& setFillClear();
GlopBuilder& setFillLayer(Texture& texture, const SkColorFilter* colorFilter,
float alpha, SkBlendMode mode, Blend::ModeOrderSwap modeUsage);
- GlopBuilder& setFillTextureLayer(Layer& layer, float alpha);
+ GlopBuilder& setFillTextureLayer(GlLayer& layer, float alpha);
// TODO: setFillLayer normally forces its own wrap & filter mode,
// which isn't always correct.
GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform);
diff --git a/libs/hwui/GpuMemoryTracker.cpp b/libs/hwui/GpuMemoryTracker.cpp
index 4fb5701..a52ec87 100644
--- a/libs/hwui/GpuMemoryTracker.cpp
+++ b/libs/hwui/GpuMemoryTracker.cpp
@@ -67,13 +67,13 @@
gObjectStats[static_cast<int>(mType)].count--;
}
-void GpuMemoryTracker::onGLContextCreated() {
- LOG_ALWAYS_FATAL_IF(gGpuThread != 0, "We already have a GL thread? "
- "current = %lu, gl thread = %lu", pthread_self(), gGpuThread);
+void GpuMemoryTracker::onGpuContextCreated() {
+ LOG_ALWAYS_FATAL_IF(gGpuThread != 0, "We already have a gpu thread? "
+ "current = %lu, gpu thread = %lu", pthread_self(), gGpuThread);
gGpuThread = pthread_self();
}
-void GpuMemoryTracker::onGLContextDestroyed() {
+void GpuMemoryTracker::onGpuContextDestroyed() {
gGpuThread = 0;
if (CC_UNLIKELY(gObjectSet.size() > 0)) {
std::stringstream os;
diff --git a/libs/hwui/GpuMemoryTracker.h b/libs/hwui/GpuMemoryTracker.h
index bfb1bf1..18e2330 100644
--- a/libs/hwui/GpuMemoryTracker.h
+++ b/libs/hwui/GpuMemoryTracker.h
@@ -15,10 +15,11 @@
*/
#pragma once
-#include <cutils/log.h>
#include <pthread.h>
#include <ostream>
+#include <log/log.h>
+
namespace android {
namespace uirenderer {
@@ -43,8 +44,8 @@
GpuObjectType objectType() { return mType; }
int objectSize() { return mSize; }
- static void onGLContextCreated();
- static void onGLContextDestroyed();
+ static void onGpuContextCreated();
+ static void onGpuContextDestroyed();
static void dump();
static void dump(std::ostream& stream);
static int getInstanceCount(GpuObjectType type);
diff --git a/libs/hwui/Interpolator.cpp b/libs/hwui/Interpolator.cpp
index f94a22d..d740c03 100644
--- a/libs/hwui/Interpolator.cpp
+++ b/libs/hwui/Interpolator.cpp
@@ -16,10 +16,11 @@
#include "Interpolator.h"
-#include "utils/MathUtils.h"
-
#include <algorithm>
-#include <cutils/log.h>
+
+#include <log/log.h>
+
+#include "utils/MathUtils.h"
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index ed6b211..0a9bf54 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -15,19 +15,21 @@
*/
#include "JankTracker.h"
-#include "Properties.h"
-#include "utils/TimeUtils.h"
-
-#include <algorithm>
-#include <cutils/ashmem.h>
-#include <cutils/log.h>
-#include <cstdio>
#include <errno.h>
#include <inttypes.h>
-#include <limits>
+
+#include <algorithm>
#include <cmath>
+#include <cstdio>
+#include <limits>
#include <sys/mman.h>
+#include <cutils/ashmem.h>
+#include <log/log.h>
+
+#include "Properties.h"
+#include "utils/TimeUtils.h"
+
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 88817ef..331bb81 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -16,77 +16,36 @@
#include "Layer.h"
-#include "Caches.h"
-#include "RenderNode.h"
#include "renderstate/RenderState.h"
-#include "utils/TraceUtils.h"
-#include <utils/Log.h>
-
-#define ATRACE_LAYER_WORK(label) \
- ATRACE_FORMAT("%s HW Layer DisplayList %s %ux%u", \
- label, \
- (renderNode.get() != NULL) ? renderNode->getName() : "", \
- getWidth(), getHeight())
+#include <SkColorFilter.h>
namespace android {
namespace uirenderer {
-Layer::Layer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
+Layer::Layer(RenderState& renderState, Api api)
: GpuMemoryTracker(GpuObjectType::Layer)
- , state(State::Uncached)
- , caches(Caches::getInstance())
- , renderState(renderState)
- , texture(caches) {
+ , mRenderState(renderState)
+ , mApi(api) {
// TODO: This is a violation of Android's typical ref counting, but it
// preserves the old inc/dec ref locations. This should be changed...
incStrong(nullptr);
- texture.mWidth = layerWidth;
- texture.mHeight = layerHeight;
+
renderState.registerLayer(this);
}
Layer::~Layer() {
- renderState.unregisterLayer(this);
SkSafeUnref(colorFilter);
- if (texture.mId) {
- texture.deleteTexture();
- }
-}
-
-void Layer::onGlContextLost() {
- texture.deleteTexture();
+ mRenderState.unregisterLayer(this);
}
void Layer::setColorFilter(SkColorFilter* filter) {
SkRefCnt_SafeAssign(colorFilter, filter);
}
-void Layer::bindTexture() const {
- if (texture.mId) {
- caches.textureState().bindTexture(texture.target(), texture.mId);
- }
-}
-
-void Layer::generateTexture() {
- if (!texture.mId) {
- glGenTextures(1, &texture.mId);
- }
-}
-
-void Layer::clearTexture() {
- // There's a rare possibility that Caches could have been destroyed already
- // since this method is queued up as a task.
- // Since this is a reset method, treat this as non-fatal.
- if (caches.isInitialized()) {
- caches.textureState().unbindTexture(texture.mId);
- }
- texture.mId = 0;
-}
-
void Layer::postDecStrong() {
- renderState.postDecStrong(this);
+ mRenderState.postDecStrong(this);
}
}; // namespace uirenderer
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 8e71cd1..3b639ee 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -16,25 +16,13 @@
#pragma once
-#include <cutils/compiler.h>
-#include <sys/types.h>
-#include <utils/StrongPointer.h>
#include <utils/RefBase.h>
-#include <memory>
-
-#include <GLES2/gl2.h>
#include <GpuMemoryTracker.h>
-#include <ui/Region.h>
-
#include <SkPaint.h>
#include <SkBlendMode.h>
#include "Matrix.h"
-#include "Rect.h"
-#include "RenderBuffer.h"
-#include "Texture.h"
-#include "Vertex.h"
namespace android {
namespace uirenderer {
@@ -43,49 +31,33 @@
// Layers
///////////////////////////////////////////////////////////////////////////////
-// Forward declarations
-class Caches;
class RenderState;
/**
- * A layer has dimensions and is backed by an OpenGL texture or FBO.
+ * A layer has dimensions and is backed by a backend specific texture or framebuffer.
*/
class Layer : public VirtualLightRefBase, GpuMemoryTracker {
public:
- // layer lifecycle, controlled from outside
- enum class State {
- Uncached = 0,
- InCache = 1,
- FailedToCache = 2,
- RemovedFromCache = 3,
- DeletedFromCache = 4,
- InGarbageList = 5,
+ enum class Api {
+ OpenGL = 0,
+ Vulkan = 1,
};
- State state; // public for logging/debugging purposes
- Layer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
+ Api getApi() const {
+ return mApi;
+ }
+
~Layer();
- inline uint32_t getWidth() const {
- return texture.mWidth;
- }
+ virtual uint32_t getWidth() const = 0;
- inline uint32_t getHeight() const {
- return texture.mHeight;
- }
+ virtual uint32_t getHeight() const = 0;
- void setSize(uint32_t width, uint32_t height) {
- texture.updateSize(width, height, texture.internalFormat(), texture.format(),
- texture.target());
- }
+ virtual void setSize(uint32_t width, uint32_t height) = 0;
- inline void setBlend(bool blend) {
- texture.blend = blend;
- }
+ virtual void setBlend(bool blend) = 0;
- inline bool isBlend() const {
- return texture.blend;
- }
+ virtual bool isBlend() const = 0;
inline void setForceFilter(bool forceFilter) {
this->forceFilter = forceFilter;
@@ -112,50 +84,12 @@
return mode;
}
- inline GLuint getTextureId() const {
- return texture.id();
- }
-
- inline Texture& getTexture() {
- return texture;
- }
-
- inline GLenum getRenderTarget() const {
- return texture.target();
- }
-
- inline void setRenderTarget(GLenum renderTarget) {
- texture.mTarget = renderTarget;
- }
-
- inline bool isRenderable() const {
- return texture.target() != GL_NONE;
- }
-
- void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
- texture.setWrap(wrap, bindTexture, force);
- }
-
- void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
- texture.setFilter(filter, bindTexture, force);
- }
-
inline SkColorFilter* getColorFilter() const {
return colorFilter;
}
void setColorFilter(SkColorFilter* filter);
- void bindTexture() const;
- void generateTexture();
-
- /**
- * When the caller frees the texture itself, the caller
- * must call this method to tell this layer that it lost
- * the texture.
- */
- void clearTexture();
-
inline mat4& getTexTransform() {
return texTransform;
}
@@ -170,21 +104,13 @@
*/
void postDecStrong();
- /**
- * Lost the GL context but the layer is still around, mark it invalid internally
- * so the dtor knows not to do any GL work
- */
- void onGlContextLost();
+protected:
+ Layer(RenderState& renderState, Api api);
+
+ RenderState& mRenderState;
private:
- Caches& caches;
-
- RenderState& renderState;
-
- /**
- * The texture backing this layer.
- */
- Texture texture;
+ Api mApi;
/**
* Color filter used to draw this layer. Optional.
diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
index 938b6ef..c460c0d 100644
--- a/libs/hwui/OpenGLReadback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -19,7 +19,7 @@
#include "Caches.h"
#include "Image.h"
#include "GlopBuilder.h"
-#include "Layer.h"
+#include "GlLayer.h"
#include "renderstate/RenderState.h"
#include "renderthread/EglManager.h"
#include "utils/GLUtils.h"
@@ -262,7 +262,7 @@
}
bool OpenGLReadbackImpl::copyLayerInto(renderthread::RenderThread& renderThread,
- Layer& layer, SkBitmap* bitmap) {
+ GlLayer& layer, SkBitmap* bitmap) {
return CopyResult::Success == copyTextureInto(Caches::getInstance(),
renderThread.renderState(), layer.getTexture(), layer.getTexTransform(),
Rect(), bitmap);
diff --git a/libs/hwui/OpenGLReadback.h b/libs/hwui/OpenGLReadback.h
index f4ebabc..c9222cf 100644
--- a/libs/hwui/OpenGLReadback.h
+++ b/libs/hwui/OpenGLReadback.h
@@ -22,7 +22,7 @@
namespace uirenderer {
class Matrix4;
-class Layer;
+class GlLayer;
class OpenGLReadback : public Readback {
public:
@@ -49,7 +49,7 @@
/**
* Copies the layer's contents into the provided bitmap.
*/
- static bool copyLayerInto(renderthread::RenderThread& renderThread, Layer& layer,
+ static bool copyLayerInto(renderthread::RenderThread& renderThread, GlLayer& layer,
SkBitmap* bitmap);
protected:
diff --git a/libs/hwui/PixelBuffer.h b/libs/hwui/PixelBuffer.h
index 9536bc8..77d5e41 100644
--- a/libs/hwui/PixelBuffer.h
+++ b/libs/hwui/PixelBuffer.h
@@ -18,7 +18,8 @@
#define ANDROID_HWUI_PIXEL_BUFFER_H
#include <GLES3/gl3.h>
-#include <cutils/log.h>
+
+#include <log/log.h>
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 848161e..a766381 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -13,17 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include "Properties.h"
-
#include "Debug.h"
-#include <cutils/compiler.h>
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
#include <algorithm>
#include <cstdlib>
+#include <log/log.h>
+#include <cutils/compiler.h>
+#include <cutils/properties.h>
+
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index f9a7c36f2..dea2be6 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -17,6 +17,7 @@
#pragma once
#include "font/FontUtil.h"
+#include "GlLayer.h"
#include "Matrix.h"
#include "Rect.h"
#include "RenderNode.h"
@@ -413,7 +414,7 @@
};
struct TextureLayerOp : RecordedOp {
- TextureLayerOp(BASE_PARAMS_PAINTLESS, Layer* layer)
+ TextureLayerOp(BASE_PARAMS_PAINTLESS, GlLayer* layer)
: SUPER_PAINTLESS(TextureLayerOp)
, layer(layer) {}
@@ -424,7 +425,7 @@
, layer(op.layer) {
}
- Layer* layer;
+ GlLayer* layer;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index ee6279d..b5e5d68 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -606,13 +606,14 @@
// We ref the DeferredLayerUpdater due to its thread-safe ref-counting semantics.
mDisplayList->ref(layerHandle);
+ LOG_ALWAYS_FATAL_IF(layerHandle->backingLayer()->getApi() != Layer::Api::OpenGL);
// Note that the backing layer has *not* yet been updated, so don't trust
// its width, height, transform, etc...!
addOp(alloc().create_trivial<TextureLayerOp>(
Rect(layerHandle->getWidth(), layerHandle->getHeight()),
*(mState.currentSnapshot()->transform),
getRecordedClip(),
- layerHandle->backingLayer()));
+ static_cast<GlLayer*>(layerHandle->backingLayer())));
}
void RecordingCanvas::callDrawGLFunction(Functor* functor,
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index c5156cf..f32612d 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -16,9 +16,11 @@
#include "SkiaCanvasProxy.h"
-#include "hwui/Bitmap.h"
+#include <memory>
-#include <cutils/log.h>
+#include <log/log.h>
+
+#include "hwui/Bitmap.h"
#include <SkLatticeIter.h>
#include <SkPatchUtils.h>
#include <SkPaint.h>
@@ -30,8 +32,6 @@
#include <SkSurface.h>
#include <SkTextBlobRunIterator.h>
-#include <memory>
-
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index fadb960..9239986 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -18,7 +18,6 @@
#include "Caches.h"
#include "Extensions.h"
-#include "Layer.h"
#include "Matrix.h"
#include "Texture.h"
#include "hwui/Bitmap.h"
@@ -317,42 +316,6 @@
return true;
}
-bool tryStoreLayer(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix,
- GLuint* textureUnit, ProgramDescription* description,
- SkiaShaderData::LayerShaderData* outData) {
- Layer* layer;
- if (!shader.asACustomShader(reinterpret_cast<void**>(&layer))) {
- return false;
- }
-
- description->hasBitmap = true;
- outData->layer = layer;
- outData->bitmapSampler = (*textureUnit)++;
-
- const float width = layer->getWidth();
- const float height = layer->getHeight();
-
- computeScreenSpaceMatrix(outData->textureTransform, SkMatrix::I(), shader.getLocalMatrix(),
- modelViewMatrix);
-
- outData->textureDimension[0] = 1.0f / width;
- outData->textureDimension[1] = 1.0f / height;
- return true;
-}
-
-void applyLayer(Caches& caches, const SkiaShaderData::LayerShaderData& data) {
- caches.textureState().activateTexture(data.bitmapSampler);
-
- data.layer->bindTexture();
- data.layer->setWrap(GL_CLAMP_TO_EDGE);
- data.layer->setFilter(GL_LINEAR);
-
- glUniform1i(caches.program().getUniform("bitmapSampler"), data.bitmapSampler);
- glUniformMatrix4fv(caches.program().getUniform("textureTransform"), 1,
- GL_FALSE, &data.textureTransform.data[0]);
- glUniform2fv(caches.program().getUniform("textureDimension"), 1, &data.textureDimension[0]);
-}
-
void SkiaShader::store(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix,
GLuint* textureUnit, ProgramDescription* description,
SkiaShaderData* outData) {
@@ -374,12 +337,6 @@
return;
}
- if (tryStoreLayer(caches, shader, modelViewMatrix,
- textureUnit, description, &outData->layerData)) {
- outData->skiaShaderType = kLayer_SkiaShaderType;
- return;
- }
-
// Unknown/unsupported type, so explicitly ignore shader
outData->skiaShaderType = kNone_SkiaShaderType;
}
@@ -394,10 +351,6 @@
if (data.skiaShaderType & kBitmap_SkiaShaderType) {
applyBitmap(caches, data.bitmapData);
}
-
- if (data.skiaShaderType == kLayer_SkiaShaderType) {
- applyLayer(caches, data.layerData);
- }
}
}; // namespace uirenderer
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index d2f37cd..ab578d5 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -29,7 +29,6 @@
class Caches;
class Extensions;
-class Layer;
class Texture;
struct ProgramDescription;
@@ -45,7 +44,6 @@
kBitmap_SkiaShaderType = 1,
kGradient_SkiaShaderType = 2,
kCompose_SkiaShaderType = kBitmap_SkiaShaderType | kGradient_SkiaShaderType,
- kLayer_SkiaShaderType = 4,
};
struct SkiaShaderData {
@@ -71,15 +69,6 @@
GLuint gradientSampler;
GLenum wrapST;
} gradientData;
- struct LayerShaderData {
- Layer* layer;
- GLuint bitmapSampler;
- GLenum wrapS;
- GLenum wrapT;
-
- Matrix4 textureTransform;
- float textureDimension[2];
- } layerData;
};
class SkiaShader {
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index c75e88f..b8397cc 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -159,10 +159,10 @@
*/
void* isInUse = nullptr;
private:
- // TODO: Temporarily grant private access to Layer, remove once
- // Layer can be de-tangled from being a dual-purpose render target
+ // TODO: Temporarily grant private access to GlLayer, remove once
+ // GlLayer can be de-tangled from being a dual-purpose render target
// and external texture wrapper
- friend class Layer;
+ friend class GlLayer;
// Returns true if the size changed, false if it was the same
bool updateSize(uint32_t width, uint32_t height, GLint internalFormat,
diff --git a/libs/hwui/VkLayer.cpp b/libs/hwui/VkLayer.cpp
new file mode 100644
index 0000000..391acf1
--- /dev/null
+++ b/libs/hwui/VkLayer.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VkLayer.h"
+
+#include "renderstate/RenderState.h"
+
+#include <SkCanvas.h>
+#include <SkSurface.h>
+
+namespace android {
+namespace uirenderer {
+
+void VkLayer::updateTexture() {
+ sk_sp<SkSurface> surface;
+ SkImageInfo info = SkImageInfo::MakeS32(mWidth, mHeight, kPremul_SkAlphaType);
+ surface = SkSurface::MakeRenderTarget(mRenderState.getGrContext(), SkBudgeted::kNo, info);
+ surface->getCanvas()->clear(SK_ColorBLUE);
+ mImage = surface->makeImageSnapshot(SkBudgeted::kNo, SkSurface::kNo_ForceUnique);
+}
+
+void VkLayer::onVkContextDestroyed() {
+ mImage = nullptr;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/VkLayer.h b/libs/hwui/VkLayer.h
new file mode 100644
index 0000000..39522b3
--- /dev/null
+++ b/libs/hwui/VkLayer.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Layer.h"
+
+#include <SkImage.h>
+
+namespace android {
+namespace uirenderer {
+/**
+ * A layer has dimensions and is backed by a VkImage.
+ */
+class VkLayer : public Layer {
+public:
+ VkLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
+ : Layer(renderState, Api::Vulkan) {}
+
+ virtual ~VkLayer() {}
+
+ uint32_t getWidth() const override {
+ return mWidth;
+ }
+
+ uint32_t getHeight() const override {
+ return mHeight;
+ }
+
+ void setSize(uint32_t width, uint32_t height) override {
+ mWidth = width;
+ mHeight = height;
+ }
+
+ void setBlend(bool blend) override {
+ mBlend = blend;
+ }
+
+ bool isBlend() const override {
+ return mBlend;
+ }
+
+ sk_sp<SkImage> getImage() {
+ return mImage;
+ }
+
+ void updateTexture();
+
+ // If we've destroyed the vulkan context (VkInstance, VkDevice, etc.), we must make sure to
+ // destroy any VkImages that were made with that context.
+ void onVkContextDestroyed();
+
+private:
+ int mWidth;
+ int mHeight;
+ bool mBlend;
+
+ sk_sp<SkImage> mImage;
+
+}; // struct VkLayer
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index f172473..956f66e 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -16,9 +16,10 @@
#include "MinikinSkia.h"
+#include <log/log.h>
+
#include <SkPaint.h>
#include <SkTypeface.h>
-#include <cutils/log.h>
namespace android {
diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp
index 8dd165c..713e509 100644
--- a/libs/hwui/hwui/MinikinUtils.cpp
+++ b/libs/hwui/hwui/MinikinUtils.cpp
@@ -13,15 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include "MinikinUtils.h"
+#include <string>
+
+#include <log/log.h>
+
#include "Paint.h"
#include "SkPathMeasure.h"
#include "Typeface.h"
-#include <cutils/log.h>
-#include <string>
-
namespace android {
minikin::FontStyle MinikinUtils::prepareMinikinPaint(minikin::MinikinPaint* minikinPaint,
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index fb2134c..419c8a9 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -52,6 +52,11 @@
canvas->flush();
+ if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
+ canvas->clear(SK_ColorRED);
+ return;
+ }
+
SkImageInfo canvasInfo = canvas->imageInfo();
SkMatrix44 mat4(canvas->getTotalMatrix());
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index f2af4a8..2ebfbcc 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -14,8 +14,12 @@
* limitations under the License.
*/
+#include "GlLayer.h"
#include "LayerDrawable.h"
+#include "VkLayer.h"
+
#include "SkColorFilter.h"
+#include "SkSurface.h"
#include "gl/GrGLTypes.h"
namespace android {
@@ -35,16 +39,27 @@
layer->getTransform().copyTo(transform);
canvas->concat(transform);
}
- GrGLTextureInfo externalTexture;
- externalTexture.fTarget = layer->getRenderTarget();
- externalTexture.fID = layer->getTextureId();
- GrBackendTextureDesc textureDescription;
- textureDescription.fWidth = layer->getWidth();
- textureDescription.fHeight = layer->getHeight();
- textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
- textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
- textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
- sk_sp<SkImage> layerImage = SkImage::MakeFromTexture(context, textureDescription);
+
+ sk_sp<SkImage> layerImage;
+ if (layer->getApi() == Layer::Api::OpenGL) {
+ GlLayer* glLayer = static_cast<GlLayer*>(layer);
+ GrGLTextureInfo externalTexture;
+ externalTexture.fTarget = glLayer->getRenderTarget();
+ externalTexture.fID = glLayer->getTextureId();
+ GrBackendTextureDesc textureDescription;
+ textureDescription.fWidth = glLayer->getWidth();
+ textureDescription.fHeight = glLayer->getHeight();
+ textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
+ textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
+ textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
+ layerImage = SkImage::MakeFromTexture(context, textureDescription);
+ } else {
+ SkASSERT(layer->getApi() == Layer::Api::Vulkan);
+ VkLayer* vkLayer = static_cast<VkLayer*>(layer);
+ canvas->clear(SK_ColorGREEN);
+ layerImage = vkLayer->getImage();
+ }
+
if (layerImage) {
SkPaint paint;
paint.setAlpha(layer->getAlpha());
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index c8258f7..65a1dc3 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -17,6 +17,7 @@
#include "SkiaOpenGLPipeline.h"
#include "DeferredLayerUpdater.h"
+#include "GlLayer.h"
#include "LayerDrawable.h"
#include "renderthread/EglManager.h"
#include "renderthread/Frame.h"
@@ -136,7 +137,7 @@
DeferredLayerUpdater* SkiaOpenGLPipeline::createTextureLayer() {
mEglManager.initialize();
- Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
+ GlLayer* layer = new GlLayer(mRenderThread.renderState(), 0, 0);
layer->generateTexture();
return new DeferredLayerUpdater(layer);
}
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 0d3f4ef..910c339 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -22,6 +22,7 @@
#include "renderstate/RenderState.h"
#include "SkiaPipeline.h"
#include "SkiaProfileRenderer.h"
+#include "VkLayer.h"
#include <SkSurface.h>
#include <SkTypes.h>
@@ -119,7 +120,8 @@
DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
mVkManager.initialize();
- Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
+
+ VkLayer* layer = new VkLayer(mRenderThread.renderState(), 0, 0);
return new DeferredLayerUpdater(layer);
}
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 72af7c9..17ee390 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "GlLayer.h"
+#include "VkLayer.h"
#include <GpuMemoryTracker.h>
#include "renderstate/RenderState.h"
@@ -40,7 +42,7 @@
void RenderState::onGLContextCreated() {
LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil,
"State object lifecycle not managed correctly");
- GpuMemoryTracker::onGLContextCreated();
+ GpuMemoryTracker::onGpuContextCreated();
mBlend = new Blend();
mMeshState = new MeshState();
@@ -55,7 +57,9 @@
}
static void layerLostGlContext(Layer* layer) {
- layer->onGlContextLost();
+ LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::OpenGL,
+ "layerLostGlContext on non GL layer");
+ static_cast<GlLayer*>(layer)->onGlContextLost();
}
void RenderState::onGLContextDestroyed() {
@@ -75,7 +79,29 @@
delete mStencil;
mStencil = nullptr;
- GpuMemoryTracker::onGLContextDestroyed();
+ GpuMemoryTracker::onGpuContextDestroyed();
+}
+
+void RenderState::onVkContextCreated() {
+ LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil,
+ "State object lifecycle not managed correctly");
+ GpuMemoryTracker::onGpuContextCreated();
+}
+
+static void layerDestroyedVkContext(Layer* layer) {
+ LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::Vulkan,
+ "layerLostVkContext on non Vulkan layer");
+ static_cast<VkLayer*>(layer)->onVkContextDestroyed();
+}
+
+void RenderState::onVkContextDestroyed() {
+ mLayerPool.clear();
+ std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerDestroyedVkContext);
+ GpuMemoryTracker::onGpuContextDestroyed();
+}
+
+GrContext* RenderState::getGrContext() const {
+ return mRenderThread.getGrContext();
}
void RenderState::flush(Caches::FlushMode mode) {
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index 3d119dc..d183a15 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -35,6 +35,8 @@
#include <utils/RefBase.h>
#include <private/hwui/DrawGlInfo.h>
+class GrContext;
+
namespace android {
namespace uirenderer {
@@ -56,6 +58,9 @@
void onGLContextCreated();
void onGLContextDestroyed();
+ void onVkContextCreated();
+ void onVkContextDestroyed();
+
void flush(Caches::FlushMode flushMode);
void setViewport(GLsizei width, GLsizei height);
@@ -98,6 +103,8 @@
OffscreenBufferPool& layerPool() { return mLayerPool; }
+ GrContext* getGrContext() const;
+
void dump();
private:
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index df08599..df40a44 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -19,6 +19,7 @@
#include "DeferredLayerUpdater.h"
#include "EglManager.h"
#include "Frame.h"
+#include "GlLayer.h"
#include "ProfileRenderer.h"
#include "renderstate/RenderState.h"
#include "OpenGLReadback.h"
@@ -120,12 +121,13 @@
bool OpenGLPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
ATRACE_CALL();
layer->apply();
- return OpenGLReadbackImpl::copyLayerInto(mRenderThread, *(layer->backingLayer()), bitmap);
+ return OpenGLReadbackImpl::copyLayerInto(mRenderThread,
+ static_cast<GlLayer&>(*layer->backingLayer()), bitmap);
}
DeferredLayerUpdater* OpenGLPipeline::createTextureLayer() {
mEglManager.initialize();
- Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
+ GlLayer* layer = new GlLayer(mRenderThread.renderState(), 0, 0);
Caches::getInstance().textureState().activateTexture(0);
layer->generateTexture();
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 68c04af..2b90744 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -19,6 +19,7 @@
#include "DeviceInfo.h"
#include "Properties.h"
#include "RenderThread.h"
+#include "renderstate/RenderState.h"
#include <GrContext.h>
#include <GrTypes.h>
@@ -37,10 +38,14 @@
void VulkanManager::destroy() {
if (!hasVkContext()) return;
+ mRenderThread.renderState().onVkContextDestroyed();
+ mRenderThread.setGrContext(nullptr);
+
if (VK_NULL_HANDLE != mCommandPool) {
mDestroyCommandPool(mBackendContext->fDevice, mCommandPool, nullptr);
mCommandPool = VK_NULL_HANDLE;
}
+ mBackendContext.reset();
}
void VulkanManager::initialize() {
@@ -105,6 +110,8 @@
if (Properties::enablePartialUpdates && Properties::useBufferAge) {
mSwapBehavior = SwapBehavior::BufferAge;
}
+
+ mRenderThread.renderState().onVkContextCreated();
}
// Returns the next BackbufferInfo to use for the next draw. The function will make sure all
@@ -156,6 +163,9 @@
if (!createSwapchain(surface)) {
return nullptr;
}
+ backbuffer = getAvailableBackbuffer(surface);
+ res = mResetFences(mBackendContext->fDevice, 2, backbuffer->mUsageFences);
+ SkASSERT(VK_SUCCESS == res);
// acquire the image
res = mAcquireNextImageKHR(mBackendContext->fDevice, surface->mSwapchain, UINT64_MAX,
diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
index 0326aa9..f1b8882 100644
--- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
+++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
@@ -15,6 +15,7 @@
*/
#include "DeferredLayerUpdater.h"
+#include "GlLayer.h"
#include "renderthread/OpenGLPipeline.h"
#include "tests/common/TestUtils.h"
@@ -32,7 +33,10 @@
// updates are deferred so the backing layer should still be in its default state
- EXPECT_EQ((uint32_t)GL_NONE, layerUpdater->backingLayer()->getRenderTarget());
+ if (layerUpdater->backingLayer()->getApi() == Layer::Api::OpenGL) {
+ GlLayer* glLayer = static_cast<GlLayer*>(layerUpdater->backingLayer());
+ EXPECT_EQ((uint32_t)GL_NONE, glLayer->getRenderTarget());
+ }
EXPECT_EQ(0u, layerUpdater->backingLayer()->getWidth());
EXPECT_EQ(0u, layerUpdater->backingLayer()->getHeight());
EXPECT_FALSE(layerUpdater->backingLayer()->getForceFilter());
@@ -45,7 +49,10 @@
layerUpdater->updateLayer(true, GL_TEXTURE_EXTERNAL_OES, scaledMatrix.data);
// the backing layer should now have all the properties applied.
- EXPECT_EQ((uint32_t)GL_TEXTURE_EXTERNAL_OES, layerUpdater->backingLayer()->getRenderTarget());
+ if (layerUpdater->backingLayer()->getApi() == Layer::Api::OpenGL) {
+ GlLayer* glLayer = static_cast<GlLayer*>(layerUpdater->backingLayer());
+ EXPECT_EQ((uint32_t)GL_TEXTURE_EXTERNAL_OES, glLayer->getRenderTarget());
+ }
EXPECT_EQ(100u, layerUpdater->backingLayer()->getWidth());
EXPECT_EQ(100u, layerUpdater->backingLayer()->getHeight());
EXPECT_TRUE(layerUpdater->backingLayer()->getForceFilter());
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 21394ae..71c7516 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -19,6 +19,7 @@
#include <BakedOpState.h>
#include <DeferredLayerUpdater.h>
#include <FrameBuilder.h>
+#include <GlLayer.h>
#include <LayerUpdateQueue.h>
#include <RecordedOp.h>
#include <RecordingCanvas.h>
@@ -698,7 +699,10 @@
RENDERTHREAD_TEST(FrameBuilder, textureLayer_reject) {
auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100,
SkMatrix::MakeTrans(5, 5));
- layerUpdater->backingLayer()->setRenderTarget(GL_NONE); // Should be rejected
+ if (layerUpdater->backingLayer()->getApi() != Layer::Api::OpenGL) return;
+
+ GlLayer* glLayer = static_cast<GlLayer*>(layerUpdater->backingLayer());
+ glLayer->setRenderTarget(GL_NONE); // Should be rejected
auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
[&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
diff --git a/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp b/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp
index aa1dcb2..8cbd24e 100644
--- a/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp
+++ b/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp
@@ -51,7 +51,7 @@
TEST(GpuMemoryTracker, sizeCheck) {
destroyEglContext();
- GpuMemoryTracker::onGLContextCreated();
+ GpuMemoryTracker::onGpuContextCreated();
ASSERT_EQ(0, GpuMemoryTracker::getTotalSize(GpuObjectType::Texture));
ASSERT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture));
{
@@ -66,5 +66,5 @@
}
ASSERT_EQ(0, GpuMemoryTracker::getTotalSize(GpuObjectType::Texture));
ASSERT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture));
- GpuMemoryTracker::onGLContextDestroyed();
+ GpuMemoryTracker::onGpuContextDestroyed();
}
diff --git a/libs/hwui/utils/GLUtils.h b/libs/hwui/utils/GLUtils.h
index 94818b2..c127478 100644
--- a/libs/hwui/utils/GLUtils.h
+++ b/libs/hwui/utils/GLUtils.h
@@ -18,7 +18,7 @@
#include "Debug.h"
-#include <cutils/log.h>
+#include <log/log.h>
namespace android {
namespace uirenderer {
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 0b22ad5..7c60467 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -15,7 +15,6 @@
*/
#define LOG_TAG "PointerController"
-
//#define LOG_NDEBUG 0
// Log debug messages about pointer updates
@@ -23,8 +22,9 @@
#include "PointerController.h"
-#include <cutils/log.h>
+#include <log/log.h>
+// ToDo: Fix code to be warning free
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <SkBitmap.h>
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index 18ebd47..4991f04 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -15,15 +15,15 @@
*/
#define LOG_TAG "Sprites"
-
//#define LOG_NDEBUG 0
#include "SpriteController.h"
-#include <cutils/log.h>
+#include <log/log.h>
#include <utils/String8.h>
#include <gui/Surface.h>
+// ToDo: Fix code to be warning free
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <SkBitmap.h>
diff --git a/media/mca/filterpacks/native/base/geometry.cpp b/media/mca/filterpacks/native/base/geometry.cpp
index 7812d502..44b13e4 100644
--- a/media/mca/filterpacks/native/base/geometry.cpp
+++ b/media/mca/filterpacks/native/base/geometry.cpp
@@ -13,10 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "geometry"
-#include <cutils/log.h>
#include <cmath>
+#include <log/log.h>
+
#include "geometry.h"
namespace android {
diff --git a/media/mca/filterpacks/native/base/time_util.cpp b/media/mca/filterpacks/native/base/time_util.cpp
index 1a78a95..7d383df 100644
--- a/media/mca/filterpacks/native/base/time_util.cpp
+++ b/media/mca/filterpacks/native/base/time_util.cpp
@@ -13,14 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "time_util"
#include "time_util.h"
#include "utilities.h"
-#include <cutils/log.h>
#include <sys/time.h>
#include <map>
+#include <log/log.h>
+
namespace android {
namespace filterfw {
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 5574753..62f6136 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -483,6 +483,21 @@
android:exported="true"
android:enabled="@bool/config_enableKeyguardService" />
+ <activity android:name=".keyguard.WorkLockActivity"
+ android:label="@string/accessibility_desc_work_lock"
+ android:permission="android.permission.MANAGE_USERS"
+ android:exported="false"
+ android:launchMode="singleTop"
+ android:excludeFromRecents="true"
+ android:stateNotNeeded="true"
+ android:resumeWhilePausing="true"
+ android:theme="@android:style/Theme.Black.NoTitleBar">
+ <intent-filter>
+ <action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".Somnambulator"
android:label="@string/start_dreams"
android:icon="@mipmap/ic_launcher_dreams"
diff --git a/packages/SystemUI/res/layout/qs_customize_panel_content.xml b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
index ca0248e..04d0e65 100644
--- a/packages/SystemUI/res/layout/qs_customize_panel_content.xml
+++ b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
@@ -27,7 +27,7 @@
<android.support.v7.widget.RecyclerView
android:id="@android:id/list"
- android:layout_width="@dimen/notification_panel_width"
+ android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollIndicators="top"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 34a0397..05963ac 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -460,6 +460,8 @@
<string name="accessibility_desc_settings">Settings</string>
<!-- Content description for the recent apps panel (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_desc_recent_apps">Overview.</string>
+ <!-- Content description for the graphic shown instead of an activity window while the activity is locked (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_desc_work_lock">Work lock screen</string>
<!-- Content description for the close button in the zen mode panel introduction message. [CHAR LIMIT=NONE] -->
<string name="accessibility_desc_close">Close</string>
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 8e5db97..ce89aab 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -326,6 +326,12 @@
*/
private boolean mPendingLock;
+ /**
+ * Controller for showing individual "work challenge" lock screen windows inside managed profile
+ * tasks when the current user has been unlocked but the profile is still locked.
+ */
+ private WorkLockActivityController mWorkLockController;
+
private boolean mLockLater;
private boolean mWakeAndUnlocking;
@@ -708,6 +714,8 @@
mHideAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.lock_screen_behind_enter);
+
+ mWorkLockController = new WorkLockActivityController(mContext);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
new file mode 100644
index 0000000..12cf6fa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.keyguard;
+
+import static android.app.ActivityManager.TaskDescription;
+
+import android.annotation.ColorInt;
+import android.annotation.UserIdInt;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.KeyguardManager;
+import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * Bouncer between work activities and the activity used to confirm credentials before unlocking
+ * a managed profile.
+ * <p>
+ * Shows a solid color when started, based on the organization color of the user it is supposed to
+ * be blocking. Once focused, it switches to a screen to confirm credentials and auto-dismisses if
+ * credentials are accepted.
+ */
+public class WorkLockActivity extends Activity {
+ private static final String TAG = "WorkLockActivity";
+
+ /**
+ * ID of the locked user that this activity blocks access to.
+ */
+ @UserIdInt
+ private int mUserId;
+
+ /**
+ * {@see KeyguardManager}
+ */
+ private KeyguardManager mKgm;
+
+ /**
+ * {@see DevicePolicyManager}
+ */
+ private DevicePolicyManager mDpm;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mUserId = getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId());
+ mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+ mKgm = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+
+ final IntentFilter lockFilter = new IntentFilter();
+ lockFilter.addAction(Intent.ACTION_DEVICE_LOCKED_CHANGED);
+ registerReceiverAsUser(mLockEventReceiver, UserHandle.ALL, lockFilter,
+ /* permission */ null, /* scheduler */ null);
+
+ // Once the receiver is registered, check whether anything happened between now and the time
+ // when this activity was launched. If it did and the user is unlocked now, just quit.
+ if (!mKgm.isDeviceLocked(mUserId)) {
+ finish();
+ return;
+ }
+
+ // Get the organization color; this is a 24-bit integer provided by a DPC, guaranteed to
+ // be completely opaque.
+ final @ColorInt int color = mDpm.getOrganizationColorForUser(mUserId);
+
+ // Draw captions overlaid on the content view, so the whole window is one solid color.
+ setOverlayWithDecorCaptionEnabled(true);
+
+ // Match task description to the task stack we are replacing so it's still recognizably the
+ // original task stack with the same icon and title text.
+ setTaskDescription(new TaskDescription(null, null, color));
+
+ // Blank out the activity. When it is on-screen it will look like a Recents thumbnail with
+ // redaction switched on.
+ final View blankView = new View(this);
+ blankView.setBackgroundColor(color);
+ setContentView(blankView);
+
+ // Respond to input events by showing the prompt to confirm credentials.
+ blankView.setOnClickListener((View v) -> {
+ showConfirmCredentialActivity();
+ });
+ }
+
+ @Override
+ public void onDestroy() {
+ unregisterReceiver(mLockEventReceiver);
+ super.onDestroy();
+ }
+
+ @Override
+ public void onBackPressed() {
+ // Ignore back presses.
+ return;
+ }
+
+ private final BroadcastReceiver mLockEventReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, mUserId);
+ if (userId == mUserId && !mKgm.isDeviceLocked(mUserId)) {
+ finish();
+ }
+ }
+ };
+
+ private void showConfirmCredentialActivity() {
+ if (isFinishing() || !mKgm.isDeviceLocked(mUserId)) {
+ // Don't show the confirm credentials screen if we are already unlocked / unlocking.
+ return;
+ }
+
+ final Intent credential = mKgm.createConfirmDeviceCredentialIntent(null, null, mUserId);
+ if (credential == null) {
+ return;
+ }
+
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchTaskId(getTaskId());
+
+ // Bring this activity back to the foreground after confirming credentials.
+ final PendingIntent target = PendingIntent.getActivity(this, /* request */ -1, getIntent(),
+ PendingIntent.FLAG_CANCEL_CURRENT |
+ PendingIntent.FLAG_ONE_SHOT |
+ PendingIntent.FLAG_IMMUTABLE, options.toBundle());
+
+ credential.putExtra(Intent.EXTRA_INTENT, target.getIntentSender());
+ try {
+ ActivityManager.getService().startConfirmDeviceCredentialIntent(credential);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to start confirm credential intent", e);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
new file mode 100644
index 0000000..22fceff
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.keyguard;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.KeyguardManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+
+public class WorkLockActivityController {
+ private final Context mContext;
+
+ public WorkLockActivityController(Context context) {
+ mContext = context;
+ EventBus.getDefault().register(this);
+ SystemServicesProxy.getInstance(context).registerTaskStackListener(mLockListener);
+ }
+
+ private void startWorkChallengeInTask(int taskId, int userId) {
+ Intent intent = new Intent(KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER)
+ .setComponent(new ComponentName(mContext, WorkLockActivity.class))
+ .putExtra(Intent.EXTRA_USER_ID, userId)
+ .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchTaskId(taskId);
+ options.setTaskOverlay(true);
+ mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
+ }
+
+ private final TaskStackListener mLockListener = new TaskStackListener() {
+ @Override
+ public void onTaskProfileLocked(int taskId, int userId) {
+ startWorkChallengeInTask(taskId, userId);
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 2ba408e..7791132 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -154,6 +154,7 @@
public void onPinnedStackAnimationEnded() { }
public void onActivityForcedResizable(String packageName, int taskId) { }
public void onActivityDismissingDockedStack() { }
+ public void onTaskProfileLocked(int taskId, int userId) { }
}
/**
@@ -197,6 +198,11 @@
public void onActivityDismissingDockedStack() throws RemoteException {
mHandler.sendEmptyMessage(H.ON_ACTIVITY_DISMISSING_DOCKED_STACK);
}
+
+ @Override
+ public void onTaskProfileLocked(int taskId, int userId) {
+ mHandler.obtainMessage(H.ON_TASK_PROFILE_LOCKED, taskId, userId).sendToTarget();
+ }
};
/**
@@ -1155,6 +1161,7 @@
private static final int ON_PINNED_STACK_ANIMATION_ENDED = 4;
private static final int ON_ACTIVITY_FORCED_RESIZABLE = 5;
private static final int ON_ACTIVITY_DISMISSING_DOCKED_STACK = 6;
+ private static final int ON_TASK_PROFILE_LOCKED = 7;
@Override
public void handleMessage(Message msg) {
@@ -1196,6 +1203,12 @@
}
break;
}
+ case ON_TASK_PROFILE_LOCKED: {
+ for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+ mTaskStackListeners.get(i).onTaskProfileLocked(msg.arg1, msg.arg2);
+ }
+ break;
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 088f538..c7adb60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -313,7 +313,7 @@
} else if (mHighImportanceButton.isChecked()) {
return NotificationManager.IMPORTANCE_HIGH;
} else {
- return NotificationManager.IMPORTANCE_NONE;
+ return NotificationManager.IMPORTANCE_UNSPECIFIED;
}
}
@@ -333,10 +333,10 @@
// Set to current importance setting
switch (importance) {
+ case NotificationManager.IMPORTANCE_UNSPECIFIED:
case NotificationManager.IMPORTANCE_NONE:
break;
case NotificationManager.IMPORTANCE_MIN:
- case NotificationManager.IMPORTANCE_UNSPECIFIED:
mMinImportanceButton.setChecked(true);
break;
case NotificationManager.IMPORTANCE_LOW:
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java
index 2cd6dbd..c65f7150 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java
@@ -210,6 +210,18 @@
@Test
@UiThreadTest
+ public void testCloseControls_DoesNotUpdateNotificationChannelIfUnspecified() throws Exception {
+ mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
+ mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
+ mMockStatusBarNotification, null, null, null);
+
+ mNotificationGuts.closeControls(-1, -1, true);
+ verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ anyString(), anyInt(), any());
+ }
+
+ @Test
+ @UiThreadTest
public void testCloseControls_CallsUpdateNotificationChannelIfChanged() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index bf3620e..21139da 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3181,6 +3181,11 @@
// user accepted
ACTION_SKIP_DISCLAIMER_SELECTED = 760;
+ // Enclosing category for group of APP_TRANSITION_FOO events,
+ // logged when we execute an app transition.
+ APP_TRANSITION = 761;
+
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5b4b4fe..2c1871d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -11875,20 +11875,20 @@
}
synchronized (this) {
- if (mStackSupervisor.isUserLockedProfile(userId)) {
- final long ident = Binder.clearCallingIdentity();
- try {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ if (mUserController.shouldConfirmCredentials(userId)) {
final int currentUserId = mUserController.getCurrentUserIdLocked();
- if (mUserController.isLockScreenDisabled(currentUserId)) {
- // If there is no device lock, we will show the profile's credential page.
- mActivityStarter.showConfirmDeviceCredential(userId);
+ if (!mKeyguardController.isKeyguardLocked()) {
+ // If the device is not locked, we will prompt for credentials immediately.
+ mStackSupervisor.lockAllProfileTasks(userId);
} else {
// Showing launcher to avoid user entering credential twice.
startHomeActivityLocked(currentUserId, "notifyLockedProfile");
}
- } finally {
- Binder.restoreCallingIdentity(ident);
}
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 3f166fe..e46d204 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -172,7 +172,7 @@
MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS,
(int) (SystemClock.uptimeMillis() / 1000));
- LogBuilder builder = new LogBuilder();
+ LogBuilder builder = new LogBuilder(MetricsEvent.APP_TRANSITION);
builder.addTaggedData(MetricsEvent.APP_TRANSITION_COMPONENT_NAME, componentName);
builder.addTaggedData(MetricsEvent.APP_TRANSITION_PROCESS_RUNNING, processRunning ? 1 : 0);
builder.addTaggedData(MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a0bb192..8cf0708 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -764,43 +764,52 @@
}
/**
- * TODO: Handle freefom mode.
- * @return true when credential confirmation is needed for the user and there is any
- * activity started by the user in any visible stack.
+ * Detects whether we should show a lock screen in front of this task for a locked user.
+ * <p>
+ * We'll do this if either of the following holds:
+ * <ul>
+ * <li>The top activity explicitly belongs to {@param userId}.</li>
+ * <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
+ * </ul>
+ *
+ * @return {@code true} if the top activity looks like it belongs to {@param userId}.
*/
- boolean isUserLockedProfile(@UserIdInt int userId) {
- if (!mService.mUserController.shouldConfirmCredentials(userId)) {
- return false;
- }
- final ActivityStack fullScreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
- final ActivityStack dockedStack = getStack(DOCKED_STACK_ID);
- final ActivityStack[] activityStacks = new ActivityStack[] {fullScreenStack, dockedStack};
- for (final ActivityStack activityStack : activityStacks) {
- if (activityStack == null) {
- continue;
- }
- if (activityStack.topRunningActivityLocked() == null) {
- continue;
- }
- if (activityStack.getStackVisibilityLocked(null) == STACK_INVISIBLE) {
- continue;
- }
- if (activityStack.isDockedStack() && mIsDockMinimized) {
- continue;
- }
- final TaskRecord topTask = activityStack.topTask();
- if (topTask == null) {
- continue;
- }
- // To handle the case that work app is in the task but just is not the top one.
- for (int i = topTask.mActivities.size() - 1; i >= 0; i--) {
- final ActivityRecord activityRecord = topTask.mActivities.get(i);
- if (activityRecord.userId == userId) {
- return true;
+ private boolean taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId) {
+ // To handle the case that work app is in the task but just is not the top one.
+ final ActivityRecord activityRecord = task.getTopActivity();
+ final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
+
+ return (activityRecord != null && activityRecord.userId == userId)
+ || (resultTo != null && resultTo.userId == userId);
+ }
+
+ /**
+ * Find all visible task stacks containing {@param userId} and intercept them with an activity
+ * to block out the contents and possibly start a credential-confirming intent.
+ *
+ * @param userId user handle for the locked managed profile.
+ */
+ void lockAllProfileTasks(@UserIdInt int userId) {
+ mWindowManager.deferSurfaceLayout();
+ try {
+ final List<ActivityStack> stacks = getStacks();
+ for (int stackNdx = stacks.size() - 1; stackNdx >= 0; stackNdx--) {
+ final List<TaskRecord> tasks = stacks.get(stackNdx).getAllTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
+ final TaskRecord task = tasks.get(taskNdx);
+
+ // Check the task for a top activity belonging to userId, or returning a result
+ // to an activity belonging to userId. Example case: a document picker for
+ // personal files, opened by a work app, should still get locked.
+ if (taskTopActivityIsUser(task, userId)) {
+ mService.mTaskChangeNotificationController.notifyTaskProfileLocked(
+ task.taskId, userId);
+ }
}
}
+ } finally {
+ mWindowManager.continueSurfaceLayout();
}
- return false;
}
void setNextTaskIdForUserLocked(int taskId, int userId) {
diff --git a/services/core/java/com/android/server/am/TaskChangeNotificationController.java b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
index fd248c6..fbdbb1b 100644
--- a/services/core/java/com/android/server/am/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
@@ -39,6 +39,7 @@
static final int NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG = 11;
static final int NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS = 12;
static final int NOTIFY_TASK_REMOVAL_STARTED_LISTENERS = 13;
+ static final int NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG = 14;
// Delay in notifying task stack change listeners (in millis)
static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -110,6 +111,9 @@
case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG:
forAllListeners((listener) -> listener.onActivityDismissingDockedStack());
break;
+ case NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG:
+ forAllListeners((listener) -> listener.onTaskProfileLocked(msg.arg1, msg.arg2));
+ break;
}
}
}
@@ -228,4 +232,13 @@
mHandler.obtainMessage(NOTIFY_TASK_REMOVAL_STARTED_LISTENERS, taskId, 0 /* unused */)
.sendToTarget();
}
+
+ /**
+ * Notify listeners that the task has been put in a locked state because one or more of the
+ * activities inside it belong to a managed profile user that has been locked.
+ */
+ void notifyTaskProfileLocked(int taskId, int userId) {
+ mHandler.obtainMessage(NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG, taskId, userId)
+ .sendToTarget();
+ }
}
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 2514012..b0f67a8 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -1142,12 +1142,6 @@
mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */)
.sendToTarget();
}
-
- @Override
- public void onForegroundProfileSwitch(int newProfileId) throws RemoteException {
- mHandler.obtainMessage(MSG_USER_SWITCHING, newProfileId, 0 /* unused */)
- .sendToTarget();
- }
}, TAG);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to listen for user switching event" ,e);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 775d8a0..6ac172b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -322,7 +322,7 @@
if (!configChanged) {
return null;
}
- displayContent.onOverrideConfigurationChanged(currentConfig);
+ displayContent.onOverrideConfigurationChanged(newConfiguration);
if (displayId == DEFAULT_DISPLAY) {
// Override configuration of the default display duplicates global config. In this case
diff --git a/services/core/jni/com_android_server_connectivity_Vpn.cpp b/services/core/jni/com_android_server_connectivity_Vpn.cpp
index c54d732..4d85d9a 100644
--- a/services/core/jni/com_android_server_connectivity_Vpn.cpp
+++ b/services/core/jni/com_android_server_connectivity_Vpn.cpp
@@ -17,24 +17,25 @@
#define LOG_NDEBUG 0
#define LOG_TAG "VpnJni"
-#include <cutils/log.h>
-#include "netutils/ifc.h"
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
-
#include <linux/if.h>
#include <linux/if_tun.h>
#include <linux/route.h>
#include <linux/ipv6_route.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <log/log.h>
+
+#include "netutils/ifc.h"
#include "jni.h"
#include "JNIHelp.h"
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 5046265..fa6405a 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -894,11 +894,11 @@
* interface.
*/
struct AGnssRilCallback : IAGnssRilCallback {
- Return<void> requestSetIdCb(IAGnssRilCallback::ID setIdFlag) override;
+ Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Return<void> requestRefLocCb() override;
};
-Return<void> AGnssRilCallback::requestSetIdCb(IAGnssRilCallback::ID setIdFlag) {
+Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
JNIEnv* env = getJniEnv();
env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 786c2bb..85931e8 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -19,6 +19,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import android.content.res.Configuration;
import android.hardware.display.DisplayManagerGlobal;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
@@ -208,6 +209,10 @@
voiceInteractionWindow.removeImmediately();
}
+ /**
+ * This tests stack movement between displays and proper stack's, task's and app token's display
+ * container references updates.
+ */
@Test
public void testMoveStackBetweenDisplays() throws Exception {
// Create second display.
@@ -238,4 +243,28 @@
assertEquals(sDisplayContent, task.getDisplayContent());
assertEquals(sDisplayContent, token.getDisplayContent());
}
+
+ /**
+ * This tests override configuration updates for display content.
+ */
+ @Test
+ public void testDisplayOverrideConfigUpdate() throws Exception {
+ final int displayId = sDisplayContent.getDisplayId();
+ final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();
+
+ // Create new, slightly changed override configuration and apply it to the display.
+ final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
+ newOverrideConfig.densityDpi += 120;
+ newOverrideConfig.fontScale += 0.3;
+
+ sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
+
+ // Check that override config is applied.
+ assertEquals(newOverrideConfig, sDisplayContent.getOverrideConfiguration());
+
+ // Check that global configuration is updated, as we've updated default display's config.
+ final Configuration globalConfig = sWm.mRoot.getConfiguration();
+ assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
+ assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
+ }
}