Merge "Add feature flags for verified boot and securely remove users." into lmp-dev
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 85c353e..c8ee75e 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -296,7 +296,7 @@
/* forks a command and waits for it to finish */
int run_command(const char *title, int timeout_seconds, const char *command, ...) {
fflush(stdout);
- clock_t start = clock();
+ time_t start = time(NULL);
pid_t pid = fork();
/* handle error case */
@@ -340,19 +340,19 @@
for (;;) {
int status;
pid_t p = waitpid(pid, &status, WNOHANG);
- float elapsed = (float) (clock() - start) / CLOCKS_PER_SEC;
+ time_t elapsed = time(NULL) - start;
if (p == pid) {
if (WIFSIGNALED(status)) {
printf("*** %s: Killed by signal %d\n", command, WTERMSIG(status));
} else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
printf("*** %s: Exit code %d\n", command, WEXITSTATUS(status));
}
- if (title) printf("[%s: %.1fs elapsed]\n\n", command, elapsed);
+ if (title) printf("[%s: %ds elapsed]\n\n", command, (int) elapsed);
return status;
}
if (timeout_seconds && elapsed > timeout_seconds) {
- printf("*** %s: Timed out after %.1fs (killing pid %d)\n", command, elapsed, pid);
+ printf("*** %s: Timed out after %ds (killing pid %d)\n", command, (int) elapsed, pid);
kill(pid, SIGTERM);
return -1;
}
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 3e2d953..fc3972e 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -313,10 +313,16 @@
int delete_code_cache(const char *pkgname, userid_t userid)
{
char codecachedir[PKG_PATH_MAX];
+ struct stat s;
if (create_pkg_path(codecachedir, pkgname, CODE_CACHE_DIR_POSTFIX, userid))
return -1;
+ /* it's okay if code cache is missing */
+ if (lstat(codecachedir, &s) == -1 && errno == ENOENT) {
+ return 0;
+ }
+
/* delete contents, not the directory, no exceptions */
return delete_dir_contents(codecachedir, 0, NULL);
}
@@ -416,8 +422,14 @@
char src_dex[PKG_PATH_MAX];
char dst_dex[PKG_PATH_MAX];
- if (validate_apk_path(src)) return -1;
- if (validate_apk_path(dst)) return -1;
+ if (validate_apk_path(src)) {
+ ALOGE("invalid apk path '%s' (bad prefix)\n", src);
+ return -1;
+ }
+ if (validate_apk_path(dst)) {
+ ALOGE("invalid apk path '%s' (bad prefix)\n", dst);
+ return -1;
+ }
if (create_cache_path(src_dex, src, instruction_set)) return -1;
if (create_cache_path(dst_dex, dst, instruction_set)) return -1;
@@ -435,12 +447,18 @@
{
char dex_path[PKG_PATH_MAX];
- if (validate_apk_path(path)) return -1;
+ if (validate_apk_path(path) && validate_system_app_path(path)) {
+ ALOGE("invalid apk path '%s' (bad prefix)\n", path);
+ return -1;
+ }
+
if (create_cache_path(dex_path, path, instruction_set)) return -1;
ALOGV("unlink %s\n", dex_path);
if (unlink(dex_path) < 0) {
- ALOGE("Couldn't unlink %s: %s\n", dex_path, strerror(errno));
+ if (errno != ENOENT) {
+ ALOGE("Couldn't unlink %s: %s\n", dex_path, strerror(errno));
+ }
return -1;
} else {
return 0;
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index c7fdf7a..3078f20 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -328,7 +328,7 @@
}
// Take note of the system and vendor directories.
- android_system_dirs.count = 2;
+ android_system_dirs.count = 4;
android_system_dirs.dirs = calloc(android_system_dirs.count, sizeof(dir_rec_t));
if (android_system_dirs.dirs == NULL) {
@@ -336,22 +336,24 @@
return -1;
}
- // system
- if (get_path_from_env(&android_system_dirs.dirs[0], "ANDROID_ROOT") < 0) {
- free_globals();
+ dir_rec_t android_root_dir;
+ if (get_path_from_env(&android_root_dir, "ANDROID_ROOT") < 0) {
+ ALOGE("Missing ANDROID_ROOT; aborting\n");
return -1;
}
- // append "app/" to dirs[0]
- char *system_app_path = build_string2(android_system_dirs.dirs[0].path, APP_SUBDIR);
- android_system_dirs.dirs[0].path = system_app_path;
- android_system_dirs.dirs[0].len = strlen(system_app_path);
+ android_system_dirs.dirs[0].path = build_string2(android_root_dir.path, APP_SUBDIR);
+ android_system_dirs.dirs[0].len = strlen(android_system_dirs.dirs[0].path);
- // vendor
- // TODO replace this with an environment variable (doesn't exist yet)
- android_system_dirs.dirs[1].path = "/vendor/app/";
+ android_system_dirs.dirs[1].path = build_string2(android_root_dir.path, PRIV_APP_SUBDIR);
android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path);
+ android_system_dirs.dirs[2].path = "/vendor/app/";
+ android_system_dirs.dirs[2].len = strlen(android_system_dirs.dirs[2].path);
+
+ android_system_dirs.dirs[3].path = "/oem/app/";
+ android_system_dirs.dirs[3].len = strlen(android_system_dirs.dirs[3].path);
+
return 0;
}
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 99f037c..a5cad45 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -62,6 +62,7 @@
#define CODE_CACHE_DIR_POSTFIX "/code_cache"
#define APP_SUBDIR "app/" // sub-directory under ANDROID_DATA
+#define PRIV_APP_SUBDIR "priv-app/" // sub-directory under ANDROID_DATA
#define APP_LIB_SUBDIR "app-lib/" // sub-directory under ANDROID_DATA
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 8cd1168..60d20de 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -952,7 +952,6 @@
} else if (!strncmp(path, android_asec_dir.path, android_asec_dir.len)) {
dir = &android_asec_dir;
} else {
- ALOGE("invalid apk path '%s' (bad prefix)\n", path);
return -1;
}
diff --git a/data/etc/android.hardware.gamepad.xml b/data/etc/android.hardware.gamepad.xml
new file mode 100644
index 0000000..98d8d42
--- /dev/null
+++ b/data/etc/android.hardware.gamepad.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is the standard feature indicating that the device is a compatible gamepad or includes
+ one in the box. -->
+<permissions>
+ <feature name="android.hardware.gamepad" />
+</permissions>
+
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 9f1937b..742fc83 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -62,6 +62,13 @@
eDisplayIdHdmi = 1
};
+ enum Rotation {
+ eRotateNone = 0,
+ eRotate90 = 1,
+ eRotate180 = 2,
+ eRotate270 = 3
+ };
+
/* create connection with surface flinger, requires
* ACCESS_SURFACE_FLINGER permission
*/
@@ -130,7 +137,8 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform) = 0;
+ bool useIdentityTransform,
+ Rotation rotation = eRotateNone) = 0;
/* Clears the frame statistics for animations.
*
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index c73ef70..4cbfc09 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -209,6 +209,10 @@
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform);
+ status_t update(const sp<IBinder>& display,
+ Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
+ uint32_t minLayerZ, uint32_t maxLayerZ,
+ bool useIdentityTransform, uint32_t rotation);
sp<CpuConsumer> getCpuConsumer() const;
diff --git a/include/media/hardware/CryptoAPI.h b/include/media/hardware/CryptoAPI.h
index 59ae795..c800825 100644
--- a/include/media/hardware/CryptoAPI.h
+++ b/include/media/hardware/CryptoAPI.h
@@ -64,6 +64,12 @@
// media data of the given mime type.
virtual bool requiresSecureDecoderComponent(const char *mime) const = 0;
+ // To implement resolution constraints, the crypto plugin needs to know
+ // the resolution of the video being decrypted. The media player should
+ // call this method when the resolution is determined and any time it
+ // is subsequently changed.
+ virtual void notifyResolution(uint32_t width, uint32_t height) {}
+
// If the error returned falls into the range
// ERROR_DRM_VENDOR_MIN..ERROR_DRM_VENDOR_MAX, errorDetailMsg should be
// filled in with an appropriate string.
diff --git a/include/powermanager/IPowerManager.h b/include/powermanager/IPowerManager.h
index 511797a..91ecc5a 100644
--- a/include/powermanager/IPowerManager.h
+++ b/include/powermanager/IPowerManager.h
@@ -31,12 +31,15 @@
public:
DECLARE_META_INTERFACE(PowerManager);
+ // FIXME remove the bool isOneWay parameters as they are not oneway in the .aidl
virtual status_t acquireWakeLock(int flags, const sp<IBinder>& lock, const String16& tag,
- const String16& packageName) = 0;
+ const String16& packageName, bool isOneWay = false) = 0;
virtual status_t acquireWakeLockWithUid(int flags, const sp<IBinder>& lock, const String16& tag,
- const String16& packageName, int uid) = 0;
- virtual status_t releaseWakeLock(const sp<IBinder>& lock, int flags) = 0;
- virtual status_t updateWakeLockUids(const sp<IBinder>& lock, int len, const int *uids) = 0;
+ const String16& packageName, int uid, bool isOneWay = false) = 0;
+ virtual status_t releaseWakeLock(const sp<IBinder>& lock, int flags, bool isOneWay = false) = 0;
+ virtual status_t updateWakeLockUids(const sp<IBinder>& lock, int len, const int *uids,
+ bool isOneWay = false) = 0;
+ // oneway in the .aidl
virtual status_t powerHint(int hintId, int data) = 0;
};
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 4680168..4d65c56 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -106,7 +106,8 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform)
+ bool useIdentityTransform,
+ ISurfaceComposer::Rotation rotation)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -118,6 +119,7 @@
data.writeInt32(minLayerZ);
data.writeInt32(maxLayerZ);
data.writeInt32(static_cast<int32_t>(useIdentityTransform));
+ data.writeInt32(static_cast<int32_t>(rotation));
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
return reply.readInt32();
}
@@ -329,10 +331,12 @@
uint32_t minLayerZ = data.readInt32();
uint32_t maxLayerZ = data.readInt32();
bool useIdentityTransform = static_cast<bool>(data.readInt32());
+ uint32_t rotation = data.readInt32();
status_t res = captureScreen(display, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform);
+ useIdentityTransform,
+ static_cast<ISurfaceComposer::Rotation>(rotation));
reply->writeInt32(res);
return NO_ERROR;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6e13207..6446926 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -717,7 +717,7 @@
status_t ScreenshotClient::update(const sp<IBinder>& display,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform) {
+ bool useIdentityTransform, uint32_t rotation) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT;
sp<CpuConsumer> cpuConsumer = getCpuConsumer();
@@ -729,7 +729,8 @@
}
status_t err = s->captureScreen(display, mProducer, sourceCrop,
- reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
+ reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
+ static_cast<ISurfaceComposer::Rotation>(rotation));
if (err == NO_ERROR) {
err = mCpuConsumer->lockNextBuffer(&mBuffer);
@@ -740,16 +741,25 @@
return err;
}
+status_t ScreenshotClient::update(const sp<IBinder>& display,
+ Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
+ uint32_t minLayerZ, uint32_t maxLayerZ,
+ bool useIdentityTransform) {
+
+ return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight,
+ minLayerZ, maxLayerZ, useIdentityTransform, ISurfaceComposer::eRotateNone);
+}
+
status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop,
bool useIdentityTransform) {
return ScreenshotClient::update(display, sourceCrop, 0, 0, 0, -1UL,
- useIdentityTransform);
+ useIdentityTransform, ISurfaceComposer::eRotateNone);
}
status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop,
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) {
return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight,
- 0, -1UL, useIdentityTransform);
+ 0, -1UL, useIdentityTransform, ISurfaceComposer::eRotateNone);
}
void ScreenshotClient::release() {
diff --git a/services/powermanager/IPowerManager.cpp b/services/powermanager/IPowerManager.cpp
index 926c050..ec864ee 100644
--- a/services/powermanager/IPowerManager.cpp
+++ b/services/powermanager/IPowerManager.cpp
@@ -45,7 +45,7 @@
}
virtual status_t acquireWakeLock(int flags, const sp<IBinder>& lock, const String16& tag,
- const String16& packageName)
+ const String16& packageName, bool isOneWay)
{
Parcel data, reply;
data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor());
@@ -56,11 +56,12 @@
data.writeString16(packageName);
data.writeInt32(0); // no WorkSource
data.writeString16(NULL, 0); // no history tag
- return remote()->transact(ACQUIRE_WAKE_LOCK, data, &reply, IBinder::FLAG_ONEWAY);
+ return remote()->transact(ACQUIRE_WAKE_LOCK, data, &reply,
+ isOneWay ? IBinder::FLAG_ONEWAY : 0);
}
virtual status_t acquireWakeLockWithUid(int flags, const sp<IBinder>& lock, const String16& tag,
- const String16& packageName, int uid)
+ const String16& packageName, int uid, bool isOneWay)
{
Parcel data, reply;
data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor());
@@ -70,26 +71,28 @@
data.writeString16(tag);
data.writeString16(packageName);
data.writeInt32(uid); // uid to blame for the work
- return remote()->transact(ACQUIRE_WAKE_LOCK_UID, data, &reply, IBinder::FLAG_ONEWAY);
+ return remote()->transact(ACQUIRE_WAKE_LOCK_UID, data, &reply,
+ isOneWay ? IBinder::FLAG_ONEWAY : 0);
}
- virtual status_t releaseWakeLock(const sp<IBinder>& lock, int flags)
+ virtual status_t releaseWakeLock(const sp<IBinder>& lock, int flags, bool isOneWay)
{
Parcel data, reply;
data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor());
data.writeStrongBinder(lock);
data.writeInt32(flags);
- return remote()->transact(RELEASE_WAKE_LOCK, data, &reply, IBinder::FLAG_ONEWAY);
+ return remote()->transact(RELEASE_WAKE_LOCK, data, &reply,
+ isOneWay ? IBinder::FLAG_ONEWAY : 0);
}
- virtual status_t updateWakeLockUids(const sp<IBinder>& lock, int len, const int *uids) {
+ virtual status_t updateWakeLockUids(const sp<IBinder>& lock, int len, const int *uids,
+ bool isOneWay) {
Parcel data, reply;
data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor());
data.writeStrongBinder(lock);
data.writeInt32Array(len, uids);
- // We don't really care too much if this succeeds (there's nothing we can do if it doesn't)
- // but it should return ASAP
- return remote()->transact(UPDATE_WAKE_LOCK_UIDS, data, &reply, IBinder::FLAG_ONEWAY);
+ return remote()->transact(UPDATE_WAKE_LOCK_UIDS, data, &reply,
+ isOneWay ? IBinder::FLAG_ONEWAY : 0);
}
virtual status_t powerHint(int hintId, int param)
@@ -98,6 +101,7 @@
data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor());
data.writeInt32(hintId);
data.writeInt32(param);
+ // This FLAG_ONEWAY is in the .aidl, so there is no way to disable it
return remote()->transact(POWER_HINT, data, &reply, IBinder::FLAG_ONEWAY);
}
};
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index bf42b77..564f974 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -288,7 +288,8 @@
size_t w = mDisplayWidth;
size_t h = mDisplayHeight;
Rect sourceCrop(0, 0, w, h);
- mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, false);
+ mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h,
+ false, Transform::ROT_0);
}
// ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
index d1e324c..c2768f3 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
@@ -21,6 +21,7 @@
#include <utils/String8.h>
#include <cutils/compiler.h>
+#include <gui/ISurfaceComposer.h>
#include "GLES11RenderEngine.h"
#include "Mesh.h"
@@ -74,7 +75,8 @@
}
void GLES11RenderEngine::setViewportAndProjection(
- size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap) {
+ size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap,
+ Transform::orientation_flags rotation) {
glViewport(0, 0, vpw, vph);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -91,6 +93,23 @@
} else {
glOrthof(l, r, b, t, 0, 1);
}
+
+ switch (rotation) {
+ case Transform::ROT_0:
+ break;
+ case Transform::ROT_90:
+ glRotatef(90, 0, 0, 1);
+ break;
+ case Transform::ROT_180:
+ glRotatef(180, 0, 0, 1);
+ break;
+ case Transform::ROT_270:
+ glRotatef(270, 0, 0, 1);
+ break;
+ default:
+ break;
+ }
+
glMatrixMode(GL_MODELVIEW);
}
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
index 1a94592..87eb3e4 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <GLES/gl.h>
+#include <Transform.h>
#include "RenderEngine.h"
@@ -50,7 +51,7 @@
virtual void dump(String8& result);
virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap);
+ Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation);
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
virtual void setupDimLayerBlending(int alpha);
virtual void setupLayerTexturing(const Texture& texture);
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 8c1f04e..8ebafbc 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -25,6 +25,8 @@
#include <utils/Trace.h>
#include <cutils/compiler.h>
+#include <gui/ISurfaceComposer.h>
+#include <math.h>
#include "GLES20RenderEngine.h"
#include "Program.h"
@@ -80,7 +82,8 @@
}
void GLES20RenderEngine::setViewportAndProjection(
- size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap) {
+ size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap,
+ Transform::orientation_flags rotation) {
size_t l = sourceCrop.left;
size_t r = sourceCrop.right;
@@ -96,6 +99,24 @@
m = mat4::ortho(l, r, b, t, 0, 1);
}
+ // Apply custom rotation to the projection.
+ float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
+ switch (rotation) {
+ case Transform::ROT_0:
+ break;
+ case Transform::ROT_90:
+ m = mat4::rotate(rot90InRadians, vec3(0,0,1)) * m;
+ break;
+ case Transform::ROT_180:
+ m = mat4::rotate(rot90InRadians * 2.0f, vec3(0,0,1)) * m;
+ break;
+ case Transform::ROT_270:
+ m = mat4::rotate(rot90InRadians * 3.0f, vec3(0,0,1)) * m;
+ break;
+ default:
+ break;
+ }
+
glViewport(0, 0, vpw, vph);
mState.setProjectionMatrix(m);
mVpWidth = vpw;
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index b6d32fc..3d6243e 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <GLES2/gl2.h>
+#include <Transform.h>
#include "RenderEngine.h"
#include "ProgramCache.h"
@@ -65,7 +66,7 @@
virtual void dump(String8& result);
virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap);
+ Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation);
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
virtual void setupDimLayerBlending(int alpha);
virtual void setupLayerTexturing(const Texture& texture);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index a2d8242..acbff9b 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -24,6 +24,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <ui/mat4.h>
+#include <Transform.h>
#define EGL_NO_CONFIG ((EGLConfig)0)
@@ -90,7 +91,7 @@
// set-up
virtual void checkErrors() const;
virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap) = 0;
+ Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0;
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0;
virtual void setupDimLayerBlending(int alpha) = 0;
virtual void setupLayerTexturing(const Texture& texture) = 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4070f03..043b075 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2938,7 +2938,7 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform) {
+ bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
if (CC_UNLIKELY(display == 0))
return BAD_VALUE;
@@ -2958,6 +2958,27 @@
}
}
+ // Convert to surfaceflinger's internal rotation type.
+ Transform::orientation_flags rotationFlags;
+ switch (rotation) {
+ case ISurfaceComposer::eRotateNone:
+ rotationFlags = Transform::ROT_0;
+ break;
+ case ISurfaceComposer::eRotate90:
+ rotationFlags = Transform::ROT_90;
+ break;
+ case ISurfaceComposer::eRotate180:
+ rotationFlags = Transform::ROT_180;
+ break;
+ case ISurfaceComposer::eRotate270:
+ rotationFlags = Transform::ROT_270;
+ break;
+ default:
+ rotationFlags = Transform::ROT_0;
+ ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
+ break;
+ }
+
class MessageCaptureScreen : public MessageBase {
SurfaceFlinger* flinger;
sp<IBinder> display;
@@ -2966,6 +2987,7 @@
uint32_t reqWidth, reqHeight;
uint32_t minLayerZ,maxLayerZ;
bool useIdentityTransform;
+ Transform::orientation_flags rotation;
status_t result;
public:
MessageCaptureScreen(SurfaceFlinger* flinger,
@@ -2973,11 +2995,12 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform)
+ bool useIdentityTransform, Transform::orientation_flags rotation)
: flinger(flinger), display(display), producer(producer),
sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
useIdentityTransform(useIdentityTransform),
+ rotation(rotation),
result(PERMISSION_DENIED)
{
}
@@ -2989,7 +3012,7 @@
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
result = flinger->captureScreenImplLocked(hw, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform);
+ useIdentityTransform, rotation);
static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
return true;
}
@@ -3012,7 +3035,7 @@
sp<MessageBase> msg = new MessageCaptureScreen(this,
display, IGraphicBufferProducer::asInterface( wrapper ),
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform);
+ useIdentityTransform, rotationFlags);
status_t res = postMessageAsync(msg);
if (res == NO_ERROR) {
@@ -3026,7 +3049,7 @@
const sp<const DisplayDevice>& hw,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool yswap, bool useIdentityTransform)
+ bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
{
ATRACE_CALL();
RenderEngine& engine(getRenderEngine());
@@ -3061,7 +3084,8 @@
engine.checkErrors();
// set-up our viewport
- engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, hw_h, yswap);
+ engine.setViewportAndProjection(
+ reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
engine.disableTexturing();
// redraw the screen entirely...
@@ -3094,7 +3118,7 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform)
+ bool useIdentityTransform, Transform::orientation_flags rotation)
{
ATRACE_CALL();
@@ -3148,8 +3172,9 @@
// via an FBO, which means we didn't have to create
// an EGLSurface and therefore we're not
// dependent on the context's EGLConfig.
- renderScreenImplLocked(hw, sourceCrop, reqWidth, reqHeight,
- minLayerZ, maxLayerZ, true, useIdentityTransform);
+ renderScreenImplLocked(
+ hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
+ useIdentityTransform, rotation);
// Attempt to create a sync khr object that can produce a sync point. If that
// isn't available, create a non-dupable sync object in the fallback path and
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d5547b3..26f0acf 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -205,7 +205,7 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform);
+ bool useIdentityTransform, ISurfaceComposer::Rotation rotation);
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
Vector<DisplayInfo>* configs);
virtual int getActiveConfig(const sp<IBinder>& display);
@@ -313,14 +313,14 @@
const sp<const DisplayDevice>& hw,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool yswap, bool useIdentityTransform);
+ bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation);
status_t captureScreenImplLocked(
const sp<const DisplayDevice>& hw,
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform);
+ bool useIdentityTransform, Transform::orientation_flags rotation);
/* ------------------------------------------------------------------------
* EGL