# Deviceinfo
Library to detect and configure devices


## Config files
Deviceinfo has 2 types of configs:

* halium.yaml, which is read by libdeviceinfo if a device-specific configuration cannot be found.
* [device].yaml, which is read by libdeviceinfo and prioritized over halium.yaml.

In any case, the syntax is same for both configurations, which is as follows:

```
$ cat /etc/deviceinfo/devices/sample.yaml
sample:
    Names:
      - SAMPLE1
      - 2SAMPLE
      - SAMPL3
    PrettyName: Hello World!
    DeviceType: phone
    GridUnit: 21
    SupportedOrientation:
      - Portrait
      - Landscape
      - InvertedLandscape

```
`sample` is actually supposed to match the name of the device-specific yaml (if you're using that), but in case of halium.yaml, it is supposed to be match your device model (aka ro.product.vendor.device).

## Built in config keys (with special logic and fallback logic)
 - Name: Device name/codename
 - PrettyName: Pretty name of the device
 - DeviceType: Sets device type (desktop, tablet, phone)
 - GridUnit: Sets scale units
 - SupportedOrientations: (Portrait,InvertedPortrait,Landscape,InvertedLandscape)
 - PrimaryOrientation
 - PortraitOrientation
 - InvertedPortraitOrientation
 - LandscapeOrientation
 - InvertedLandscapeOrientation

Any key can be added to your yaml for using it yourself, without needing to modify deviceinfo itself. But beware, you will not get the fancy fallbacks that you get with the built-in configs.

## Detect logic

`Name` is autodetected by using the model of the device, using android props for halium/android devices and dtb for native linux devices. (this can be overwritten by config)

`DeviceType` on android/halium this is autodetected by trying to look at the android characteristics prop, if this include tablet we assume its a tablet, if not we assume it's an phpne. On linux we have no way of detecting this atm, it fallsback to desktop. (this can be overwritten by config)

`DriverType` is autodetected by trying to get any type of android prop, if it can find it we assume its an android device, if not we assume it's a native linux device. (this can `NOT` be overwritten by config)

## Tool usage

```
$ device-info get PrettyName
Hello World!
```

## Override enviroment varables
 - DEVICEINFO_CONFIG_PATH overrides path to find config files
 - DEVICEINFO_DEFAULT_CONFIG overrides default config file
 - DEVICEINFO_DEVICE_CONFIG overrides device config file
 - DEVICEINFO_ALIAS_CONFIG overrides alias config file
 - DEVICEINFO_DEVICE_NAME overrides device detected name
 - DEVICEINFO_DEBUG overrides debug level (-1 = None, 0 = Info, 1 = Debug, 2 = Verbose)

## Building

```
mkdir build
cd build
cmake ..
```

## C++ API

The API is fairly simple, look into headers/deviceinfo.h for the full API.

Example: 
```
// Include deviceinfo headers
#include <deviceinfo.h> // Considering you added /usr/include/deviceinfo to includes.
...
// To initialize the object
std::shared_ptr<DeviceInfo> info = std::make_shared<DeviceInfo>();
std::cout << info->name() << std::endl;
```

## C API
Deviceinfo can be used with pure C projects just like you would with C++, except you will include deviceinfo_c_api.h instead of deviceinfo.h. Full API is present in headers/deviceinfo_c_api.h.

Example:
```
// Include C API header
#include <deviceinfo_c_api.h> // Considering you added /usr/include/deviceinfo to includes.
...
struct DeviceInfo* di = new DeviceInfo();
printf("device name is %s", di->deviceinfo_name());
```

## Notes
* Deviceinfo picks the device-specific yaml by reading either the `ro.product.vendor.device` prop or `ro.product.device` prop. The former is prioritized and the latter serves as a fallback. The 

* If `PrettyName` is not defined, then either `ro.product.vendor.model` or `ro.product.model` is used as a fallback. Like before, the latter is only a fallback for the prop.
