Merge "TimeStats: refactor libtimestats blueprint interface"
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 5186ad3..cf75bba 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -854,7 +854,6 @@
tags |= c.tags;
}
}
- ok &= setTagsProperty(tags);
bool coreServicesTagEnabled = false;
for (size_t i = 0; i < arraysize(k_categories); i++) {
@@ -876,9 +875,11 @@
packageList += android::base::GetProperty(k_coreServicesProp, "");
}
ok &= setAppCmdlineProperty(&packageList[0]);
+ ok &= setTagsProperty(tags);
+#if !ATRACE_SHMEM
ok &= pokeBinderServices();
pokeHalServices();
-
+#endif
if (g_tracePdx) {
ok &= ServiceUtility::PokeServices();
}
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index a10baa6..e7b0d5d 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -273,7 +273,7 @@
ps->startThreadPool();
ps->giveThreadPoolName();
sAppDataIsolationEnabled = android::base::GetBoolProperty(
- kAppDataIsolationEnabledProperty, false);
+ kAppDataIsolationEnabledProperty, true);
return android::OK;
}
diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp
index 0d6c31e..675aad6 100644
--- a/cmds/surfacereplayer/replayer/Replayer.cpp
+++ b/cmds/surfacereplayer/replayer/Replayer.cpp
@@ -606,7 +606,7 @@
pc.viewport().bottom());
Rect frame = Rect(pc.frame().left(), pc.frame().top(), pc.frame().right(), pc.frame().bottom());
- t.setDisplayProjection(mDisplays[id], pc.orientation(), viewport, frame);
+ t.setDisplayProjection(mDisplays[id], ui::toRotation(pc.orientation()), viewport, frame);
}
status_t Replayer::createSurfaceControl(
diff --git a/include/android/bitmap.h b/include/android/bitmap.h
index 01cf2f8..41718b2 100644
--- a/include/android/bitmap.h
+++ b/include/android/bitmap.h
@@ -100,6 +100,19 @@
int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
AndroidBitmapInfo* info);
+#if __ANDROID_API__ >= 30
+
+/**
+ * Given a java bitmap object, return its ADataSpace.
+ *
+ * Note that ADataSpace only exposes a few values. This may return
+ * ADATASPACE_UNKNOWN, even for Named ColorSpaces, if they have no
+ * corresponding ADataSpace.
+ */
+int32_t AndroidBitmap_getDataSpace(JNIEnv* env, jobject jbitmap) __INTRODUCED_IN(30);
+
+#endif // __ANDROID_API__ >= 30
+
/**
* Given a java bitmap object, attempt to lock the pixel address.
* Locking will ensure that the memory for the pixels will not move
diff --git a/include/input/DisplayViewport.h b/include/input/DisplayViewport.h
index fa456bb..6100626 100644
--- a/include/input/DisplayViewport.h
+++ b/include/input/DisplayViewport.h
@@ -17,16 +17,23 @@
#ifndef _LIBINPUT_DISPLAY_VIEWPORT_H
#define _LIBINPUT_DISPLAY_VIEWPORT_H
-#include <android-base/stringprintf.h>
-#include <ui/DisplayInfo.h>
-#include <input/Input.h>
-#include <inttypes.h>
+#include <cinttypes>
#include <optional>
+#include <android-base/stringprintf.h>
+#include <input/Input.h>
+
using android::base::StringPrintf;
namespace android {
+enum {
+ DISPLAY_ORIENTATION_0 = 0,
+ DISPLAY_ORIENTATION_90 = 1,
+ DISPLAY_ORIENTATION_180 = 2,
+ DISPLAY_ORIENTATION_270 = 3
+};
+
/**
* Describes the different type of viewports supported by input flinger.
* Keep in sync with values in InputManagerService.java.
diff --git a/include/input/TouchVideoFrame.h b/include/input/TouchVideoFrame.h
index b49c623..4fa2f86 100644
--- a/include/input/TouchVideoFrame.h
+++ b/include/input/TouchVideoFrame.h
@@ -19,7 +19,6 @@
#include <stdint.h>
#include <sys/time.h>
-#include <ui/DisplayInfo.h>
#include <vector>
namespace android {
diff --git a/libs/cputimeinstate/Android.bp b/libs/cputimeinstate/Android.bp
index a8f7d92..b1943a4 100644
--- a/libs/cputimeinstate/Android.bp
+++ b/libs/cputimeinstate/Android.bp
@@ -14,6 +14,7 @@
"-Wall",
"-Wextra",
],
+ export_include_dirs: ["."],
}
cc_test {
diff --git a/libs/cputimeinstate/cputimeinstate.cpp b/libs/cputimeinstate/cputimeinstate.cpp
index 4ee9f55..ee44cf5 100644
--- a/libs/cputimeinstate/cputimeinstate.cpp
+++ b/libs/cputimeinstate/cputimeinstate.cpp
@@ -85,6 +85,16 @@
return policyN1 - policyN2;
}
+static int bpf_obj_get_wronly(const char *pathname) {
+ union bpf_attr attr;
+
+ memset(&attr, 0, sizeof(attr));
+ attr.pathname = ptr_to_u64((void *)pathname);
+ attr.file_flags = BPF_F_WRONLY;
+
+ return syscall(__NR_bpf, BPF_OBJ_GET, &attr, sizeof(attr));
+}
+
static bool initGlobals() {
std::lock_guard<std::mutex> guard(gInitializedMutex);
if (gInitialized) return true;
@@ -153,17 +163,17 @@
bool startTrackingUidTimes() {
if (!initGlobals()) return false;
- unique_fd fd(bpf_obj_get(BPF_FS_PATH "map_time_in_state_cpu_policy_map"));
- if (fd < 0) return false;
+ unique_fd cpuPolicyFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_cpu_policy_map"));
+ if (cpuPolicyFd < 0) return false;
for (uint32_t i = 0; i < gPolicyCpus.size(); ++i) {
for (auto &cpu : gPolicyCpus[i]) {
- if (writeToMapEntry(fd, &cpu, &i, BPF_ANY)) return false;
+ if (writeToMapEntry(cpuPolicyFd, &cpu, &i, BPF_ANY)) return false;
}
}
- unique_fd fd2(bpf_obj_get(BPF_FS_PATH "map_time_in_state_freq_to_idx_map"));
- if (fd2 < 0) return false;
+ unique_fd freqToIdxFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_freq_to_idx_map"));
+ if (freqToIdxFd < 0) return false;
freq_idx_key_t key;
for (uint32_t i = 0; i < gNPolicies; ++i) {
key.policy = i;
@@ -173,14 +183,41 @@
// The uid_times map still uses 0-based indexes, and the sched_switch program handles
// conversion between them, so this does not affect our map reading code.
uint32_t idx = j + 1;
- if (writeToMapEntry(fd2, &key, &idx, BPF_ANY)) return false;
+ if (writeToMapEntry(freqToIdxFd, &key, &idx, BPF_ANY)) return false;
}
}
+ unique_fd cpuLastUpdateFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_cpu_last_update_map"));
+ if (cpuLastUpdateFd < 0) return false;
+ std::vector<uint64_t> zeros(get_nprocs_conf(), 0);
+ uint32_t zero = 0;
+ if (writeToMapEntry(cpuLastUpdateFd, &zero, zeros.data(), BPF_ANY)) return false;
+
+ unique_fd nrActiveFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_nr_active_map"));
+ if (nrActiveFd < 0) return false;
+ if (writeToMapEntry(nrActiveFd, &zero, &zero, BPF_ANY)) return false;
+
+ unique_fd policyNrActiveFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_policy_nr_active_map"));
+ if (policyNrActiveFd < 0) return false;
+ for (uint32_t i = 0; i < gNPolicies; ++i) {
+ if (writeToMapEntry(policyNrActiveFd, &i, &zero, BPF_ANY)) return false;
+ }
+
+ unique_fd policyFreqIdxFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_policy_freq_idx_map"));
+ if (policyFreqIdxFd < 0) return false;
+ for (uint32_t i = 0; i < gNPolicies; ++i) {
+ if (writeToMapEntry(policyFreqIdxFd, &i, &zero, BPF_ANY)) return false;
+ }
+
return attachTracepointProgram("sched", "sched_switch") &&
attachTracepointProgram("power", "cpu_frequency");
}
+std::optional<std::vector<std::vector<uint32_t>>> getCpuFreqs() {
+ if (!gInitialized && !initGlobals()) return {};
+ return gPolicyFreqs;
+}
+
// Retrieve the times in ns that uid spent running at each CPU frequency.
// Return contains no value on error, otherwise it contains a vector of vectors using the format:
// [[t0_0, t0_1, ...],
diff --git a/libs/cputimeinstate/cputimeinstate.h b/libs/cputimeinstate/cputimeinstate.h
index f620715..49469d8 100644
--- a/libs/cputimeinstate/cputimeinstate.h
+++ b/libs/cputimeinstate/cputimeinstate.h
@@ -26,6 +26,7 @@
std::optional<std::vector<std::vector<uint64_t>>> getUidCpuFreqTimes(uint32_t uid);
std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>>
getUidsCpuFreqTimes();
+std::optional<std::vector<std::vector<uint32_t>>> getCpuFreqs();
struct concurrent_time_t {
std::vector<uint64_t> active;
diff --git a/libs/cputimeinstate/testtimeinstate.cpp b/libs/cputimeinstate/testtimeinstate.cpp
index c0cd3e0..23d87fd 100644
--- a/libs/cputimeinstate/testtimeinstate.cpp
+++ b/libs/cputimeinstate/testtimeinstate.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 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 <bpf_timeinstate.h>
@@ -351,5 +367,16 @@
ASSERT_EQ(allConcurrentTimes->find(uid), allConcurrentTimes->end());
}
+TEST(TimeInStateTest, GetCpuFreqs) {
+ auto freqs = getCpuFreqs();
+ ASSERT_TRUE(freqs.has_value());
+
+ auto times = getUidCpuFreqTimes(0);
+ ASSERT_TRUE(times.has_value());
+
+ ASSERT_EQ(freqs->size(), times->size());
+ for (size_t i = 0; i < freqs->size(); ++i) EXPECT_EQ((*freqs)[i].size(), (*times)[i].size());
+}
+
} // namespace bpf
} // namespace android
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index a5e5693..f88ddf1 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -37,8 +37,6 @@
mHeight(height),
mNextTransaction(nullptr) {
BufferQueue::createBufferQueue(&mProducer, &mConsumer);
- mConsumer->setMaxBufferCount(MAX_BUFFERS);
- mProducer->setMaxDequeuedBufferCount(MAX_BUFFERS - 1);
mConsumer->setMaxAcquiredBufferCount(MAX_ACQUIRED_BUFFERS);
mBufferItemConsumer =
new BufferItemConsumer(mConsumer, AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER, 1, true);
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index ab4d51e..d34fe3b 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -110,10 +110,10 @@
}
virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
- bool& outCapturedSecureLayers, const ui::Dataspace reqDataspace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+ bool& outCapturedSecureLayers, ui::Dataspace reqDataspace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
- ISurfaceComposer::Rotation rotation, bool captureSecureLayers) {
+ ui::Rotation rotation, bool captureSecureLayers) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeStrongBinder(display);
@@ -1214,8 +1214,7 @@
bool capturedSecureLayers = false;
status_t res = captureScreen(display, &outBuffer, capturedSecureLayers, reqDataspace,
reqPixelFormat, sourceCrop, reqWidth, reqHeight,
- useIdentityTransform,
- static_cast<ISurfaceComposer::Rotation>(rotation),
+ useIdentityTransform, ui::toRotation(rotation),
captureSecureLayers);
reply->writeInt32(res);
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index e033f93..a7c4f46 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -203,7 +203,6 @@
DisplayState::DisplayState() :
what(0),
layerStack(0),
- orientation(eOrientationDefault),
viewport(Rect::EMPTY_RECT),
frame(Rect::EMPTY_RECT),
width(0),
@@ -215,7 +214,7 @@
output.writeStrongBinder(IInterface::asBinder(surface));
output.writeUint32(what);
output.writeUint32(layerStack);
- output.writeUint32(orientation);
+ output.writeUint32(toRotationInt(orientation));
output.write(viewport);
output.write(frame);
output.writeUint32(width);
@@ -228,7 +227,7 @@
surface = interface_cast<IGraphicBufferProducer>(input.readStrongBinder());
what = input.readUint32();
layerStack = input.readUint32();
- orientation = input.readUint32();
+ orientation = ui::toRotation(input.readUint32());
input.read(viewport);
input.read(frame);
width = input.readUint32();
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 9fba3d5..5e259e2 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1401,9 +1401,9 @@
}
void SurfaceComposerClient::Transaction::setDisplayProjection(const sp<IBinder>& token,
- uint32_t orientation,
- const Rect& layerStackRect,
- const Rect& displayRect) {
+ ui::Rotation orientation,
+ const Rect& layerStackRect,
+ const Rect& displayRect) {
DisplayState& s(getDisplayState(token));
s.orientation = orientation;
s.viewport = layerStackRect;
@@ -1775,28 +1775,26 @@
// ----------------------------------------------------------------------------
-status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+status_t ScreenshotClient::capture(const sp<IBinder>& display, ui::Dataspace reqDataSpace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
- uint32_t rotation, bool captureSecureLayers,
+ ui::Rotation rotation, bool captureSecureLayers,
sp<GraphicBuffer>* outBuffer, bool& outCapturedSecureLayers) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == nullptr) return NO_INIT;
- status_t ret =
- s->captureScreen(display, outBuffer, outCapturedSecureLayers, reqDataSpace,
- reqPixelFormat, sourceCrop, reqWidth, reqHeight, useIdentityTransform,
- static_cast<ISurfaceComposer::Rotation>(rotation),
- captureSecureLayers);
+ status_t ret = s->captureScreen(display, outBuffer, outCapturedSecureLayers, reqDataSpace,
+ reqPixelFormat, sourceCrop, reqWidth, reqHeight,
+ useIdentityTransform, rotation, captureSecureLayers);
if (ret != NO_ERROR) {
return ret;
}
return ret;
}
-status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+status_t ScreenshotClient::capture(const sp<IBinder>& display, ui::Dataspace reqDataSpace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
- uint32_t rotation, sp<GraphicBuffer>* outBuffer) {
+ ui::Rotation rotation, sp<GraphicBuffer>* outBuffer) {
bool ignored;
return capture(display, reqDataSpace, reqPixelFormat, sourceCrop, reqWidth, reqHeight,
useIdentityTransform, rotation, false, outBuffer, ignored);
@@ -1809,9 +1807,8 @@
return s->captureScreen(displayOrLayerStack, outDataspace, outBuffer);
}
-status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle,
- const ui::Dataspace reqDataSpace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, ui::Dataspace reqDataSpace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
float frameScale, sp<GraphicBuffer>* outBuffer) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == nullptr) return NO_INIT;
@@ -1821,8 +1818,8 @@
}
status_t ScreenshotClient::captureChildLayers(
- const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+ const sp<IBinder>& layerHandle, ui::Dataspace reqDataSpace, ui::PixelFormat reqPixelFormat,
+ const Rect& sourceCrop,
const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& excludeHandles,
float frameScale, sp<GraphicBuffer>* outBuffer) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
@@ -1832,5 +1829,5 @@
excludeHandles, frameScale, true /* childrenOnly */);
return ret;
}
-// ----------------------------------------------------------------------------
-}; // namespace android
+
+} // namespace android
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 0a0a03c..be429fe 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -69,7 +69,6 @@
std::mutex mMutex;
std::condition_variable mCallbackCV;
- static const int MAX_BUFFERS = 3;
static const int MAX_ACQUIRED_BUFFERS = 2;
int32_t mNumFrameAvailable GUARDED_BY(mMutex);
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 998973c..9804c92 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -34,6 +34,7 @@
#include <ui/GraphicTypes.h>
#include <ui/PhysicalDisplayId.h>
#include <ui/PixelFormat.h>
+#include <ui/Rotation.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -81,13 +82,6 @@
eEarlyWakeup = 0x04
};
- enum Rotation {
- eRotateNone = 0,
- eRotate90 = 1,
- eRotate180 = 2,
- eRotate270 = 3
- };
-
enum VsyncSource {
eVsyncSourceApp = 0,
eVsyncSourceSurfaceFlinger = 1
@@ -249,10 +243,10 @@
* it) around its center.
*/
virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
- bool& outCapturedSecureLayers, const ui::Dataspace reqDataspace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+ bool& outCapturedSecureLayers, ui::Dataspace reqDataspace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
- Rotation rotation = eRotateNone,
+ ui::Rotation rotation = ui::ROTATION_0,
bool captureSecureLayers = false) = 0;
/**
* Capture the specified screen. This requires READ_FRAME_BUFFER
@@ -276,8 +270,9 @@
* it) around its center.
*/
virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
- Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
- bool useIdentityTransform, Rotation rotation = eRotateNone) {
+ const Rect& sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
+ bool useIdentityTransform,
+ ui::Rotation rotation = ui::ROTATION_0) {
bool outIgnored;
return captureScreen(display, outBuffer, outIgnored, ui::Dataspace::V0_SRGB,
ui::PixelFormat::RGBA_8888, sourceCrop, reqWidth, reqHeight,
@@ -301,8 +296,7 @@
*/
virtual status_t captureLayers(
const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
- const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat,
- const Rect& sourceCrop,
+ ui::Dataspace reqDataspace, ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& excludeHandles,
float frameScale = 1.0, bool childrenOnly = false) = 0;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index c2b5119..fb18639 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -35,6 +35,7 @@
#include <ui/GraphicTypes.h>
#include <ui/Rect.h>
#include <ui/Region.h>
+#include <ui/Rotation.h>
namespace android {
@@ -218,15 +219,6 @@
struct DisplayState {
enum {
- eOrientationDefault = 0,
- eOrientation90 = 1,
- eOrientation180 = 2,
- eOrientation270 = 3,
- eOrientationUnchanged = 4,
- eOrientationSwapMask = 0x01
- };
-
- enum {
eSurfaceChanged = 0x01,
eLayerStackChanged = 0x02,
eDisplayProjectionChanged = 0x04,
@@ -252,7 +244,7 @@
// 0, layers will be scaled by a factor of 2 and translated by (20, 10).
// When orientation is 1, layers will be additionally rotated by 90
// degrees around the origin clockwise and translated by (W, 0).
- uint32_t orientation;
+ ui::Rotation orientation = ui::ROTATION_0;
Rect viewport;
Rect frame;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 86468a4..44f29ea 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -35,6 +35,7 @@
#include <ui/FrameStats.h>
#include <ui/GraphicTypes.h>
#include <ui/PixelFormat.h>
+#include <ui/Rotation.h>
#include <gui/CpuConsumer.h>
#include <gui/ISurfaceComposer.h>
@@ -531,10 +532,8 @@
* mapped to. displayRect is specified post-orientation, that is
* it uses the orientation seen by the end-user.
*/
- void setDisplayProjection(const sp<IBinder>& token,
- uint32_t orientation,
- const Rect& layerStackRect,
- const Rect& displayRect);
+ void setDisplayProjection(const sp<IBinder>& token, ui::Rotation orientation,
+ const Rect& layerStackRect, const Rect& displayRect);
void setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height);
void setAnimationTransaction();
void setEarlyWakeup();
@@ -548,10 +547,8 @@
static status_t getHdrCapabilities(const sp<IBinder>& display,
HdrCapabilities* outCapabilities);
- static void setDisplayProjection(const sp<IBinder>& token,
- uint32_t orientation,
- const Rect& layerStackRect,
- const Rect& displayRect);
+ static void setDisplayProjection(const sp<IBinder>& token, ui::Rotation orientation,
+ const Rect& layerStackRect, const Rect& displayRect);
inline sp<ISurfaceComposerClient> getClient() { return mClient; }
@@ -583,23 +580,23 @@
public:
// if cropping isn't required, callers may pass in a default Rect, e.g.:
// capture(display, producer, Rect(), reqWidth, ...);
- static status_t capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+ static status_t capture(const sp<IBinder>& display, ui::Dataspace reqDataSpace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
- uint32_t rotation, bool captureSecureLayers,
+ ui::Rotation rotation, bool captureSecureLayers,
sp<GraphicBuffer>* outBuffer, bool& outCapturedSecureLayers);
- static status_t capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+ static status_t capture(const sp<IBinder>& display, ui::Dataspace reqDataSpace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
- uint32_t rotation, sp<GraphicBuffer>* outBuffer);
+ ui::Rotation rotation, sp<GraphicBuffer>* outBuffer);
static status_t capture(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
sp<GraphicBuffer>* outBuffer);
- static status_t captureLayers(const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+ static status_t captureLayers(const sp<IBinder>& layerHandle, ui::Dataspace reqDataSpace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
float frameScale, sp<GraphicBuffer>* outBuffer);
static status_t captureChildLayers(
- const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+ const sp<IBinder>& layerHandle, ui::Dataspace reqDataSpace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>&
excludeHandles,
float frameScale, sp<GraphicBuffer>* outBuffer);
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index 0f618f1..8fca883 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -123,11 +123,12 @@
void setUpProducer(BLASTBufferQueueHelper adapter, sp<IGraphicBufferProducer>& producer) {
auto igbProducer = adapter.getIGraphicBufferProducer();
ASSERT_NE(nullptr, igbProducer.get());
+ ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
IGraphicBufferProducer::QueueBufferOutput qbOutput;
ASSERT_EQ(NO_ERROR,
igbProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
&qbOutput));
- ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
+ ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
producer = igbProducer;
}
@@ -266,7 +267,7 @@
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
Fence::NO_FENCE);
igbProducer->queueBuffer(slot, input, &qbOutput);
- ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
+ ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
adapter.waitForCallbacks();
@@ -349,7 +350,7 @@
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
Fence::NO_FENCE);
igbProducer->queueBuffer(slot, input, &qbOutput);
- ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
+ ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
adapter.waitForCallbacks();
// capture screen and verify that it is red
@@ -410,7 +411,7 @@
NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
Fence::NO_FENCE);
igbProducer->queueBuffer(slot, input, &qbOutput);
- ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
+ ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
adapter.waitForCallbacks();
// capture screen and verify that it is red
@@ -456,7 +457,7 @@
NATIVE_WINDOW_SCALING_MODE_FREEZE, tr,
Fence::NO_FENCE);
igbProducer->queueBuffer(slot, input, &qbOutput);
- ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
+ ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
adapter.waitForCallbacks();
bool capturedSecureLayers;
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 8d36ba7..04749e6 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -112,22 +112,31 @@
if (consumed != OK) {
return nullptr;
}
- mInputConsumer->sendFinishedSignal(seqId, true);
+ status_t status = mInputConsumer->sendFinishedSignal(seqId, true);
+ EXPECT_EQ(OK, status) << "Could not send finished signal";
return ev;
}
+ void assertFocusChange(bool hasFocus) {
+ InputEvent *ev = consumeEvent();
+ ASSERT_NE(ev, nullptr);
+ ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, ev->getType());
+ FocusEvent *focusEvent = static_cast<FocusEvent *>(ev);
+ EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
+ }
+
void expectTap(int x, int y) {
InputEvent* ev = consumeEvent();
- EXPECT_TRUE(ev != nullptr);
- EXPECT_TRUE(ev->getType() == AINPUT_EVENT_TYPE_MOTION);
+ ASSERT_NE(ev, nullptr);
+ ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
MotionEvent* mev = static_cast<MotionEvent*>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
EXPECT_EQ(x, mev->getX(0));
EXPECT_EQ(y, mev->getY(0));
ev = consumeEvent();
- EXPECT_TRUE(ev != nullptr);
- EXPECT_TRUE(ev->getType() == AINPUT_EVENT_TYPE_MOTION);
+ ASSERT_NE(ev, nullptr);
+ ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
mev = static_cast<MotionEvent*>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
}
@@ -212,7 +221,7 @@
ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
const auto display = mComposerClient->getInternalDisplayToken();
- ASSERT_FALSE(display == nullptr);
+ ASSERT_NE(display, nullptr);
DisplayInfo info;
ASSERT_EQ(NO_ERROR, mComposerClient->getDisplayInfo(display, &info));
@@ -259,18 +268,28 @@
TEST_F(InputSurfacesTest, can_receive_input) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
surface->showAt(100, 100);
+ surface->assertFocusChange(true);
injectTap(101, 101);
- EXPECT_TRUE(surface->consumeEvent() != nullptr);
+ EXPECT_NE(surface->consumeEvent(), nullptr);
}
+/**
+ * Set up two surfaces side-by-side. Tap each surface.
+ * Next, swap the positions of the two surfaces. Inject tap into the two
+ * original locations. Ensure that the tap is received by the surfaces in the
+ * reverse order.
+ */
TEST_F(InputSurfacesTest, input_respects_positioning) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
surface->showAt(100, 100);
+ surface->assertFocusChange(true);
std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
surface2->showAt(200, 200);
+ surface->assertFocusChange(false);
+ surface2->assertFocusChange(true);
injectTap(201, 201);
surface2->expectTap(1, 1);
@@ -297,11 +316,16 @@
std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
surface->showAt(10, 10);
+ surface->assertFocusChange(true);
surface2->showAt(10, 10);
+ surface->assertFocusChange(false);
+ surface2->assertFocusChange(true);
surface->doTransaction([](auto &t, auto &sc) {
t.setLayer(sc, LAYER_BASE + 1);
});
+ surface2->assertFocusChange(false);
+ surface->assertFocusChange(true);
injectTap(11, 11);
surface->expectTap(1, 1);
@@ -309,6 +333,8 @@
surface2->doTransaction([](auto &t, auto &sc) {
t.setLayer(sc, LAYER_BASE + 1);
});
+ surface2->assertFocusChange(true);
+ surface->assertFocusChange(false);
injectTap(11, 11);
surface2->expectTap(1, 1);
@@ -316,6 +342,8 @@
surface2->doTransaction([](auto &t, auto &sc) {
t.hide(sc);
});
+ surface2->assertFocusChange(false);
+ surface->assertFocusChange(true);
injectTap(11, 11);
surface->expectTap(1, 1);
@@ -328,9 +356,12 @@
std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
bgSurface->showAt(100, 100);
+ bgSurface->assertFocusChange(true);
fgSurface->mInputInfo.surfaceInset = 5;
fgSurface->showAt(100, 100);
+ fgSurface->assertFocusChange(true);
+ bgSurface->assertFocusChange(false);
injectTap(106, 106);
fgSurface->expectTap(1, 1);
@@ -344,9 +375,12 @@
std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100);
parentSurface->showAt(100, 100);
+ parentSurface->assertFocusChange(true);
childSurface->mInputInfo.surfaceInset = 10;
childSurface->showAt(100, 100);
+ childSurface->assertFocusChange(true);
+ parentSurface->assertFocusChange(false);
childSurface->doTransaction([&](auto &t, auto &sc) {
t.setPosition(sc, -5, -5);
@@ -365,9 +399,12 @@
std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
bgSurface->showAt(100, 100);
+ bgSurface->assertFocusChange(true);
fgSurface->mInputInfo.surfaceInset = 5;
fgSurface->showAt(100, 100);
+ bgSurface->assertFocusChange(false);
+ fgSurface->assertFocusChange(true);
fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });
@@ -384,6 +421,7 @@
// In case we pass the very big inset without any checking.
fgSurface->mInputInfo.surfaceInset = INT32_MAX;
fgSurface->showAt(100, 100);
+ fgSurface->assertFocusChange(true);
fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
@@ -400,6 +438,7 @@
t.setTransparentRegionHint(sc, transparentRegion);
});
surface->showAt(100, 100);
+ surface->assertFocusChange(true);
injectTap(101, 101);
surface->expectTap(1, 1);
}
@@ -414,7 +453,10 @@
InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
bgSurface->showAt(10, 10);
+ bgSurface->assertFocusChange(true);
bufferSurface->showAt(10, 10);
+ bgSurface->assertFocusChange(false);
+ bufferSurface->assertFocusChange(true);
injectTap(11, 11);
bufferSurface->expectTap(1, 1);
@@ -431,7 +473,10 @@
postBuffer(bufferSurface->mSurfaceControl);
bgSurface->showAt(10, 10);
+ bgSurface->assertFocusChange(true);
bufferSurface->showAt(10, 10);
+ bufferSurface->assertFocusChange(true);
+ bgSurface->assertFocusChange(false);
injectTap(11, 11);
bufferSurface->expectTap(1, 1);
@@ -447,7 +492,10 @@
std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
bgSurface->showAt(10, 10);
+ bgSurface->assertFocusChange(true);
fgSurface->showAt(10, 10);
+ bgSurface->assertFocusChange(false);
+ fgSurface->assertFocusChange(true);
injectTap(11, 11);
fgSurface->expectTap(1, 1);
@@ -464,12 +512,17 @@
InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
bgSurface->showAt(10, 10);
+ bgSurface->assertFocusChange(true);
containerSurface->showAt(10, 10);
+ bgSurface->assertFocusChange(false);
+ containerSurface->assertFocusChange(true);
injectTap(11, 11);
containerSurface->expectTap(1, 1);
containerSurface->doTransaction([](auto &t, auto &sc) { t.hide(sc); });
+ containerSurface->assertFocusChange(false);
+ bgSurface->assertFocusChange(true);
injectTap(11, 11);
bgSurface->expectTap(1, 1);
@@ -478,6 +531,7 @@
TEST_F(InputSurfacesTest, input_respects_outscreen) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
surface->showAt(-1, -1);
+ surface->assertFocusChange(true);
injectTap(0, 0);
surface->expectTap(1, 1);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 0445755..f9540b2 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -742,11 +742,10 @@
status_t setActiveColorMode(const sp<IBinder>& /*display*/,
ColorMode /*colorMode*/) override { return NO_ERROR; }
status_t captureScreen(const sp<IBinder>& /*display*/, sp<GraphicBuffer>* /*outBuffer*/,
- bool& /* outCapturedSecureLayers */,
- const ui::Dataspace /*reqDataspace*/,
- const ui::PixelFormat /*reqPixelFormat*/, Rect /*sourceCrop*/,
+ bool& /*outCapturedSecureLayers*/, ui::Dataspace /*reqDataspace*/,
+ ui::PixelFormat /*reqPixelFormat*/, const Rect& /*sourceCrop*/,
uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
- bool /*useIdentityTransform*/, Rotation /*rotation*/,
+ bool /*useIdentityTransform*/, ui::Rotation,
bool /*captureSecureLayers*/) override {
return NO_ERROR;
}
@@ -766,7 +765,7 @@
}
virtual status_t captureLayers(
const sp<IBinder>& /*parentHandle*/, sp<GraphicBuffer>* /*outBuffer*/,
- const ui::Dataspace /*reqDataspace*/, const ui::PixelFormat /*reqPixelFormat*/,
+ ui::Dataspace /*reqDataspace*/, ui::PixelFormat /*reqPixelFormat*/,
const Rect& /*sourceCrop*/,
const std::unordered_set<sp<IBinder>,
ISurfaceComposer::SpHash<IBinder>>& /*excludeHandles*/,
diff --git a/libs/input/TouchVideoFrame.cpp b/libs/input/TouchVideoFrame.cpp
index 8a4298a..145b4ae 100644
--- a/libs/input/TouchVideoFrame.cpp
+++ b/libs/input/TouchVideoFrame.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <input/DisplayViewport.h>
#include <input/TouchVideoFrame.h>
namespace android {
diff --git a/libs/input/tests/TouchVideoFrame_test.cpp b/libs/input/tests/TouchVideoFrame_test.cpp
index 815424e..1ec9358 100644
--- a/libs/input/tests/TouchVideoFrame_test.cpp
+++ b/libs/input/tests/TouchVideoFrame_test.cpp
@@ -16,6 +16,7 @@
#include <gtest/gtest.h>
+#include <input/DisplayViewport.h>
#include <input/TouchVideoFrame.h>
namespace android {
diff --git a/libs/ui/include/ui/DisplayInfo.h b/libs/ui/include/ui/DisplayInfo.h
index 0772210..38f8d6b 100644
--- a/libs/ui/include/ui/DisplayInfo.h
+++ b/libs/ui/include/ui/DisplayInfo.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <ui/Rotation.h>
#include <utils/Timers.h>
namespace android {
@@ -33,7 +34,7 @@
float ydpi{0};
float fps{0};
float density{0};
- uint8_t orientation{0};
+ ui::Rotation orientation{ui::ROTATION_0};
bool secure{false};
nsecs_t appVsyncOffset{0};
nsecs_t presentationDeadline{0};
@@ -42,14 +43,6 @@
uint32_t layerStack{NO_LAYER_STACK};
};
-/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
-enum {
- DISPLAY_ORIENTATION_0 = 0,
- DISPLAY_ORIENTATION_90 = 1,
- DISPLAY_ORIENTATION_180 = 2,
- DISPLAY_ORIENTATION_270 = 3
-};
-
} // namespace android
#endif // ANDROID_COMPOSER_DISPLAY_INFO_H
diff --git a/libs/ui/include/ui/Rotation.h b/libs/ui/include/ui/Rotation.h
new file mode 100644
index 0000000..89008f6
--- /dev/null
+++ b/libs/ui/include/ui/Rotation.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2019 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 <type_traits>
+
+namespace android::ui {
+
+enum class Rotation { Rotation0 = 0, Rotation90 = 1, Rotation180 = 2, Rotation270 = 3 };
+
+// Equivalent to Surface.java constants.
+constexpr auto ROTATION_0 = Rotation::Rotation0;
+constexpr auto ROTATION_90 = Rotation::Rotation90;
+constexpr auto ROTATION_180 = Rotation::Rotation180;
+constexpr auto ROTATION_270 = Rotation::Rotation270;
+
+constexpr auto toRotation(std::underlying_type_t<Rotation> rotation) {
+ return static_cast<Rotation>(rotation);
+}
+
+constexpr auto toRotationInt(Rotation rotation) {
+ return static_cast<std::underlying_type_t<Rotation>>(rotation);
+}
+
+constexpr Rotation operator+(Rotation lhs, Rotation rhs) {
+ constexpr auto N = toRotationInt(ROTATION_270) + 1;
+ return toRotation((toRotationInt(lhs) + toRotationInt(rhs)) % N);
+}
+
+constexpr const char* toCString(Rotation rotation) {
+ switch (rotation) {
+ case ROTATION_0:
+ return "ROTATION_0";
+ case ROTATION_90:
+ return "ROTATION_90";
+ case ROTATION_180:
+ return "ROTATION_180";
+ case ROTATION_270:
+ return "ROTATION_270";
+ }
+}
+
+} // namespace android::ui
diff --git a/libs/ui/include/ui/Transform.h b/libs/ui/include/ui/Transform.h
index de07684..c6bb598 100644
--- a/libs/ui/include/ui/Transform.h
+++ b/libs/ui/include/ui/Transform.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef ANDROID_TRANSFORM_H
-#define ANDROID_TRANSFORM_H
+#pragma once
#include <stdint.h>
#include <sys/types.h>
@@ -28,6 +27,7 @@
#include <math/vec3.h>
#include <ui/Point.h>
#include <ui/Rect.h>
+#include <ui/Rotation.h>
namespace android {
@@ -42,13 +42,13 @@
explicit Transform(uint32_t orientation, int w = 0, int h = 0);
~Transform();
- enum orientation_flags {
- ROT_0 = 0x00000000,
- FLIP_H = HAL_TRANSFORM_FLIP_H,
- FLIP_V = HAL_TRANSFORM_FLIP_V,
- ROT_90 = HAL_TRANSFORM_ROT_90,
- ROT_180 = FLIP_H|FLIP_V,
- ROT_270 = ROT_180|ROT_90,
+ enum RotationFlags : uint32_t {
+ ROT_0 = 0,
+ FLIP_H = HAL_TRANSFORM_FLIP_H,
+ FLIP_V = HAL_TRANSFORM_FLIP_V,
+ ROT_90 = HAL_TRANSFORM_ROT_90,
+ ROT_180 = FLIP_H | FLIP_V,
+ ROT_270 = ROT_180 | ROT_90,
ROT_INVALID = 0x80
};
@@ -100,6 +100,8 @@
void dump(std::string& result, const char* name) const;
void dump(const char* name) const;
+ static RotationFlags toRotationFlags(Rotation);
+
private:
struct mat33 {
vec3 v[3];
@@ -117,13 +119,26 @@
mutable uint32_t mType;
};
-static inline void PrintTo(const Transform& t, ::std::ostream* os) {
+inline void PrintTo(const Transform& t, ::std::ostream* os) {
std::string out;
t.dump(out, "ui::Transform");
*os << out;
}
+inline Transform::RotationFlags Transform::toRotationFlags(Rotation rotation) {
+ switch (rotation) {
+ case ROTATION_0:
+ return ROT_0;
+ case ROTATION_90:
+ return ROT_90;
+ case ROTATION_180:
+ return ROT_180;
+ case ROTATION_270:
+ return ROT_270;
+ default:
+ return ROT_INVALID;
+ }
+}
+
} // namespace ui
} // namespace android
-
-#endif /* ANDROID_TRANSFORM_H */
diff --git a/libs/ui/include_vndk/ui/Rotation.h b/libs/ui/include_vndk/ui/Rotation.h
new file mode 120000
index 0000000..d84fb4b
--- /dev/null
+++ b/libs/ui/include_vndk/ui/Rotation.h
@@ -0,0 +1 @@
+../../include/ui/Rotation.h
\ No newline at end of file
diff --git a/opengl/tests/lib/WindowSurface.cpp b/opengl/tests/lib/WindowSurface.cpp
index a0bd4e2..4dcc1ca 100644
--- a/opengl/tests/lib/WindowSurface.cpp
+++ b/opengl/tests/lib/WindowSurface.cpp
@@ -48,8 +48,7 @@
}
uint32_t width, height;
- if (mainDpyInfo.orientation != DISPLAY_ORIENTATION_0 &&
- mainDpyInfo.orientation != DISPLAY_ORIENTATION_180) {
+ if (mainDpyInfo.orientation != ui::ROTATION_0 && mainDpyInfo.orientation != ui::ROTATION_180) {
// rotated
width = mainDpyInfo.h;
height = mainDpyInfo.w;
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index e925f5b..b723654 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -111,6 +111,21 @@
msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
}
+// --- FocusEntry ---
+
+// Focus notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries
+FocusEntry::FocusEntry(uint32_t sequenceNum, nsecs_t eventTime, sp<IBinder> connectionToken,
+ bool hasFocus)
+ : EventEntry(sequenceNum, Type::FOCUS, eventTime, POLICY_FLAG_PASS_TO_USER),
+ connectionToken(connectionToken),
+ hasFocus(hasFocus) {}
+
+FocusEntry::~FocusEntry() {}
+
+void FocusEntry::appendDescription(std::string& msg) const {
+ msg += StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
+}
+
// --- KeyEntry ---
KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 9dcaadc..e8c37f0 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -33,7 +33,13 @@
constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
struct EventEntry {
- enum class Type { CONFIGURATION_CHANGED, DEVICE_RESET, KEY, MOTION };
+ enum class Type {
+ CONFIGURATION_CHANGED,
+ DEVICE_RESET,
+ FOCUS,
+ KEY,
+ MOTION,
+ };
static const char* typeToString(Type type) {
switch (type) {
@@ -41,6 +47,8 @@
return "CONFIGURATION_CHANGED";
case Type::DEVICE_RESET:
return "DEVICE_RESET";
+ case Type::FOCUS:
+ return "FOCUS";
case Type::KEY:
return "KEY";
case Type::MOTION:
@@ -102,6 +110,17 @@
virtual ~DeviceResetEntry();
};
+struct FocusEntry : EventEntry {
+ sp<IBinder> connectionToken;
+ bool hasFocus;
+
+ FocusEntry(uint32_t sequenceNum, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus);
+ virtual void appendDescription(std::string& msg) const;
+
+protected:
+ virtual ~FocusEntry();
+};
+
struct KeyEntry : EventEntry {
int32_t deviceId;
uint32_t source;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 6157d99..77bf1e9 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -530,6 +530,14 @@
break;
}
+ case EventEntry::Type::FOCUS: {
+ FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
+ dispatchFocusLocked(currentTime, typedEntry);
+ done = true;
+ dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
+ break;
+ }
+
case EventEntry::Type::KEY: {
KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
if (isAppSwitchDue) {
@@ -634,7 +642,8 @@
break;
}
case EventEntry::Type::CONFIGURATION_CHANGED:
- case EventEntry::Type::DEVICE_RESET: {
+ case EventEntry::Type::DEVICE_RESET:
+ case EventEntry::Type::FOCUS: {
// nothing to do
break;
}
@@ -773,6 +782,7 @@
}
break;
}
+ case EventEntry::Type::FOCUS:
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
@@ -933,6 +943,25 @@
return true;
}
+void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
+ FocusEntry* focusEntry =
+ new FocusEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, now(), window.getToken(), hasFocus);
+ enqueueInboundEventLocked(focusEntry);
+}
+
+void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) {
+ sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
+ if (channel == nullptr) {
+ return; // Window has gone away
+ }
+ InputTarget target;
+ target.inputChannel = channel;
+ target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
+ entry->dispatchInProgress = true;
+
+ dispatchEventLocked(currentTime, entry, {target});
+}
+
bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
DropReason* dropReason, nsecs_t* nextWakeupTime) {
// Preprocessing.
@@ -1315,6 +1344,7 @@
displayId = motionEntry.displayId;
break;
}
+ case EventEntry::Type::FOCUS:
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
@@ -2062,6 +2092,10 @@
}
void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
+ if (eventEntry.type == EventEntry::Type::FOCUS) {
+ // Focus events are passed to apps, but do not represent user activity.
+ return;
+ }
int32_t displayId = getTargetDisplayId(eventEntry);
sp<InputWindowHandle> focusedWindowHandle =
getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
@@ -2096,6 +2130,7 @@
eventType = USER_ACTIVITY_EVENT_BUTTON;
break;
}
+ case EventEntry::Type::FOCUS:
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
LOG_ALWAYS_FATAL("%s events are not user activity",
@@ -2292,6 +2327,9 @@
break;
}
+ case EventEntry::Type::FOCUS: {
+ break;
+ }
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
LOG_ALWAYS_FATAL("%s events should not go to apps",
@@ -2427,6 +2465,14 @@
reportTouchEventForStatistics(*motionEntry);
break;
}
+ case EventEntry::Type::FOCUS: {
+ FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
+ status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
+ focusEntry->hasFocus,
+ mInTouchMode);
+ break;
+ }
+
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
@@ -2666,6 +2712,10 @@
*cancelationEventEntry));
break;
}
+ case EventEntry::Type::FOCUS: {
+ LOG_ALWAYS_FATAL("Canceling focus events is not supported");
+ break;
+ }
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
@@ -3456,6 +3506,7 @@
CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
"focus left window");
synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
+ enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
}
mFocusedWindowHandlesByDisplay.erase(displayId);
}
@@ -3465,6 +3516,7 @@
newFocusedWindowHandle->getName().c_str(), displayId);
}
mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
+ enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
}
if (mFocusedDisplayId == displayId) {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 50b5250..a4ba0de 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -157,6 +157,9 @@
// Cleans up input state when dropping an inbound event.
void dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) REQUIRES(mLock);
+ // Enqueues a focus event.
+ void enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) REQUIRES(mLock);
+
// Adds an event to a queue of recent events for debugging purposes.
void addRecentEventLocked(EventEntry* entry) REQUIRES(mLock);
@@ -299,6 +302,7 @@
nsecs_t* nextWakeupTime) REQUIRES(mLock);
bool dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason,
nsecs_t* nextWakeupTime) REQUIRES(mLock);
+ void dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) REQUIRES(mLock);
void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
const std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index bd8d2a4..98ebf50 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -482,12 +482,31 @@
EXPECT_EQ(expectedFlags, motionEvent.getFlags());
break;
}
+ case AINPUT_EVENT_TYPE_FOCUS: {
+ FAIL() << "Use 'consumeFocusEvent' for FOCUS events";
+ }
default: {
FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
}
}
}
+ void consumeFocusEvent(bool hasFocus, bool inTouchMode) {
+ InputEvent* event = consume();
+ ASSERT_NE(nullptr, event) << mName.c_str()
+ << ": consumer should have returned non-NULL event.";
+ ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, event->getType())
+ << "Got " << inputEventTypeToString(event->getType())
+ << " event instead of FOCUS event";
+
+ ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId())
+ << mName.c_str() << ": event displayId should always be NONE.";
+
+ FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
+ EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
+ EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode());
+ }
+
void assertNoEvents() {
InputEvent* event = consume();
ASSERT_EQ(nullptr, event)
@@ -508,7 +527,6 @@
public:
static const int32_t WIDTH = 600;
static const int32_t HEIGHT = 800;
- const std::string mName;
FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
const sp<InputDispatcher>& dispatcher, const std::string name,
@@ -551,7 +569,7 @@
virtual bool updateInfo() { return true; }
- void setFocus() { mInfo.hasFocus = true; }
+ void setFocus(bool hasFocus) { mInfo.hasFocus = hasFocus; }
void setFrame(const Rect& frame) {
mInfo.frameLeft = frame.left;
@@ -586,6 +604,12 @@
expectedFlags);
}
+ void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
+ ASSERT_NE(mInputReceiver, nullptr)
+ << "Cannot consume events from a window with no receiver";
+ mInputReceiver->consumeFocusEvent(hasFocus, inTouchMode);
+ }
+
void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
int32_t expectedFlags) {
ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
@@ -608,7 +632,10 @@
sp<IBinder> getToken() { return mInfo.token; }
+ const std::string& getName() { return mName; }
+
private:
+ const std::string mName;
std::unique_ptr<FakeInputReceiver> mInputReceiver;
};
@@ -759,10 +786,11 @@
// Set focused application.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
- // Expect one focus window exist in display.
- windowSecond->setFocus();
-
+ // Display should have only one focused window
+ windowSecond->setFocus(true);
mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+
+ windowSecond->consumeFocusEvent(true);
ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
<< "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -782,10 +810,11 @@
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
// Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
- windowTop->setFocus();
- windowSecond->setFocus();
+ windowTop->setFocus(true);
+ windowSecond->setFocus(true);
mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+ windowTop->consumeFocusEvent(true);
ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
<< "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -805,11 +834,12 @@
// Set focused application.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
- windowTop->setFocus();
- windowSecond->setFocus();
+ windowTop->setFocus(true);
+ windowSecond->setFocus(true);
// Release channel for window is no longer valid.
windowTop->releaseChannel();
mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+ windowSecond->consumeFocusEvent(true);
// Test inject a key down, should dispatch to a valid window.
ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
@@ -849,9 +879,10 @@
sp<FakeApplicationHandle> application = new FakeApplicationHandle();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
- window->setFocus();
+ window->setFocus(true);
mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ window->consumeFocusEvent(true);
NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
mDispatcher->notifyKey(&keyArgs);
@@ -890,6 +921,59 @@
0 /*expectedFlags*/);
}
+TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {
+ sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+ sp<FakeWindowHandle> window =
+ new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
+
+ window->setFocus(true);
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+
+ window->consumeFocusEvent(true);
+
+ NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
+ mDispatcher->notifyKey(&keyArgs);
+
+ // Window should receive key down event.
+ window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
+}
+
+TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) {
+ sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+ sp<FakeWindowHandle> window =
+ new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
+
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+
+ NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
+ mDispatcher->notifyKey(&keyArgs);
+ mDispatcher->waitForIdle();
+
+ window->assertNoEvents();
+}
+
+// If a window is touchable, but does not have focus, it should receive motion events, but not keys
+TEST_F(InputDispatcherTest, UnfocusedWindow_ReceivesMotionsButNotKeys) {
+ sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+ sp<FakeWindowHandle> window =
+ new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
+
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+
+ // Send key
+ NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
+ mDispatcher->notifyKey(&keyArgs);
+ // Send motion
+ NotifyMotionArgs motionArgs =
+ generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
+ ADISPLAY_ID_DEFAULT);
+ mDispatcher->notifyMotion(&motionArgs);
+
+ // Window should receive only the motion event
+ window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
+ window->assertNoEvents(); // Key event or focus event will not be received
+}
+
class FakeMonitorReceiver {
public:
FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
@@ -946,9 +1030,10 @@
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
- window->setFocus();
+ window->setFocus(true);
mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ window->consumeFocusEvent(true);
FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
true /*isGestureMonitor*/);
@@ -1010,6 +1095,49 @@
0 /*expectedFlags*/);
}
+/**
+ * Dispatcher has touch mode enabled by default. Typically, the policy overrides that value to
+ * the device default right away. In the test scenario, we check both the default value,
+ * and the action of enabling / disabling.
+ */
+TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
+ sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+ sp<FakeWindowHandle> window =
+ new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
+
+ // Set focused application.
+ mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
+ window->setFocus(true);
+
+ SCOPED_TRACE("Check default value of touch mode");
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
+
+ SCOPED_TRACE("Remove the window to trigger focus loss");
+ window->setFocus(false);
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
+
+ SCOPED_TRACE("Disable touch mode");
+ mDispatcher->setInTouchMode(false);
+ window->setFocus(true);
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
+
+ SCOPED_TRACE("Remove the window to trigger focus loss");
+ window->setFocus(false);
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
+
+ SCOPED_TRACE("Enable touch mode again");
+ mDispatcher->setInTouchMode(true);
+ window->setFocus(true);
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
+
+ window->assertNoEvents();
+}
+
/* Test InputDispatcher for MultiDisplay */
class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
public:
@@ -1023,8 +1151,9 @@
// Set focus window for primary display, but focused display would be second one.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
- windowInPrimary->setFocus();
+ windowInPrimary->setFocus(true);
mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT);
+ windowInPrimary->consumeFocusEvent(true);
application2 = new FakeApplicationHandle();
windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
@@ -1034,8 +1163,9 @@
mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
// Set focus window for second display.
mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
- windowInSecondary->setFocus();
+ windowInSecondary->setFocus(true);
mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID);
+ windowInSecondary->consumeFocusEvent(true);
}
virtual void TearDown() override {
@@ -1094,6 +1224,7 @@
ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
<< "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
windowInPrimary->assertNoEvents();
+ windowInSecondary->consumeFocusEvent(false);
windowInSecondary->assertNoEvents();
}
@@ -1244,10 +1375,11 @@
// Set focused application.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
- mFocusedWindow->setFocus();
+ mFocusedWindow->setFocus(true);
// Expect one focus window exist in display.
mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
+ mFocusedWindow->consumeFocusEvent(true);
}
virtual void TearDown() override {
@@ -1350,7 +1482,7 @@
void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction,
const std::vector<PointF>& points) {
- std::string name = window->mName;
+ const std::string name = window->getName();
InputEvent* event = window->consume();
ASSERT_NE(nullptr, event) << name.c_str()
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index bdecdb7..3b1b796 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -207,7 +207,7 @@
* the code below applies the primary display's inverse transform to
* the texture transform
*/
- uint32_t transform = DisplayDevice::getPrimaryDisplayOrientationTransform();
+ uint32_t transform = DisplayDevice::getPrimaryDisplayRotationFlags();
mat4 tr = inverseOrientation(transform);
/**
@@ -622,7 +622,7 @@
}
if (getTransformToDisplayInverse()) {
- uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
+ uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
if (invTransform & ui::Transform::ROT_90) {
std::swap(bufWidth, bufHeight);
}
@@ -658,7 +658,7 @@
}
if (getTransformToDisplayInverse()) {
- uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
+ uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
if (invTransform & ui::Transform::ROT_90) {
std::swap(bufWidth, bufHeight);
}
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 63f3242..067aa46 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -473,7 +473,7 @@
}
if (s.transformToDisplayInverse) {
- uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
+ uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
if (invTransform & ui::Transform::ROT_90) {
std::swap(bufferWidth, bufferHeight);
}
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 84ec597..e0dc3e7 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -41,12 +41,7 @@
using android::base::StringAppendF;
-/*
- * Initialize the display to the specified values.
- *
- */
-
-uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0;
+ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::Transform::ROT_0;
DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(const sp<SurfaceFlinger>& flinger,
const wp<IBinder>& displayToken,
@@ -57,13 +52,11 @@
: mFlinger(args.flinger),
mDisplayToken(args.displayToken),
mSequenceId(args.sequenceId),
- mDisplayInstallOrientation(args.displayInstallOrientation),
+ mIsVirtual(args.isVirtual),
mCompositionDisplay{mFlinger->getCompositionEngine().createDisplay(
compositionengine::DisplayCreationArgs{args.isVirtual, args.displayId,
args.powerAdvisor})},
- mIsVirtual(args.isVirtual),
- mOrientation(),
- mActiveConfig(0),
+ mPhysicalOrientation(args.physicalOrientation),
mIsPrimary(args.isPrimary) {
mCompositionDisplay->editState().isSecure = args.isSecure;
mCompositionDisplay->createRenderSurface(
@@ -88,7 +81,7 @@
setPowerMode(args.initialPowerMode);
// initialize the display orientation transform.
- setProjection(DisplayState::eOrientationDefault, Rect::INVALID_RECT, Rect::INVALID_RECT);
+ setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
}
DisplayDevice::~DisplayDevice() = default;
@@ -131,7 +124,6 @@
return mPowerMode != HWC_POWER_MODE_OFF;
}
-// ----------------------------------------------------------------------------
void DisplayDevice::setActiveConfig(HwcConfigIndexType mode) {
mActiveConfig = mode;
}
@@ -140,53 +132,19 @@
return mActiveConfig;
}
-// ----------------------------------------------------------------------------
-
ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
return mCompositionDisplay->getState().dataspace;
}
-// ----------------------------------------------------------------------------
-
void DisplayDevice::setLayerStack(uint32_t stack) {
mCompositionDisplay->setLayerStackFilter(stack, isPrimary());
}
-// ----------------------------------------------------------------------------
-
-uint32_t DisplayDevice::displayStateOrientationToTransformOrientation(int orientation) {
- switch (orientation) {
- case DisplayState::eOrientationDefault:
- return ui::Transform::ROT_0;
- case DisplayState::eOrientation90:
- return ui::Transform::ROT_90;
- case DisplayState::eOrientation180:
- return ui::Transform::ROT_180;
- case DisplayState::eOrientation270:
- return ui::Transform::ROT_270;
- default:
- return ui::Transform::ROT_INVALID;
- }
-}
-
-status_t DisplayDevice::orientationToTransfrom(int orientation, int w, int h, ui::Transform* tr) {
- uint32_t flags = displayStateOrientationToTransformOrientation(orientation);
- if (flags == ui::Transform::ROT_INVALID) {
- return BAD_VALUE;
- }
- tr->set(flags, w, h);
- return NO_ERROR;
-}
-
void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
mCompositionDisplay->setBounds(ui::Size(newWidth, newHeight));
}
-void DisplayDevice::setProjection(int orientation,
- const Rect& newViewport, const Rect& newFrame) {
- Rect viewport(newViewport);
- Rect frame(newFrame);
-
+void DisplayDevice::setProjection(ui::Rotation orientation, Rect viewport, Rect frame) {
mOrientation = orientation;
const Rect& displayBounds = getCompositionDisplay()->getState().bounds;
@@ -194,7 +152,10 @@
const int h = displayBounds.height();
ui::Transform R;
- DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
+ if (const auto flags = ui::Transform::toRotationFlags(orientation);
+ flags != ui::Transform::ROT_INVALID) {
+ R.set(flags, w, h);
+ }
if (!frame.isValid()) {
// the destination frame can be invalid if it has never been set,
@@ -236,9 +197,10 @@
// need to take care of primary display rotation for globalTransform
// for case if the panel is not installed aligned with device orientation
if (isPrimary()) {
- DisplayDevice::orientationToTransfrom(
- (orientation + mDisplayInstallOrientation) % (DisplayState::eOrientation270 + 1),
- w, h, &R);
+ if (const auto flags = ui::Transform::toRotationFlags(orientation + mPhysicalOrientation);
+ flags != ui::Transform::ROT_INVALID) {
+ R.set(flags, w, h);
+ }
}
// The viewport and frame are both in the logical orientation.
@@ -258,19 +220,18 @@
uint32_t transformOrientation;
if (isPrimary()) {
- sPrimaryDisplayOrientation = displayStateOrientationToTransformOrientation(orientation);
- transformOrientation = displayStateOrientationToTransformOrientation(
- (orientation + mDisplayInstallOrientation) % (DisplayState::eOrientation270 + 1));
+ sPrimaryDisplayRotationFlags = ui::Transform::toRotationFlags(orientation);
+ transformOrientation = ui::Transform::toRotationFlags(orientation + mPhysicalOrientation);
} else {
- transformOrientation = displayStateOrientationToTransformOrientation(orientation);
+ transformOrientation = ui::Transform::toRotationFlags(orientation);
}
getCompositionDisplay()->setProjection(globalTransform, transformOrientation,
frame, viewport, scissor, needsFiltering);
}
-uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
- return sPrimaryDisplayOrientation;
+ui::Transform::RotationFlags DisplayDevice::getPrimaryDisplayRotationFlags() {
+ return sPrimaryDisplayRotationFlags;
}
std::string DisplayDevice::getDebugName() const {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 79a1185..605e7c8 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef ANDROID_DISPLAY_DEVICE_H
-#define ANDROID_DISPLAY_DEVICE_H
+#pragma once
#include <stdlib.h>
@@ -83,14 +82,17 @@
int getWidth() const;
int getHeight() const;
- int getInstallOrientation() const { return mDisplayInstallOrientation; }
void setLayerStack(uint32_t stack);
void setDisplaySize(const int newWidth, const int newHeight);
- void setProjection(int orientation, const Rect& viewport, const Rect& frame);
- int getOrientation() const { return mOrientation; }
- static uint32_t getPrimaryDisplayOrientationTransform();
+ void setProjection(ui::Rotation orientation, Rect viewport, Rect frame);
+
+ ui::Rotation getPhysicalOrientation() const { return mPhysicalOrientation; }
+ ui::Rotation getOrientation() const { return mOrientation; }
+
+ static ui::Transform::RotationFlags getPrimaryDisplayRotationFlags();
+
const ui::Transform& getTransform() const;
const Rect& getViewport() const;
const Rect& getFrame() const;
@@ -156,37 +158,21 @@
void dump(std::string& result) const;
private:
- /*
- * Constants, set during initialization
- */
const sp<SurfaceFlinger> mFlinger;
const wp<IBinder> mDisplayToken;
const int32_t mSequenceId;
+ const bool mIsVirtual;
- const int mDisplayInstallOrientation;
const std::shared_ptr<compositionengine::Display> mCompositionDisplay;
std::string mDisplayName;
- const bool mIsVirtual;
- /*
- * Can only accessed from the main thread, these members
- * don't need synchronization.
- */
+ const ui::Rotation mPhysicalOrientation;
+ ui::Rotation mOrientation = ui::ROTATION_0;
- /*
- * Transaction state
- */
- static uint32_t displayStateOrientationToTransformOrientation(int orientation);
- static status_t orientationToTransfrom(int orientation,
- int w, int h, ui::Transform* tr);
+ static ui::Transform::RotationFlags sPrimaryDisplayRotationFlags;
- int mOrientation;
- static uint32_t sPrimaryDisplayOrientation;
-
- // Current power mode
- int mPowerMode;
- // Current active config
+ int mPowerMode = HWC_POWER_MODE_OFF;
HwcConfigIndexType mActiveConfig;
// TODO(b/74619554): Remove special cases for primary display.
@@ -202,7 +188,7 @@
uint32_t layerStack = NO_LAYER_STACK;
Rect viewport;
Rect frame;
- uint8_t orientation = 0;
+ ui::Rotation orientation = ui::ROTATION_0;
uint32_t width = 0;
uint32_t height = 0;
std::string displayName;
@@ -227,7 +213,7 @@
bool isSecure{false};
sp<ANativeWindow> nativeWindow;
sp<compositionengine::DisplaySurface> displaySurface;
- int displayInstallOrientation{DisplayState::eOrientationDefault};
+ ui::Rotation physicalOrientation{ui::ROTATION_0};
bool hasWideColorGamut{false};
HdrCapabilities hdrCapabilities;
int32_t supportedPerFrameMetadata{0};
@@ -239,31 +225,33 @@
class DisplayRenderArea : public RenderArea {
public:
- DisplayRenderArea(const sp<const DisplayDevice> device,
- ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
- : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(),
- device->getCompositionDataSpace(), rotation) {}
- DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth,
- uint32_t reqHeight, ui::Dataspace reqDataSpace,
- ui::Transform::orientation_flags rotation, bool allowSecureLayers = true)
+ DisplayRenderArea(const sp<const DisplayDevice>& display,
+ RotationFlags rotation = ui::Transform::ROT_0)
+ : DisplayRenderArea(display, display->getBounds(), display->getWidth(),
+ display->getHeight(), display->getCompositionDataSpace(), rotation) {}
+
+ DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, uint32_t reqWidth,
+ uint32_t reqHeight, ui::Dataspace reqDataSpace, RotationFlags rotation,
+ bool allowSecureLayers = true)
: RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, reqDataSpace,
- device->getViewport(),
- getDisplayRotation(rotation, device->getInstallOrientation())),
- mDevice(device),
+ display->getViewport(),
+ applyInversePhysicalOrientation(rotation,
+ display->getPhysicalOrientation())),
+ mDisplay(std::move(display)),
mSourceCrop(sourceCrop),
mAllowSecureLayers(allowSecureLayers) {}
- const ui::Transform& getTransform() const override { return mDevice->getTransform(); }
- Rect getBounds() const override { return mDevice->getBounds(); }
- int getHeight() const override { return mDevice->getHeight(); }
- int getWidth() const override { return mDevice->getWidth(); }
- bool isSecure() const override { return mAllowSecureLayers && mDevice->isSecure(); }
- const sp<const DisplayDevice> getDisplayDevice() const override { return mDevice; }
+ const ui::Transform& getTransform() const override { return mDisplay->getTransform(); }
+ Rect getBounds() const override { return mDisplay->getBounds(); }
+ int getHeight() const override { return mDisplay->getHeight(); }
+ int getWidth() const override { return mDisplay->getWidth(); }
+ bool isSecure() const override { return mAllowSecureLayers && mDisplay->isSecure(); }
+ sp<const DisplayDevice> getDisplayDevice() const override { return mDisplay; }
bool needsFiltering() const override {
// check if the projection from the logical display to the physical
// display needs filtering
- if (mDevice->needsFiltering()) {
+ if (mDisplay->needsFiltering()) {
return true;
}
@@ -281,7 +269,7 @@
Rect getSourceCrop() const override {
// use the projected display viewport by default.
if (mSourceCrop.isEmpty()) {
- return mDevice->getScissor();
+ return mDisplay->getScissor();
}
// Recompute the device transformation for the source crop.
@@ -289,27 +277,13 @@
ui::Transform translatePhysical;
ui::Transform translateLogical;
ui::Transform scale;
- const Rect& viewport = mDevice->getViewport();
- const Rect& scissor = mDevice->getScissor();
- const Rect& frame = mDevice->getFrame();
+ const Rect& viewport = mDisplay->getViewport();
+ const Rect& scissor = mDisplay->getScissor();
+ const Rect& frame = mDisplay->getFrame();
- const int orientation = mDevice->getInstallOrientation();
- // Install orientation is transparent to the callers. Apply it now.
- uint32_t flags = 0x00;
- switch (orientation) {
- case DisplayState::eOrientation90:
- flags = ui::Transform::ROT_90;
- break;
- case DisplayState::eOrientation180:
- flags = ui::Transform::ROT_180;
- break;
- case DisplayState::eOrientation270:
- flags = ui::Transform::ROT_270;
- break;
- default:
- break;
- }
+ const auto flags = ui::Transform::toRotationFlags(mDisplay->getPhysicalOrientation());
rotation.set(flags, getWidth(), getHeight());
+
translateLogical.set(-viewport.left, -viewport.top);
translatePhysical.set(scissor.left, scissor.top);
scale.set(frame.getWidth() / float(viewport.getWidth()), 0, 0,
@@ -320,49 +294,44 @@
}
private:
- // Install orientation is transparent to the callers. We need to cancel
- // it out by modifying rotation flags.
- static ui::Transform::orientation_flags getDisplayRotation(
- ui::Transform::orientation_flags rotation, int orientation) {
- if (orientation == DisplayState::eOrientationDefault) {
- return rotation;
- }
+ static RotationFlags applyInversePhysicalOrientation(RotationFlags orientation,
+ ui::Rotation physicalOrientation) {
+ uint32_t inverseRotate90 = 0;
+ uint32_t inverseReflect = 0;
- // convert hw orientation into flag presentation
- // here inverse transform needed
- uint8_t hw_rot_90 = 0x00;
- uint8_t hw_flip_hv = 0x00;
- switch (orientation) {
- case DisplayState::eOrientation90:
- hw_rot_90 = ui::Transform::ROT_90;
- hw_flip_hv = ui::Transform::ROT_180;
+ switch (physicalOrientation) {
+ case ui::ROTATION_0:
+ return orientation;
+
+ case ui::ROTATION_90:
+ inverseRotate90 = ui::Transform::ROT_90;
+ inverseReflect = ui::Transform::ROT_180;
break;
- case DisplayState::eOrientation180:
- hw_flip_hv = ui::Transform::ROT_180;
+
+ case ui::ROTATION_180:
+ inverseReflect = ui::Transform::ROT_180;
break;
- case DisplayState::eOrientation270:
- hw_rot_90 = ui::Transform::ROT_90;
+
+ case ui::ROTATION_270:
+ inverseRotate90 = ui::Transform::ROT_90;
break;
}
- // transform flags operation
- // 1) flip H V if both have ROT_90 flag
- // 2) XOR these flags
- uint8_t rotation_rot_90 = rotation & ui::Transform::ROT_90;
- uint8_t rotation_flip_hv = rotation & ui::Transform::ROT_180;
- if (rotation_rot_90 & hw_rot_90) {
- rotation_flip_hv = (~rotation_flip_hv) & ui::Transform::ROT_180;
+ const uint32_t rotate90 = orientation & ui::Transform::ROT_90;
+ uint32_t reflect = orientation & ui::Transform::ROT_180;
+
+ // Apply reflection for double rotation.
+ if (rotate90 & inverseRotate90) {
+ reflect = ~reflect & ui::Transform::ROT_180;
}
- return static_cast<ui::Transform::orientation_flags>(
- (rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv));
+ return static_cast<RotationFlags>((rotate90 ^ inverseRotate90) |
+ (reflect ^ inverseReflect));
}
- const sp<const DisplayDevice> mDevice;
+ const sp<const DisplayDevice> mDisplay;
const Rect mSourceCrop;
const bool mAllowSecureLayers;
};
-}; // namespace android
-
-#endif // ANDROID_DISPLAY_DEVICE_H
+} // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5bc0860..2593681 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1893,6 +1893,18 @@
setTransactionFlags(eTransactionNeeded);
}
+LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags) const {
+ LayerProto* layerProto = layersProto.add_layers();
+ writeToProtoDrawingState(layerProto, traceFlags);
+ writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags);
+
+ for (const sp<Layer>& layer : mDrawingChildren) {
+ layer->writeToProto(layersProto, traceFlags);
+ }
+
+ return layerProto;
+}
+
void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags) const {
ui::Transform transform = getTransform();
@@ -2014,6 +2026,8 @@
} else {
layerInfo->set_z_order_relative_of(-1);
}
+
+ layerInfo->set_is_relative_of(state.isRelativeOf);
}
if (traceFlags & SurfaceTracing::TRACE_INPUT) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 553408c..174ac8d 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -454,6 +454,9 @@
bool isRemovedFromCurrentState() const;
+ LayerProto* writeToProto(LayersProto& layersProto,
+ uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
+
// Write states that are modified by the main thread. This includes drawing
// state as well as buffer data. This should be called in the main or tracing
// thread.
diff --git a/services/surfaceflinger/LayerRejecter.cpp b/services/surfaceflinger/LayerRejecter.cpp
index 1a60f1e..412f977 100644
--- a/services/surfaceflinger/LayerRejecter.cpp
+++ b/services/surfaceflinger/LayerRejecter.cpp
@@ -49,7 +49,7 @@
}
if (mTransformToDisplayInverse) {
- uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
+ uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
if (invTransform & ui::Transform::ROT_90) {
std::swap(bufWidth, bufHeight);
}
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index a484373..73de4f8 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -337,19 +337,7 @@
}
const auto device = mFlinger.getDefaultDisplayDevice();
- const auto orientation = [](uint32_t orientation) {
- switch (orientation) {
- default:
- case DisplayState::eOrientationDefault:
- return ui::Transform::ROT_0;
- case DisplayState::eOrientation90:
- return ui::Transform::ROT_90;
- case DisplayState::eOrientation180:
- return ui::Transform::ROT_180;
- case DisplayState::eOrientation270:
- return ui::Transform::ROT_270;
- }
- }(device->getOrientation());
+ const auto orientation = ui::Transform::toRotationFlags(device->getOrientation());
std::vector<RegionSamplingThread::Descriptor> descriptors;
Region sampleRegion;
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index 532572f..a7a6dd5 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -17,13 +17,15 @@
// physical render area.
class RenderArea {
public:
+ using RotationFlags = ui::Transform::RotationFlags;
+
enum class CaptureFill {CLEAR, OPAQUE};
static float getCaptureFillValue(CaptureFill captureFill);
RenderArea(uint32_t reqWidth, uint32_t reqHeight, CaptureFill captureFill,
ui::Dataspace reqDataSpace, const Rect& displayViewport,
- ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
+ RotationFlags rotation = ui::Transform::ROT_0)
: mReqWidth(reqWidth),
mReqHeight(reqHeight),
mReqDataSpace(reqDataSpace),
@@ -66,20 +68,20 @@
virtual Rect getSourceCrop() const = 0;
// Returns the rotation of the source crop and the layers.
- ui::Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
+ RotationFlags getRotationFlags() const { return mRotationFlags; }
// Returns the size of the physical render area.
- int getReqWidth() const { return mReqWidth; };
- int getReqHeight() const { return mReqHeight; };
+ int getReqWidth() const { return mReqWidth; }
+ int getReqHeight() const { return mReqHeight; }
// Returns the composition data space of the render area.
ui::Dataspace getReqDataSpace() const { return mReqDataSpace; }
// Returns the fill color of the physical render area. Regions not
// covered by any rendered layer should be filled with this color.
- CaptureFill getCaptureFill() const { return mCaptureFill; };
+ CaptureFill getCaptureFill() const { return mCaptureFill; }
- virtual const sp<const DisplayDevice> getDisplayDevice() const = 0;
+ virtual sp<const DisplayDevice> getDisplayDevice() const = 0;
// Returns the source display viewport.
const Rect& getDisplayViewport() const { return mDisplayViewport; }
@@ -89,7 +91,7 @@
const uint32_t mReqHeight;
const ui::Dataspace mReqDataSpace;
const CaptureFill mCaptureFill;
- const ui::Transform::orientation_flags mRotationFlags;
+ const RotationFlags mRotationFlags;
const Rect mDisplayViewport;
};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 004240b..b7a2c76 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -163,21 +163,6 @@
return false;
}
-ui::Transform::orientation_flags fromSurfaceComposerRotation(ISurfaceComposer::Rotation rotation) {
- switch (rotation) {
- case ISurfaceComposer::eRotateNone:
- return ui::Transform::ROT_0;
- case ISurfaceComposer::eRotate90:
- return ui::Transform::ROT_90;
- case ISurfaceComposer::eRotate180:
- return ui::Transform::ROT_180;
- case ISurfaceComposer::eRotate270:
- return ui::Transform::ROT_270;
- }
- ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
- return ui::Transform::ROT_0;
-}
-
#pragma clang diagnostic pop
class ConditionalLock {
@@ -215,7 +200,7 @@
bool SurfaceFlinger::useVrFlinger;
int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
bool SurfaceFlinger::hasWideColorDisplay;
-int SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault;
+ui::Rotation SurfaceFlinger::internalDisplayOrientation = ui::ROTATION_0;
bool SurfaceFlinger::useColorManagement;
bool SurfaceFlinger::useContextPriority;
Dataspace SurfaceFlinger::defaultCompositionDataspace = Dataspace::V0_SRGB;
@@ -298,23 +283,21 @@
useContextPriority = use_context_priority(true);
- auto tmpPrimaryDisplayOrientation = primary_display_orientation(
- SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_0);
- switch (tmpPrimaryDisplayOrientation) {
- case SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_90:
- SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation90;
+ using Values = SurfaceFlingerProperties::primary_display_orientation_values;
+ switch (primary_display_orientation(Values::ORIENTATION_0)) {
+ case Values::ORIENTATION_0:
break;
- case SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_180:
- SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation180;
+ case Values::ORIENTATION_90:
+ internalDisplayOrientation = ui::ROTATION_90;
break;
- case SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_270:
- SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation270;
+ case Values::ORIENTATION_180:
+ internalDisplayOrientation = ui::ROTATION_180;
break;
- default:
- SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault;
+ case Values::ORIENTATION_270:
+ internalDisplayOrientation = ui::ROTATION_270;
break;
}
- ALOGV("Primary Display Orientation is set to %2d.", SurfaceFlinger::primaryDisplayOrientation);
+ ALOGV("Internal Display Orientation: %s", toCString(internalDisplayOrientation));
mInternalDisplayPrimaries = sysprop::getDisplayNativePrimaries();
@@ -789,9 +772,8 @@
}
info.density = density;
- // TODO: this needs to go away (currently needed only by webkit)
const auto display = getDefaultDisplayDeviceLocked();
- info.orientation = display ? display->getOrientation() : 0;
+ info.orientation = display->getOrientation();
// This is for screenrecord
const Rect viewport = display->getViewport();
@@ -804,7 +786,6 @@
// TODO: where should this value come from?
static const int TV_DENSITY = 213;
info.density = TV_DENSITY / 160.0f;
- info.orientation = 0;
const auto display = getDisplayDeviceLocked(displayToken);
info.layerStack = display->getLayerStack();
@@ -835,7 +816,8 @@
info.secure = true;
if (displayId == getInternalDisplayIdLocked() &&
- primaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
+ (internalDisplayOrientation == ui::ROTATION_90 ||
+ internalDisplayOrientation == ui::ROTATION_270)) {
std::swap(info.w, info.h);
}
@@ -2284,8 +2266,8 @@
nativeWindow->setSwapInterval(nativeWindow.get(), 0);
}
- creationArgs.displayInstallOrientation =
- isInternalDisplay ? primaryDisplayOrientation : DisplayState::eOrientationDefault;
+ creationArgs.physicalOrientation =
+ isInternalDisplay ? internalDisplayOrientation : ui::ROTATION_0;
// virtual displays are always considered enabled
creationArgs.initialPowerMode = state.isVirtual() ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
@@ -3822,7 +3804,7 @@
DisplayState::eLayerStackChanged;
d.token = token;
d.layerStack = 0;
- d.orientation = DisplayState::eOrientationDefault;
+ d.orientation = ui::ROTATION_0;
d.frame.makeInvalid();
d.viewport.makeInvalid();
d.width = 0;
@@ -4275,12 +4257,9 @@
LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
LayersProto layersProto;
- mDrawingState.traverseInZOrder([&](Layer* layer) {
- LayerProto* layerProto = layersProto.add_layers();
- layer->writeToProtoDrawingState(layerProto, traceFlags);
- layer->writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags);
- });
-
+ for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) {
+ layer->writeToProto(layersProto, traceFlags);
+ }
return layersProto;
}
@@ -4298,21 +4277,8 @@
rootProto->add_children(offscreenLayer->sequence);
// Add layer
- LayerProto* layerProto = layersProto.add_layers();
- offscreenLayer->writeToProtoDrawingState(layerProto, traceFlags);
- offscreenLayer->writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing,
- traceFlags);
+ LayerProto* layerProto = offscreenLayer->writeToProto(layersProto, traceFlags);
layerProto->set_parent(offscreenRootLayerId);
-
- // Add children
- offscreenLayer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
- if (layer == offscreenLayer) {
- return;
- }
- LayerProto* childProto = layersProto.add_layers();
- layer->writeToProtoDrawingState(childProto, traceFlags);
- layer->writeToProtoCommonState(childProto, LayerVector::StateSet::Drawing, traceFlags);
- });
}
}
@@ -4431,8 +4397,8 @@
if (const auto display = getDefaultDisplayDeviceLocked()) {
display->getCompositionDisplay()->getState().undefinedRegion.dump(result,
"undefinedRegion");
- StringAppendF(&result, " orientation=%d, isPoweredOn=%d\n", display->getOrientation(),
- display->isPoweredOn());
+ StringAppendF(&result, " orientation=%s, isPoweredOn=%d\n",
+ toCString(display->getOrientation()), display->isPoweredOn());
}
StringAppendF(&result,
" transaction-flags : %08x\n"
@@ -5009,17 +4975,19 @@
status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken,
sp<GraphicBuffer>* outBuffer, bool& outCapturedSecureLayers,
- const Dataspace reqDataspace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
- uint32_t reqWidth, uint32_t reqHeight,
- bool useIdentityTransform,
- ISurfaceComposer::Rotation rotation,
- bool captureSecureLayers) {
+ Dataspace reqDataspace, ui::PixelFormat reqPixelFormat,
+ const Rect& sourceCrop, uint32_t reqWidth,
+ uint32_t reqHeight, bool useIdentityTransform,
+ ui::Rotation rotation, bool captureSecureLayers) {
ATRACE_CALL();
if (!displayToken) return BAD_VALUE;
- auto renderAreaRotation = fromSurfaceComposerRotation(rotation);
+ auto renderAreaRotation = ui::Transform::toRotationFlags(rotation);
+ if (renderAreaRotation == ui::Transform::ROT_INVALID) {
+ ALOGE("%s: Invalid rotation: %s", __FUNCTION__, toCString(rotation));
+ renderAreaRotation = ui::Transform::ROT_0;
+ }
sp<DisplayDevice> display;
{
@@ -5081,7 +5049,7 @@
sp<DisplayDevice> display;
uint32_t width;
uint32_t height;
- ui::Transform::orientation_flags captureOrientation;
+ ui::Transform::RotationFlags captureOrientation;
{
Mutex::Autolock _l(mStateLock);
display = getDisplayByIdOrLayerStack(displayOrLayerStack);
@@ -5092,12 +5060,25 @@
width = uint32_t(display->getViewport().width());
height = uint32_t(display->getViewport().height());
- captureOrientation = fromSurfaceComposerRotation(
- static_cast<ISurfaceComposer::Rotation>(display->getOrientation()));
- if (captureOrientation == ui::Transform::orientation_flags::ROT_90) {
- captureOrientation = ui::Transform::orientation_flags::ROT_270;
- } else if (captureOrientation == ui::Transform::orientation_flags::ROT_270) {
- captureOrientation = ui::Transform::orientation_flags::ROT_90;
+ const auto orientation = display->getOrientation();
+ captureOrientation = ui::Transform::toRotationFlags(orientation);
+
+ switch (captureOrientation) {
+ case ui::Transform::ROT_90:
+ captureOrientation = ui::Transform::ROT_270;
+ break;
+
+ case ui::Transform::ROT_270:
+ captureOrientation = ui::Transform::ROT_90;
+ break;
+
+ case ui::Transform::ROT_INVALID:
+ ALOGE("%s: Invalid orientation: %s", __FUNCTION__, toCString(orientation));
+ captureOrientation = ui::Transform::ROT_0;
+ break;
+
+ default:
+ break;
}
*outDataspace =
pickDataspaceFromColorMode(display->getCompositionDisplay()->getState().colorMode);
@@ -5145,7 +5126,7 @@
}
bool isSecure() const override { return false; }
bool needsFiltering() const override { return mNeedsFiltering; }
- const sp<const DisplayDevice> getDisplayDevice() const override { return nullptr; }
+ sp<const DisplayDevice> getDisplayDevice() const override { return nullptr; }
Rect getSourceCrop() const override {
if (mCrop.isEmpty()) {
return getBounds();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index dcd9dc2..723e332 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -229,7 +229,7 @@
// found on devices with wide color gamut (e.g. Display-P3) display.
static bool hasWideColorDisplay;
- static int primaryDisplayOrientation;
+ static ui::Rotation internalDisplayOrientation;
// Indicate if device wants color management on its display.
static bool useColorManagement;
@@ -415,10 +415,10 @@
ISurfaceComposer::ConfigChanged configChanged =
ISurfaceComposer::eConfigChangedSuppress) override;
status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer,
- bool& outCapturedSecureLayers, const ui::Dataspace reqDataspace,
- const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
- uint32_t reqWidth, uint32_t reqHeight,
- bool useIdentityTransform, ISurfaceComposer::Rotation rotation, bool captureSecureLayers) override;
+ bool& outCapturedSecureLayers, ui::Dataspace reqDataspace,
+ ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
+ uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+ ui::Rotation rotation, bool captureSecureLayers) override;
status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace,
sp<GraphicBuffer>* outBuffer) override;
status_t captureLayers(
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 5e8910a..8e0462a 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -137,8 +137,8 @@
addDisplaySurfaceLocked(transaction, display.sequenceId, display.surface);
addDisplayLayerStackLocked(transaction, display.sequenceId, display.layerStack);
addDisplaySizeLocked(transaction, display.sequenceId, display.width, display.height);
- addDisplayProjectionLocked(transaction, display.sequenceId, display.orientation,
- display.viewport, display.frame);
+ addDisplayProjectionLocked(transaction, display.sequenceId, toRotationInt(display.orientation),
+ display.viewport, display.frame);
}
status_t SurfaceInterceptor::writeProtoFileLocked() {
@@ -467,8 +467,8 @@
addDisplaySizeLocked(transaction, sequenceId, state.width, state.height);
}
if (state.what & DisplayState::eDisplayProjectionChanged) {
- addDisplayProjectionLocked(transaction, sequenceId, state.orientation, state.viewport,
- state.frame);
+ addDisplayProjectionLocked(transaction, sequenceId, toRotationInt(state.orientation),
+ state.viewport, state.frame);
}
}
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index 23df1bb..41ecafa 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -102,6 +102,8 @@
// layer or set by a parent layer.
float shadow_radius = 49;
ColorTransformProto color_transform = 50;
+
+ bool is_relative_of = 51;
}
message PositionProto {
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index b1bb7fd..f618873 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -23,7 +23,6 @@
namespace {
const String8 DISPLAY_NAME("Credentials Display Test");
const String8 SURFACE_NAME("Test Surface Name");
-const uint32_t ROTATION = 0;
const float FRAME_SCALE = 1.0f;
} // namespace
@@ -262,7 +261,7 @@
sp<GraphicBuffer> outBuffer;
return ScreenshotClient::capture(display, ui::Dataspace::V0_SRGB,
ui::PixelFormat::RGBA_8888, Rect(), 0 /*reqWidth*/,
- 0 /*reqHeight*/, false, ROTATION, &outBuffer);
+ 0 /*reqHeight*/, false, ui::ROTATION_0, &outBuffer);
};
ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
}
diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
index 627de7a..92698f0 100644
--- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
@@ -189,12 +189,12 @@
}
TEST_P(LayerRenderTypeTransactionTest, CreateLayer_BufferState) {
- uint32_t transformHint = ui::Transform::orientation_flags::ROT_INVALID;
+ uint32_t transformHint = ui::Transform::ROT_INVALID;
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32,
ISurfaceComposerClient::eFXSurfaceBufferState,
/*parent*/ nullptr, &transformHint));
- ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, transformHint);
+ ASSERT_NE(ui::Transform::ROT_INVALID, transformHint);
}
void LayerRenderTypeTransactionTest::setRelativeZBasicHelper(uint32_t layerType) {
diff --git a/services/surfaceflinger/tests/LayerTransaction_test.cpp b/services/surfaceflinger/tests/LayerTransaction_test.cpp
index 35c51e1..7816c66 100644
--- a/services/surfaceflinger/tests/LayerTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTransaction_test.cpp
@@ -53,7 +53,7 @@
ASSERT_EQ(NO_ERROR,
composer->captureScreen(mDisplay, &outBuffer, outCapturedSecureLayers,
ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(), 0,
- 0, false, ISurfaceComposer::eRotateNone, true));
+ 0, false, ui::ROTATION_0, true));
ASSERT_EQ(true, outCapturedSecureLayers);
ScreenCapture sc(outBuffer);
sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 76e8171..55c3ab8 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -2040,8 +2040,8 @@
TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
using Case = NonHwcVirtualDisplayCase;
- constexpr int oldTransform = 0;
- constexpr int newTransform = 2;
+ constexpr ui::Rotation oldTransform = ui::ROTATION_0;
+ constexpr ui::Rotation newTransform = ui::ROTATION_180;
// --------------------------------------------------------------------
// Preconditions
@@ -2414,7 +2414,7 @@
TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
using Case = SimplePrimaryDisplayCase;
- constexpr int initialOrientation = 180;
+ constexpr ui::Rotation initialOrientation = ui::ROTATION_180;
const Rect initialFrame = {1, 2, 3, 4};
const Rect initialViewport = {5, 6, 7, 8};
@@ -2458,8 +2458,8 @@
TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
using Case = SimplePrimaryDisplayCase;
- constexpr int initialOrientation = 90;
- constexpr int desiredOrientation = 180;
+ constexpr ui::Rotation initialOrientation = ui::ROTATION_90;
+ constexpr ui::Rotation desiredOrientation = ui::ROTATION_180;
// --------------------------------------------------------------------
// Preconditions
@@ -2721,7 +2721,7 @@
// The layer stack state should be set to zero
EXPECT_EQ(0u, primaryDisplayState.layerStack);
// The orientation state should be set to zero
- EXPECT_EQ(0, primaryDisplayState.orientation);
+ EXPECT_EQ(ui::ROTATION_0, primaryDisplayState.orientation);
// The frame state should be set to INVALID
EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.frame);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index b5245e2..9728c80 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -371,7 +371,6 @@
*/
auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; }
- auto& mutablePrimaryDisplayOrientation() { return SurfaceFlinger::primaryDisplayOrientation; }
auto& mutableUseColorManagement() { return SurfaceFlinger::useColorManagement; }
auto& mutableCurrentState() { return mFlinger->mCurrentState; }