aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk7
-rw-r--r--cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java452
-rw-r--r--cm/res/AndroidManifest.xml6
-rw-r--r--cm/res/res/values/strings.xml6
-rw-r--r--src/java/cyanogenmod/app/CMContextConstants.java12
-rw-r--r--src/java/cyanogenmod/hardware/CMHardwareManager.java528
-rw-r--r--src/java/cyanogenmod/hardware/ICMHardwareService.aidl43
7 files changed, 1051 insertions, 3 deletions
diff --git a/Android.mk b/Android.mk
index bac2019..b224af8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -35,7 +35,8 @@ LOCAL_MODULE := org.cyanogenmod.platform
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LIBRARIES := \
- services
+ services \
+ org.cyanogenmod.hardware
LOCAL_SRC_FILES := \
$(call all-java-files-under, $(cyanogenmod_src)) \
@@ -155,7 +156,7 @@ LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:= build/tools/droiddoc/templates-sdk
LOCAL_DROIDDOC_OPTIONS:= \
-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/cmsdk_stubs_current_intermediates/src \
- -stubpackages cyanogenmod.alarmclock:cyanogenmod.app:cyanogenmod.os:cyanogenmod.profiles:cyanogenmod.platform:org.cyanogenmod.platform \
+ -stubpackages cyanogenmod.alarmclock:cyanogenmod.app:cyanogenmod.hardware:cyanogenmod.os:cyanogenmod.profiles:cyanogenmod.platform:org.cyanogenmod.platform \
-api $(INTERNAL_CM_PLATFORM_API_FILE) \
-removedApi $(INTERNAL_CM_PLATFORM_REMOVED_API_FILE) \
-nodocs \
@@ -184,7 +185,7 @@ LOCAL_MODULE := cm-system-api-stubs
LOCAL_DROIDDOC_OPTIONS:=\
-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/cmsdk_system_stubs_current_intermediates/src \
- -stubpackages cyanogenmod.alarmclock:cyanogenmod.app:cyanogenmod.os:cyanogenmod.profiles:cyanogenmod.platform:org.cyanogenmod.platform \
+ -stubpackages cyanogenmod.alarmclock:cyanogenmod.app:cyanogenmod.hardware:cyanogenmod.os:cyanogenmod.profiles:cyanogenmod.platform:org.cyanogenmod.platform \
-showAnnotation android.annotation.SystemApi \
-api $(INTERNAL_CM_PLATFORM_SYSTEM_API_FILE) \
-removedApi $(INTERNAL_CM_PLATFORM_SYSTEM_REMOVED_API_FILE) \
diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java
new file mode 100644
index 0000000..9b880ef
--- /dev/null
+++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java
@@ -0,0 +1,452 @@
+/*
+ * 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.platform.internal;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.IBinder;
+import android.util.Log;
+
+import com.android.server.SystemService;
+
+import cyanogenmod.app.CMContextConstants;
+import cyanogenmod.hardware.ICMHardwareService;
+import cyanogenmod.hardware.CMHardwareManager;
+
+import java.io.File;
+
+import org.cyanogenmod.hardware.AdaptiveBacklight;
+import org.cyanogenmod.hardware.ColorEnhancement;
+import org.cyanogenmod.hardware.DisplayColorCalibration;
+import org.cyanogenmod.hardware.DisplayGammaCalibration;
+import org.cyanogenmod.hardware.HighTouchSensitivity;
+import org.cyanogenmod.hardware.KeyDisabler;
+import org.cyanogenmod.hardware.LongTermOrbits;
+import org.cyanogenmod.hardware.SerialNumber;
+import org.cyanogenmod.hardware.SunlightEnhancement;
+import org.cyanogenmod.hardware.TapToWake;
+import org.cyanogenmod.hardware.TouchscreenHovering;
+import org.cyanogenmod.hardware.VibratorHW;
+
+public class CMHardwareService extends SystemService {
+
+ private static final boolean DEBUG = true;
+ private static final String TAG = CMHardwareService.class.getSimpleName();
+
+ private final Context mContext;
+ private final CMHardwareInterface mCmHwImpl;
+
+ private interface CMHardwareInterface {
+ public int getSupportedFeatures();
+ public boolean get(int feature);
+ public boolean set(int feature, boolean enable);
+
+ public int[] getDisplayColorCalibration();
+ public boolean setDisplayColorCalibration(int[] rgb);
+
+ public int getNumGammaControls();
+ public int[] getDisplayGammaCalibration(int idx);
+ public boolean setDisplayGammaCalibration(int idx, int[] rgb);
+
+ public int[] getVibratorIntensity();
+ public boolean setVibratorIntensity(int intensity);
+
+ public String getLtoSource();
+ public String getLtoDestination();
+ public long getLtoDownloadInterval();
+
+ public String getSerialNumber();
+
+ public boolean requireAdaptiveBacklightForSunlightEnhancement();
+ }
+
+ private class LegacyCMHardware implements CMHardwareInterface {
+
+ private int mSupportedFeatures = 0;
+
+ public LegacyCMHardware() {
+ if (AdaptiveBacklight.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_ADAPTIVE_BACKLIGHT;
+ if (ColorEnhancement.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_COLOR_ENHANCEMENT;
+ if (DisplayColorCalibration.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_DISPLAY_COLOR_CALIBRATION;
+ if (DisplayGammaCalibration.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_DISPLAY_GAMMA_CALIBRATION;
+ if (HighTouchSensitivity.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY;
+ if (KeyDisabler.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_KEY_DISABLE;
+ if (LongTermOrbits.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_LONG_TERM_ORBITS;
+ if (SerialNumber.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_SERIAL_NUMBER;
+ if (SunlightEnhancement.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_SUNLIGHT_ENHANCEMENT;
+ if (TapToWake.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_TAP_TO_WAKE;
+ if (VibratorHW.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_VIBRATOR;
+ if (TouchscreenHovering.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_TOUCH_HOVERING;
+ }
+
+ public int getSupportedFeatures() {
+ return mSupportedFeatures;
+ }
+
+ public boolean get(int feature) {
+ switch(feature) {
+ case CMHardwareManager.FEATURE_ADAPTIVE_BACKLIGHT:
+ return AdaptiveBacklight.isEnabled();
+ case CMHardwareManager.FEATURE_COLOR_ENHANCEMENT:
+ return ColorEnhancement.isEnabled();
+ case CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY:
+ return HighTouchSensitivity.isEnabled();
+ case CMHardwareManager.FEATURE_KEY_DISABLE:
+ return KeyDisabler.isActive();
+ case CMHardwareManager.FEATURE_SUNLIGHT_ENHANCEMENT:
+ return SunlightEnhancement.isEnabled();
+ case CMHardwareManager.FEATURE_TAP_TO_WAKE:
+ return TapToWake.isEnabled();
+ case CMHardwareManager.FEATURE_TOUCH_HOVERING:
+ return TouchscreenHovering.isEnabled();
+ default:
+ Log.e(TAG, "feature " + feature + " is not a boolean feature");
+ return false;
+ }
+ }
+
+ public boolean set(int feature, boolean enable) {
+ switch(feature) {
+ case CMHardwareManager.FEATURE_ADAPTIVE_BACKLIGHT:
+ return AdaptiveBacklight.setEnabled(enable);
+ case CMHardwareManager.FEATURE_COLOR_ENHANCEMENT:
+ return ColorEnhancement.setEnabled(enable);
+ case CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY:
+ return HighTouchSensitivity.setEnabled(enable);
+ case CMHardwareManager.FEATURE_KEY_DISABLE:
+ return KeyDisabler.setActive(enable);
+ case CMHardwareManager.FEATURE_SUNLIGHT_ENHANCEMENT:
+ return SunlightEnhancement.setEnabled(enable);
+ case CMHardwareManager.FEATURE_TAP_TO_WAKE:
+ return TapToWake.setEnabled(enable);
+ case CMHardwareManager.FEATURE_TOUCH_HOVERING:
+ return TouchscreenHovering.setEnabled(enable);
+ default:
+ Log.e(TAG, "feature " + feature + " is not a boolean feature");
+ return false;
+ }
+ }
+
+ private int[] splitStringToInt(String input, String delimiter) {
+ if (input == null || delimiter == null) {
+ return null;
+ }
+ String strArray[] = input.split(delimiter);
+ try {
+ int intArray[] = new int[strArray.length];
+ for(int i = 0; i < strArray.length; i++) {
+ intArray[i] = Integer.parseInt(strArray[i]);
+ }
+ return intArray;
+ } catch (NumberFormatException e) {
+ /* ignore */
+ }
+ return null;
+ }
+
+ private String rgbToString(int[] rgb) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(rgb[CMHardwareManager.COLOR_CALIBRATION_RED_INDEX]);
+ builder.append(" ");
+ builder.append(rgb[CMHardwareManager.COLOR_CALIBRATION_GREEN_INDEX]);
+ builder.append(" ");
+ builder.append(rgb[CMHardwareManager.COLOR_CALIBRATION_BLUE_INDEX]);
+ return builder.toString();
+ }
+
+ public int[] getDisplayColorCalibration() {
+ int[] rgb = splitStringToInt(DisplayColorCalibration.getCurColors(), " ");
+ if (rgb == null || rgb.length != 3) {
+ Log.e(TAG, "Invalid color calibration string");
+ return null;
+ }
+ int[] currentCalibration = new int[6];
+ currentCalibration[CMHardwareManager.COLOR_CALIBRATION_RED_INDEX] = rgb[0];
+ currentCalibration[CMHardwareManager.COLOR_CALIBRATION_GREEN_INDEX] = rgb[1];
+ currentCalibration[CMHardwareManager.COLOR_CALIBRATION_BLUE_INDEX] = rgb[2];
+ currentCalibration[CMHardwareManager.COLOR_CALIBRATION_DEFAULT_INDEX] =
+ DisplayColorCalibration.getDefValue();
+ currentCalibration[CMHardwareManager.COLOR_CALIBRATION_MIN_INDEX] =
+ DisplayColorCalibration.getMinValue();
+ currentCalibration[CMHardwareManager.COLOR_CALIBRATION_MAX_INDEX] =
+ DisplayColorCalibration.getMaxValue();
+ return currentCalibration;
+ }
+
+ public boolean setDisplayColorCalibration(int[] rgb) {
+ return DisplayColorCalibration.setColors(rgbToString(rgb));
+ }
+
+ public int getNumGammaControls() {
+ return DisplayGammaCalibration.getNumberOfControls();
+ }
+
+ public int[] getDisplayGammaCalibration(int idx) {
+ int[] rgb = splitStringToInt(DisplayGammaCalibration.getCurGamma(idx), " ");
+ if (rgb == null || rgb.length != 3) {
+ Log.e(TAG, "Invalid gamma calibration string");
+ return null;
+ }
+ int[] currentCalibration = new int[5];
+ currentCalibration[CMHardwareManager.GAMMA_CALIBRATION_RED_INDEX] = rgb[0];
+ currentCalibration[CMHardwareManager.GAMMA_CALIBRATION_GREEN_INDEX] = rgb[1];
+ currentCalibration[CMHardwareManager.GAMMA_CALIBRATION_BLUE_INDEX] = rgb[2];
+ currentCalibration[CMHardwareManager.GAMMA_CALIBRATION_MIN_INDEX] =
+ DisplayGammaCalibration.getMinValue(idx);
+ currentCalibration[CMHardwareManager.GAMMA_CALIBRATION_MAX_INDEX] =
+ DisplayGammaCalibration.getMaxValue(idx);
+ return currentCalibration;
+ }
+
+ public boolean setDisplayGammaCalibration(int idx, int[] rgb) {
+ return DisplayGammaCalibration.setGamma(idx, rgbToString(rgb));
+ }
+
+ public int[] getVibratorIntensity() {
+ int[] vibrator = new int[5];
+ vibrator[CMHardwareManager.VIBRATOR_INTENSITY_INDEX] = VibratorHW.getCurIntensity();
+ vibrator[CMHardwareManager.VIBRATOR_DEFAULT_INDEX] = VibratorHW.getDefaultIntensity();
+ vibrator[CMHardwareManager.VIBRATOR_MIN_INDEX] = VibratorHW.getMinIntensity();
+ vibrator[CMHardwareManager.VIBRATOR_MAX_INDEX] = VibratorHW.getMaxIntensity();
+ vibrator[CMHardwareManager.VIBRATOR_WARNING_INDEX] = VibratorHW.getWarningThreshold();
+ return vibrator;
+ }
+
+ public boolean setVibratorIntensity(int intensity) {
+ return VibratorHW.setIntensity(intensity);
+ }
+
+ public String getLtoSource() {
+ return LongTermOrbits.getSourceLocation();
+ }
+
+ public String getLtoDestination() {
+ File file = LongTermOrbits.getDestinationLocation();
+ return file.getAbsolutePath();
+ }
+
+ public long getLtoDownloadInterval() {
+ return LongTermOrbits.getDownloadInterval();
+ }
+
+ public String getSerialNumber() {
+ return SerialNumber.getSerialNumber();
+ }
+
+ public boolean requireAdaptiveBacklightForSunlightEnhancement() {
+ return SunlightEnhancement.isAdaptiveBacklightRequired();
+ }
+ }
+
+ private CMHardwareInterface getImpl(Context context) {
+ return new LegacyCMHardware();
+ }
+
+ public CMHardwareService(Context context) {
+ super(context);
+ mContext = context;
+ mCmHwImpl = getImpl(context);
+ publishBinderService(CMContextConstants.CM_HARDWARE_SERVICE, mService);
+ }
+
+ @Override
+ public void onStart() {
+ }
+
+ private final IBinder mService = new ICMHardwareService.Stub() {
+
+ private boolean isSupported(int feature) {
+ return (getSupportedFeatures() & feature) == feature;
+ }
+
+ @Override
+ public int getSupportedFeatures() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ return mCmHwImpl.getSupportedFeatures();
+ }
+
+ @Override
+ public boolean get(int feature) {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(feature)) {
+ Log.e(TAG, "feature " + feature + " is not supported");
+ return false;
+ }
+ return mCmHwImpl.get(feature);
+ }
+
+ @Override
+ public boolean set(int feature, boolean enable) {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(feature)) {
+ Log.e(TAG, "feature " + feature + " is not supported");
+ return false;
+ }
+ return mCmHwImpl.set(feature, enable);
+ }
+
+ @Override
+ public int[] getDisplayColorCalibration() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_DISPLAY_COLOR_CALIBRATION)) {
+ Log.e(TAG, "Display color calibration is not supported");
+ return null;
+ }
+ return mCmHwImpl.getDisplayColorCalibration();
+ }
+
+ @Override
+ public boolean setDisplayColorCalibration(int[] rgb) {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_DISPLAY_COLOR_CALIBRATION)) {
+ Log.e(TAG, "Display color calibration is not supported");
+ return false;
+ }
+ if (rgb.length < 3) {
+ Log.e(TAG, "Invalid color calibration");
+ return false;
+ }
+ return mCmHwImpl.setDisplayColorCalibration(rgb);
+ }
+
+ @Override
+ public int getNumGammaControls() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_DISPLAY_GAMMA_CALIBRATION)) {
+ Log.e(TAG, "Display gamma calibration is not supported");
+ return 0;
+ }
+ return mCmHwImpl.getNumGammaControls();
+ }
+
+ @Override
+ public int[] getDisplayGammaCalibration(int idx) {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_DISPLAY_GAMMA_CALIBRATION)) {
+ Log.e(TAG, "Display gamma calibration is not supported");
+ return null;
+ }
+ return mCmHwImpl.getDisplayGammaCalibration(idx);
+ }
+
+ @Override
+ public boolean setDisplayGammaCalibration(int idx, int[] rgb) {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_DISPLAY_GAMMA_CALIBRATION)) {
+ Log.e(TAG, "Display gamma calibration is not supported");
+ return false;
+ }
+ return mCmHwImpl.setDisplayGammaCalibration(idx, rgb);
+ }
+
+ @Override
+ public int[] getVibratorIntensity() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_VIBRATOR)) {
+ Log.e(TAG, "Vibrator is not supported");
+ return null;
+ }
+ return mCmHwImpl.getVibratorIntensity();
+ }
+
+ @Override
+ public boolean setVibratorIntensity(int intensity) {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_VIBRATOR)) {
+ Log.e(TAG, "Vibrator is not supported");
+ return false;
+ }
+ return mCmHwImpl.setVibratorIntensity(intensity);
+ }
+
+ @Override
+ public String getLtoSource() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_LONG_TERM_ORBITS)) {
+ Log.e(TAG, "Long term orbits is not supported");
+ return null;
+ }
+ return mCmHwImpl.getLtoSource();
+ }
+
+ @Override
+ public String getLtoDestination() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_LONG_TERM_ORBITS)) {
+ Log.e(TAG, "Long term orbits is not supported");
+ return null;
+ }
+ return mCmHwImpl.getLtoDestination();
+ }
+
+ @Override
+ public long getLtoDownloadInterval() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_LONG_TERM_ORBITS)) {
+ Log.e(TAG, "Long term orbits is not supported");
+ return 0;
+ }
+ return mCmHwImpl.getLtoDownloadInterval();
+ }
+
+ @Override
+ public String getSerialNumber() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_SERIAL_NUMBER)) {
+ Log.e(TAG, "Serial number is not supported");
+ return null;
+ }
+ return mCmHwImpl.getSerialNumber();
+ }
+
+ @Override
+ public boolean requireAdaptiveBacklightForSunlightEnhancement() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (!isSupported(CMHardwareManager.FEATURE_SUNLIGHT_ENHANCEMENT)) {
+ Log.e(TAG, "Sunlight enhancement is not supported");
+ return false;
+ }
+ return mCmHwImpl.requireAdaptiveBacklightForSunlightEnhancement();
+ }
+ };
+}
diff --git a/cm/res/AndroidManifest.xml b/cm/res/AndroidManifest.xml
index 0891d7f..e664f54 100644
--- a/cm/res/AndroidManifest.xml
+++ b/cm/res/AndroidManifest.xml
@@ -63,6 +63,12 @@
android:icon="@drawable/ic_launcher_cyanogenmod"
android:protectionLevel="normal" />
+ <!-- Allows an application access to the CM hardware abstraction framework -->
+ <permission android:name="cyanogenmod.permission.HARDWARE_ABSTRACTION_ACCESS"
+ android:label="@string/permlab_useHardwareFramework"
+ android:description="@string/permdesc_useHardwareFramework"
+ android:protectionLevel="system|signature" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/cm/res/res/values/strings.xml b/cm/res/res/values/strings.xml
index 758d927..6634214 100644
--- a/cm/res/res/values/strings.xml
+++ b/cm/res/res/values/strings.xml
@@ -38,6 +38,11 @@
<string name="permlab_modifyMSPhoneState">modify the phone state and data connection with support to multiple SIMs</string>
<string name="permdesc_modifyMSPhoneState">Allows an app to modify the phone state and data connection with support to multiple SIMs.</string>
+ <!-- Labels for the HARDWARE_ABSTRACTION_ACCESS permission. -->
+ <string name="permlab_useHardwareFramework">use hardware framework</string>
+ <string name="permdesc_useHardwareFramework">Allows an app access to the CM hardware framework.</string>
+
+
<!-- Label to show for a service that is running because it is observing the user's custom tiles. -->
<string name="custom_tile_listener_binding_label">Custom tile listener</string>
@@ -59,4 +64,5 @@
<!-- Name of wildcard profile. -->
<string name="wildcardProfile">Other</string>
+
</resources>
diff --git a/src/java/cyanogenmod/app/CMContextConstants.java b/src/java/cyanogenmod/app/CMContextConstants.java
index e4c6578..b79063a 100644
--- a/src/java/cyanogenmod/app/CMContextConstants.java
+++ b/src/java/cyanogenmod/app/CMContextConstants.java
@@ -73,4 +73,16 @@ public final class CMContextConstants {
* @hide
*/
public static final String CM_TELEPHONY_MANAGER_SERVICE = "cmtelephonymanager";
+
+ /**
+ * Use with {@link android.content.Context#getSystemService} to retrieve a
+ * {@link cyanogenmod.hardware.CMHardwareManager} to manage the extended
+ * hardware features of the device.
+ *
+ * @see android.content.Context#getSystemService
+ * @see cyanogenmod.hardware.CMHardwareManager
+ *
+ * @hide
+ */
+ public static final String CM_HARDWARE_SERVICE = "cmhardware";
}
diff --git a/src/java/cyanogenmod/hardware/CMHardwareManager.java b/src/java/cyanogenmod/hardware/CMHardwareManager.java
new file mode 100644
index 0000000..62e5c66
--- /dev/null
+++ b/src/java/cyanogenmod/hardware/CMHardwareManager.java
@@ -0,0 +1,528 @@
+/*
+ * 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 cyanogenmod.hardware;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import cyanogenmod.app.CMContextConstants;
+
+import java.lang.IllegalArgumentException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Manages access to CyanogenMod hardware extensions
+ *
+ * To get the instance of this class, utilize CMHardwareManager#getInstance(Context context)
+ *
+ */
+public final class CMHardwareManager {
+ private static final String TAG = "CMHardwareManager";
+
+ private static ICMHardwareService sService;
+
+ private Context mContext;
+ /**
+ * Adaptive backlight support (this refers to technologies like NVIDIA SmartDimmer,
+ * QCOM CABL or Samsung CABC)
+ */
+ public static final int FEATURE_ADAPTIVE_BACKLIGHT = 0x1;
+
+ /**
+ * Color enhancement support
+ */
+ public static final int FEATURE_COLOR_ENHANCEMENT = 0x2;
+
+ /**
+ * Display RGB color calibration
+ */
+ public static final int FEATURE_DISPLAY_COLOR_CALIBRATION = 0x4;
+
+ /**
+ * Display gamma calibration
+ */
+ public static final int FEATURE_DISPLAY_GAMMA_CALIBRATION = 0x8;
+
+ /**
+ * High touch sensitivity for touch panels
+ */
+ public static final int FEATURE_HIGH_TOUCH_SENSITIVITY = 0x10;
+
+ /**
+ * Hardware navigation key disablement
+ */
+ public static final int FEATURE_KEY_DISABLE = 0x20;
+
+ /**
+ * Long term orbits (LTO)
+ */
+ public static final int FEATURE_LONG_TERM_ORBITS = 0x40;
+
+ /**
+ * Serial number other than ro.serialno
+ */
+ public static final int FEATURE_SERIAL_NUMBER = 0x80;
+
+ /**
+ * Increased display readability in bright light
+ */
+ public static final int FEATURE_SUNLIGHT_ENHANCEMENT = 0x100;
+
+ /**
+ * Double-tap the touch panel to wake up the device
+ */
+ public static final int FEATURE_TAP_TO_WAKE = 0x200;
+
+ /**
+ * Variable vibrator intensity
+ */
+ public static final int FEATURE_VIBRATOR = 0x400;
+
+ /**
+ * Touchscreen hovering
+ */
+ public static final int FEATURE_TOUCH_HOVERING = 0x800;
+
+ private static final List<Integer> BOOLEAN_FEATURES = Arrays.asList(
+ FEATURE_ADAPTIVE_BACKLIGHT,
+ FEATURE_COLOR_ENHANCEMENT,
+ FEATURE_HIGH_TOUCH_SENSITIVITY,
+ FEATURE_KEY_DISABLE,
+ FEATURE_SUNLIGHT_ENHANCEMENT,
+ FEATURE_TAP_TO_WAKE,
+ FEATURE_TOUCH_HOVERING,
+ );
+
+ private static CMHardwareManager sCMHardwareManagerInstance;
+
+ /**
+ * @hide to prevent subclassing from outside of the framework
+ */
+ private CMHardwareManager(Context context) {
+ Context appContext = context.getApplicationContext();
+ if (appContext != null) {
+ mContext = appContext;
+ } else {
+ mContext = context;
+ }
+ sService = getService();
+ }
+
+ /**
+ * Get or create an instance of the {@link cyanogenmod.hardware.CMHardwareManager}
+ * @param context
+ * @return {@link CMHardwareManager}
+ */
+ public static CMHardwareManager getInstance(Context context) {
+ if (sCMHardwareManagerInstance == null) {
+ sCMHardwareManagerInstance = new CMHardwareManager(context);
+ }
+ return sCMHardwareManagerInstance;
+ }
+
+ /** @hide */
+ private static ICMHardwareService getService() {
+ if (sService != null) {
+ return sService;
+ }
+ IBinder b = ServiceManager.getService(CMContextConstants.CM_HARDWARE_SERVICE);
+ if (b != null) {
+ sService = ICMHardwareService.Stub.asInterface(b);
+ return sService;
+ }
+ return null;
+ }
+
+ /**
+ * @return the supported features bitmask
+ */
+ public int getSupportedFeatures() {
+ try {
+ return getService().getSupportedFeatures();
+ } catch (RemoteException e) {
+ }
+ return 0;
+ }
+
+ /**
+ * Determine if a CM Hardware feature is supported on this device
+ *
+ * @param feature The CM Hardware feature to query
+ *
+ * @return true if the feature is supported, false otherwise.
+ */
+ public boolean isSupported(int feature) {
+ return feature == (getSupportedFeatures() & feature);
+ }
+
+ /**
+ * Determine if the given feature is enabled or disabled.
+ *
+ * Only used for features which have simple enable/disable controls.
+ *
+ * @param feature the CM Hardware feature to query
+ *
+ * @return true if the feature is enabled, false otherwise.
+ */
+ public boolean get(int feature) {
+ if (!BOOLEAN_FEATURES.contains(feature)) {
+ throw new IllegalArgumentException(feature + " is not a boolean");
+ }
+
+ try {
+ return getService().get(feature);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Enable or disable the given feature
+ *
+ * Only used for features which have simple enable/disable controls.
+ *
+ * @param feature the CM Hardware feature to set
+ * @param enable true to enable, false to disale
+ *
+ * @return true if the feature is enabled, false otherwise.
+ */
+ public boolean set(int feature, boolean enable) {
+ if (!BOOLEAN_FEATURES.contains(feature)) {
+ throw new IllegalArgumentException(feature + " is not a boolean");
+ }
+
+ try {
+ return getService().set(feature, enable);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ private int getArrayValue(int[] arr, int idx, int defaultValue) {
+ if (arr == null || arr.length <= idx) {
+ return defaultValue;
+ }
+
+ return arr[idx];
+ }
+
+ /**
+ * {@hide}
+ */
+ public static final int VIBRATOR_INTENSITY_INDEX = 0;
+ /**
+ * {@hide}
+ */
+ public static final int VIBRATOR_DEFAULT_INDEX = 1;
+ /**
+ * {@hide}
+ */
+ public static final int VIBRATOR_MIN_INDEX = 2;
+ /**
+ * {@hide}
+ */
+ public static final int VIBRATOR_MAX_INDEX = 3;
+ /**
+ * {@hide}
+ */
+ public static final int VIBRATOR_WARNING_INDEX = 4;
+
+ private int[] getVibratorIntensityArray() {
+ try {
+ return getService().getVibratorIntensity();
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * @return The current vibrator intensity.
+ */
+ public int getVibratorIntensity() {
+ return getArrayValue(getVibratorIntensityArray(), VIBRATOR_INTENSITY_INDEX, 0);
+ }
+
+ /**
+ * @return The default vibrator intensity.
+ */
+ public int getVibratorDefaultIntensity() {
+ return getArrayValue(getVibratorIntensityArray(), VIBRATOR_DEFAULT_INDEX, 0);
+ }
+
+ /**
+ * @return The minimum vibrator intensity.
+ */
+ public int getVibratorMinIntensity() {
+ return getArrayValue(getVibratorIntensityArray(), VIBRATOR_MIN_INDEX, 0);
+ }
+
+ /**
+ * @return The maximum vibrator intensity.
+ */
+ public int getVibratorMaxIntensity() {
+ return getArrayValue(getVibratorIntensityArray(), VIBRATOR_MAX_INDEX, 0);
+ }
+
+ /**
+ * @return The warning threshold vibrator intensity.
+ */
+ public int getVibratorWarningIntensity() {
+ return getArrayValue(getVibratorIntensityArray(), VIBRATOR_WARNING_INDEX, 0);
+ }
+
+ /**
+ * Set the current vibrator intensity
+ *
+ * @param intensity the intensity to set, between {@link #getVibratorMinIntensity()} and
+ * {@link #getVibratorMaxIntensity()} inclusive.
+ *
+ * @return true on success, false otherwise.
+ */
+ public boolean setVibratorIntensity(int intensity) {
+ try {
+ return getService().setVibratorIntensity(intensity);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
+ * {@hide}
+ */
+ public static final int COLOR_CALIBRATION_RED_INDEX = 0;
+ /**
+ * {@hide}
+ */
+ public static final int COLOR_CALIBRATION_GREEN_INDEX = 1;
+ /**
+ * {@hide}
+ */
+ public static final int COLOR_CALIBRATION_BLUE_INDEX = 2;
+ /**
+ * {@hide}
+ */
+ public static final int COLOR_CALIBRATION_DEFAULT_INDEX = 3;
+ /**
+ * {@hide}
+ */
+ public static final int COLOR_CALIBRATION_MIN_INDEX = 4;
+ /**
+ * {@hide}
+ */
+ public static final int COLOR_CALIBRATION_MAX_INDEX = 5;
+
+ private int[] getDisplayColorCalibrationArray() {
+ try {
+ return getService().getDisplayColorCalibration();
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * @return the current RGB calibration, where int[0] = R, int[1] = G, int[2] = B.
+ */
+ public int[] getDisplayColorCalibration() {
+ int[] arr = getDisplayColorCalibrationArray();
+ if (arr == null || arr.length < 3) {
+ return null;
+ }
+ return Arrays.copyOf(arr, 3);
+ }
+
+ /**
+ * @return the default value for all colors
+ */
+ public int getDisplayColorCalibrationDefault() {
+ return getArrayValue(getDisplayColorCalibrationArray(), COLOR_CALIBRATION_DEFAULT_INDEX, 0);
+ }
+
+ /**
+ * @return The minimum value for all colors
+ */
+ public int getDisplayColorCalibrationMin() {
+ return getArrayValue(getDisplayColorCalibrationArray(), COLOR_CALIBRATION_MIN_INDEX, 0);
+ }
+
+ /**
+ * @return The minimum value for all colors
+ */
+ public int getDisplayColorCalibrationMax() {
+ return getArrayValue(getDisplayColorCalibrationArray(), COLOR_CALIBRATION_MAX_INDEX, 0);
+ }
+
+ /**
+ * Set the display color calibration to the given rgb triplet
+ *
+ * @param rgb RGB color calibration. Each value must be between
+ * {@link getDisplayColorCalibrationMin()} and {@link getDisplayColorCalibrationMax()},
+ * inclusive.
+ *
+ * @return true on success, false otherwise.
+ */
+ public boolean setDisplayColorCalibration(int[] rgb) {
+ try {
+ return getService().setDisplayColorCalibration(rgb);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
+ * {@hide}
+ */
+ public static final int GAMMA_CALIBRATION_RED_INDEX = 0;
+ /**
+ * {@hide}
+ */
+ public static final int GAMMA_CALIBRATION_GREEN_INDEX = 1;
+ /**
+ * {@hide}
+ */
+ public static final int GAMMA_CALIBRATION_BLUE_INDEX = 2;
+ /**
+ * {@hide}
+ */
+ public static final int GAMMA_CALIBRATION_MIN_INDEX = 3;
+ /**
+ * {@hide}
+ */
+ public static final int GAMMA_CALIBRATION_MAX_INDEX = 4;
+
+ private int[] getDisplayGammaCalibrationArray(int idx) {
+ try {
+ return getService().getDisplayGammaCalibration(idx);
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * @return the number of RGB controls the device supports
+ */
+ public int getNumGammaControls() {
+ try {
+ return getService().getNumGammaControls();
+ } catch (RemoteException e) {
+ }
+ return 0;
+ }
+
+ /**
+ * @param the control to query
+ *
+ * @return the current RGB gamma calibration for the given control
+ */
+ public int[] getDisplayGammaCalibration(int idx) {
+ int[] arr = getDisplayGammaCalibrationArray(idx);
+ if (arr == null || arr.length < 3) {
+ return null;
+ }
+ return Arrays.copyOf(arr, 3);
+ }
+
+ /**
+ * @return the minimum value for all colors
+ */
+ public int getDisplayGammaCalibrationMin() {
+ return getArrayValue(getDisplayGammaCalibrationArray(0), GAMMA_CALIBRATION_MIN_INDEX, 0);
+ }
+
+ /**
+ * @return the maximum value for all colors
+ */
+ public int getDisplayGammaCalibrationMax() {
+ return getArrayValue(getDisplayGammaCalibrationArray(0), GAMMA_CALIBRATION_MAX_INDEX, 0);
+ }
+
+ /**
+ * Set the display gamma calibration for a specific control
+ *
+ * @param idx the control to set
+ * @param rgb RGB color calibration. Each value must be between
+ * {@link getDisplayGammaCalibrationMin()} and {@link getDisplayGammaCalibrationMax()},
+ * inclusive.
+ *
+ * @return true on success, false otherwise.
+ */
+ public boolean setDisplayGammaCalibration(int idx, int[] rgb) {
+ try {
+ return getService().setDisplayGammaCalibration(idx, rgb);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
+ * @return the source location of LTO data, or null on failure
+ */
+ public String getLtoSource() {
+ try {
+ return getService().getLtoSource();
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * @return the destination location of LTO data, or null on failure
+ */
+ public String getLtoDestination() {
+ try {
+ return getService().getLtoDestination();
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * @return the interval, in milliseconds, to trigger LTO data download
+ */
+ public long getLtoDownloadInterval() {
+ try {
+ return getService().getLtoDownloadInterval();
+ } catch (RemoteException e) {
+ }
+ return 0;
+ }
+
+ /**
+ * @return the serial number to display instead of ro.serialno, or null on failure
+ */
+ public String getSerialNumber() {
+ try {
+ return getService().getSerialNumber();
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * @return true if adaptive backlight should be enabled when sunlight enhancement
+ * is enabled.
+ */
+ public boolean requireAdaptiveBacklightForSunlightEnhancement() {
+ try {
+ return getService().requireAdaptiveBacklightForSunlightEnhancement();
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+}
diff --git a/src/java/cyanogenmod/hardware/ICMHardwareService.aidl b/src/java/cyanogenmod/hardware/ICMHardwareService.aidl
new file mode 100644
index 0000000..ef85d94
--- /dev/null
+++ b/src/java/cyanogenmod/hardware/ICMHardwareService.aidl
@@ -0,0 +1,43 @@
+/**
+ * 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 cyanogenmod.hardware;
+
+/** @hide */
+interface ICMHardwareService {
+
+ int getSupportedFeatures();
+ boolean get(int feature);
+ boolean set(int feature, boolean enable);
+
+ int[] getDisplayColorCalibration();
+ boolean setDisplayColorCalibration(in int[] rgb);
+
+ int getNumGammaControls();
+ int[] getDisplayGammaCalibration(int idx);
+ boolean setDisplayGammaCalibration(int idx, in int[] rgb);
+
+ int[] getVibratorIntensity();
+ boolean setVibratorIntensity(int intensity);
+
+ String getLtoSource();
+ String getLtoDestination();
+ long getLtoDownloadInterval();
+
+ String getSerialNumber();
+
+ boolean requireAdaptiveBacklightForSunlightEnhancement();
+}