aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVachounet <vachounet@live.fr>2017-07-18 09:38:10 +0200
committerwzedlare <vedatak01@gmail.com>2017-07-28 18:23:47 +0000
commitb1cea3b86b228ef4e9107b1961d02fbeae473dfd (patch)
tree500409bb0caa467f7aa269e585c7d6738613b168
parent7fc005a011d581ca3c5898e0fa367a4061ef6d38 (diff)
cedric: import some cmhw features
Change-Id: I20278917c6016e102ed8ef8d9b043c5ac4159274
-rw-r--r--BoardConfig.mk2
-rw-r--r--cmhw/org/cyanogenmod/hardware/DisplayModeControl.java96
-rw-r--r--cmhw/org/cyanogenmod/hardware/LiveDisplayVendorImpl.java88
-rw-r--r--cmhw/org/cyanogenmod/hardware/PersistentStorage.java196
-rw-r--r--cmhw/org/cyanogenmod/hardware/PictureAdjustment.java141
-rw-r--r--cmhw/org/cyanogenmod/hardware/SunlightEnhancement.java122
-rw-r--r--cmhw/org/cyanogenmod/hardware/UniqueDeviceId.java82
-rw-r--r--cmhw/org/cyanogenmod/hardware/VibratorHW.java82
8 files changed, 808 insertions, 1 deletions
diff --git a/BoardConfig.mk b/BoardConfig.mk
index b3887cf..74d2d14 100644
--- a/BoardConfig.mk
+++ b/BoardConfig.mk
@@ -85,7 +85,7 @@ BOARD_NO_CHARGER_LED := true
# CMHW
BOARD_USES_CYANOGEN_HARDWARE := true
-BOARD_HARDWARE_CLASS += hardware/cyanogen/cmhw
+BOARD_HARDWARE_CLASS += $(LOCAL_PATH)/cmhw
# Crypto
TARGET_HW_DISK_ENCRYPTION := true
diff --git a/cmhw/org/cyanogenmod/hardware/DisplayModeControl.java b/cmhw/org/cyanogenmod/hardware/DisplayModeControl.java
new file mode 100644
index 0000000..cf1b6ae
--- /dev/null
+++ b/cmhw/org/cyanogenmod/hardware/DisplayModeControl.java
@@ -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();
+ }
+}
diff --git a/cmhw/org/cyanogenmod/hardware/LiveDisplayVendorImpl.java b/cmhw/org/cyanogenmod/hardware/LiveDisplayVendorImpl.java
new file mode 100644
index 0000000..36a19a2
--- /dev/null
+++ b/cmhw/org/cyanogenmod/hardware/LiveDisplayVendorImpl.java
@@ -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();
+}
diff --git a/cmhw/org/cyanogenmod/hardware/PersistentStorage.java b/cmhw/org/cyanogenmod/hardware/PersistentStorage.java
new file mode 100644
index 0000000..910f41b
--- /dev/null
+++ b/cmhw/org/cyanogenmod/hardware/PersistentStorage.java
@@ -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;
+ }
+}
diff --git a/cmhw/org/cyanogenmod/hardware/PictureAdjustment.java b/cmhw/org/cyanogenmod/hardware/PictureAdjustment.java
new file mode 100644
index 0000000..dc0b68a
--- /dev/null
+++ b/cmhw/org/cyanogenmod/hardware/PictureAdjustment.java
@@ -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);
+ }
+}
diff --git a/cmhw/org/cyanogenmod/hardware/SunlightEnhancement.java b/cmhw/org/cyanogenmod/hardware/SunlightEnhancement.java
new file mode 100644
index 0000000..4558be4
--- /dev/null
+++ b/cmhw/org/cyanogenmod/hardware/SunlightEnhancement.java
@@ -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;
+ }
+}
diff --git a/cmhw/org/cyanogenmod/hardware/UniqueDeviceId.java b/cmhw/org/cyanogenmod/hardware/UniqueDeviceId.java
new file mode 100644
index 0000000..7fa9e12
--- /dev/null
+++ b/cmhw/org/cyanogenmod/hardware/UniqueDeviceId.java
@@ -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;
+ }
+}
diff --git a/cmhw/org/cyanogenmod/hardware/VibratorHW.java b/cmhw/org/cyanogenmod/hardware/VibratorHW.java
new file mode 100644
index 0000000..33e5d34
--- /dev/null
+++ b/cmhw/org/cyanogenmod/hardware/VibratorHW.java
@@ -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));
+ }
+}