potter: import some cmhw features

Change-Id: I20278917c6016e102ed8ef8d9b043c5ac4159274
This commit is contained in:
Vachounet
2017-07-18 09:38:10 +02:00
committed by Vachounet
parent f0139dea0b
commit 5198da0fcc
8 changed files with 808 additions and 0 deletions

View File

@@ -88,6 +88,7 @@ BOARD_NO_CHARGER_LED := true
# CMHW
BOARD_USES_CYANOGEN_HARDWARE := true
BOARD_HARDWARE_CLASS += $(DEVICE_PATH)/cmhw
# Crypto
TARGET_HW_DISK_ENCRYPTION := true

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cyanogenmod.hardware;
import android.util.Log;
import cyanogenmod.hardware.DisplayMode;
/*
* Display Modes API
*
* A device may implement a list of preset display modes for different
* viewing intents, such as movies, photos, or extra vibrance. These
* modes may have multiple components such as gamma correction, white
* point adjustment, etc, but are activated by a single control point.
*
* This API provides support for enumerating and selecting the
* modes supported by the hardware.
*/
public class DisplayModeControl {
private static final boolean sHasNativeSupport =
LiveDisplayVendorImpl.hasNativeFeature(LiveDisplayVendorImpl.DISPLAY_MODES);
/*
* All HAF classes should export this boolean.
* Real implementations must, of course, return true
*/
public static boolean isSupported() {
return sHasNativeSupport;
}
/*
* Get the list of available modes. A mode has an integer
* identifier and a string name.
*
* It is the responsibility of the upper layers to
* map the name to a human-readable format or perform translation.
*/
public static DisplayMode[] getAvailableModes() {
if (!sHasNativeSupport) {
return new DisplayMode[0];
}
return LiveDisplayVendorImpl.native_getDisplayModes();
}
/*
* Get the name of the currently selected mode. This can return
* null if no mode is selected.
*/
public static DisplayMode getCurrentMode() {
if (!sHasNativeSupport) {
return null;
}
return LiveDisplayVendorImpl.native_getCurrentDisplayMode();
}
/*
* Selects a mode from the list of available modes by it's
* string identifier. Returns true on success, false for
* failure. It is up to the implementation to determine
* if this mode is valid.
*/
public static boolean setMode(DisplayMode mode, boolean makeDefault) {
if (!sHasNativeSupport) {
return false;
}
return LiveDisplayVendorImpl.native_setDisplayMode(mode, makeDefault);
}
/*
* Gets the preferred default mode for this device by it's
* string identifier. Can return null if there is no default.
*/
public static DisplayMode getDefaultMode() {
if (!sHasNativeSupport) {
return null;
}
return LiveDisplayVendorImpl.native_getDefaultDisplayMode();
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cyanogenmod.hardware;
import android.util.Log;
import android.util.Range;
import cyanogenmod.hardware.DisplayMode;
import cyanogenmod.hardware.HSIC;
/**
* This class loads an implementation of the LiveDisplay native interface.
*/
public class LiveDisplayVendorImpl {
public static final String TAG = "LiveDisplayVendorImpl";
public static final int DISPLAY_MODES = 0x1;
public static final int COLOR_BALANCE = 0x2;
public static final int OUTDOOR_MODE = 0x4;
public static final int ADAPTIVE_BACKLIGHT = 0x8;
public static final int PICTURE_ADJUSTMENT = 0x10;
private static boolean sNativeLibraryLoaded;
private static int sFeatures;
static {
try {
System.loadLibrary("jni_livedisplay");
final int features = native_getSupportedFeatures();
if (features > 0) {
Log.i(TAG, "Using native LiveDisplay backend (features: " + sFeatures + ")");
}
sNativeLibraryLoaded = features > 0;
sFeatures = features;
} catch (Throwable t) {
sNativeLibraryLoaded = false;
sFeatures = 0;
}
}
public static boolean hasNativeFeature(int feature) {
return sNativeLibraryLoaded && ((sFeatures & feature) != 0);
}
private static native int native_getSupportedFeatures();
public static native DisplayMode[] native_getDisplayModes();
public static native DisplayMode native_getCurrentDisplayMode();
public static native DisplayMode native_getDefaultDisplayMode();
public static native boolean native_setDisplayMode(DisplayMode mode, boolean makeDefault);
public static native boolean native_setAdaptiveBacklightEnabled(boolean enabled);
public static native boolean native_isAdaptiveBacklightEnabled();
public static native boolean native_setOutdoorModeEnabled(boolean enabled);
public static native boolean native_isOutdoorModeEnabled();
public static native Range<Integer> native_getColorBalanceRange();
public static native int native_getColorBalance();
public static native boolean native_setColorBalance(int value);
public static native boolean native_setPictureAdjustment(final HSIC hsic);
public static native HSIC native_getPictureAdjustment();
public static native HSIC native_getDefaultPictureAdjustment();
public static native Range<Float> native_getHueRange();
public static native Range<Float> native_getSaturationRange();
public static native Range<Float> native_getIntensityRange();
public static native Range<Float> native_getContrastRange();
public static native Range<Float> native_getSaturationThresholdRange();
}

View File

@@ -0,0 +1,196 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cyanogenmod.hardware;
import android.os.FileUtils;
import android.util.Slog;
import java.io.File;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Support for storage of key-value pairs which persists across device wipes /
* factory resets. This is used for various security related features. A
* reasonable implementation of this needs to store items on a partition which
* is unaffected by factory reset. The actual format of the storage is left up
* to the implementation. The implementation in this file is suitable for
* devices which have a /persist partition (recent QCOM devices fit this
* criteria).
*/
public class PersistentStorage {
public static final int MAX_KEY_LEN = 64;
public static final int MAX_VALUE_LEN = 4096;
private static final String TAG = "PersistentStorage";
private static final String PERSIST_DATA_PATH = "/persist/properties";
private static final boolean DEBUG = false;
private static final ReadWriteLock rwl = new ReentrantReadWriteLock();
/**
* Whether device supports persistent properties
*
* @return boolean Supported devices must return always true
*/
public static boolean isSupported() {
final File file = new File(PERSIST_DATA_PATH);
return file.exists() && file.isDirectory() && file.canRead() && file.canWrite();
}
/**
* Gets an array of bytes from persistent storage.
*
* @param key
* @return previously stored byte array, null if not found
*/
public static byte[] get(String key) {
if (!isSupported() || key.length() > MAX_KEY_LEN) {
return null;
}
final String encodedKey = encode(key);
if (encodedKey == null) {
return null;
}
FileInputStream fis = null;
try {
rwl.readLock().lock();
final File prop = new File(PERSIST_DATA_PATH + "/" + encodedKey);
if (!prop.exists()) {
if (DEBUG) {
Slog.e(TAG, "Unable to read from " + prop.getAbsolutePath());
}
return null;
}
final byte[] buffer = new byte[MAX_VALUE_LEN];
fis = new FileInputStream(prop);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len = fis.read(buffer);
bos.write(buffer, 0, len);
return bos.toByteArray();
} catch (Exception e) {
Slog.e(TAG, e.getMessage(), e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException ex) {
// skip it
}
}
rwl.readLock().unlock();
}
return null;
}
/**
* Writes a byte array to persistent storage.
*
* The storage of the data is implementation specific. In this implementation,
* we hash the key with SHA-256 and use the hex string as the stored key.
*
* Implementations should delete the key if a null buffer is passed.
*
* @param key
* @param buffer
* @return true if the operation succeeded
*/
public static boolean set(String key, byte[] buffer) {
if (!isSupported() ||
key == null || key.length() > MAX_KEY_LEN ||
(buffer != null && buffer.length > MAX_VALUE_LEN)) {
return false;
}
final String encodedKey = encode(key);
if (encodedKey == null) {
return false;
}
try {
rwl.writeLock().lock();
final File prop = new File(PERSIST_DATA_PATH + "/" + encodedKey);
File tmp = null;
if (buffer != null) {
tmp = File.createTempFile(key, "tmp",
new File(PERSIST_DATA_PATH));
if (!FileUtils.copyToFile(new ByteArrayInputStream(buffer), tmp)) {
Slog.e(TAG, "Unable to create temporary file!");
return false;
}
}
if (prop.exists()) {
prop.delete();
}
if (tmp != null) {
tmp.renameTo(prop);
}
} catch (Exception e) {
Slog.e(TAG, e.getMessage(), e);
return false;
} finally {
rwl.writeLock().unlock();
}
return true;
}
/**
* Used for encoding keys with SHA-256
*
* @param key
* @return
*/
private static String encode(String key) {
try {
MessageDigest d = MessageDigest.getInstance("SHA-256");
byte[] hash = d.digest(key.getBytes("UTF-8"));
StringBuilder encoded = new StringBuilder();
for (byte b : hash) {
encoded.append(String.format("%02x", b & 0xff));
}
return encoded.toString();
} catch (Exception e) {
Slog.e(TAG, e.getMessage(), e);
}
return null;
}
}

View File

@@ -0,0 +1,141 @@
/*
* Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cyanogenmod.hardware;
import android.util.Range;
import cyanogenmod.hardware.HSIC;
/**
* Color balance support
*
* Color balance controls allow direct adjustment of display color temperature
* using a range of values. A zero implies no adjustment, negative values
* move towards warmer temperatures, and positive values move towards
* cool temperatures.
*/
public class PictureAdjustment {
private static final boolean sHasNativeSupport =
LiveDisplayVendorImpl.hasNativeFeature(LiveDisplayVendorImpl.PICTURE_ADJUSTMENT);
/**
* Whether device supports color balance control
*
* @return boolean Supported devices must return always true
*/
public static boolean isSupported() {
return sHasNativeSupport;
}
/**
* This method returns the current picture adjustment values
*
* @return HSIC
*/
public static HSIC getHSIC() {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_getPictureAdjustment();
}
return null;
}
/**
* This method returns the default picture adjustment for the current mode
*
* @return HSIC
*/
public static HSIC getDefaultHSIC() {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_getDefaultPictureAdjustment();
}
return null;
}
/**
* This method allows to set the picture adjustment
*
* @param hsic
* @return boolean Must be false if feature is not supported or the operation
* failed; true in any other case.
*/
public static boolean setHSIC(final HSIC hsic) {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_setPictureAdjustment(hsic);
}
return false;
}
/**
* Get the range available for hue adjustment
* @return range
*/
public static Range<Float> getHueRange() {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_getHueRange();
}
return new Range(0.0f, 0.0f);
}
/**
* Get the range available for saturation adjustment
* @return range
*/
public static Range<Float> getSaturationRange() {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_getSaturationRange();
}
return new Range(0.0f, 0.0f);
}
/**
* Get the range available for intensity adjustment
* @return range
*/
public static Range<Float> getIntensityRange() {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_getIntensityRange();
}
return new Range(0.0f, 0.0f);
}
/**
* Get the range available for contrast adjustment
* @return range
*/
public static Range<Float> getContrastRange() {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_getContrastRange();
}
return new Range(0.0f, 0.0f);
}
/**
* Get the range available for saturation threshold adjustment
*
* This is an adjustable lower limit where the image is fully
* desaturated.
*
* @return range
*/
public static Range<Float> getSaturationThresholdRange() {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_getSaturationThresholdRange();
}
return new Range(0.0f, 0.0f);
}
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright (C) 2014 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cyanogenmod.hardware;
import org.cyanogenmod.internal.util.FileUtils;
import android.util.Log;
/**
* Facemelt mode!
*/
public class SunlightEnhancement {
private static final String TAG = "SunlightEnhancement";
private static final String FACEMELT_PATH = getFacemeltPath();
private static final String FACEMELT_MODE = getFacemeltMode();
private static final String FILE_HBM = "/sys/class/graphics/fb0/hbm";
private static final String FILE_SRE = "/sys/class/graphics/fb0/sre";
private static final boolean sHasNativeSupport =
LiveDisplayVendorImpl.hasNativeFeature(LiveDisplayVendorImpl.OUTDOOR_MODE);
private static String getFacemeltPath() {
if (FileUtils.fileExists(FILE_HBM)) {
return FILE_HBM;
} else {
return FILE_SRE;
}
}
private static String getFacemeltMode() {
if (FileUtils.fileExists(FILE_HBM)) {
return "1";
} else {
return "2";
}
}
/**
* Whether device supports sunlight enhancement
*
* @return boolean Supported devices must return always true
*/
public static boolean isSupported() {
if (sHasNativeSupport) {
return true;
}
return FileUtils.isFileWritable(FACEMELT_PATH);
}
/**
* This method return the current activation status of sunlight enhancement
*
* @return boolean Must be false when sunlight enhancement is not supported or not activated,
* or the operation failed while reading the status; true in any other case.
*/
public static boolean isEnabled() {
try {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_isOutdoorModeEnabled();
}
return Integer.parseInt(FileUtils.readOneLine(FACEMELT_PATH)) > 0;
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
return false;
}
/**
* This method allows to setup sunlight enhancement
*
* @param status The new sunlight enhancement status
* @return boolean Must be false if sunlight enhancement is not supported or the operation
* failed; true in any other case.
*/
public static boolean setEnabled(boolean status) {
if (sHasNativeSupport) {
return LiveDisplayVendorImpl.native_setOutdoorModeEnabled(status);
}
return FileUtils.writeLine(FACEMELT_PATH, status ? FACEMELT_MODE : "0");
}
/**
* Whether adaptive backlight (CABL / CABC) is required to be enabled
*
* @return boolean False if adaptive backlight is not a dependency
*/
public static boolean isAdaptiveBacklightRequired() {
return false;
}
/**
* Set this to true if the implementation is self-managed and does
* it's own ambient sensing. In this case, setEnabled is assumed
* to toggle the feature on or off, but not activate it. If set
* to false, LiveDisplay will call setEnabled when the ambient lux
* threshold is crossed.
*
* @return true if this enhancement is self-managed
*/
public static boolean isSelfManaged() {
return false;
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cyanogenmod.hardware;
import android.util.Log;
import org.cyanogenmod.internal.util.FileUtils;
/**
* Generate a unique but deterministic ID for this hardware, based on unchangeable
* hardware serial numbers.
*/
public class UniqueDeviceId {
private static final String TAG = "UniqueDeviceId";
private static final int TYPE_MMC0_CID = 0;
private static String sUniqueId = null;
private static final String MMC_TYPE = "/sys/block/mmcblk0/device/type";
private static final String MMC_CID = "/sys/block/mmcblk0/device/cid";
/**
* Whether device supports reporting a unique device id.
*
* @return boolean Supported devices must return always true
*/
public static boolean isSupported() {
return FileUtils.isFileReadable(MMC_TYPE) &&
FileUtils.isFileReadable(MMC_CID) &&
getUniqueDeviceIdInternal() != null;
}
/**
* This method retreives a unique ID for the device.
*
* @return String The unique device ID
*/
public static String getUniqueDeviceId() {
return getUniqueDeviceIdInternal();
}
private static String getUniqueDeviceIdInternal() {
if (sUniqueId != null) {
return sUniqueId;
}
try {
String sMmcType = FileUtils.readOneLine(MMC_TYPE);
String sCid = FileUtils.readOneLine(MMC_CID);
if ("MMC".equals(sMmcType) && sCid != null) {
sCid = sCid.trim();
if (sCid.length() == 32) {
sUniqueId = String.format("%03x00000%32s", TYPE_MMC0_CID, sCid);
return sUniqueId;
}
}
} catch (Exception e) {
Log.e(TAG, "Failed to get unique device ID: " + e.getMessage());
return null;
}
/* Any additional types should be added here. */
return null;
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cyanogenmod.hardware;
import org.cyanogenmod.internal.util.FileUtils;
import android.util.Log;
public class VibratorHW {
private static final String TAG = "VibratorHW";
private static final String DEFAULT_PATH = "/sys/class/timed_output/vibrator/vtg_default";
private static final String LEVEL_PATH = "/sys/class/timed_output/vibrator/vtg_level";
private static final String MAX_PATH = "/sys/class/timed_output/vibrator/vtg_max";
private static final String MIN_PATH = "/sys/class/timed_output/vibrator/vtg_min";
public static boolean isSupported() {
return FileUtils.isFileWritable(LEVEL_PATH) &&
FileUtils.isFileReadable(DEFAULT_PATH) &&
FileUtils.isFileReadable(MAX_PATH) &&
FileUtils.isFileReadable(MIN_PATH);
}
public static int getMaxIntensity() {
try {
return Integer.parseInt(FileUtils.readOneLine(MAX_PATH));
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
return -1;
}
public static int getMinIntensity() {
try {
return Integer.parseInt(FileUtils.readOneLine(MIN_PATH));
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
return -1;
}
public static int getWarningThreshold() {
return -1;
}
public static int getCurIntensity() {
try {
return Integer.parseInt(FileUtils.readOneLine(LEVEL_PATH));
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
return -1;
}
public static int getDefaultIntensity() {
try {
return Integer.parseInt(FileUtils.readOneLine(DEFAULT_PATH));
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
return -1;
}
public static boolean setIntensity(int intensity) {
return FileUtils.writeLine(LEVEL_PATH, String.valueOf(intensity));
}
}