aboutsummaryrefslogtreecommitdiff
path: root/cmactions/src
diff options
context:
space:
mode:
authorMister Oyster <oysterized@gmail.com>2017-01-02 12:44:35 +0100
committerMister Oyster <oysterized@gmail.com>2017-01-02 12:44:35 +0100
commita184d985bf43d3fe6eeba971bc6b32f79ea38b37 (patch)
tree6f6e56e090777cc149bc1ab39e5987cc2b03e867 /cmactions/src
initial releasecm-13.0
Diffstat (limited to 'cmactions/src')
-rw-r--r--cmactions/src/com/cyanogenmod/settings/device/BootCompletedReceiver.java48
-rw-r--r--cmactions/src/com/cyanogenmod/settings/device/GestureController.java112
-rw-r--r--cmactions/src/com/cyanogenmod/settings/device/SwitchPlusPreference.java125
-rw-r--r--cmactions/src/com/cyanogenmod/settings/device/TouchscreenGestureSettings.java155
-rw-r--r--cmactions/src/com/cyanogenmod/settings/device/utils/FileUtils.java115
5 files changed, 555 insertions, 0 deletions
diff --git a/cmactions/src/com/cyanogenmod/settings/device/BootCompletedReceiver.java b/cmactions/src/com/cyanogenmod/settings/device/BootCompletedReceiver.java
new file mode 100644
index 0000000..c52ca65
--- /dev/null
+++ b/cmactions/src/com/cyanogenmod/settings/device/BootCompletedReceiver.java
@@ -0,0 +1,48 @@
+/*
+ * 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 com.cyanogenmod.settings.device;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.util.Log;
+
+public class BootCompletedReceiver extends BroadcastReceiver {
+ static final String TAG = "CMActions";
+
+ @Override
+ public void onReceive(final Context context, Intent intent) {
+ Log.d(TAG, "Booting");
+ enableComponent(context, TouchscreenGestureSettings.class.getName());
+ GestureController.updateGestureControl(context);
+ }
+
+ private void enableComponent(Context context, String component) {
+ ComponentName name = new ComponentName(context, component);
+ PackageManager pm = context.getPackageManager();
+ if (pm.getComponentEnabledSetting(name)
+ == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+ pm.setComponentEnabledSetting(name,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
+ }
+ }
+}
diff --git a/cmactions/src/com/cyanogenmod/settings/device/GestureController.java b/cmactions/src/com/cyanogenmod/settings/device/GestureController.java
new file mode 100644
index 0000000..2cef1a3
--- /dev/null
+++ b/cmactions/src/com/cyanogenmod/settings/device/GestureController.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod Project
+ * Copyright (C) 2016 faust93 adaptation for Meizu PRO5 FTS Driver
+ *
+ * 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 com.cyanogenmod.settings.device;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import android.util.Log;
+import android.util.SparseIntArray;
+
+import com.cyanogenmod.settings.device.utils.FileUtils;
+
+public class GestureController {
+ private static final String TAG = GestureController.class.getSimpleName();
+
+ public static final String TOUCHSCREEN_GESTURE_CONTROL_NODE = "/sys/devices/platform/mx-gs/gesture_control";
+ public static final String TOUCHSCREEN_GESTURE_CONTROL_KEY = "touchscreen_gesture_control";
+
+ // M2Note gesture keys
+ public static final int DOUBLE_TAP = 0xA0; //160
+ public static final int SWIPE_X_LEFT = 0xB0; //176
+ public static final int SWIPE_X_RIGHT = 0xB1;
+ public static final int SWIPE_Y_UP = 0xB2;
+ public static final int SWIPE_Y_DOWN = 0xB3;
+
+ public static final int UNICODE_E = 0xC0; // 192
+ public static final int UNICODE_C = 0xC1;
+ public static final int UNICODE_W = 0xC2;
+ public static final int UNICODE_M = 0xC3;
+ public static final int UNICODE_O = 0xC4;
+ public static final int UNICODE_S = 0xC5;
+ public static final int UNICODE_V_UP = 0xC6;
+ public static final int UNICODE_V_DOWN = 0xC7;
+ public static final int UNICODE_V_L = 0xC8;
+ public static final int UNICODE_V_R = 0xC9;
+ public static final int UNICODE_Z = 0xCA;
+
+
+ public static final int GESTURES_DISABLED_MASK = 0x100;
+ public static final int GESTURES_ENABLED_MASK = 0x1000100;
+
+ // Supported gesture keys and masks
+ public static SparseIntArray keysToMasks = new SparseIntArray();
+
+ static {
+ keysToMasks.put(DOUBLE_TAP, 0x000100);
+
+ keysToMasks.put(SWIPE_X_LEFT, 0x000001);
+ keysToMasks.put(SWIPE_X_RIGHT, 0x000002);
+ keysToMasks.put(SWIPE_Y_DOWN, 0x000004);
+ keysToMasks.put(SWIPE_Y_UP, 0x000008);
+
+ keysToMasks.put(UNICODE_E, 0x040000);
+ keysToMasks.put(UNICODE_C, 0x020000);
+ keysToMasks.put(UNICODE_M, 0x100000);
+ keysToMasks.put(UNICODE_O, 0x800000);
+ keysToMasks.put(UNICODE_S, 0x200000);
+ keysToMasks.put(UNICODE_V_UP, 0x010000);
+ keysToMasks.put(UNICODE_W, 0x080000);
+ keysToMasks.put(UNICODE_Z, 0x400000);
+ }
+
+ public static void updateGestureControl(Context context) {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ if (sharedPreferences.getBoolean(TOUCHSCREEN_GESTURE_CONTROL_KEY, false)) {
+ int gestureMask = 0x000000;
+ FileUtils.writeAsByte(TOUCHSCREEN_GESTURE_CONTROL_NODE, GESTURES_ENABLED_MASK);
+ for (int i = 0; i < keysToMasks.size(); i++) {
+ int key = keysToMasks.keyAt(i);
+ int mask = keysToMasks.get(key);
+ if (sharedPreferences.getBoolean(key + "_enabled", false))
+ gestureMask += mask;
+ }
+ byte swipeMask = (byte) (gestureMask & 0xff);
+ FileUtils.writeByteArray(TOUCHSCREEN_GESTURE_CONTROL_NODE, new byte[]{swipeMask, 0, 4, 0});
+ byte doubleTapMask = (byte) ((gestureMask >> 8) & 0xff);
+ FileUtils.writeByteArray(TOUCHSCREEN_GESTURE_CONTROL_NODE, new byte[]{doubleTapMask, 0, 2, 0});
+ byte unicodeMask = (byte) ((gestureMask >> 16) & 0xff);
+ FileUtils.writeByteArray(TOUCHSCREEN_GESTURE_CONTROL_NODE, new byte[]{unicodeMask, 0, 3, 0});
+ } else {
+ FileUtils.writeAsByte(TOUCHSCREEN_GESTURE_CONTROL_NODE, GESTURES_DISABLED_MASK);
+ }
+ }
+
+ public static void masterSwitch(boolean enabled) {
+ if (enabled) {
+ Log.i(TAG, "Gestures enabled");
+ FileUtils.writeAsByte(TOUCHSCREEN_GESTURE_CONTROL_NODE, GESTURES_ENABLED_MASK);
+ } else {
+ Log.i(TAG, "Gestures disabled");
+ FileUtils.writeAsByte(TOUCHSCREEN_GESTURE_CONTROL_NODE, GESTURES_DISABLED_MASK);
+ }
+ }
+}
+
+
diff --git a/cmactions/src/com/cyanogenmod/settings/device/SwitchPlusPreference.java b/cmactions/src/com/cyanogenmod/settings/device/SwitchPlusPreference.java
new file mode 100644
index 0000000..acf7843
--- /dev/null
+++ b/cmactions/src/com/cyanogenmod/settings/device/SwitchPlusPreference.java
@@ -0,0 +1,125 @@
+package com.cyanogenmod.settings.device;
+
+import android.content.Context;
+import android.preference.SwitchPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Switch;
+
+/**
+ * Custom preference for handling a switch with a clickable preference area as well
+ *
+ * Source: https://gist.github.com/marchold/45e22839eb94aa14dfb5
+ */
+public class SwitchPlusPreference extends SwitchPreference {
+
+ //
+ // Public interface
+ //
+
+ /**
+ * Sets listeners for the switch and the background container preference view cell
+ *
+ * @param listener A valid SwitchPlusClickListener
+ */
+ public void setSwitchClickListener(SwitchPlusClickListener listener) {
+ this.listener = listener;
+ }
+
+ private SwitchPlusClickListener listener = null;
+
+ /**
+ * Interface gives callbacks in to both parts of the preference
+ */
+ public interface SwitchPlusClickListener {
+ /**
+ * Called when the switch is switched
+ *
+ * @param preference
+ * @param isChecked
+ */
+ public void onCheckedChanged(SwitchPlusPreference preference, boolean isChecked);
+
+ /**
+ * Called when the preference view is clicked
+ *
+ * @param view
+ * @param preference
+ */
+ public void onClick(View view, SwitchPlusPreference preference);
+ }
+
+ public SwitchPlusPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public SwitchPlusPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SwitchPlusPreference(Context context) {
+ super(context);
+ }
+
+
+ //
+ // Internal Functions
+ //
+
+ /**
+ * Recursively go through view tree until we find an android.widget.Switch
+ *
+ * @param view Root view to start searching
+ * @return A Switch class or null
+ */
+ private Switch findSwitchWidget(View view) {
+ if (view instanceof Switch) {
+ return (Switch) view;
+ }
+ if (view instanceof ViewGroup) {
+ ViewGroup viewGroup = (ViewGroup) view;
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ View child = viewGroup.getChildAt(i);
+ if (child instanceof ViewGroup) {
+ Switch result = findSwitchWidget(child);
+ if (result != null) return result;
+ }
+ if (child instanceof Switch) {
+ return (Switch) child;
+ }
+ }
+ }
+ return null;
+ }
+
+ //Get a handle on the 2 parts of the switch preference and assign handlers to them
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+ final SwitchPlusPreference that = this;
+
+ final Switch switchView = findSwitchWidget(view);
+ if (switchView != null) {
+ switchView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (listener != null)
+ listener.onCheckedChanged(that, ((Switch) v).isChecked());
+ }
+ });
+ switchView.setChecked(getSharedPreferences().getBoolean(getKey(), false));
+ switchView.setFocusable(true);
+ //switchView.setEnabled(true);
+ }
+
+
+ view.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (listener != null) listener.onClick(v, that);
+ }
+ });
+ }
+}
+
diff --git a/cmactions/src/com/cyanogenmod/settings/device/TouchscreenGestureSettings.java b/cmactions/src/com/cyanogenmod/settings/device/TouchscreenGestureSettings.java
new file mode 100644
index 0000000..2945404
--- /dev/null
+++ b/cmactions/src/com/cyanogenmod/settings/device/TouchscreenGestureSettings.java
@@ -0,0 +1,155 @@
+/*
+ * 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 com.cyanogenmod.settings.device;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.view.MenuItem;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class TouchscreenGestureSettings extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, new GestureFragment())
+ .commit();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ onBackPressed();
+ return true;
+ }
+ return false;
+ }
+
+ public static class GestureFragment extends PreferenceFragment implements SwitchPlusPreference.SwitchPlusClickListener {
+
+ public static final String TAG = GestureFragment.class.getSimpleName();
+
+ private SharedPreferences sharedPrefs;
+ private String[] actionTitles;
+ private String[] actionValues;
+ private List<String> actionTitlesList;
+ private List<String> actionValuesList;
+ private static final List<String> allowedSystemApps = new ArrayList<>();
+
+ static {
+ allowedSystemApps.add("com.android.dialer");
+ allowedSystemApps.add("com.android.mms");
+ allowedSystemApps.add("com.android.settings");
+ allowedSystemApps.add("com.android.deskclock");
+ allowedSystemApps.add("com.android.calculator2");
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.touchscreen_panel);
+ sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+
+ actionTitlesList = new ArrayList<>();
+ actionValuesList = new ArrayList<>();
+ actionTitles = this.getResources().getStringArray(R.array.gesture_action_titles);
+ actionValues = this.getResources().getStringArray(R.array.gesture_action_values);
+ actionTitlesList.addAll(Arrays.asList(actionTitles));
+ actionValuesList.addAll(Arrays.asList(actionValues));
+
+ List<ApplicationInfo> packages = getActivity().getPackageManager()
+ .getInstalledApplications(PackageManager.GET_META_DATA);
+ for (ApplicationInfo appInfo : packages) {
+ if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 &&
+ allowedSystemApps.indexOf(appInfo.packageName) == -1)
+ continue;
+ actionTitlesList.add(appInfo.loadLabel(getActivity().getPackageManager()).toString());
+ actionValuesList.add("launch$" + appInfo.packageName);
+ }
+ actionTitles = actionTitlesList.toArray(new String[actionTitlesList.size()]);
+ actionValues = actionValuesList.toArray(new String[actionValuesList.size()]);
+ for (int x = 0; x < GestureController.keysToMasks.size(); x++) {
+ int prefKey = GestureController.keysToMasks.keyAt(x);
+ SwitchPlusPreference preference = (SwitchPlusPreference) findPreference(String.valueOf(prefKey) + "_enabled");
+ preference.setSwitchClickListener(this);
+ String prefValue = sharedPrefs.getString(String.valueOf(prefKey) + "_action", "disabled");
+ int i = actionValuesList.indexOf(prefValue);
+ if (i >= 0)
+ preference.setSummaryOn(actionTitles[i]);
+ else
+ preference.setSummaryOn(" ");
+ }
+
+ findPreference(GestureController.TOUCHSCREEN_GESTURE_CONTROL_KEY).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object o) {
+ boolean newValue = (boolean) o;
+ GestureController.masterSwitch(newValue);
+ return true;
+ }
+ });
+ }
+
+ @Override
+ public void onCheckedChanged(SwitchPlusPreference preference, boolean isChecked) {
+ GestureController.updateGestureControl(getActivity());
+ }
+
+ @Override
+ public void onClick(View view, final SwitchPlusPreference preference) {
+ if (!preference.isChecked()) return;
+
+ String prefValue = sharedPrefs.getString(preference.getKey().replace("_enabled", "_action"), "disabled");
+ int i = actionValuesList.indexOf(prefValue);
+ AlertDialog dialog = new AlertDialog.Builder(getActivity()).setSingleChoiceItems(actionTitles, i, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ preference.setSummaryOn(actionTitles[which]);
+ sharedPrefs.edit().putString(preference.getKey().replace("_enabled", "_action"),
+ actionValues[which]).apply();
+ dialog.dismiss();
+ }
+ }).create();
+ dialog.show();
+ }
+ }
+}
+
+
diff --git a/cmactions/src/com/cyanogenmod/settings/device/utils/FileUtils.java b/cmactions/src/com/cyanogenmod/settings/device/utils/FileUtils.java
new file mode 100644
index 0000000..e0ed400
--- /dev/null
+++ b/cmactions/src/com/cyanogenmod/settings/device/utils/FileUtils.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2013 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 com.cyanogenmod.settings.device.utils;
+
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public final class FileUtils {
+ private static final String TAG = "FileUtils";
+
+ private FileUtils() {
+ // this class is not supposed to be instantiated
+ }
+
+ /**
+ * Reads the first line of text from the given file
+ */
+ public static String readOneLine(String fileName) {
+ String line = null;
+ BufferedReader reader = null;
+
+ try {
+ reader = new BufferedReader(new FileReader(fileName), 512);
+ line = reader.readLine();
+ } catch (IOException e) {
+ Log.e(TAG, "Could not read from file " + fileName, e);
+ } finally {
+ try {
+ if (reader != null) {
+ reader.close();
+ }
+ } catch (IOException e) {
+ // ignored, not much we can do anyway
+ }
+ }
+
+ return line;
+ }
+
+ /**
+ * Writes the given value into the given file
+ *
+ * @return true on success, false on failure
+ */
+ public static boolean writeLine(String fileName, String value) {
+ try {
+ FileOutputStream fos = new FileOutputStream(fileName);
+ fos.write(value.getBytes());
+ fos.flush();
+ fos.close();
+ } catch (IOException e) {
+ Log.e(TAG, "Could not write to file " + fileName, e);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Writes the given value as bytes into the given file
+ *
+ * @return true on success, false on failure
+ */
+ public static boolean writeAsByte(String fileName, int value) {
+ byte[] bytes = ByteBuffer.allocate(4).putInt(value).array();
+ try {
+ FileOutputStream fos = new FileOutputStream(fileName);
+ fos.write(bytes);
+ fos.flush();
+ fos.close();
+ } catch (IOException e) {
+ Log.e(TAG, "Could not write to file " + fileName, e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Writes the given byte array into the given file
+ *
+ * @return true on success, false on failure
+ */
+ public static boolean writeByteArray(String fileName, byte[] bytes) {
+ try {
+ FileOutputStream fos = new FileOutputStream(fileName);
+ fos.write(bytes);
+ fos.flush();
+ fos.close();
+ } catch (IOException e) {
+ Log.e(TAG, "Could not write to file " + fileName, e);
+ return false;
+ }
+ return true;
+ }
+}
+