diff options
| author | Mister Oyster <oysterized@gmail.com> | 2017-01-02 12:44:35 +0100 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-01-02 12:44:35 +0100 |
| commit | a184d985bf43d3fe6eeba971bc6b32f79ea38b37 (patch) | |
| tree | 6f6e56e090777cc149bc1ab39e5987cc2b03e867 /cmactions/src | |
initial releasecm-13.0
Diffstat (limited to 'cmactions/src')
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; + } +} + |
