diff --git a/.classpath b/.classpath
index 807316fa..5e3f5cca 100644
--- a/.classpath
+++ b/.classpath
@@ -1,10 +1,10 @@
-
+
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index efeaae1b..4f1898be 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -82,7 +82,7 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/notification_template_part_chronometer.xml b/res/layout/notification_template_part_chronometer.xml
new file mode 100644
index 00000000..14a4758a
--- /dev/null
+++ b/res/layout/notification_template_part_chronometer.xml
@@ -0,0 +1,25 @@
+
+
+
+
diff --git a/res/layout/notification_template_part_time.xml b/res/layout/notification_template_part_time.xml
new file mode 100644
index 00000000..e3b91fad
--- /dev/null
+++ b/res/layout/notification_template_part_time.xml
@@ -0,0 +1,25 @@
+
+
+
+
diff --git a/res/menu/main.xml b/res/menu/main.xml
old mode 100755
new mode 100644
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
new file mode 100644
index 00000000..f96195c8
--- /dev/null
+++ b/res/values/dimens.xml
@@ -0,0 +1,361 @@
+
+
+
+
+ 164dp
+
+ 145dp
+
+ 48dip
+
+ 2
+ 64dip
+
+ 25dip
+
+ 48dp
+
+ 48dp
+
+ 42dp
+
+ 24dip
+
+ 48sp
+
+ @dimen/navigation_bar_height
+
+ 32dip
+
+ 5dp
+
+
+ 104dp
+
+ 52sp
+
+ 16dp
+
+ 64dp
+
+ 52dp
+
+ 800dp
+
+
+ 56dip
+
+ 56dip
+
+ 4dip
+
+ 3dip
+
+ 9dip
+
+
+ 270dp
+
+
+ 135dip
+
+
+ 75dip
+
+
+ 40dip
+
+
+ 15dip
+
+
+ 0dp
+
+ 0dp
+
+ 0dp
+
+ 0dp
+
+ 48dp
+
+ 0dp
+
+ 16dp
+
+ 4
+
+ 6
+
+ 0dp
+
+ 0dp
+
+ 0dp
+
+ - 65%
+
+
+ - 320dp
+
+ - 320dp
+
+ - 80%
+
+ - 100%
+
+
+ 0dp
+
+ 16dip
+ 0x02000000
+
+ 0x02000000
+
+ 8dip
+ 8dip
+ 16dip
+
+
+ - 95%
+
+
+ 64dp
+
+ 64dp
+
+
+ 160dip
+
+
+ 320dip
+
+
+ 64dip
+
+ 48dip
+
+
+ 48dip
+
+ 8dip
+
+ 18dp
+
+ 14dp
+
+ -3dp
+
+ 5dip
+
+
+ 80dip
+
+
+ 14dip
+
+
+ 42dip
+
+
+ 22dip
+
+
+ 12dip
+
+
+ 40dip
+
+
+ 330dip
+
+
+ 200dip
+
+
+ 8dip
+
+
+ 8dip
+
+
+ 8dip
+
+
+ 32dip
+
+
+ 240dip
+
+
+ 80dp
+
+
+ 8dp
+ 8dp
+ 8dp
+ 8dp
+
+
+ 56dip
+
+
+ 48dp
+
+
+ 180dp
+
+
+ 14dp
+
+ 18dp
+
+ 12dp
+
+
+
+ 600dp
+
+
+ 480dp
+
+
+ 0dp
+
+
+ 0dp
+
+
+ 75dp
+
+
+ 15dp
+
+
+ 13dp
+
+
+ 16dp
+
+
+ -16dp
+
+
+ 0dp
+
+
+ 0dp
+
+
+ 60dp
+
+
+ 46dp
+
+
+ 7dp
+
+
+ 2dp
+
+
+ 16dp
+
+
+ 0dp
+
+
+ 64dp
+
+
+ 0dp
+
+
+ 80dip
+
+
+ 320dp
+
+
+ 400dp
+
+
+ 8dp
+
+
+ 8dp
+
+
+ 2dp
+
+
+ 1dp
+
+
+ 66dp
+
+
+ 10sp
+
+
+ 24dp
+
+
+ 600dp
+
+
+ 160dp
+
+
+ 2dp
+
+
+ 2dp
+
+
+ 2dp
+
+
+ 2dp
+
+
+ -1px
+
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 00000000..b3fe8af4
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/org/torproject/android/Orbot.java b/src/org/torproject/android/Orbot.java
index f55474c6..35d508e9 100644
--- a/src/org/torproject/android/Orbot.java
+++ b/src/org/torproject/android/Orbot.java
@@ -526,6 +526,7 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
}
+
private synchronized void handleIntents ()
{
if (getIntent() == null)
diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java
index a983812b..4d5bb6dd 100644
--- a/src/org/torproject/android/service/TorService.java
+++ b/src/org/torproject/android/service/TorService.java
@@ -23,6 +23,10 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.concurrent.TimeoutException;
import net.freehaven.tor.control.ConfigEntry;
@@ -39,6 +43,7 @@ import org.torproject.android.settings.AppManager;
import android.annotation.SuppressLint;
import android.app.Application;
+import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
@@ -59,7 +64,10 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
+import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
+import android.widget.RemoteViews;
+import android.widget.Toast;
public class TorService extends Service implements TorServiceConstants, TorConstants, EventHandler
{
@@ -80,6 +88,9 @@ public class TorService extends Service implements TorServiceConstants, TorConst
private static final int HS_NOTIFY_ID = 4;
private boolean prefPersistNotifications = true;
+ private String IPADDRESS_PATTERN =
+ "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
+ private long exitIPTime = 0;
private static final int MAX_START_TRIES = 3;
@@ -109,6 +120,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst
private NotificationManager mNotificationManager = null;
private Builder mNotifyBuilder;
+ private Notification mNotification;
+ private String exitIP = "";
private boolean mHasRoot = false;
private boolean mEnableTransparentProxy = false;
@@ -204,17 +217,28 @@ public class TorService extends Service implements TorServiceConstants, TorConst
mNotificationManager.cancelAll();
}
-
- private void showToolbarNotification (String notifyMsg, int notifyId, int icon, boolean isOngoing)
- {
-
+
+ @SuppressLint("NewApi")
+ private void showToolbarNotification (String notifyMsg, int notifyId, int icon, boolean isOngoing)
+ {
+
+ //Reusable code.
+ Intent intent = new Intent(TorService.this, Orbot.class);
+ PendingIntent pendIntent = PendingIntent.getActivity(TorService.this, 0, intent, 0);
+
+ // Create remote view that needs to be set as bigContentView for the notification.
+ RemoteViews expandedView = new RemoteViews(this.getPackageName(),
+ R.layout.layout_notification_expanded);
+
+ expandedView.setTextViewText(R.id.text, notifyMsg);
+ expandedView.setTextViewText(R.id.title, "ORBOT "+exitIP);
+ //expandedView.setTextViewText(R.id.exitIP, exitIP);
+ //expandedView.setOnClickPendingIntent(R.id._tor_notificationBT, pendIntent);
+ expandedView.setImageViewResource(R.id.icon, icon);
+
if (mNotifyBuilder == null)
{
- //Reusable code.
- Intent intent = new Intent(TorService.this, Orbot.class);
- PendingIntent pendIntent = PendingIntent.getActivity(TorService.this, 0, intent, 0);
-
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (mNotifyBuilder == null)
@@ -232,6 +256,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
mNotifyBuilder.setContentText(notifyMsg);
mNotifyBuilder.setSmallIcon(icon);
+
if (notifyId == ERROR_NOTIFY_ID)
{
mNotifyBuilder.setTicker(notifyMsg);
@@ -243,19 +268,19 @@ public class TorService extends Service implements TorServiceConstants, TorConst
mNotifyBuilder.setTicker(null); //make sure to clear ticker
}
+ mNotification = mNotifyBuilder.build();
+ mNotification.bigContentView = expandedView;
+
if (isOngoing)
{
- startForeground(notifyId,
- mNotifyBuilder.build());
+ startForeground(notifyId, mNotification);
}
else
{
- mNotificationManager.notify(
- notifyId,
- mNotifyBuilder.build());
+ mNotificationManager.notify(notifyId, mNotification);
}
-
+
}
@@ -1311,10 +1336,13 @@ public class TorService extends Service implements TorServiceConstants, TorConst
while (st.hasMoreTokens())
{
node = st.nextToken();
+ final String nodeName = parseNodeName(node);
+ sb.append(nodeName);
- sb.append(parseNodeName(node));
-
-
+ if(status.equals("BUILT") && currentStatus==STATUS_ON){
+ new getExternalIP().execute(nodeName);
+ }
+
if (st.hasMoreTokens())
sb.append (" > ");
}
@@ -1342,6 +1370,49 @@ public class TorService extends Service implements TorServiceConstants, TorConst
}
+ private class getExternalIP extends AsyncTask{
+
+ private long time;
+ private String nodeDetails;
+
+ @Override
+ protected Void doInBackground(String... params) {
+ time = System.nanoTime();
+ try {
+ nodeDetails = conn.getInfo("ns/name/"+params[0]);
+ if (ENABLE_DEBUG_LOG)
+ {
+ Log.d(TAG,"Node Details: "+nodeDetails);
+ sendCallbackLogMessage("Node Details: "+nodeDetails);
+
+ }
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ // check if we need to update the exit IP
+ if(time > exitIPTime) {
+ exitIPTime = time;
+
+ Pattern pattern = Pattern.compile(IPADDRESS_PATTERN);
+ Matcher matcher = null;
+ if(nodeDetails!=null){
+ matcher = pattern.matcher(nodeDetails);
+ if (matcher.find()) {
+ Log.d(TAG, "ip: "+matcher.group());
+ exitIP = matcher.group();
+ }
+ }
+ }
+ }
+
+ }
+
private String parseNodeName(String node)
{
if (node.indexOf('=')!=-1)
diff --git a/update-ant-build.sh b/update-ant-build.sh
old mode 100755
new mode 100644