1 // Copyright 2021, The Android Open Source Project
2 //
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 //! Native helpers for composd.
16 
17 pub use art::*;
18 
19 mod art {
20     use anyhow::{anyhow, Result};
21     use libc::c_char;
22     use std::ffi::{CStr, OsStr};
23     use std::io::Error;
24     use std::os::unix::ffi::OsStrExt;
25     use std::path::Path;
26     use std::ptr::null;
27 
28     // From libartpalette(-system)
29     extern "C" {
PaletteCreateOdrefreshStagingDirectory(out_staging_dir: *mut *const c_char) -> i3230         fn PaletteCreateOdrefreshStagingDirectory(out_staging_dir: *mut *const c_char) -> i32;
31     }
32     const PALETTE_STATUS_OK: i32 = 0;
33     const PALETTE_STATUS_CHECK_ERRNO: i32 = 1;
34 
35     /// Creates and returns the staging directory for odrefresh.
palette_create_odrefresh_staging_directory() -> Result<&'static Path>36     pub fn palette_create_odrefresh_staging_directory() -> Result<&'static Path> {
37         let mut staging_dir: *const c_char = null();
38         // SAFETY: The C function always returns a non-null C string (after created the directory).
39         let status = unsafe { PaletteCreateOdrefreshStagingDirectory(&mut staging_dir) };
40         match status {
41             PALETTE_STATUS_OK => {
42                 // SAFETY: The previously returned `*const c_char` should point to a legitimate C
43                 // string.
44                 let cstr = unsafe { CStr::from_ptr(staging_dir) };
45                 let path = OsStr::from_bytes(cstr.to_bytes()).as_ref();
46                 Ok(path)
47             }
48             PALETTE_STATUS_CHECK_ERRNO => Err(anyhow!(Error::last_os_error().to_string())),
49             _ => Err(anyhow!("Failed with palette status {}", status)),
50         }
51     }
52 }
53