Skip to content

Commit

Permalink
Improve CPU resources when ignoring blocked apps
Browse files Browse the repository at this point in the history
Use improved iptables rules to ignore logging for blocked apps.

Instead of logging all apps and having to parse each and every log message
to determine if a message belongs to a blocked app, we can now simply add
an iptables rule to not provide any log messages for blocked apps!

This means we no longer have to waste precious CPU/battery resources parsing
messages that we don't care about.
  • Loading branch information
pragma- committed Aug 2, 2015
1 parent d8654ef commit c0f924b
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 36 deletions.
7 changes: 7 additions & 0 deletions src/com/googlecode/networklog/AppFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,13 @@ public boolean onContextItemSelected(MenuItem item) {
groupItem = (GroupItem) adapter.getGroup(groupPos);
if(NetworkLogService.blockedApps.remove(groupItem.app.packageName) == null) {
NetworkLogService.blockedApps.put(groupItem.app.packageName, groupItem.app.packageName);
if (NetworkLogService.instance != null) {
Iptables.ignoreApp(NetworkLog.context, groupItem.app.uid);
}
} else {
if (NetworkLogService.instance != null) {
Iptables.unignoreApp(NetworkLog.context, groupItem.app.uid);
}
}
new SelectBlockedApps().saveBlockedApps(NetworkLog.context, NetworkLogService.blockedApps);
return true;
Expand Down
132 changes: 101 additions & 31 deletions src/com/googlecode/networklog/Iptables.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Iptables {
public static HashMap<String, String> targets = null;
Expand Down Expand Up @@ -65,31 +66,31 @@ public static boolean addRules(Context context) {
return false;
}

ArrayList<String> commands = new ArrayList<String>();

if(targets.get("LOG") != null) {
if(NetworkLogService.behindFirewall) {
commands.add(iptablesBinary + " -A OUTPUT ! -o lo -j LOG --log-prefix \"{NL}\" --log-uid");
commands.add(iptablesBinary + " -A INPUT ! -i lo -j LOG --log-prefix \"{NL}\" --log-uid");
} else {
commands.add(iptablesBinary + " -I OUTPUT 1 ! -o lo -j LOG --log-prefix \"{NL}\" --log-uid");
commands.add(iptablesBinary + " -I INPUT 1 ! -i lo -j LOG --log-prefix \"{NL}\" --log-uid");
}
} else if(targets.get("NFLOG") != null) {
if(NetworkLogService.behindFirewall) {
commands.add(iptablesBinary + " -A OUTPUT ! -o lo -j NFLOG --nflog-prefix \"{NL}\"");
commands.add(iptablesBinary + " -A INPUT ! -i lo -j NFLOG --nflog-prefix \"{NL}\"");
} else {
commands.add(iptablesBinary + " -I OUTPUT 1 ! -o lo -j NFLOG --nflog-prefix \"{NL}\"");
commands.add(iptablesBinary + " -I INPUT 1 ! -i lo -j NFLOG --nflog-prefix \"{NL}\"");
}
} else {
if (targets.get("LOG") == null && targets.get("NFLOG") == null) {
SysUtils.showError(context,
context.getResources().getString(R.string.iptables_error_unsupported_title),
context.getResources().getString(R.string.iptables_error_missingfeatures_text));
return false;
}

ArrayList<String> commands = new ArrayList<String>();

commands.add(iptablesBinary + " -N NetworkLog");

if(NetworkLogService.behindFirewall) {
commands.add(iptablesBinary + " -A OUTPUT ! -o lo -j NetworkLog");
commands.add(iptablesBinary + " -A INPUT ! -i lo -j NetworkLog");
} else {
commands.add(iptablesBinary + " -I OUTPUT ! -o lo -j NetworkLog");
commands.add(iptablesBinary + " -I INPUT ! -i lo -j NetworkLog");
}

if(targets.get("LOG") != null) {
commands.add(iptablesBinary + " -A NetworkLog -j LOG --log-prefix \"{NL}\" --log-uid");
} else if(targets.get("NFLOG") != null) {
commands.add(iptablesBinary + " -A NetworkLog -j NFLOG --nflog-prefix \"{NL}\"");
}

for(String command : commands) {
if(!NetworkLog.shell.sendCommand(command)) {
SysUtils.showError(context, context.getResources().getString(R.string.iptables_error_add_rules), NetworkLog.shell.getError(true));
Expand Down Expand Up @@ -123,6 +124,11 @@ public static boolean addRules(Context context) {
}
}

for (Map.Entry<String, String> entry : NetworkLogService.blockedApps.entrySet()) {
Integer appId = ApplicationsTracker.packageMap.get(entry.getValue()).uid;
ignoreApp(context, appId);
}

return true;
}

Expand All @@ -136,22 +142,22 @@ public static boolean removeRules(Context context) {
return false;
}

if (targets.get("LOG") == null && targets.get("NFLOG") == null) {
SysUtils.showError(context,
context.getResources().getString(R.string.iptables_error_unsupported_title),
context.getResources().getString(R.string.iptables_error_missingfeatures_text));
return false;
}

int tries = 0;

while(checkRules(context) == true) {
ArrayList<String> commands = new ArrayList<String>();
if(targets.get("LOG") != null) {
commands.add(iptablesBinary + " -D OUTPUT ! -o lo -j LOG --log-prefix \"{NL}\" --log-uid");
commands.add(iptablesBinary + " -D INPUT ! -i lo -j LOG --log-prefix \"{NL}\" --log-uid");
} else if(targets.get("NFLOG") != null) {
commands.add(iptablesBinary + " -D OUTPUT ! -o lo -j NFLOG --nflog-prefix \"{NL}\"");
commands.add(iptablesBinary + " -D INPUT ! -i lo -j NFLOG --nflog-prefix \"{NL}\"");
} else {
SysUtils.showError(context,
context.getResources().getString(R.string.iptables_error_unsupported_title),
context.getResources().getString(R.string.iptables_error_missingfeatures_text));
return false;
}

commands.add(iptablesBinary + " -D INPUT ! -i lo -j NetworkLog");
commands.add(iptablesBinary + " -D OUTPUT ! -o lo -j NetworkLog");
commands.add(iptablesBinary + " -F NetworkLog");
commands.add(iptablesBinary + " -X NetworkLog");

for(String command : commands) {
if(!NetworkLog.shell.sendCommand(command)) {
Expand Down Expand Up @@ -248,4 +254,68 @@ public static boolean checkRules(Context context) {

return rules.indexOf("{NL}", 0) == -1 ? false : true;
}

public static boolean ignoreApp(Context context, Integer appId) {
String iptablesBinary = SysUtils.getIptablesBinary(context);
if(iptablesBinary == null) {
return false;
}

if(!NetworkLog.shell.sendCommand(iptablesBinary + " -I NetworkLog -m owner --uid-owner " + appId + " -j RETURN")) {
SysUtils.showError(context, context.getResources().getString(R.string.iptables_error_add_rules), NetworkLog.shell.getError(true));
return false;
}

List<String> output = new ArrayList<String>();
NetworkLog.shell.waitForCommandExit(output);

StringBuilder result = new StringBuilder();
for(String line : output) {
result.append(line);
}

if(MyLog.enabled) {
MyLog.d("ignoreApp result: [" + result + "]");
}

if(NetworkLog.shell.exitval != 0) {
Log.e("NetworkLog", "Bad exit for ignoreApp (exit " + NetworkLog.shell.exitval + ")");
SysUtils.showError(context, context.getResources().getString(R.string.iptables_error_add_rules), result.toString());
return false;
}

return true;
}

public static boolean unignoreApp(Context context, Integer appId) {
String iptablesBinary = SysUtils.getIptablesBinary(context);
if(iptablesBinary == null) {
return false;
}

if(!NetworkLog.shell.sendCommand(iptablesBinary + " -D NetworkLog -m owner --uid-owner " + appId + " -j RETURN")) {
SysUtils.showError(context, context.getResources().getString(R.string.iptables_error_add_rules), NetworkLog.shell.getError(true));
return false;
}

List<String> output = new ArrayList<String>();
NetworkLog.shell.waitForCommandExit(output);

StringBuilder result = new StringBuilder();
for(String line : output) {
result.append(line);
}

if(MyLog.enabled) {
MyLog.d("unignoreApp result: [" + result + "]");
}

if(NetworkLog.shell.exitval != 0) {
Log.e("NetworkLog", "Bad exit for unignoreApp (exit " + NetworkLog.shell.exitval + ")");
SysUtils.showError(context, context.getResources().getString(R.string.iptables_error_add_rules), result.toString());
return false;
}

return true;
}
}
7 changes: 7 additions & 0 deletions src/com/googlecode/networklog/LogFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ public boolean onContextItemSelected(MenuItem item) {
case R.id.log_toggle_app_logging:
if(NetworkLogService.blockedApps.remove(listItem.app.packageName) == null) {
NetworkLogService.blockedApps.put(listItem.app.packageName, listItem.app.packageName);
if (NetworkLogService.instance != null) {
Iptables.ignoreApp(NetworkLog.context, listItem.app.uid);
}
} else {
if (NetworkLogService.instance != null) {
Iptables.unignoreApp(NetworkLog.context, listItem.app.uid);
}
}
new SelectBlockedApps().saveBlockedApps(NetworkLog.context, NetworkLogService.blockedApps);
return true;
Expand Down
5 changes: 0 additions & 5 deletions src/com/googlecode/networklog/NetworkLogService.java
Original file line number Diff line number Diff line change
Expand Up @@ -794,11 +794,6 @@ public void parseResult(String result) {
public void notifyNewEntry(LogEntry entry) {
appEntry = ApplicationsTracker.uidMap.get(entry.uidString);

// check if logging is disabled for this entry's app
if(appEntry != null && blockedApps.get(appEntry.packageName) != null) {
return;
}

// check if logfile needs to be opened and that external storage is available
if(logWriter == null) {
if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
Expand Down

0 comments on commit c0f924b

Please sign in to comment.