frameworks/native
Revision | 3f6986346e5215feddf22e6e0261a674d6272def (tree) |
---|---|
Time | 2015-12-22 13:05:59 |
Author | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge branch 'android-ia' into lollipop-x86
@@ -19,6 +19,8 @@ | ||
19 | 19 | |
20 | 20 | #include <android/rect.h> |
21 | 21 | |
22 | +#include <system/window.h> | |
23 | + | |
22 | 24 | #ifdef __cplusplus |
23 | 25 | extern "C" { |
24 | 26 | #endif |
@@ -32,9 +34,6 @@ enum { | ||
32 | 34 | WINDOW_FORMAT_RGB_565 = 4, |
33 | 35 | }; |
34 | 36 | |
35 | -struct ANativeWindow; | |
36 | -typedef struct ANativeWindow ANativeWindow; | |
37 | - | |
38 | 37 | typedef struct ANativeWindow_Buffer { |
39 | 38 | // The number of pixels that are show horizontally. |
40 | 39 | int32_t width; |
@@ -159,14 +159,20 @@ status_t BpBinder::dump(int fd, const Vector<String16>& args) | ||
159 | 159 | status_t BpBinder::transact( |
160 | 160 | uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) |
161 | 161 | { |
162 | - // Once a binder has died, it will never come back to life. | |
162 | + // Once a binder has died, it will never come back to life. But | |
163 | + // note that the special case of the global service manager cannot | |
164 | + // die; there is no guarantee in the framework that it will be | |
165 | + // alive before a binder service object is instantiated, so we | |
166 | + // ignore errors for that special object so that | |
167 | + // IServiceManager::addService() calls can be retried. | |
163 | 168 | if (mAlive) { |
164 | 169 | status_t status = IPCThreadState::self()->transact( |
165 | 170 | mHandle, code, data, reply, flags); |
166 | - if (status == DEAD_OBJECT) mAlive = 0; | |
171 | + if (status == DEAD_OBJECT) | |
172 | + if (this != ProcessState::self()->getContextObject(NULL).get()) | |
173 | + mAlive = 0; | |
167 | 174 | return status; |
168 | 175 | } |
169 | - | |
170 | 176 | return DEAD_OBJECT; |
171 | 177 | } |
172 | 178 |
@@ -28,6 +28,8 @@ | ||
28 | 28 | |
29 | 29 | #include <unistd.h> |
30 | 30 | |
31 | +#define ADD_SERVICE_RETRY_SECS 10 | |
32 | + | |
31 | 33 | namespace android { |
32 | 34 | |
33 | 35 | sp<IServiceManager> defaultServiceManager() |
@@ -155,13 +157,26 @@ public: | ||
155 | 157 | virtual status_t addService(const String16& name, const sp<IBinder>& service, |
156 | 158 | bool allowIsolated) |
157 | 159 | { |
158 | - Parcel data, reply; | |
159 | - data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); | |
160 | - data.writeString16(name); | |
161 | - data.writeStrongBinder(service); | |
162 | - data.writeInt32(allowIsolated ? 1 : 0); | |
163 | - status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); | |
164 | - return err == NO_ERROR ? reply.readExceptionCode() : err; | |
160 | + status_t err; | |
161 | + for (int i=0; i<ADD_SERVICE_RETRY_SECS; i++) { | |
162 | + Parcel data, reply; | |
163 | + data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); | |
164 | + data.writeString16(name); | |
165 | + data.writeStrongBinder(service); | |
166 | + data.writeInt32(allowIsolated ? 1 : 0); | |
167 | + err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); | |
168 | + if (err == NO_ERROR) | |
169 | + return reply.readExceptionCode(); | |
170 | + if (i != ADD_SERVICE_RETRY_SECS) { | |
171 | + ALOGI("addService() %s failed (err %d - no service manager yet?). Retrying...\n", | |
172 | + String8(name).string(), err); | |
173 | + sleep(1); | |
174 | + } else { | |
175 | + ALOGE("addService() %s failed (err %d). Giving up.\n", | |
176 | + String8(name).string(), err); | |
177 | + } | |
178 | + } | |
179 | + return err; | |
165 | 180 | } |
166 | 181 | |
167 | 182 | virtual Vector<String16> listServices() |
@@ -335,10 +335,10 @@ size_t Sensor::getFlattenedSize() const | ||
335 | 335 | sizeof(int32_t) * 5; |
336 | 336 | |
337 | 337 | size_t variableSize = |
338 | - sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) + | |
339 | - sizeof(uint32_t) + FlattenableUtils::align<4>(mVendor.length()) + | |
340 | - sizeof(uint32_t) + FlattenableUtils::align<4>(mStringType.length()) + | |
341 | - sizeof(uint32_t) + FlattenableUtils::align<4>(mRequiredPermission.length()); | |
338 | + sizeof(size_t) + FlattenableUtils::align<sizeof(size_t)>(mName.length()) + | |
339 | + sizeof(size_t) + FlattenableUtils::align<sizeof(size_t)>(mVendor.length()) + | |
340 | + sizeof(size_t) + FlattenableUtils::align<sizeof(size_t)>(mStringType.length()) + | |
341 | + sizeof(size_t) + FlattenableUtils::align<sizeof(size_t)>(mRequiredPermission.length()); | |
342 | 342 | |
343 | 343 | return fixedSize + variableSize; |
344 | 344 | } |
@@ -1441,6 +1441,9 @@ EGLBoolean eglGetConfigs( EGLDisplay dpy, | ||
1441 | 1441 | if (egl_display_t::is_valid(dpy) == EGL_FALSE) |
1442 | 1442 | return setError(EGL_BAD_DISPLAY, EGL_FALSE); |
1443 | 1443 | |
1444 | + if (ggl_unlikely(num_config==0)) | |
1445 | + return setError(EGL_BAD_PARAMETER, EGL_FALSE); | |
1446 | + | |
1444 | 1447 | GLint numConfigs = NELEM(gConfigs); |
1445 | 1448 | if (!configs) { |
1446 | 1449 | *num_config = numConfigs; |
@@ -23,6 +23,7 @@ | ||
23 | 23 | |
24 | 24 | #include <hardware/gralloc.h> |
25 | 25 | #include <system/window.h> |
26 | +#include <sys/mman.h> | |
26 | 27 | |
27 | 28 | #include <EGL/egl.h> |
28 | 29 | #include <EGL/eglext.h> |
@@ -369,6 +370,35 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, | ||
369 | 370 | } |
370 | 371 | |
371 | 372 | // ---------------------------------------------------------------------------- |
373 | +// Utility procedure to test a NativeWindowType for validity before referencing | |
374 | +// through the pointer. It's not feasible to test for deliberate forgeries, | |
375 | +// but this heuristic is good enough to test for basic accidental cases, using | |
376 | +// the special "magic" value placed in a native-window structure. | |
377 | +// ---------------------------------------------------------------------------- | |
378 | +EGLBoolean isValidNativeWindow(NativeWindowType window) | |
379 | +{ | |
380 | + ANativeWindow *nwindow = static_cast<ANativeWindow*>(window); | |
381 | + // the msync system call returns with ENOMEM error for unmapped memory | |
382 | + // pages. This is used here as a way to test whether we can read through a | |
383 | + // pointer without getting a segfault. | |
384 | + uintptr_t pagesize = (uintptr_t) sysconf(_SC_PAGESIZE); | |
385 | + uintptr_t addr = ((uintptr_t)(&nwindow->common.magic)) & (~(pagesize - 1)); | |
386 | + int rc = msync((void *)addr, pagesize, MS_ASYNC); | |
387 | + if (0 == rc) { | |
388 | + if (nwindow->common.magic == ANDROID_NATIVE_WINDOW_MAGIC) | |
389 | + return EGL_TRUE; | |
390 | + else | |
391 | + return EGL_FALSE; | |
392 | + } | |
393 | + if (ENOMEM == errno) | |
394 | + return EGL_FALSE; | |
395 | + ALOGE("error unexpected msync error: %s (%d)", | |
396 | + strerror(-errno), errno); | |
397 | + return EGL_FALSE; | |
398 | +} | |
399 | + | |
400 | + | |
401 | +// ---------------------------------------------------------------------------- | |
372 | 402 | // surfaces |
373 | 403 | // ---------------------------------------------------------------------------- |
374 | 404 |
@@ -408,6 +438,10 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, | ||
408 | 438 | if (dp) { |
409 | 439 | EGLDisplay iDpy = dp->disp.dpy; |
410 | 440 | |
441 | + if (!isValidNativeWindow(window)) { | |
442 | + ALOGE("EGLNativeWindow %p invalid", window); | |
443 | + return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); | |
444 | + } | |
411 | 445 | int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); |
412 | 446 | if (result != OK) { |
413 | 447 | ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) " |
@@ -108,11 +108,6 @@ void egl_context_t::onMakeCurrent(EGLSurface draw, EGLSurface read) { | ||
108 | 108 | // call the implementation's glGetString(GL_EXTENSIONS) |
109 | 109 | const char* exts = (const char *)gEGLImpl.hooks[version]->gl.glGetString(GL_EXTENSIONS); |
110 | 110 | gl_extensions.setTo(exts); |
111 | - if (gl_extensions.find("GL_EXT_debug_marker") < 0) { | |
112 | - String8 temp("GL_EXT_debug_marker "); | |
113 | - temp.append(gl_extensions); | |
114 | - gl_extensions.setTo(temp); | |
115 | - } | |
116 | 111 | } |
117 | 112 | } |
118 | 113 |
@@ -78,7 +78,7 @@ namespace android { | ||
78 | 78 | |
79 | 79 | #elif defined(__i386__) |
80 | 80 | |
81 | - #define API_ENTRY(_api) __attribute__((noinline)) _api | |
81 | + #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api | |
82 | 82 | |
83 | 83 | #define CALL_GL_EXTENSION_API(_api) \ |
84 | 84 | register void** fn; \ |
@@ -100,7 +100,7 @@ namespace android { | ||
100 | 100 | |
101 | 101 | #elif defined(__x86_64__) |
102 | 102 | |
103 | - #define API_ENTRY(_api) __attribute__((noinline)) _api | |
103 | + #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api | |
104 | 104 | |
105 | 105 | #define CALL_GL_EXTENSION_API(_api) \ |
106 | 106 | register void** fn; \ |
@@ -82,7 +82,7 @@ using namespace android; | ||
82 | 82 | |
83 | 83 | #elif defined(__i386__) |
84 | 84 | |
85 | - #define API_ENTRY(_api) __attribute__((noinline)) _api | |
85 | + #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api | |
86 | 86 | |
87 | 87 | #define CALL_GL_API(_api, ...) \ |
88 | 88 | register void** fn; \ |
@@ -101,7 +101,7 @@ using namespace android; | ||
101 | 101 | |
102 | 102 | #elif defined(__x86_64__) |
103 | 103 | |
104 | - #define API_ENTRY(_api) __attribute__((noinline)) _api | |
104 | + #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api | |
105 | 105 | |
106 | 106 | #define CALL_GL_API(_api, ...) \ |
107 | 107 | register void** fn; \ |
@@ -138,7 +138,7 @@ GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, | ||
138 | 138 | |
139 | 139 | #elif defined(__i386__) |
140 | 140 | |
141 | - #define API_ENTRY(_api) __attribute__((noinline)) _api | |
141 | + #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api | |
142 | 142 | |
143 | 143 | #define CALL_GL_API(_api, ...) \ |
144 | 144 | register void* fn; \ |
@@ -157,7 +157,7 @@ GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, | ||
157 | 157 | |
158 | 158 | #elif defined(__x86_64__) |
159 | 159 | |
160 | - #define API_ENTRY(_api) __attribute__((noinline)) _api | |
160 | + #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api | |
161 | 161 | |
162 | 162 | #define CALL_GL_API(_api, ...) \ |
163 | 163 | register void** fn; \ |
@@ -53,6 +53,13 @@ protected: | ||
53 | 53 | } |
54 | 54 | }; |
55 | 55 | |
56 | +TEST_F(EGLTest, EGLGetConfigsWithNullNumConfigs) { | |
57 | + EGLBoolean success; | |
58 | + success = eglGetConfigs(mEglDisplay, NULL, 0, NULL); | |
59 | + ASSERT_EQ(EGL_FALSE, success); | |
60 | + ASSERT_EQ(EGL_BAD_PARAMETER, eglGetError()); | |
61 | +} | |
62 | + | |
56 | 63 | TEST_F(EGLTest, DISABLED_EGLConfigEightBitFirst) { |
57 | 64 | |
58 | 65 | EGLint numConfigs; |
@@ -41,7 +41,7 @@ protected: | ||
41 | 41 | }; |
42 | 42 | |
43 | 43 | TEST_F(EGLCacheTest, UninitializedCacheAlwaysMisses) { |
44 | - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; | |
44 | + unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee }; | |
45 | 45 | mCache->setBlob("abcd", 4, "efgh", 4); |
46 | 46 | ASSERT_EQ(0, mCache->getBlob("abcd", 4, buf, 4)); |
47 | 47 | ASSERT_EQ(0xee, buf[0]); |
@@ -51,7 +51,7 @@ TEST_F(EGLCacheTest, UninitializedCacheAlwaysMisses) { | ||
51 | 51 | } |
52 | 52 | |
53 | 53 | TEST_F(EGLCacheTest, InitializedCacheAlwaysHits) { |
54 | - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; | |
54 | + unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee }; | |
55 | 55 | mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); |
56 | 56 | mCache->setBlob("abcd", 4, "efgh", 4); |
57 | 57 | ASSERT_EQ(4, mCache->getBlob("abcd", 4, buf, 4)); |
@@ -62,7 +62,7 @@ TEST_F(EGLCacheTest, InitializedCacheAlwaysHits) { | ||
62 | 62 | } |
63 | 63 | |
64 | 64 | TEST_F(EGLCacheTest, TerminatedCacheAlwaysMisses) { |
65 | - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; | |
65 | + unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee }; | |
66 | 66 | mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); |
67 | 67 | mCache->setBlob("abcd", 4, "efgh", 4); |
68 | 68 | mCache->terminate(); |
@@ -94,7 +94,7 @@ protected: | ||
94 | 94 | }; |
95 | 95 | |
96 | 96 | TEST_F(EGLCacheSerializationTest, ReinitializedCacheContainsValues) { |
97 | - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; | |
97 | + unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee }; | |
98 | 98 | mCache->setCacheFilename(mFilename); |
99 | 99 | mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); |
100 | 100 | mCache->setBlob("abcd", 4, "efgh", 4); |
@@ -1065,8 +1065,17 @@ static const int32_t GAMEPAD_KEYCODES[] = { | ||
1065 | 1065 | }; |
1066 | 1066 | |
1067 | 1067 | status_t EventHub::openDeviceLocked(const char *devicePath) { |
1068 | + return openDeviceLocked(devicePath, false); | |
1069 | +} | |
1070 | + | |
1071 | +status_t EventHub::openDeviceLocked(const char *devicePath, bool ignoreAlreadyOpened) { | |
1068 | 1072 | char buffer[80]; |
1069 | 1073 | |
1074 | + if (ignoreAlreadyOpened && (getDeviceByPathLocked(devicePath) != 0)) { | |
1075 | + ALOGV("Ignoring device '%s' that has already been opened.", devicePath); | |
1076 | + return 0; | |
1077 | + } | |
1078 | + | |
1070 | 1079 | ALOGV("Opening device: %s", devicePath); |
1071 | 1080 | |
1072 | 1081 | int fd = open(devicePath, O_RDWR | O_CLOEXEC); |
@@ -1264,7 +1273,11 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { | ||
1264 | 1273 | |
1265 | 1274 | // 'Q' key support = cheap test of whether this is an alpha-capable kbd |
1266 | 1275 | if (hasKeycodeLocked(device, AKEYCODE_Q)) { |
1267 | - device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; | |
1276 | + char value[PROPERTY_VALUE_MAX]; | |
1277 | + property_get("ro.ignore_atkbd", value, "0"); | |
1278 | + if ((device->identifier.name != "AT Translated Set 2 keyboard") || (!atoi(value))) { | |
1279 | + device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; | |
1280 | + } | |
1268 | 1281 | } |
1269 | 1282 | |
1270 | 1283 | // See if this device has a DPAD. |
@@ -1588,7 +1601,7 @@ status_t EventHub::readNotifyLocked() { | ||
1588 | 1601 | if(event->len) { |
1589 | 1602 | strcpy(filename, event->name); |
1590 | 1603 | if(event->mask & IN_CREATE) { |
1591 | - openDeviceLocked(devname); | |
1604 | + openDeviceLocked(devname, true); | |
1592 | 1605 | } else { |
1593 | 1606 | ALOGI("Removing device '%s' due to inotify event\n", devname); |
1594 | 1607 | closeDeviceByPathLocked(devname); |
@@ -371,6 +371,7 @@ private: | ||
371 | 371 | }; |
372 | 372 | |
373 | 373 | status_t openDeviceLocked(const char *devicePath); |
374 | + status_t openDeviceLocked(const char *devicePath, bool ignoreAlreadyOpened); | |
374 | 375 | void createVirtualKeyboardLocked(); |
375 | 376 | void addDeviceLocked(Device* device); |
376 | 377 | void assignDescriptorLocked(InputDeviceIdentifier& identifier); |
@@ -400,7 +400,7 @@ status_t HWComposer::queryDisplayProperties(int disp) { | ||
400 | 400 | } |
401 | 401 | |
402 | 402 | // FIXME: what should we set the format to? |
403 | - mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888; | |
403 | + mDisplayData[disp].format = HAL_PIXEL_FORMAT_BGRA_8888; | |
404 | 404 | mDisplayData[disp].connected = true; |
405 | 405 | return NO_ERROR; |
406 | 406 | } |
@@ -823,7 +823,7 @@ int HWComposer::getVisualID() const { | ||
823 | 823 | // FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED |
824 | 824 | // is supported by the implementation. we can only be in this case |
825 | 825 | // if we have HWC 1.1 |
826 | - return HAL_PIXEL_FORMAT_RGBA_8888; | |
826 | + return HAL_PIXEL_FORMAT_BGRA_8888; | |
827 | 827 | //return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; |
828 | 828 | } else { |
829 | 829 | return mFbDev->format; |
@@ -276,11 +276,11 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent( | ||
276 | 276 | } |
277 | 277 | |
278 | 278 | // Here we figure out if we need to enable or disable vsyncs |
279 | - if (timestamp && !waitForVSync) { | |
280 | - // we received a VSYNC but we have no clients | |
281 | - // don't report it, and disable VSYNC events | |
279 | + if (!waitForVSync) { | |
280 | + // we have no clients waiting on next VSYNC | |
281 | + // just disable VSYNC events. | |
282 | 282 | disableVSyncLocked(); |
283 | - } else if (!timestamp && waitForVSync) { | |
283 | + } else if (!timestamp) { | |
284 | 284 | // we have at least one client, so we want vsync enabled |
285 | 285 | // (TODO: this function is called right after we finish |
286 | 286 | // notifying clients of a vsync, so this call will be made |