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
{
89 File insmod
= new File("/system/bin/insmod");
90 if (!insmod
.exists()) {
91 insmod
= new File("/system/xbin/insmod");
92 if (!insmod
.exists()) {
97 File debounce_ko
= new File("/system/lib/modules/debounce.ko");
98 if (!debounce_ko
.exists()) {
99 debounce_ko
= new File(ctx
.getFilesDir() + "/debounce.ko");
104 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
105 SharedPreferences
.Editor editor
= settings
.edit();
106 if (is_safe_to_load()) {
107 editor
.putBoolean("safe_to_load", false);
111 runAsRoot(insmod
+ " " + debounce_ko
);
114 while ((!isLoaded()) && (cnt
> 0)) {
117 } catch (Exception e
) {
127 if (getDelay() < 0) {
131 /* Module was obviously loaded, so it is safe to load on boot */
132 editor
.putBoolean("safe_to_load", true);
138 public synchronized void unloadModule() throws NotRootedException
,ShellException
{
139 File rmmod
= new File("/system/bin/rmmod");
141 if (!rmmod
.exists()) {
142 rmmod
= new File("/system/xbin/rmmod");
143 if (!rmmod
.exists()) {
148 runAsRoot(rmmod
+ " debounce");
151 public synchronized boolean isLoaded() {
152 boolean loaded
= false;
157 FileReader modules
= new FileReader("/proc/modules");
158 BufferedReader modules_buf
= new BufferedReader(modules
);
160 while((read
= modules_buf
.readLine()) != null) {
161 if (read
.regionMatches(0, "debounce", 0, 8)) {
162 File sysdir
= new File("/sys/devices/debounce");
163 if (sysdir
.exists() && sysdir
.isDirectory()) {
169 } catch (Exception e
) {
176 private synchronized int getValue(String parameter
) {
182 FileReader fr
= new FileReader("/sys/devices/debounce/" + parameter
);
183 BufferedReader fbuf
= new BufferedReader(fr
);
185 read
= fbuf
.readLine();
187 value
= Integer
.parseInt(read
.trim());
191 } catch (Exception e
) {}
196 private synchronized void setValue(String parameter
, int value
) {
202 FileWriter fw
= new FileWriter("/sys/devices/debounce/" + parameter
);
203 BufferedWriter fbuf
= new BufferedWriter(fw
);
205 fbuf
.write((new Integer(value
)).toString());
208 } catch (Exception e
) {}
211 public synchronized int getDelay() {
212 return getValue("debounce_delay");
215 public synchronized void setDelay(int debounce_delay
) {
216 setValue("debounce_delay", debounce_delay
);
219 public synchronized int getSettle() {
220 return getValue("settle_time");
223 public synchronized void setSettle(int settle_time
) {
224 setValue("settle_time", settle_time
);
227 public synchronized int getPoll() {
228 return getValue("poll_time");
231 public synchronized void setPoll(int poll_time
) {
232 setValue("poll_time", poll_time
);
235 public synchronized boolean getHwDebounce() {
236 if (getValue("hw_debounce") == 1)
242 public synchronized void setHwDebounce(boolean enable
) {
244 setValue("hw_debounce", 1);
246 setValue("hw_debounce", 0);
249 public synchronized int getHwDebounceTime() {
250 return getValue("hw_debounce_time");
253 public synchronized void setHwDebounceTime(int time
) {
254 setValue("hw_debounce_time", time
);
257 public synchronized boolean getDriveInactive() {
258 if (getValue("drive_inactive_flag") == 1)
264 public synchronized void setDriveInactive(boolean enable
) {
266 setValue("drive_inactive_flag", 1);
268 setValue("drive_inactive_flag", 0);
271 public synchronized boolean getActiveHigh() {
272 if (getValue("active_high_flag") == 1)
278 public synchronized void setActiveHigh(boolean enable
) {
280 setValue("active_high_flag", 1);
282 setValue("active_high_flag", 0);
285 public synchronized int getSavedDelay() {
286 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
288 return settings
.getInt("debounce_delay", 15);
291 public synchronized void setSavedDelay(int delay
) {
292 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
293 SharedPreferences
.Editor editor
= settings
.edit();
295 editor
.putInt("debounce_delay", delay
);
299 public synchronized int getSavedSettle() {
300 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
302 return settings
.getInt("settle_time", 40);
305 public synchronized void setSavedSettle(int settle
) {
306 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
307 SharedPreferences
.Editor editor
= settings
.edit();
309 editor
.putInt("settle_time", settle
);
313 public synchronized int getSavedPoll() {
314 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
316 return settings
.getInt("poll_time", 20);
319 public synchronized void setSavedPoll(int poll
) {
320 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
321 SharedPreferences
.Editor editor
= settings
.edit();
323 editor
.putInt("poll_time", poll
);
327 public synchronized boolean getSavedHwDebounce() {
328 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
330 return settings
.getBoolean("hw_debounce", false);
333 public synchronized void setSavedHwDebounce(boolean enable
) {
334 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
335 SharedPreferences
.Editor editor
= settings
.edit();
337 editor
.putBoolean("hw_debounce", enable
);
341 public synchronized int getSavedHwDebounceTime() {
342 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
344 return settings
.getInt("hw_debounce_time", 1);
347 public synchronized void setSavedHwDebounceTime(int time
) {
348 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
349 SharedPreferences
.Editor editor
= settings
.edit();
351 editor
.putInt("hw_debounce_time", time
);
355 public synchronized boolean getSavedDriveInactive() {
356 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
358 return settings
.getBoolean("drive_inactive", false);
361 public synchronized void setSavedDriveInactive(boolean enable
) {
362 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
363 SharedPreferences
.Editor editor
= settings
.edit();
365 editor
.putBoolean("drive_inactive", enable
);
369 public synchronized boolean getSavedActiveHigh() {
370 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
372 return settings
.getBoolean("active_high", false);
375 public synchronized void setSavedActiveHigh(boolean enable
) {
376 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
377 SharedPreferences
.Editor editor
= settings
.edit();
379 editor
.putBoolean("active_high", enable
);
383 public synchronized boolean is_safe_to_load() {
384 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
385 return settings
.getBoolean("safe_to_load", false);
388 public synchronized boolean get_on_boot() {
389 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
390 return settings
.getBoolean("on_boot", false);
393 public synchronized void set_on_boot(boolean on_boot
) {
394 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
395 SharedPreferences
.Editor editor
= settings
.edit();
397 editor
.putBoolean("on_boot", on_boot
);
401 private synchronized void extractModule() {
402 File debounce_ko
= new File(ctx
.getFilesDir() + "/debounce.ko");
404 if (debounce_ko
.exists()) {
409 InputStream apk
= ctx
.getAssets().open("debounce.ko");
410 OutputStream mod
= ctx
.openFileOutput("debounce.ko.tmp", 0);
412 //I assume a page is 4k...
413 byte buf
[] = new byte[4096];
416 while((bytes
= apk
.read(buf
)) != -1) {
417 mod
.write(buf
, 0, bytes
);
423 File tmpfile
= new File(debounce_ko
+ ".tmp");
424 tmpfile
.renameTo(debounce_ko
);
425 } catch (Exception e
) {}