Merge "SF: Add systrace lines for layer transactions"
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index abf7b06..5548699 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -14,9 +14,6 @@
"libz",
"libbase",
],
- static_libs: [
- "libpdx_default_transport",
- ],
init_rc: ["atrace.rc"],
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 1ce88b9..054b00e 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -39,7 +39,6 @@
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/ServiceManagement.h>
-#include <pdx/default_transport/service_utility.h>
#include <utils/String8.h>
#include <utils/Timers.h>
#include <utils/Tokenizer.h>
@@ -50,7 +49,6 @@
#include <android-base/stringprintf.h>
using namespace android;
-using pdx::default_transport::ServiceUtility;
using std::string;
@@ -809,7 +807,6 @@
ok &= setAppCmdlineProperty(&packageList[0]);
ok &= pokeBinderServices();
pokeHalServices();
- ok &= ServiceUtility::PokeServices();
// Disable all the sysfs enables. This is done as a separate loop from
// the enables to allow the same enable to exist in multiple categories.
@@ -847,7 +844,6 @@
setTagsProperty(0);
clearAppProperties();
pokeBinderServices();
- ServiceUtility::PokeServices();
// Set the options back to their defaults.
setTraceOverwriteEnable(true);
diff --git a/cmds/cmd/cmd.cpp b/cmds/cmd/cmd.cpp
index 73d274f..7e05d72 100644
--- a/cmds/cmd/cmd.cpp
+++ b/cmds/cmd/cmd.cpp
@@ -123,6 +123,13 @@
{
signal(SIGPIPE, SIG_IGN);
sp<ProcessState> proc = ProcessState::self();
+ // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
+ // not allowed to spawn any additional threads, but we still spawn
+ // a binder thread from userspace when we call startThreadPool().
+ // This is safe because we only have 2 callbacks, neither of which
+ // block.
+ // See b/36066697 for rationale
+ proc->setThreadPoolMaxThreadCount(0);
proc->startThreadPool();
sp<IServiceManager> sm = defaultServiceManager();
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index a0d987d..6e89f3a 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -1782,6 +1782,16 @@
return ok();
}
+// Copy the contents of a system profile over the data profile.
+binder::Status InstalldNativeService::copySystemProfile(const std::string& systemProfile,
+ int32_t packageUid, const std::string& packageName, bool* _aidl_return) {
+ ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_PACKAGE_NAME(packageName);
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+ *_aidl_return = copy_system_profile(systemProfile, packageUid, packageName);
+ return ok();
+}
+
// TODO: Consider returning error codes.
binder::Status InstalldNativeService::mergeProfiles(int32_t uid, const std::string& packageName,
bool* _aidl_return) {
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 200fc77..a94223c 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -91,6 +91,8 @@
binder::Status mergeProfiles(int32_t uid, const std::string& packageName, bool* _aidl_return);
binder::Status dumpProfiles(int32_t uid, const std::string& packageName,
const std::string& codePaths, bool* _aidl_return);
+ binder::Status copySystemProfile(const std::string& systemProfile,
+ int32_t uid, const std::string& packageName, bool* _aidl_return);
binder::Status clearAppProfiles(const std::string& packageName);
binder::Status destroyAppProfiles(const std::string& packageName);
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 6b99c1d..efcae4f 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -57,6 +57,8 @@
boolean mergeProfiles(int uid, @utf8InCpp String packageName);
boolean dumpProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String codePaths);
+ boolean copySystemProfile(@utf8InCpp String systemProfile, int uid,
+ @utf8InCpp String packageName);
void clearAppProfiles(@utf8InCpp String packageName);
void destroyAppProfiles(@utf8InCpp String packageName);
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 3bbe3a1..5a78d78 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -847,6 +847,66 @@
return true;
}
+bool copy_system_profile(const std::string& system_profile,
+ uid_t packageUid, const std::string& data_profile_location) {
+ unique_fd in_fd(open(system_profile.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC));
+ unique_fd out_fd(open_reference_profile(packageUid,
+ data_profile_location,
+ /*read_write*/ true,
+ /*secondary*/ false));
+ if (in_fd.get() < 0) {
+ PLOG(WARNING) << "Could not open profile " << system_profile;
+ return false;
+ }
+ if (out_fd.get() < 0) {
+ PLOG(WARNING) << "Could not open profile " << data_profile_location;
+ return false;
+ }
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ /* child -- drop privileges before continuing */
+ drop_capabilities(packageUid);
+
+ if (flock(out_fd.get(), LOCK_EX | LOCK_NB) != 0) {
+ if (errno != EWOULDBLOCK) {
+ PLOG(WARNING) << "Error locking profile " << data_profile_location;
+ }
+ // This implies that the app owning this profile is running
+ // (and has acquired the lock).
+ //
+ // The app never acquires the lock for the reference profiles of primary apks.
+ // Only dex2oat from installd will do that. Since installd is single threaded
+ // we should not see this case. Nevertheless be prepared for it.
+ PLOG(WARNING) << "Failed to flock " << data_profile_location;
+ return false;
+ }
+
+ bool truncated = ftruncate(out_fd.get(), 0) == 0;
+ if (!truncated) {
+ PLOG(WARNING) << "Could not truncate " << data_profile_location;
+ }
+
+ // Copy over data.
+ static constexpr size_t kBufferSize = 4 * 1024;
+ char buffer[kBufferSize];
+ while (true) {
+ ssize_t bytes = read(in_fd.get(), buffer, kBufferSize);
+ if (bytes == 0) {
+ break;
+ }
+ write(out_fd.get(), buffer, bytes);
+ }
+ if (flock(out_fd.get(), LOCK_UN) != 0) {
+ PLOG(WARNING) << "Error unlocking profile " << data_profile_location;
+ }
+ exit(0);
+ }
+ /* parent */
+ int return_code = wait_child(pid);
+ return return_code == 0;
+}
+
static std::string replace_file_extension(const std::string& oat_path, const std::string& new_ext) {
// A standard dalvik-cache entry. Replace ".dex" with `new_ext`.
if (EndsWith(oat_path, ".dex")) {
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index cb8aaeb..d171ee5 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -50,6 +50,10 @@
bool dump_profiles(int32_t uid, const std::string& pkgname, const char* code_paths);
+bool copy_system_profile(const std::string& system_profile,
+ uid_t packageUid,
+ const std::string& data_profile_location);
+
bool delete_odex(const char* apk_path, const char* instruction_set, const char* output_path);
bool reconcile_secondary_dex_file(const std::string& dex_path,
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 299ea17..43d0780 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -734,6 +734,10 @@
}
static const char* ParseNull(const char* arg) {
+ // b/38186355. Revert soon.
+ if (strcmp(arg, "!null") == 0) {
+ return nullptr;
+ }
return (strcmp(arg, "!") == 0) ? nullptr : arg;
}
diff --git a/include/input/DisplayViewport.h b/include/input/DisplayViewport.h
new file mode 100644
index 0000000..86da4d3
--- /dev/null
+++ b/include/input/DisplayViewport.h
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+#ifndef _LIBINPUT_DISPLAY_VIEWPORT_H
+#define _LIBINPUT_DISPLAY_VIEWPORT_H
+
+#include <ui/DisplayInfo.h>
+#include <input/Input.h>
+
+namespace android {
+
+/*
+ * Describes how coordinates are mapped on a physical display.
+ * See com.android.server.display.DisplayViewport.
+ */
+struct DisplayViewport {
+ int32_t displayId; // -1 if invalid
+ int32_t orientation;
+ int32_t logicalLeft;
+ int32_t logicalTop;
+ int32_t logicalRight;
+ int32_t logicalBottom;
+ int32_t physicalLeft;
+ int32_t physicalTop;
+ int32_t physicalRight;
+ int32_t physicalBottom;
+ int32_t deviceWidth;
+ int32_t deviceHeight;
+ String8 uniqueId;
+
+ DisplayViewport() :
+ displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0),
+ logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0),
+ physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0),
+ deviceWidth(0), deviceHeight(0) {
+ }
+
+ bool operator==(const DisplayViewport& other) const {
+ return displayId == other.displayId
+ && orientation == other.orientation
+ && logicalLeft == other.logicalLeft
+ && logicalTop == other.logicalTop
+ && logicalRight == other.logicalRight
+ && logicalBottom == other.logicalBottom
+ && physicalLeft == other.physicalLeft
+ && physicalTop == other.physicalTop
+ && physicalRight == other.physicalRight
+ && physicalBottom == other.physicalBottom
+ && deviceWidth == other.deviceWidth
+ && deviceHeight == other.deviceHeight
+ && uniqueId == other.uniqueId;
+ }
+
+ bool operator!=(const DisplayViewport& other) const {
+ return !(*this == other);
+ }
+
+ inline bool isValid() const {
+ return displayId >= 0;
+ }
+
+ void setNonDisplayViewport(int32_t width, int32_t height) {
+ displayId = ADISPLAY_ID_NONE;
+ orientation = DISPLAY_ORIENTATION_0;
+ logicalLeft = 0;
+ logicalTop = 0;
+ logicalRight = width;
+ logicalBottom = height;
+ physicalLeft = 0;
+ physicalTop = 0;
+ physicalRight = width;
+ physicalBottom = height;
+ deviceWidth = width;
+ deviceHeight = height;
+ uniqueId.clear();
+ }
+};
+
+/**
+ * Describes the different type of viewports supported by input flinger.
+ * Keep in sync with values in InputManagerService.java.
+ */
+enum class ViewportType : int32_t {
+ VIEWPORT_INTERNAL = 1,
+ VIEWPORT_EXTERNAL = 2,
+ VIEWPORT_VIRTUAL = 3,
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_DISPLAY_VIEWPORT_H
diff --git a/include/powermanager/IPowerManager.h b/include/powermanager/IPowerManager.h
index 3230189..3c81f0f 100644
--- a/include/powermanager/IPowerManager.h
+++ b/include/powermanager/IPowerManager.h
@@ -44,10 +44,12 @@
NAP = IBinder::FIRST_CALL_TRANSACTION + 10,
IS_INTERACTIVE = IBinder::FIRST_CALL_TRANSACTION + 11,
IS_POWER_SAVE_MODE = IBinder::FIRST_CALL_TRANSACTION + 12,
- SET_POWER_SAVE_MODE = IBinder::FIRST_CALL_TRANSACTION + 13,
- REBOOT = IBinder::FIRST_CALL_TRANSACTION + 14,
- SHUTDOWN = IBinder::FIRST_CALL_TRANSACTION + 15,
- CRASH = IBinder::FIRST_CALL_TRANSACTION + 16,
+ GET_POWER_SAVE_STATE = IBinder::FIRST_CALL_TRANSACTION + 13,
+ SET_POWER_SAVE_MODE = IBinder::FIRST_CALL_TRANSACTION + 14,
+ REBOOT = IBinder::FIRST_CALL_TRANSACTION + 17,
+ REBOOT_SAFE_MODE = IBinder::FIRST_CALL_TRANSACTION + 18,
+ SHUTDOWN = IBinder::FIRST_CALL_TRANSACTION + 19,
+ CRASH = IBinder::FIRST_CALL_TRANSACTION + 20,
};
DECLARE_META_INTERFACE(PowerManager)
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index aec8f10..6fefb38 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -2547,8 +2547,16 @@
objectsSize = 0;
} else {
while (objectsSize > 0) {
- if (mObjects[objectsSize-1] < desired)
+ if (mObjects[objectsSize-1] < desired) {
+ // Check for an object being sliced
+ if (desired < mObjects[objectsSize-1] + sizeof(flat_binder_object)) {
+ ALOGE("Attempt to shrink Parcel would slice an objects allocated memory");
+ return UNKNOWN_ERROR + 0xBADF10;
+ }
break;
+ }
+ // STOPSHIP: Above code to be replaced with following commented code:
+ // if (mObjects[objectsSize-1] + sizeof(flat_binder_object) <= desired) break;
objectsSize--;
}
}
diff --git a/libs/binder/include/binder/Parcelable.h b/libs/binder/include/binder/Parcelable.h
index d5b57ac..a9166e2 100644
--- a/libs/binder/include/binder/Parcelable.h
+++ b/libs/binder/include/binder/Parcelable.h
@@ -36,6 +36,9 @@
public:
virtual ~Parcelable() = default;
+ Parcelable() = default;
+ Parcelable(const Parcelable&) = default;
+
// Write |this| parcelable to the given |parcel|. Keep in mind that
// implementations of writeToParcel must be manually kept in sync
// with readFromParcel and the Java equivalent versions of these methods.
diff --git a/libs/graphicsenv/Android.bp b/libs/graphicsenv/Android.bp
new file mode 100644
index 0000000..f2686d5
--- /dev/null
+++ b/libs/graphicsenv/Android.bp
@@ -0,0 +1,28 @@
+// 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.
+
+cc_library_shared {
+ name: "libgraphicsenv",
+
+ srcs: [
+ "GraphicsEnv.cpp",
+ ],
+
+ shared_libs: [
+ "libnativeloader",
+ "liblog",
+ ],
+
+ export_include_dirs: ["include"],
+}
diff --git a/libs/ui/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
similarity index 98%
rename from libs/ui/GraphicsEnv.cpp
rename to libs/graphicsenv/GraphicsEnv.cpp
index 1d20424..0276008 100644
--- a/libs/ui/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -16,7 +16,7 @@
//#define LOG_NDEBUG 1
#define LOG_TAG "GraphicsEnv"
-#include <ui/GraphicsEnv.h>
+#include <graphicsenv/GraphicsEnv.h>
#include <mutex>
diff --git a/include/ui/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
similarity index 100%
rename from include/ui/GraphicsEnv.h
rename to libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index b891c2a..bb703da 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -112,54 +112,60 @@
void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
Mutex::Autolock lock(mMutex);
- String8 fifo;
+ outResult->appendFormat("%s- BufferQueue ", prefix.string());
+ outResult->appendFormat("mMaxAcquiredBufferCount=%d mMaxDequeuedBufferCount=%d\n",
+ mMaxAcquiredBufferCount, mMaxDequeuedBufferCount);
+ outResult->appendFormat("%s mDequeueBufferCannotBlock=%d mAsyncMode=%d\n", prefix.string(),
+ mDequeueBufferCannotBlock, mAsyncMode);
+ outResult->appendFormat("%s default-size=[%dx%d] default-format=%d ", prefix.string(),
+ mDefaultWidth, mDefaultHeight, mDefaultBufferFormat);
+ outResult->appendFormat("transform-hint=%02x frame-counter=%" PRIu64, mTransformHint,
+ mFrameCounter);
+
+ outResult->appendFormat("\n%sFIFO(%zu):\n", prefix.string(), mQueue.size());
Fifo::const_iterator current(mQueue.begin());
while (current != mQueue.end()) {
- fifo.appendFormat("%02d:%p crop=[%d,%d,%d,%d], "
- "xform=0x%02x, time=%#" PRIx64 ", scale=%s\n",
- current->mSlot, current->mGraphicBuffer.get(),
- current->mCrop.left, current->mCrop.top, current->mCrop.right,
- current->mCrop.bottom, current->mTransform, current->mTimestamp,
- BufferItem::scalingModeName(current->mScalingMode));
+ double timestamp = current->mTimestamp / 1e9;
+ outResult->appendFormat("%s %02d:%p ", prefix.string(), current->mSlot,
+ current->mGraphicBuffer.get());
+ outResult->appendFormat("crop=[%d,%d,%d,%d] ", current->mCrop.left, current->mCrop.top,
+ current->mCrop.right, current->mCrop.bottom);
+ outResult->appendFormat("xform=0x%02x time=%.4f scale=%s\n", current->mTransform, timestamp,
+ BufferItem::scalingModeName(current->mScalingMode));
++current;
}
- outResult->appendFormat("%s-BufferQueue mMaxAcquiredBufferCount=%d, "
- "mMaxDequeuedBufferCount=%d, mDequeueBufferCannotBlock=%d "
- "mAsyncMode=%d, default-size=[%dx%d], default-format=%d, "
- "transform-hint=%02x, FIFO(%zu)={%s}\n", prefix.string(),
- mMaxAcquiredBufferCount, mMaxDequeuedBufferCount,
- mDequeueBufferCannotBlock, mAsyncMode, mDefaultWidth,
- mDefaultHeight, mDefaultBufferFormat, mTransformHint, mQueue.size(),
- fifo.string());
-
+ outResult->appendFormat("%sSlots:\n", prefix.string());
for (int s : mActiveBuffers) {
const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
// A dequeued buffer might be null if it's still being allocated
if (buffer.get()) {
- outResult->appendFormat("%s%s[%02d:%p] state=%-8s, %p "
- "[%4ux%4u:%4u,%3X]\n", prefix.string(),
- (mSlots[s].mBufferState.isAcquired()) ? ">" : " ", s,
- buffer.get(), mSlots[s].mBufferState.string(),
- buffer->handle, buffer->width, buffer->height,
- buffer->stride, buffer->format);
+ outResult->appendFormat("%s %s[%02d:%p] ", prefix.string(),
+ (mSlots[s].mBufferState.isAcquired()) ? ">" : " ", s,
+ buffer.get());
+ outResult->appendFormat("state=%-8s %p frame=%" PRIu64, mSlots[s].mBufferState.string(),
+ buffer->handle, mSlots[s].mFrameNumber);
+ outResult->appendFormat(" [%4ux%4u:%4u,%3X]\n", buffer->width, buffer->height,
+ buffer->stride, buffer->format);
} else {
- outResult->appendFormat("%s [%02d:%p] state=%-8s\n", prefix.string(), s,
- buffer.get(), mSlots[s].mBufferState.string());
+ outResult->appendFormat("%s [%02d:%p] ", prefix.string(), s, buffer.get());
+ outResult->appendFormat("state=%-8s frame=%" PRIu64 "\n",
+ mSlots[s].mBufferState.string(), mSlots[s].mFrameNumber);
}
}
for (int s : mFreeBuffers) {
const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
- outResult->appendFormat("%s [%02d:%p] state=%-8s, %p [%4ux%4u:%4u,%3X]\n",
- prefix.string(), s, buffer.get(), mSlots[s].mBufferState.string(),
- buffer->handle, buffer->width, buffer->height, buffer->stride,
- buffer->format);
+ outResult->appendFormat("%s [%02d:%p] ", prefix.string(), s, buffer.get());
+ outResult->appendFormat("state=%-8s %p frame=%" PRIu64, mSlots[s].mBufferState.string(),
+ buffer->handle, mSlots[s].mFrameNumber);
+ outResult->appendFormat(" [%4ux%4u:%4u,%3X]\n", buffer->width, buffer->height,
+ buffer->stride, buffer->format);
}
for (int s : mFreeSlots) {
const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
- outResult->appendFormat("%s [%02d:%p] state=%-8s\n", prefix.string(), s,
- buffer.get(), mSlots[s].mBufferState.string());
+ outResult->appendFormat("%s [%02d:%p] state=%-8s\n", prefix.string(), s, buffer.get(),
+ mSlots[s].mBufferState.string());
}
}
diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h
index a12bdd7..5290dd5 100644
--- a/libs/nativewindow/include/android/native_window.h
+++ b/libs/nativewindow/include/android/native_window.h
@@ -21,6 +21,7 @@
/**
* @file native_window.h
+ * @brief API for accessing a native window.
*/
#ifndef ANDROID_NATIVE_WINDOW_H
@@ -71,16 +72,16 @@
struct ANativeWindow;
/**
- * {@link ANativeWindow} is opaque type that provides access to a native window.
+ * Opaque type that provides access to a native window.
*
- * A pointer can be obtained using ANativeWindow_fromSurface().
+ * A pointer can be obtained using {@link ANativeWindow_fromSurface()}.
*/
typedef struct ANativeWindow ANativeWindow;
/**
- * {@link ANativeWindow} is a struct that represents a windows buffer.
+ * Struct that represents a windows buffer.
*
- * A pointer can be obtained using ANativeWindow_lock().
+ * A pointer can be obtained using {@link ANativeWindow_lock()}.
*/
typedef struct ANativeWindow_Buffer {
// The number of pixels that are show horizontally.
@@ -90,10 +91,10 @@
int32_t height;
// The number of *pixels* that a line in the buffer takes in
- // memory. This may be >= width.
+ // memory. This may be >= width.
int32_t stride;
- // The format of the buffer. One of AHARDWAREBUFFER_FORMAT_*
+ // The format of the buffer. One of AHARDWAREBUFFER_FORMAT_*
int32_t format;
// The actual bits.
@@ -104,49 +105,53 @@
} ANativeWindow_Buffer;
/**
- * Acquire a reference on the given ANativeWindow object. This prevents the object
+ * Acquire a reference on the given {@link ANativeWindow} object. This prevents the object
* from being deleted until the reference is removed.
*/
void ANativeWindow_acquire(ANativeWindow* window);
/**
- * Remove a reference that was previously acquired with ANativeWindow_acquire().
+ * Remove a reference that was previously acquired with {@link ANativeWindow_acquire()}.
*/
void ANativeWindow_release(ANativeWindow* window);
/**
- * Return the current width in pixels of the window surface. Returns a
- * negative value on error.
+ * Return the current width in pixels of the window surface.
+ *
+ * \return negative value on error.
*/
int32_t ANativeWindow_getWidth(ANativeWindow* window);
/**
- * Return the current height in pixels of the window surface. Returns a
- * negative value on error.
+ * Return the current height in pixels of the window surface.
+ *
+ * \return a negative value on error.
*/
int32_t ANativeWindow_getHeight(ANativeWindow* window);
/**
- * Return the current pixel format (AHARDWAREBUFFER_FORMAT_*) of the window surface. Returns a
- * negative value on error.
+ * Return the current pixel format (AHARDWAREBUFFER_FORMAT_*) of the window surface.
+ *
+ * \return a negative value on error.
*/
int32_t ANativeWindow_getFormat(ANativeWindow* window);
/**
* Change the format and size of the window buffers.
*
- * format: one of AHARDWAREBUFFER_FORMAT_ constants
- *
* The width and height control the number of pixels in the buffers, not the
- * dimensions of the window on screen. If these are different than the
- * window's physical size, then it buffer will be scaled to match that size
- * when compositing it to the screen.
+ * dimensions of the window on screen. If these are different than the
+ * window's physical size, then its buffer will be scaled to match that size
+ * when compositing it to the screen. The width and height must be either both zero
+ * or both non-zero.
*
* For all of these parameters, if 0 is supplied then the window's base
* value will come back in force.
*
- * width and height must be either both zero or both non-zero.
- *
+ * \param width width of the buffers in pixels.
+ * \param height height of the buffers in pixels.
+ * \param format one of AHARDWAREBUFFER_FORMAT_* constants.
+ * \return 0 for success, or a negative value on error.
*/
int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
int32_t width, int32_t height, int32_t format);
@@ -157,7 +162,9 @@
* function, it contains the dirty region, that is, the region the caller
* intends to redraw. When the function returns, inOutDirtyBounds is updated
* with the actual area the caller needs to redraw -- this region is often
- * extended by ANativeWindow_lock.
+ * extended by {@link ANativeWindow_lock}.
+ *
+ * \return 0 for success, or a negative value on error.
*/
int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
ARect* inOutDirtyBounds);
@@ -165,6 +172,8 @@
/**
* Unlock the window's drawing surface after previously locking it,
* posting the new buffer to the display.
+ *
+ * \return 0 for success, or a negative value on error.
*/
int32_t ANativeWindow_unlockAndPost(ANativeWindow* window);
@@ -173,9 +182,8 @@
/**
* Set a transform that will be applied to future buffers posted to the window.
*
- * @param transform combination of {@link ANativeWindowTransform} flags
- * @return 0 if successful
- * @return -EINVAL if @param transform is invalid
+ * \param transform combination of {@link ANativeWindowTransform} flags
+ * \return 0 for success, or -EINVAL if \p transform is invalid
*/
int32_t ANativeWindow_setBuffersTransform(ANativeWindow* window, int32_t transform);
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index 42ef075..6429c52 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -530,7 +530,6 @@
/* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C).
* android_native_window_t is deprecated.
*/
-typedef struct ANativeWindow ANativeWindow;
typedef struct ANativeWindow android_native_window_t __deprecated;
/*
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index cb661e1..c2e93d8 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -53,7 +53,6 @@
"GraphicBuffer.cpp",
"GraphicBufferAllocator.cpp",
"GraphicBufferMapper.cpp",
- "GraphicsEnv.cpp",
"HdrCapabilities.cpp",
"PixelFormat.cpp",
"Rect.cpp",
@@ -67,7 +66,6 @@
"android.hardware.configstore@1.0",
"android.hardware.configstore-utils",
"libbase",
- "libnativeloader",
"libcutils",
"libhardware",
"libhidlbase",
@@ -75,6 +73,7 @@
"libsync",
"libutils",
"liblog",
+ "libgraphicsenv",
],
static_libs: [
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
index 3876745..fa78b1c 100644
--- a/libs/vr/libdvr/Android.bp
+++ b/libs/vr/libdvr/Android.bp
@@ -19,47 +19,69 @@
export_include_dirs: ["include"],
}
-cc_library_static {
+cflags = [
+ "-DLOG_TAG=\"libdvr\"",
+]
+
+srcs = [
+ "dvr_api.cpp",
+ "dvr_buffer.cpp",
+ "dvr_buffer_queue.cpp",
+ "dvr_display_manager.cpp",
+ "dvr_hardware_composer_client.cpp",
+ "dvr_surface.cpp",
+ "dvr_vsync.cpp",
+]
+
+static_libs = [
+ "libbufferhub",
+ "libbufferhubqueue",
+ "libdisplay",
+ "libvrsensor",
+ "libvirtualtouchpadclient",
+ "libvr_hwc-impl",
+ "libvr_hwc-binder",
+ "libgrallocusage",
+ "libpdx_default_transport",
+]
+
+shared_libs = [
+ "android.hardware.graphics.bufferqueue@1.0",
+ "android.hidl.token@1.0-utils",
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libcutils",
+ "libutils",
+ "libnativewindow",
+ "libgui",
+ "libui",
+]
+
+cc_library_shared {
name: "libdvr",
owner: "google",
-
- cflags: [
- "-fvisibility=hidden",
- "-DLOG_TAG=\"libdvr\"",
- "-DDVR_EXPORT=__attribute__((visibility(\"default\")))",
- ],
-
+ cflags: cflags,
header_libs: ["libdvr_headers"],
export_header_lib_headers: ["libdvr_headers"],
+ srcs: srcs,
+ static_libs: static_libs,
+ shared_libs: shared_libs,
+ version_script: "exported_apis.lds",
+}
- srcs: [
- "dvr_api.cpp",
- "dvr_buffer.cpp",
- "dvr_buffer_queue.cpp",
- "dvr_display_manager.cpp",
- "dvr_hardware_composer_client.cpp",
- "dvr_surface.cpp",
- "dvr_vsync.cpp",
- ],
-
- static_libs: [
- "libbufferhub",
- "libbufferhubqueue",
- "libdisplay",
- "libvrsensor",
- "libvirtualtouchpadclient",
- "libvr_hwc-impl",
- "libvr_hwc-binder",
- "libgrallocusage",
- ],
-
- shared_libs: [
- "android.hardware.graphics.bufferqueue@1.0",
- "android.hidl.token@1.0-utils",
- "libbase",
- "libnativewindow",
- ],
-
+// Also build a static libdvr for linking into tests. The linker script
+// restricting function access in the shared lib makes it inconvenient to use in
+// test code.
+cc_library_static {
+ name: "libdvr_static",
+ owner: "google",
+ cflags: cflags,
+ header_libs: ["libdvr_headers"],
+ export_header_lib_headers: ["libdvr_headers"],
+ srcs: srcs,
+ static_libs: static_libs,
+ shared_libs: shared_libs,
}
subdirs = [
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
index 4d7e1a6..2c95583 100644
--- a/libs/vr/libdvr/dvr_api.cpp
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -18,7 +18,7 @@
extern "C" {
-DVR_EXPORT int dvrGetApi(void* api, size_t struct_size, int version) {
+int dvrGetApi(void* api, size_t struct_size, int version) {
ALOGI("dvrGetApi: api=%p struct_size=%zu version=%d", api, struct_size,
version);
if (version == 1) {
diff --git a/libs/vr/libdvr/exported_apis.lds b/libs/vr/libdvr/exported_apis.lds
new file mode 100644
index 0000000..5ecb498
--- /dev/null
+++ b/libs/vr/libdvr/exported_apis.lds
@@ -0,0 +1,9 @@
+{
+ global:
+ # Whitelist the function to load the dvr api.
+ dvrGetApi;
+
+ local:
+ # Hide everything else.
+ *;
+};
diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp
index af202b4..ef746e2 100644
--- a/libs/vr/libdvr/tests/Android.bp
+++ b/libs/vr/libdvr/tests/Android.bp
@@ -25,7 +25,7 @@
]
static_libraries = [
- "libdvr",
+ "libdvr_static",
"libbufferhubqueue",
"libbufferhub",
"libchrome",
diff --git a/libs/vr/libpdx_uds/Android.bp b/libs/vr/libpdx_uds/Android.bp
index cfc2022..82a5ea7 100644
--- a/libs/vr/libpdx_uds/Android.bp
+++ b/libs/vr/libpdx_uds/Android.bp
@@ -24,6 +24,9 @@
"libbase",
"libpdx",
],
+ whole_static_libs: [
+ "libselinux",
+ ],
}
cc_test {
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
index d96eeff..27a56f9 100644
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ b/libs/vr/libpdx_uds/service_endpoint.cpp
@@ -11,6 +11,7 @@
#include <android-base/strings.h>
#include <cutils/sockets.h>
#include <pdx/service.h>
+#include <selinux/selinux.h>
#include <uds/channel_manager.h>
#include <uds/client_channel_factory.h>
#include <uds/ipc_helper.h>
@@ -364,6 +365,36 @@
Status<void> Endpoint::CreateChannelSocketPair(LocalHandle* local_socket,
LocalHandle* remote_socket) {
Status<void> status;
+ char* endpoint_context = nullptr;
+ // Make sure the channel socket has the correct SELinux label applied.
+ // Here we get the label from the endpoint file descriptor, which should be
+ // something like "u:object_r:pdx_service_endpoint_socket:s0" and replace
+ // "endpoint" with "channel" to produce the channel label such as this:
+ // "u:object_r:pdx_service_channel_socket:s0".
+ if (fgetfilecon_raw(socket_fd_.Get(), &endpoint_context) > 0) {
+ std::string channel_context = endpoint_context;
+ freecon(endpoint_context);
+ const std::string suffix = "_endpoint_socket";
+ auto pos = channel_context.find(suffix);
+ if (pos != std::string::npos) {
+ channel_context.replace(pos, suffix.size(), "_channel_socket");
+ } else {
+ ALOGW(
+ "Endpoint::CreateChannelSocketPair: Endpoint security context '%s' "
+ "does not contain expected substring '%s'",
+ channel_context.c_str(), suffix.c_str());
+ }
+ ALOGE_IF(setsockcreatecon_raw(channel_context.c_str()) == -1,
+ "Endpoint::CreateChannelSocketPair: Failed to set channel socket "
+ "security context: %s",
+ strerror(errno));
+ } else {
+ ALOGE(
+ "Endpoint::CreateChannelSocketPair: Failed to obtain the endpoint "
+ "socket's security context: %s",
+ strerror(errno));
+ }
+
int channel_pair[2] = {};
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_pair) == -1) {
ALOGE("Endpoint::CreateChannelSocketPair: Failed to create socket pair: %s",
@@ -372,6 +403,8 @@
return status;
}
+ setsockcreatecon_raw(nullptr);
+
local_socket->Reset(channel_pair[0]);
remote_socket->Reset(channel_pair[1]);
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index a895e63..bff80cd 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -81,7 +81,7 @@
shared_libs: [
// ***** DO NOT ADD NEW DEPENDENCIES HERE *****
// In particular, DO NOT add libutils nor anything "above" libui
- "libui",
+ "libgraphicsenv",
"libnativewindow",
"libbacktrace",
],
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 7d20ba1..1116400 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -28,7 +28,7 @@
#include <cutils/properties.h>
#include <log/log.h>
-#include <ui/GraphicsEnv.h>
+#include <graphicsenv/GraphicsEnv.h>
#include "egl_trace.h"
#include "egldefs.h"
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 8af9038..97565aa 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -227,18 +227,65 @@
// --- InputReaderConfiguration ---
-bool InputReaderConfiguration::getDisplayInfo(bool external, DisplayViewport* outViewport) const {
- const DisplayViewport& viewport = external ? mExternalDisplay : mInternalDisplay;
- if (viewport.displayId >= 0) {
- *outViewport = viewport;
+bool InputReaderConfiguration::getDisplayViewport(ViewportType viewportType,
+ const String8* uniqueDisplayId, DisplayViewport* outViewport) const {
+ const DisplayViewport* viewport = NULL;
+ if (viewportType == ViewportType::VIEWPORT_VIRTUAL && uniqueDisplayId != NULL) {
+ for (DisplayViewport currentViewport : mVirtualDisplays) {
+ if (currentViewport.uniqueId == *uniqueDisplayId) {
+ viewport = ¤tViewport;
+ break;
+ }
+ }
+ } else if (viewportType == ViewportType::VIEWPORT_EXTERNAL) {
+ viewport = &mExternalDisplay;
+ } else if (viewportType == ViewportType::VIEWPORT_INTERNAL) {
+ viewport = &mInternalDisplay;
+ }
+
+ if (viewport != NULL && viewport->displayId >= 0) {
+ *outViewport = *viewport;
return true;
}
return false;
}
-void InputReaderConfiguration::setDisplayInfo(bool external, const DisplayViewport& viewport) {
- DisplayViewport& v = external ? mExternalDisplay : mInternalDisplay;
- v = viewport;
+void InputReaderConfiguration::setPhysicalDisplayViewport(ViewportType viewportType,
+ const DisplayViewport& viewport) {
+ if (viewportType == ViewportType::VIEWPORT_EXTERNAL) {
+ mExternalDisplay = viewport;
+ } else if (viewportType == ViewportType::VIEWPORT_INTERNAL) {
+ mInternalDisplay = viewport;
+ }
+}
+
+void InputReaderConfiguration::setVirtualDisplayViewports(
+ const Vector<DisplayViewport>& viewports) {
+ mVirtualDisplays = viewports;
+}
+
+void InputReaderConfiguration::dump(String8& dump) const {
+ dump.append(INDENT4 "ViewportInternal:\n");
+ dumpViewport(dump, mInternalDisplay);
+ dump.append(INDENT4 "ViewportExternal:\n");
+ dumpViewport(dump, mExternalDisplay);
+ dump.append(INDENT4 "ViewportVirtual:\n");
+ for (const DisplayViewport& viewport : mVirtualDisplays) {
+ dumpViewport(dump, viewport);
+ }
+}
+
+void InputReaderConfiguration::dumpViewport(String8& dump, const DisplayViewport& viewport) const {
+ dump.appendFormat(INDENT5 "Viewport: displayId=%d, orientation=%d, uniqueId='%s', "
+ "logicalFrame=[%d, %d, %d, %d], "
+ "physicalFrame=[%d, %d, %d, %d], "
+ "deviceSize=[%d, %d]\n",
+ viewport.displayId, viewport.orientation, viewport.uniqueId.c_str(),
+ viewport.logicalLeft, viewport.logicalTop,
+ viewport.logicalRight, viewport.logicalBottom,
+ viewport.physicalLeft, viewport.physicalTop,
+ viewport.physicalRight, viewport.physicalBottom,
+ viewport.deviceWidth, viewport.deviceHeight);
}
@@ -863,6 +910,9 @@
mConfig.pointerGestureMovementSpeedRatio);
dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
mConfig.pointerGestureZoomSpeedRatio);
+
+ dump.append(INDENT3 "Viewports:\n");
+ mConfig.dump(dump);
}
void InputReader::monitor() {
@@ -2199,7 +2249,7 @@
if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
DisplayViewport v;
- if (config->getDisplayInfo(false /*external*/, &v)) {
+ if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, NULL, &v)) {
mOrientation = v.orientation;
} else {
mOrientation = DISPLAY_ORIENTATION_0;
@@ -2572,7 +2622,7 @@
if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
DisplayViewport v;
- if (config->getDisplayInfo(false /*external*/, &v)) {
+ if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, NULL, &v)) {
mOrientation = v.orientation;
} else {
mOrientation = DISPLAY_ORIENTATION_0;
@@ -3017,7 +3067,7 @@
}
void TouchInputMapper::dump(String8& dump) {
- dump.append(INDENT2 "Touch Input Mapper:\n");
+ dump.appendFormat(INDENT2 "Touch Input Mapper (mode - %s):\n", modeToString(mDeviceMode));
dumpParameters(dump);
dumpVirtualKeys(dump);
dumpRawPointerAxes(dump);
@@ -3109,6 +3159,22 @@
}
}
+const char* TouchInputMapper::modeToString(DeviceMode deviceMode) {
+ switch (deviceMode) {
+ case DEVICE_MODE_DISABLED:
+ return "disabled";
+ case DEVICE_MODE_DIRECT:
+ return "direct";
+ case DEVICE_MODE_UNSCALED:
+ return "unscaled";
+ case DEVICE_MODE_NAVIGATION:
+ return "navigation";
+ case DEVICE_MODE_POINTER:
+ return "pointer";
+ }
+ return "unknown";
+}
+
void TouchInputMapper::configure(nsecs_t when,
const InputReaderConfiguration* config, uint32_t changes) {
InputMapper::configure(when, config, changes);
@@ -3234,9 +3300,11 @@
|| mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
|| mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
mParameters.hasAssociatedDisplay = true;
- mParameters.associatedDisplayIsExternal =
- mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
- && getDevice()->isExternal();
+ if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
+ mParameters.associatedDisplayIsExternal = getDevice()->isExternal();
+ getDevice()->getConfiguration().tryGetProperty(String8("touch.displayId"),
+ mParameters.uniqueDisplayId);
+ }
}
// Initial downs on external touch devices should wake the device.
@@ -3278,9 +3346,11 @@
ALOG_ASSERT(false);
}
- dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
+ dump.appendFormat(
+ INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s, displayId='%s'\n",
toString(mParameters.hasAssociatedDisplay),
- toString(mParameters.associatedDisplayIsExternal));
+ toString(mParameters.associatedDisplayIsExternal),
+ mParameters.uniqueDisplayId.c_str());
dump.appendFormat(INDENT4 "OrientationAware: %s\n",
toString(mParameters.orientationAware));
}
@@ -3356,7 +3426,21 @@
// Get associated display dimensions.
DisplayViewport newViewport;
if (mParameters.hasAssociatedDisplay) {
- if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
+ const String8* uniqueDisplayId = NULL;
+ ViewportType viewportTypeToUse;
+
+ if (mParameters.associatedDisplayIsExternal) {
+ viewportTypeToUse = ViewportType::VIEWPORT_EXTERNAL;
+ } else if (!mParameters.uniqueDisplayId.isEmpty()) {
+ // If the IDC file specified a unique display Id, then it expects to be linked to a
+ // virtual display with the same unique ID.
+ uniqueDisplayId = &mParameters.uniqueDisplayId;
+ viewportTypeToUse = ViewportType::VIEWPORT_VIRTUAL;
+ } else {
+ viewportTypeToUse = ViewportType::VIEWPORT_INTERNAL;
+ }
+
+ if (!mConfig.getDisplayViewport(viewportTypeToUse, uniqueDisplayId, &newViewport)) {
ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
"display. The device will be inoperable until the display size "
"becomes available.",
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 647f271..157fa4f 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -21,6 +21,7 @@
#include "PointerControllerInterface.h"
#include "InputListener.h"
+#include <input/DisplayViewport.h>
#include <input/Input.h>
#include <input/VelocityControl.h>
#include <input/VelocityTracker.h>
@@ -52,70 +53,6 @@
class InputMapper;
/*
- * Describes how coordinates are mapped on a physical display.
- * See com.android.server.display.DisplayViewport.
- */
-struct DisplayViewport {
- int32_t displayId; // -1 if invalid
- int32_t orientation;
- int32_t logicalLeft;
- int32_t logicalTop;
- int32_t logicalRight;
- int32_t logicalBottom;
- int32_t physicalLeft;
- int32_t physicalTop;
- int32_t physicalRight;
- int32_t physicalBottom;
- int32_t deviceWidth;
- int32_t deviceHeight;
-
- DisplayViewport() :
- displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0),
- logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0),
- physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0),
- deviceWidth(0), deviceHeight(0) {
- }
-
- bool operator==(const DisplayViewport& other) const {
- return displayId == other.displayId
- && orientation == other.orientation
- && logicalLeft == other.logicalLeft
- && logicalTop == other.logicalTop
- && logicalRight == other.logicalRight
- && logicalBottom == other.logicalBottom
- && physicalLeft == other.physicalLeft
- && physicalTop == other.physicalTop
- && physicalRight == other.physicalRight
- && physicalBottom == other.physicalBottom
- && deviceWidth == other.deviceWidth
- && deviceHeight == other.deviceHeight;
- }
-
- bool operator!=(const DisplayViewport& other) const {
- return !(*this == other);
- }
-
- inline bool isValid() const {
- return displayId >= 0;
- }
-
- void setNonDisplayViewport(int32_t width, int32_t height) {
- displayId = ADISPLAY_ID_NONE;
- orientation = DISPLAY_ORIENTATION_0;
- logicalLeft = 0;
- logicalTop = 0;
- logicalRight = width;
- logicalBottom = height;
- physicalLeft = 0;
- physicalTop = 0;
- physicalRight = width;
- physicalBottom = height;
- deviceWidth = width;
- deviceHeight = height;
- }
-};
-
-/*
* Input reader configuration.
*
* Specifies various options that modify the behavior of the input reader.
@@ -264,12 +201,19 @@
pointerGestureZoomSpeedRatio(0.3f),
showTouches(false) { }
- bool getDisplayInfo(bool external, DisplayViewport* outViewport) const;
- void setDisplayInfo(bool external, const DisplayViewport& viewport);
+ bool getDisplayViewport(ViewportType viewportType, const String8* displayId,
+ DisplayViewport* outViewport) const;
+ void setPhysicalDisplayViewport(ViewportType viewportType, const DisplayViewport& viewport);
+ void setVirtualDisplayViewports(const Vector<DisplayViewport>& viewports);
+
+
+ void dump(String8& dump) const;
+ void dumpViewport(String8& dump, const DisplayViewport& viewport) const;
private:
DisplayViewport mInternalDisplay;
DisplayViewport mExternalDisplay;
+ Vector<DisplayViewport> mVirtualDisplays;
};
@@ -1358,6 +1302,7 @@
bool associatedDisplayIsExternal;
bool orientationAware;
bool hasButtonUnderPad;
+ String8 uniqueDisplayId;
enum GestureMode {
GESTURE_MODE_SINGLE_TOUCH,
@@ -1906,6 +1851,8 @@
const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
static void assignPointerIds(const RawState* last, RawState* current);
+
+ const char* modeToString(DeviceMode deviceMode);
};
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 7082fe1..76291a5 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -30,6 +30,10 @@
static const int32_t DISPLAY_ID = 0;
static const int32_t DISPLAY_WIDTH = 480;
static const int32_t DISPLAY_HEIGHT = 800;
+static const int32_t VIRTUAL_DISPLAY_ID = 1;
+static const int32_t VIRTUAL_DISPLAY_WIDTH = 400;
+static const int32_t VIRTUAL_DISPLAY_HEIGHT = 500;
+static const char* VIRTUAL_DISPLAY_UNIQUE_ID = "Vr-display-unique-ID";
// Error tolerance for floating point assertions.
static const float EPSILON = 0.001f;
@@ -137,25 +141,19 @@
FakeInputReaderPolicy() {
}
- void setDisplayInfo(int32_t displayId, int32_t width, int32_t height, int32_t orientation) {
+ void setDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation,
+ const String8& uniqueId) {
+ DisplayViewport v = createDisplayViewport(displayId, width, height, orientation, uniqueId);
// Set the size of both the internal and external display at the same time.
- bool isRotated = (orientation == DISPLAY_ORIENTATION_90
- || orientation == DISPLAY_ORIENTATION_270);
- DisplayViewport v;
- v.displayId = displayId;
- v.orientation = orientation;
- v.logicalLeft = 0;
- v.logicalTop = 0;
- v.logicalRight = isRotated ? height : width;
- v.logicalBottom = isRotated ? width : height;
- v.physicalLeft = 0;
- v.physicalTop = 0;
- v.physicalRight = isRotated ? height : width;
- v.physicalBottom = isRotated ? width : height;
- v.deviceWidth = isRotated ? height : width;
- v.deviceHeight = isRotated ? width : height;
- mConfig.setDisplayInfo(false /*external*/, v);
- mConfig.setDisplayInfo(true /*external*/, v);
+ mConfig.setPhysicalDisplayViewport(ViewportType::VIEWPORT_INTERNAL, v);
+ mConfig.setPhysicalDisplayViewport(ViewportType::VIEWPORT_EXTERNAL, v);
+ }
+
+ void setVirtualDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation,
+ const String8& uniqueId) {
+ Vector<DisplayViewport> viewports;
+ viewports.push_back(createDisplayViewport(displayId, width, height, orientation, uniqueId));
+ mConfig.setVirtualDisplayViewports(viewports);
}
void addExcludedDeviceName(const String8& deviceName) {
@@ -204,6 +202,27 @@
}
private:
+ DisplayViewport createDisplayViewport(int32_t displayId, int32_t width, int32_t height,
+ int32_t orientation, const String8& uniqueId) {
+ bool isRotated = (orientation == DISPLAY_ORIENTATION_90
+ || orientation == DISPLAY_ORIENTATION_270);
+ DisplayViewport v;
+ v.displayId = displayId;
+ v.orientation = orientation;
+ v.logicalLeft = 0;
+ v.logicalTop = 0;
+ v.logicalRight = isRotated ? height : width;
+ v.logicalBottom = isRotated ? width : height;
+ v.physicalLeft = 0;
+ v.physicalTop = 0;
+ v.physicalRight = isRotated ? height : width;
+ v.physicalBottom = isRotated ? width : height;
+ v.deviceWidth = isRotated ? height : width;
+ v.deviceHeight = isRotated ? width : height;
+ v.uniqueId = uniqueId;
+ return v;
+ }
+
virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) {
*outConfig = mConfig;
}
@@ -1578,7 +1597,13 @@
void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
int32_t orientation) {
- mFakePolicy->setDisplayInfo(displayId, width, height, orientation);
+ mFakePolicy->setDisplayViewport(displayId, width, height, orientation, String8::empty());
+ configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+ }
+
+ void setVirtualDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
+ int32_t orientation, const String8& uniqueId) {
+ mFakePolicy->setVirtualDisplayViewport(displayId, width, height, orientation, uniqueId);
configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
}
@@ -2884,6 +2909,8 @@
static const int32_t RAW_SLOT_MAX;
static const float X_PRECISION;
static const float Y_PRECISION;
+ static const float X_PRECISION_VIRTUAL;
+ static const float Y_PRECISION_VIRTUAL;
static const float GEOMETRIC_SCALE;
static const TouchAffineTransformation AFFINE_TRANSFORM;
@@ -2905,6 +2932,7 @@
};
void prepareDisplay(int32_t orientation);
+ void prepareVirtualDisplay(int32_t orientation);
void prepareVirtualKeys();
void prepareLocationCalibration();
int32_t toRawX(float displayX);
@@ -2912,7 +2940,10 @@
float toCookedX(float rawX, float rawY);
float toCookedY(float rawX, float rawY);
float toDisplayX(int32_t rawX);
+ float toDisplayX(int32_t rawX, int32_t displayWidth);
float toDisplayY(int32_t rawY);
+ float toDisplayY(int32_t rawY, int32_t displayHeight);
+
};
const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
@@ -2937,6 +2968,10 @@
const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
+const float TouchInputMapperTest::X_PRECISION_VIRTUAL =
+ float(RAW_X_MAX - RAW_X_MIN + 1) / VIRTUAL_DISPLAY_WIDTH;
+const float TouchInputMapperTest::Y_PRECISION_VIRTUAL =
+ float(RAW_Y_MAX - RAW_Y_MIN + 1) / VIRTUAL_DISPLAY_HEIGHT;
const TouchAffineTransformation TouchInputMapperTest::AFFINE_TRANSFORM =
TouchAffineTransformation(1, -2, 3, -4, 5, -6);
@@ -2953,6 +2988,11 @@
setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation);
}
+void TouchInputMapperTest::prepareVirtualDisplay(int32_t orientation) {
+ setVirtualDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
+ VIRTUAL_DISPLAY_HEIGHT, orientation, String8(VIRTUAL_DISPLAY_UNIQUE_ID));
+}
+
void TouchInputMapperTest::prepareVirtualKeys() {
mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[0]);
mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[1]);
@@ -2983,11 +3023,19 @@
}
float TouchInputMapperTest::toDisplayX(int32_t rawX) {
- return float(rawX - RAW_X_MIN) * DISPLAY_WIDTH / (RAW_X_MAX - RAW_X_MIN + 1);
+ return toDisplayX(rawX, DISPLAY_WIDTH);
+}
+
+float TouchInputMapperTest::toDisplayX(int32_t rawX, int32_t displayWidth) {
+ return float(rawX - RAW_X_MIN) * displayWidth / (RAW_X_MAX - RAW_X_MIN + 1);
}
float TouchInputMapperTest::toDisplayY(int32_t rawY) {
- return float(rawY - RAW_Y_MIN) * DISPLAY_HEIGHT / (RAW_Y_MAX - RAW_Y_MIN + 1);
+ return toDisplayY(rawY, DISPLAY_HEIGHT);
+}
+
+float TouchInputMapperTest::toDisplayY(int32_t rawY, int32_t displayHeight) {
+ return float(rawY - RAW_Y_MIN) * displayHeight / (RAW_Y_MAX - RAW_Y_MIN + 1);
}
@@ -3447,6 +3495,105 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
+TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDisplay) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ addConfigurationProperty("touch.displayId", VIRTUAL_DISPLAY_UNIQUE_ID);
+
+ prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION);
+ prepareVirtualKeys();
+ addMapperAndConfigure(mapper);
+
+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+ NotifyMotionArgs motionArgs;
+
+ // Down.
+ int32_t x = 100;
+ int32_t y = 125;
+ processDown(mapper, x, y);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+ ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.flags);
+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, motionArgs.edgeFlags);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
+ 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
+ ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+ // Move.
+ x += 50;
+ y += 75;
+ processMove(mapper, x, y);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+ ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.flags);
+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, motionArgs.edgeFlags);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
+ 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
+ ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+ // Up.
+ processUp(mapper);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+ ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.flags);
+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, motionArgs.edgeFlags);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
+ 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
+ ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+ // Should not have sent any more keys or motions.
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
addConfigurationProperty("touch.deviceType", "touchScreen");
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3cbc2f4..0f93cd7 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -699,7 +699,16 @@
mName.string(), z, to_string(error).c_str(),
static_cast<int32_t>(error));
- error = hwcLayer->setInfo(s.type, s.appId);
+ int type = s.type;
+ int appId = s.appId;
+ sp<Layer> parent = mParent.promote();
+ if (parent.get()) {
+ auto& parentState = parent->getDrawingState();
+ type = parentState.type;
+ appId = parentState.appId;
+ }
+
+ error = hwcLayer->setInfo(type, appId);
ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)",
mName.string(), static_cast<int32_t>(error));
#else
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 505e81c..32fdc35 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1116,9 +1116,14 @@
void SurfaceFlinger::resyncWithRateLimit() {
static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
- if (systemTime() - mLastSwapTime > kIgnoreDelay) {
+
+ // No explicit locking is needed here since EventThread holds a lock while calling this method
+ static nsecs_t sLastResyncAttempted = 0;
+ const nsecs_t now = systemTime();
+ if (now - sLastResyncAttempted > kIgnoreDelay) {
resyncToHardwareVsync(false);
}
+ sLastResyncAttempted = now;
}
void SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type,
diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc
index ff6be81..aea602b 100644
--- a/services/surfaceflinger/surfaceflinger.rc
+++ b/services/surfaceflinger/surfaceflinger.rc
@@ -4,6 +4,6 @@
group graphics drmrpc readproc
onrestart restart zygote
writepid /dev/stune/foreground/tasks
- socket pdx/system/vr/display/client stream 0666 system graphics
- socket pdx/system/vr/display/manager stream 0666 system graphics
- socket pdx/system/vr/display/vsync stream 0666 system graphics
+ socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
+ socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
+ socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
diff --git a/services/vr/bufferhubd/bufferhubd.rc b/services/vr/bufferhubd/bufferhubd.rc
index 8d57723..46fe5f9 100644
--- a/services/vr/bufferhubd/bufferhubd.rc
+++ b/services/vr/bufferhubd/bufferhubd.rc
@@ -3,4 +3,4 @@
user system
group system
writepid /dev/cpuset/tasks
- socket pdx/system/buffer_hub/client stream 0660 system system
+ socket pdx/system/buffer_hub/client stream 0660 system system u:object_r:pdx_bufferhub_client_endpoint_socket:s0
diff --git a/services/vr/performanced/performanced.rc b/services/vr/performanced/performanced.rc
index 6283f37..2605a47 100644
--- a/services/vr/performanced/performanced.rc
+++ b/services/vr/performanced/performanced.rc
@@ -3,4 +3,4 @@
user root
group system readproc
writepid /dev/cpuset/tasks
- socket pdx/system/performance/client stream 0666 system system
+ socket pdx/system/performance/client stream 0666 system system u:object_r:pdx_performance_client_endpoint_socket:s0
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
index ee09d48..f0bdcd9 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
@@ -18,7 +18,7 @@
// use it to look up device configuration, so it must be unique. Vendor and
// product values must be 0 to indicate an internal device and prevent a
// similar lookup that could conflict with a physical device.
-static const char* const kDeviceNameFormat = "vr virtual touchpad %d";
+static const char* const kDeviceNameFormat = "vr-virtual-touchpad-%d";
static constexpr int16_t kDeviceBusType = BUS_VIRTUAL;
static constexpr int16_t kDeviceVendor = 0;
static constexpr int16_t kDeviceProduct = 0;
diff --git a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
index 24cfdf8..564bcd7 100644
--- a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
+++ b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
@@ -139,7 +139,7 @@
SCOPED_TRACE(t);
uidev = touchpad->injector[t].GetUiDev();
String8 name;
- name.appendFormat("vr virtual touchpad %d", t);
+ name.appendFormat("vr-virtual-touchpad-%d", t);
EXPECT_EQ(name, uidev->name);
for (int i = 0; i < ABS_CNT; ++i) {
EXPECT_EQ(0, uidev->absmin[i]);
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 6149894..5f9b357 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -75,6 +75,7 @@
"libbase",
"liblog",
"libui",
+ "libgraphicsenv",
"libutils",
"libcutils",
"libz",
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 0005a90..a869317 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -28,7 +28,7 @@
#include <android/dlext.h>
#include <cutils/properties.h>
-#include <ui/GraphicsEnv.h>
+#include <graphicsenv/GraphicsEnv.h>
#include <utils/Vector.h>
#include "driver.h"