| 1157 | } |
| 1158 | |
| 1159 | fn open_android_shared_video_memory(handle: &str) -> Result<(RawFd, *mut u8, usize), AppError> { |
| 1160 | #[cfg(not(unix))] |
| 1161 | { |
| 1162 | return Err(AppError::native(format!( |
| 1163 | "Android emulator shared video `{handle}` requires POSIX shared memory and is not available on this host." |
| 1164 | ))); |
| 1165 | } |
| 1166 | |
| 1167 | #[cfg(unix)] |
| 1168 | { |
| 1169 | let mut names = vec![handle.to_owned()]; |
| 1170 | if !handle.starts_with('/') { |
| 1171 | names.push(format!("/{handle}")); |
| 1172 | } |
| 1173 | let mut last_error = None; |
| 1174 | for name in names { |
| 1175 | let c_name = CString::new(name.as_str()).map_err(|_| { |
| 1176 | AppError::native("Android shared video handle contains a NUL byte.") |
| 1177 | })?; |
| 1178 | let fd = unsafe { libc::shm_open(c_name.as_ptr(), libc::O_RDONLY, 0) }; |
| 1179 | if fd < 0 { |
| 1180 | last_error = Some(std::io::Error::last_os_error()); |
| 1181 | continue; |
| 1182 | } |
| 1183 | |
| 1184 | let mut stat = MaybeUninit::<libc::stat>::uninit(); |
| 1185 | if unsafe { libc::fstat(fd, stat.as_mut_ptr()) } != 0 { |
| 1186 | let error = std::io::Error::last_os_error(); |
| 1187 | unsafe { |
| 1188 | libc::close(fd); |
| 1189 | } |
| 1190 | last_error = Some(error); |
| 1191 | continue; |
| 1192 | } |
| 1193 | let stat = unsafe { stat.assume_init() }; |
| 1194 | let length = usize::try_from(stat.st_size).map_err(|_| { |
| 1195 | unsafe { |
| 1196 | libc::close(fd); |
| 1197 | } |
| 1198 | AppError::native(format!( |
| 1199 | "Android emulator shared video `{handle}` reported an invalid size." |
| 1200 | )) |
| 1201 | })?; |
| 1202 | if length <= ANDROID_SHARED_VIDEO_HEADER_BYTES { |
| 1203 | unsafe { |
| 1204 | libc::close(fd); |
| 1205 | } |
| 1206 | return Err(AppError::native(format!( |
| 1207 | "Android emulator shared video `{handle}` is smaller than the display header." |
| 1208 | ))); |
| 1209 | } |
| 1210 | |
| 1211 | let ptr = unsafe { |
| 1212 | libc::mmap( |
| 1213 | ptr::null_mut(), |
| 1214 | length, |
| 1215 | libc::PROT_READ, |
| 1216 | libc::MAP_SHARED, |