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 Log
.i(TAG
, "Loading module");
88 Log
.i(TAG
, "Module already loaded");
92 File insmod
= new File("/system/bin/insmod");
93 if (!insmod
.exists()) {
94 insmod
= new File("/system/xbin/insmod");
95 if (!insmod
.exists()) {
96 Log
.e(TAG
, "insmod not found");
101 File debounce_ko
= new File("/system/lib/modules/debounce.ko");
102 if (!debounce_ko
.exists()) {
103 debounce_ko
= new File(ctx
.getFilesDir() + "/debounce.ko");
108 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
109 SharedPreferences
.Editor editor
= settings
.edit();
110 if (is_safe_to_load()) {
111 editor
.putBoolean("safe_to_load", false);
115 runAsRoot(insmod
+ " " + debounce_ko
);
118 while ((!isLoaded()) && (cnt
> 0)) {
121 } catch (Exception e
) {
122 Log
.e(TAG
, "Got Exception: " + e
.getMessage() + " (" + e
.getCause() + ")");
129 Log
.e(TAG
, "Module doesn't appear to be correctly loaded");
133 if (getDelay() < 0) {
137 /* Module was obviously loaded, so it is safe to load on boot */
138 editor
.putBoolean("safe_to_load", true);
141 Log
.i(TAG
, "Module loaded successfully");
145 public synchronized void unloadModule() throws NotRootedException
,ShellException
{
146 Log
.i(TAG
, "Unloading module");
149 Log
.i(TAG
, "Module not loaded");
153 File rmmod
= new File("/system/bin/rmmod");
155 if (!rmmod
.exists()) {
156 rmmod
= new File("/system/xbin/rmmod");
157 if (!rmmod
.exists()) {
158 Log
.e(TAG
, "rmmod not found");
163 runAsRoot(rmmod
+ " debounce");
166 public synchronized boolean isLoaded() {
167 boolean loaded
= false;
172 FileReader modules
= new FileReader("/proc/modules");
173 BufferedReader modules_buf
= new BufferedReader(modules
);
175 while((read
= modules_buf
.readLine()) != null) {
176 if (read
.regionMatches(0, "debounce", 0, 8)) {
177 File sysdir
= new File("/sys/devices/debounce");
178 if (sysdir
.exists() && sysdir
.isDirectory()) {
184 } catch (Exception e
) {
191 private synchronized int getValue(String parameter
) {
197 FileReader fr
= new FileReader("/sys/devices/debounce/" + parameter
);
198 BufferedReader fbuf
= new BufferedReader(fr
);
200 read
= fbuf
.readLine();
202 value
= Integer
.parseInt(read
.trim());
206 } catch (Exception e
) {}
211 private synchronized void setValue(String parameter
, int value
) {
217 FileWriter fw
= new FileWriter("/sys/devices/debounce/" + parameter
);
218 BufferedWriter fbuf
= new BufferedWriter(fw
);
220 fbuf
.write((new Integer(value
)).toString());
223 } catch (Exception e
) {}
226 public synchronized int getDelay() {
227 return getValue("debounce_delay");
230 public synchronized void setDelay(int debounce_delay
) {
231 setValue("debounce_delay", debounce_delay
);
234 public synchronized int getSettle() {
235 return getValue("settle_time");
238 public synchronized void setSettle(int settle_time
) {
239 setValue("settle_time", settle_time
);
242 public synchronized int getPoll() {
243 return getValue("poll_time");
246 public synchronized void setPoll(int poll_time
) {
247 setValue("poll_time", poll_time
);
250 public synchronized boolean getHwDebounce() {
251 if (getValue("hw_debounce") == 1)
257 public synchronized void setHwDebounce(boolean enable
) {
259 setValue("hw_debounce", 1);
261 setValue("hw_debounce", 0);
264 public synchronized int getHwDebounceTime() {
265 return getValue("hw_debounce_time");
268 public synchronized void setHwDebounceTime(int time
) {
269 setValue("hw_debounce_time", time
);
272 public synchronized boolean getDriveInactive() {
273 if (getValue("drive_inactive_flag") == 1)
279 public synchronized void setDriveInactive(boolean enable
) {
281 setValue("drive_inactive_flag", 1);
283 setValue("drive_inactive_flag", 0);
286 public synchronized boolean getActiveHigh() {
287 if (getValue("active_high_flag") == 1)
293 public synchronized void setActiveHigh(boolean enable
) {
295 setValue("active_high_flag", 1);
297 setValue("active_high_flag", 0);
300 public synchronized int getSavedDelay() {
301 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
303 return settings
.getInt("debounce_delay", 15);
306 public synchronized void setSavedDelay(int delay
) {
307 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
308 SharedPreferences
.Editor editor
= settings
.edit();
310 editor
.putInt("debounce_delay", delay
);
314 public synchronized int getSavedSettle() {
315 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
317 return settings
.getInt("settle_time", 40);
320 public synchronized void setSavedSettle(int settle
) {
321 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
322 SharedPreferences
.Editor editor
= settings
.edit();
324 editor
.putInt("settle_time", settle
);
328 public synchronized int getSavedPoll() {
329 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
331 return settings
.getInt("poll_time", 20);
334 public synchronized void setSavedPoll(int poll
) {
335 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
336 SharedPreferences
.Editor editor
= settings
.edit();
338 editor
.putInt("poll_time", poll
);
342 public synchronized boolean getSavedHwDebounce() {
343 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
345 return settings
.getBoolean("hw_debounce", false);
348 public synchronized void setSavedHwDebounce(boolean enable
) {
349 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
350 SharedPreferences
.Editor editor
= settings
.edit();
352 editor
.putBoolean("hw_debounce", enable
);
356 public synchronized int getSavedHwDebounceTime() {
357 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
359 return settings
.getInt("hw_debounce_time", 1);
362 public synchronized void setSavedHwDebounceTime(int time
) {
363 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
364 SharedPreferences
.Editor editor
= settings
.edit();
366 editor
.putInt("hw_debounce_time", time
);
370 public synchronized boolean getSavedDriveInactive() {
371 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
373 return settings
.getBoolean("drive_inactive", false);
376 public synchronized void setSavedDriveInactive(boolean enable
) {
377 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
378 SharedPreferences
.Editor editor
= settings
.edit();
380 editor
.putBoolean("drive_inactive", enable
);
384 public synchronized boolean getSavedActiveHigh() {
385 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
387 return settings
.getBoolean("active_high", false);
390 public synchronized void setSavedActiveHigh(boolean enable
) {
391 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
392 SharedPreferences
.Editor editor
= settings
.edit();
394 editor
.putBoolean("active_high", enable
);
398 public synchronized boolean is_safe_to_load() {
399 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
400 return settings
.getBoolean("safe_to_load", false);
403 public synchronized boolean get_on_boot() {
404 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
405 return settings
.getBoolean("on_boot", false);
408 public synchronized void set_on_boot(boolean on_boot
) {
409 SharedPreferences settings
= ctx
.getSharedPreferences(PREFS_NAME
, Context
.MODE_PRIVATE
);
410 SharedPreferences
.Editor editor
= settings
.edit();
412 editor
.putBoolean("on_boot", on_boot
);
416 private synchronized void extractModule() {
417 File debounce_ko
= new File(ctx
.getFilesDir() + "/debounce.ko");
419 if (debounce_ko
.exists()) {
424 InputStream apk
= ctx
.getAssets().open("debounce.ko");
425 OutputStream mod
= ctx
.openFileOutput("debounce.ko.tmp", 0);
427 //I assume a page is 4k...
428 byte buf
[] = new byte[4096];
431 while((bytes
= apk
.read(buf
)) != -1) {
432 mod
.write(buf
, 0, bytes
);
438 File tmpfile
= new File(debounce_ko
+ ".tmp");
439 tmpfile
.renameTo(debounce_ko
);
440 } catch (Exception e
) {}