1 package de
.rmdir
.ms2debounce
;
3 import java
.io
.InputStream
;
4 import java
.io
.OutputStream
;
6 import java
.io
.FileReader
;
7 import java
.io
.FileWriter
;
8 import java
.io
.BufferedReader
;
9 import java
.io
.BufferedWriter
;
10 import java
.io
.DataOutputStream
;
12 import android
.content
.Context
;
13 import android
.content
.SharedPreferences
;
14 import android
.util
.Log
;
16 public class DebounceModuleHelper
19 public static final String PREFS_NAME
= "DebounceCfg";
20 final int SUPERUSER_REQUEST
= 4223;
22 private static final String TAG
= "DebounceModuleHelper";
24 public DebounceModuleHelper(Context context
) {
28 public void setAllValues() {
29 setDelay(getSavedDelay());
30 setSettle(getSavedSettle());
31 setPoll(getSavedPoll());
32 setHwDebounce(getSavedHwDebounce());
33 setHwDebounceTime(getSavedHwDebounceTime());
34 //setDriveInactive(getSavedDriveInactive());
35 setActiveHigh(getSavedActiveHigh());
38 public boolean loadModule() throws NotRootedException
,ShellException
{
47 protected void runAsRoot(String command
) throws NotRootedException
,ShellException
{
50 Log
.i(TAG
, "Running as root: " + command
);
52 rootcmd
= Runtime
.getRuntime().exec(new String
[]{"su","-c","sh"});
53 } catch (java
.io
.IOException e
) {
54 Log
.e(TAG
, "Got IOException: " + e
.getMessage() + " (" + e
.getCause() + ")");
55 throw new NotRootedException();
59 DataOutputStream sh
= new DataOutputStream(rootcmd
.getOutputStream());
60 sh
.writeBytes(command
+ "\n");
61 sh
.writeBytes("exit\n");
64 } catch (java
.io
.IOException e
) {
65 Log
.e(TAG
, "Got IOException: " + e
.getMessage() + " (" + e
.getCause() + ")");
66 throw new ShellException();
70 int r
= rootcmd
.waitFor();
73 Log
.e(TAG
, "Process returned: " + r
);
74 throw new ShellException();
76 } catch (java
.lang
.InterruptedException e
) {
77 Log
.e(TAG
, "Got InterruptedException: " + e
.getMessage() + " (" + e
.getCause() + ")");
78 throw new ShellException();
81 Log
.i(TAG
, "Process executed successfully");
84 public synchronized boolean _loadModule() throws NotRootedException
,ShellException
{
85 File insmod
= new File("/system/bin/insmod");
86 if (!insmod
.exists()) {
87 insmod
= new File("/system/xbin/insmod");
88 if (!insmod
.exists()) {
93 File debounce_ko
= new File("/system/lib/modules/debounce.ko");
94 if (!debounce_ko
.exists()) {
95 debounce_ko
= new File(ctx
.getFilesDir() + "/debounce.ko");
100 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
101 SharedPreferences
.Editor editor
= settings
.edit();
102 if (is_safe_to_load()) {
103 editor
.putBoolean("safe_to_load", false);
107 runAsRoot(insmod
+ " " + debounce_ko
);
110 while ((!isLoaded()) && (cnt
> 0)) {
113 } catch (Exception e
) {
123 if (getDelay() < 0) {
127 /* Module was obviously loaded, so it is safe to load on boot */
128 editor
.putBoolean("safe_to_load", true);
134 public synchronized void unloadModule() throws NotRootedException
,ShellException
{
135 File rmmod
= new File("/system/bin/rmmod");
137 if (!rmmod
.exists()) {
138 rmmod
= new File("/system/xbin/rmmod");
139 if (!rmmod
.exists()) {
144 runAsRoot(rmmod
+ " debounce");
147 public synchronized boolean isLoaded() {
148 boolean loaded
= false;
153 FileReader modules
= new FileReader("/proc/modules");
154 BufferedReader modules_buf
= new BufferedReader(modules
);
156 while((read
= modules_buf
.readLine()) != null) {
157 if (read
.regionMatches(0, "debounce", 0, 8)) {
158 File sysdir
= new File("/sys/devices/debounce");
159 if (sysdir
.exists() && sysdir
.isDirectory()) {
165 } catch (Exception e
) {
172 private synchronized int getValue(String parameter
) {
178 FileReader fr
= new FileReader("/sys/devices/debounce/" + parameter
);
179 BufferedReader fbuf
= new BufferedReader(fr
);
181 read
= fbuf
.readLine();
183 value
= Integer
.parseInt(read
.trim());
187 } catch (Exception e
) {}
192 private synchronized void setValue(String parameter
, int value
) {
198 FileWriter fw
= new FileWriter("/sys/devices/debounce/" + parameter
);
199 BufferedWriter fbuf
= new BufferedWriter(fw
);
201 fbuf
.write((new Integer(value
)).toString());
204 } catch (Exception e
) {}
207 public synchronized int getDelay() {
208 return getValue("debounce_delay");
211 public synchronized void setDelay(int debounce_delay
) {
212 setValue("debounce_delay", debounce_delay
);
215 public synchronized int getSettle() {
216 return getValue("settle_time");
219 public synchronized void setSettle(int settle_time
) {
220 setValue("settle_time", settle_time
);
223 public synchronized int getPoll() {
224 return getValue("poll_time");
227 public synchronized void setPoll(int poll_time
) {
228 setValue("poll_time", poll_time
);
231 public synchronized boolean getHwDebounce() {
232 if (getValue("hw_debounce") == 1)
238 public synchronized void setHwDebounce(boolean enable
) {
240 setValue("hw_debounce", 1);
242 setValue("hw_debounce", 0);
245 public synchronized int getHwDebounceTime() {
246 return getValue("hw_debounce_time");
249 public synchronized void setHwDebounceTime(int time
) {
250 setValue("hw_debounce_time", time
);
253 public synchronized boolean getDriveInactive() {
254 if (getValue("drive_inactive_flag") == 1)
260 public synchronized void setDriveInactive(boolean enable
) {
262 setValue("drive_inactive_flag", 1);
264 setValue("drive_inactive_flag", 0);
267 public synchronized boolean getActiveHigh() {
268 if (getValue("active_high_flag") == 1)
274 public synchronized void setActiveHigh(boolean enable
) {
276 setValue("active_high_flag", 1);
278 setValue("active_high_flag", 0);
281 public synchronized int getSavedDelay() {
282 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
284 return settings
.getInt("debounce_delay", 15);
287 public synchronized void setSavedDelay(int delay
) {
288 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
289 SharedPreferences
.Editor editor
= settings
.edit();
291 editor
.putInt("debounce_delay", delay
);
295 public synchronized int getSavedSettle() {
296 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
298 return settings
.getInt("settle_time", 40);
301 public synchronized void setSavedSettle(int settle
) {
302 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
303 SharedPreferences
.Editor editor
= settings
.edit();
305 editor
.putInt("settle_time", settle
);
309 public synchronized int getSavedPoll() {
310 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
312 return settings
.getInt("poll_time", 20);
315 public synchronized void setSavedPoll(int poll
) {
316 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
317 SharedPreferences
.Editor editor
= settings
.edit();
319 editor
.putInt("poll_time", poll
);
323 public synchronized boolean getSavedHwDebounce() {
324 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
326 return settings
.getBoolean("hw_debounce", false);
329 public synchronized void setSavedHwDebounce(boolean enable
) {
330 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
331 SharedPreferences
.Editor editor
= settings
.edit();
333 editor
.putBoolean("hw_debounce", enable
);
337 public synchronized int getSavedHwDebounceTime() {
338 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
340 return settings
.getInt("hw_debounce_time", 1);
343 public synchronized void setSavedHwDebounceTime(int time
) {
344 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
345 SharedPreferences
.Editor editor
= settings
.edit();
347 editor
.putInt("hw_debounce_time", time
);
351 public synchronized boolean getSavedDriveInactive() {
352 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
354 return settings
.getBoolean("drive_inactive", false);
357 public synchronized void setSavedDriveInactive(boolean enable
) {
358 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
359 SharedPreferences
.Editor editor
= settings
.edit();
361 editor
.putBoolean("drive_inactive", enable
);
365 public synchronized boolean getSavedActiveHigh() {
366 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
368 return settings
.getBoolean("active_high", false);
371 public synchronized void setSavedActiveHigh(boolean enable
) {
372 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
373 SharedPreferences
.Editor editor
= settings
.edit();
375 editor
.putBoolean("active_high", enable
);
379 public synchronized boolean is_safe_to_load() {
380 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
381 return settings
.getBoolean("safe_to_load", false);
384 public synchronized boolean get_on_boot() {
385 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
386 return settings
.getBoolean("on_boot", false);
389 public synchronized void set_on_boot(boolean on_boot
) {
390 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
391 SharedPreferences
.Editor editor
= settings
.edit();
393 editor
.putBoolean("on_boot", on_boot
);
397 private synchronized void extractModule() {
398 File debounce_ko
= new File(ctx
.getFilesDir() + "/debounce.ko");
400 if (debounce_ko
.exists()) {
405 InputStream apk
= ctx
.getAssets().open("debounce.ko");
406 OutputStream mod
= ctx
.openFileOutput("debounce.ko.tmp", 0);
408 //I assume a page is 4k...
409 byte buf
[] = new byte[4096];
412 while((bytes
= apk
.read(buf
)) != -1) {
413 mod
.write(buf
, 0, bytes
);
419 File tmpfile
= new File(debounce_ko
+ ".tmp");
420 tmpfile
.renameTo(debounce_ko
);
421 } catch (Exception e
) {}