• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "dev/fbdev_driver.h"
16 #include "charger_log.h"
17 
18 #include "securec.h"
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include <fcntl.h>
23 #include <memory>
24 #include <sys/ioctl.h>
25 #include <sys/mman.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 
29 namespace OHOS {
30 namespace PowerMgr {
31 namespace {
32 constexpr unsigned int DOMAIN_FEATURE_CHARGING = 0xD002925;
33 }
34 
~FbdevDriver()35 FbdevDriver::~FbdevDriver()
36 {
37     ReleaseFb(&buff_);
38 }
39 
Init()40 bool FbdevDriver::Init()
41 {
42     if (devPath_.empty()) {
43         BATTERY_HILOGE(FEATURE_CHARGING, "dev path is empty, init failed, check whether SetDevPath correctly called");
44         return false;
45     }
46     int fd = open(devPath_.c_str(), O_RDWR | O_CLOEXEC);
47     if (fd < 0) {
48         BATTERY_HILOGE(FEATURE_CHARGING, "cannot open fb0");
49         return false;
50     }
51     fdsan_exchange_owner_tag(fd, 0, DOMAIN_FEATURE_CHARGING);
52 
53     (void)FbPowerContrl(fd, false);
54     (void)FbPowerContrl(fd, true);
55 
56     if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo_) < 0) {
57         BATTERY_HILOGE(FEATURE_CHARGING, "failed to get fb0 info");
58         fdsan_close_with_tag(fd, DOMAIN_FEATURE_CHARGING);
59         return false;
60     }
61 
62     if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo_) < 0) {
63         BATTERY_HILOGE(FEATURE_CHARGING, "failed to get fb0 info");
64         fdsan_close_with_tag(fd, DOMAIN_FEATURE_CHARGING);
65         return false;
66     }
67 
68     buff_.width = vinfo_.xres;
69     buff_.height = vinfo_.yres;
70     buff_.size = finfo_.line_length * vinfo_.yres;
71     buff_.vaddr = mmap(nullptr, finfo_.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
72     if (buff_.vaddr == MAP_FAILED) {
73         BATTERY_HILOGE(FEATURE_CHARGING, "failed to mmap framebuffer");
74         fdsan_close_with_tag(fd, DOMAIN_FEATURE_CHARGING);
75         return false;
76     }
77     (void)memset_s(buff_.vaddr, finfo_.smem_len, 0, finfo_.smem_len);
78     fd_ = fd;
79     return true;
80 }
81 
Flip(const uint8_t * buf)82 void FbdevDriver::Flip(const uint8_t* buf)
83 {
84     if (fd_ < 0 || memcpy_s(buff_.vaddr, buff_.size, buf, buff_.size) != EOK) {
85         return;
86     }
87     if (ioctl(fd_, FBIOPAN_DISPLAY, &vinfo_) < 0) {
88         BATTERY_HILOGE(FEATURE_CHARGING, "failed to display fb0!");
89     }
90 }
91 
GetDisplayInfo(DisplayInfo & dsInfo)92 void FbdevDriver::GetDisplayInfo(DisplayInfo& dsInfo)
93 {
94     dsInfo.width = static_cast<int>(vinfo_.xres);
95     dsInfo.height = static_cast<int>(vinfo_.yres);
96     dsInfo.rowBytes = finfo_.line_length;
97     dsInfo.pixelBytes = vinfo_.bits_per_pixel / 8; // 8: byte bit len
98 }
99 
Blank(bool blank)100 void FbdevDriver::Blank(bool blank)
101 {
102     FbPowerContrl(fd_, !blank);
103     if (blankHook_ != nullptr) {
104         blankHook_(fd_, blank);
105     }
106 }
107 
Exit()108 void FbdevDriver::Exit()
109 {
110     ReleaseFb(&buff_);
111 }
112 
SetDevPath(const std::string & devPath)113 void FbdevDriver::SetDevPath(const std::string& devPath)
114 {
115     devPath_ = devPath;
116 }
117 
RegisterBlankHook(FbBlankHook blankHook)118 void FbdevDriver::RegisterBlankHook(FbBlankHook blankHook)
119 {
120     blankHook_ = blankHook;
121 }
122 
ReleaseFb(const struct FbBufferObject * fbo)123 void FbdevDriver::ReleaseFb(const struct FbBufferObject* fbo)
124 {
125     /*
126      * When fd_ isn't less than 0, then fbo->vaddr is valid and can by safely munmap.
127      * this can be guaranteed by FbdevDriver::Init.
128      */
129     if (fd_ < 0) {
130         return;
131     }
132     munmap(fbo->vaddr, fbo->size);
133     fdsan_close_with_tag(fd_, DOMAIN_FEATURE_CHARGING);
134     fd_ = -1;
135 }
136 
FbPowerContrl(int fd,bool powerOn)137 bool FbdevDriver::FbPowerContrl(int fd, bool powerOn)
138 {
139     if (fd < 0) {
140         return false;
141     }
142     if (ioctl(fd, FBIOBLANK, powerOn ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN) < 0) {
143         BATTERY_HILOGE(FEATURE_CHARGING, "failed to set fb0, %{public}s", strerror(errno));
144         return false;
145     }
146     return true;
147 }
148 } // namespace PowerMgr
149 } // namespace OHOS
150