1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <assert.h> 18 #include <errno.h> 19 #include <stdlib.h> 20 #include <stdio.h> 21 #include <string.h> 22 23 #include <unistd.h> 24 #include <fcntl.h> 25 #include <signal.h> 26 #include <termios.h> 27 #include <sys/ioctl.h> 28 #include <sys/mman.h> 29 #include <sys/time.h> 30 #include <sys/types.h> 31 #include <sys/resource.h> 32 33 #include <linux/unistd.h> 34 35 #include <utils/Log.h> 36 37 #include "DisplayHardware/DisplayHardwareBase.h" 38 #include "SurfaceFlinger.h" 39 40 // ---------------------------------------------------------------------------- 41 namespace android { 42 43 static char const * const kSleepFileName = "/sys/power/wait_for_fb_sleep"; 44 static char const * const kWakeFileName = "/sys/power/wait_for_fb_wake"; 45 46 // ---------------------------------------------------------------------------- 47 48 DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase( 49 const sp<SurfaceFlinger>& flinger) 50 : Thread(false), mFlinger(flinger) { 51 } 52 53 DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() { 54 } 55 56 // ---------------------------------------------------------------------------- 57 58 DisplayHardwareBase::DisplayEventThread::DisplayEventThread( 59 const sp<SurfaceFlinger>& flinger) 60 : DisplayEventThreadBase(flinger) 61 { 62 } 63 64 DisplayHardwareBase::DisplayEventThread::~DisplayEventThread() 65 { 66 } 67 68 bool DisplayHardwareBase::DisplayEventThread::threadLoop() 69 { 70 int err = 0; 71 char buf; 72 int fd; 73 74 fd = open(kSleepFileName, O_RDONLY, 0); 75 do { 76 err = read(fd, &buf, 1); 77 } while (err < 0 && errno == EINTR); 78 close(fd); 79 LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno)); 80 if (err >= 0) { 81 sp<SurfaceFlinger> flinger = mFlinger.promote(); 82 LOGD("About to give-up screen, flinger = %p", flinger.get()); 83 if (flinger != 0) { 84 mBarrier.close(); 85 flinger->screenReleased(0); 86 mBarrier.wait(); 87 } 88 } 89 fd = open(kWakeFileName, O_RDONLY, 0); 90 do { 91 err = read(fd, &buf, 1); 92 } while (err < 0 && errno == EINTR); 93 close(fd); 94 LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno)); 95 if (err >= 0) { 96 sp<SurfaceFlinger> flinger = mFlinger.promote(); 97 LOGD("Screen about to return, flinger = %p", flinger.get()); 98 if (flinger != 0) 99 flinger->screenAcquired(0); 100 } 101 return true; 102 } 103 104 status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const 105 { 106 mBarrier.open(); 107 return NO_ERROR; 108 } 109 110 status_t DisplayHardwareBase::DisplayEventThread::readyToRun() 111 { 112 return NO_ERROR; 113 } 114 115 status_t DisplayHardwareBase::DisplayEventThread::initCheck() const 116 { 117 return ((access(kSleepFileName, R_OK) == 0 && 118 access(kWakeFileName, R_OK) == 0)) ? NO_ERROR : NO_INIT; 119 } 120 121 // ---------------------------------------------------------------------------- 122 123 DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger, 124 uint32_t displayIndex) 125 : mScreenAcquired(true) 126 { 127 mDisplayEventThread = new DisplayEventThread(flinger); 128 } 129 130 DisplayHardwareBase::~DisplayHardwareBase() 131 { 132 // request exit 133 mDisplayEventThread->requestExitAndWait(); 134 } 135 136 bool DisplayHardwareBase::canDraw() const 137 { 138 return mScreenAcquired; 139 } 140 141 void DisplayHardwareBase::releaseScreen() const 142 { 143 status_t err = mDisplayEventThread->releaseScreen(); 144 if (err >= 0) { 145 mScreenAcquired = false; 146 } 147 } 148 149 void DisplayHardwareBase::acquireScreen() const 150 { 151 status_t err = mDisplayEventThread->acquireScreen(); 152 if (err >= 0) { 153 mScreenAcquired = true; 154 } 155 } 156 157 bool DisplayHardwareBase::isScreenAcquired() const 158 { 159 return mScreenAcquired; 160 } 161 162 }; // namespace android 163