diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..850c225 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +EasyHarvestClient \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..8d2df47 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/libraries/android_maps_utils_0_4.xml b/.idea/libraries/android_maps_utils_0_4.xml new file mode 100644 index 0000000..6ccf4da --- /dev/null +++ b/.idea/libraries/android_maps_utils_0_4.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/appcompat_v7_22_2_0.xml b/.idea/libraries/appcompat_v7_22_2_0.xml new file mode 100644 index 0000000..a5fde93 --- /dev/null +++ b/.idea/libraries/appcompat_v7_22_2_0.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/commons_io_2_4.xml b/.idea/libraries/commons_io_2_4.xml new file mode 100644 index 0000000..ba1046b --- /dev/null +++ b/.idea/libraries/commons_io_2_4.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/httpclient_4_2_5.xml b/.idea/libraries/httpclient_4_2_5.xml new file mode 100644 index 0000000..ddbc48c --- /dev/null +++ b/.idea/libraries/httpclient_4_2_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/httpcore_4_2_4.xml b/.idea/libraries/httpcore_4_2_4.xml new file mode 100644 index 0000000..3b0b21e --- /dev/null +++ b/.idea/libraries/httpcore_4_2_4.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/mediarouter_v7_22_2_0.xml b/.idea/libraries/mediarouter_v7_22_2_0.xml new file mode 100644 index 0000000..84adef2 --- /dev/null +++ b/.idea/libraries/mediarouter_v7_22_2_0.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_7_8_0.xml b/.idea/libraries/play_services_7_8_0.xml new file mode 100644 index 0000000..bb1a7b1 --- /dev/null +++ b/.idea/libraries/play_services_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_ads_7_8_0.xml b/.idea/libraries/play_services_ads_7_8_0.xml new file mode 100644 index 0000000..26d47d3 --- /dev/null +++ b/.idea/libraries/play_services_ads_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_analytics_7_8_0.xml b/.idea/libraries/play_services_analytics_7_8_0.xml new file mode 100644 index 0000000..4f4cfe8 --- /dev/null +++ b/.idea/libraries/play_services_analytics_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_appindexing_7_8_0.xml b/.idea/libraries/play_services_appindexing_7_8_0.xml new file mode 100644 index 0000000..adea0d0 --- /dev/null +++ b/.idea/libraries/play_services_appindexing_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_appinvite_7_8_0.xml b/.idea/libraries/play_services_appinvite_7_8_0.xml new file mode 100644 index 0000000..ae944eb --- /dev/null +++ b/.idea/libraries/play_services_appinvite_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_appstate_7_8_0.xml b/.idea/libraries/play_services_appstate_7_8_0.xml new file mode 100644 index 0000000..2d7db4a --- /dev/null +++ b/.idea/libraries/play_services_appstate_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_base_7_8_0.xml b/.idea/libraries/play_services_base_7_8_0.xml new file mode 100644 index 0000000..cf656b9 --- /dev/null +++ b/.idea/libraries/play_services_base_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_cast_7_8_0.xml b/.idea/libraries/play_services_cast_7_8_0.xml new file mode 100644 index 0000000..1d9b7d7 --- /dev/null +++ b/.idea/libraries/play_services_cast_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_drive_7_8_0.xml b/.idea/libraries/play_services_drive_7_8_0.xml new file mode 100644 index 0000000..623a825 --- /dev/null +++ b/.idea/libraries/play_services_drive_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_fitness_7_8_0.xml b/.idea/libraries/play_services_fitness_7_8_0.xml new file mode 100644 index 0000000..db94fc0 --- /dev/null +++ b/.idea/libraries/play_services_fitness_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_games_7_8_0.xml b/.idea/libraries/play_services_games_7_8_0.xml new file mode 100644 index 0000000..931cf9c --- /dev/null +++ b/.idea/libraries/play_services_games_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_gcm_7_8_0.xml b/.idea/libraries/play_services_gcm_7_8_0.xml new file mode 100644 index 0000000..108d107 --- /dev/null +++ b/.idea/libraries/play_services_gcm_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_identity_7_8_0.xml b/.idea/libraries/play_services_identity_7_8_0.xml new file mode 100644 index 0000000..6f6e54f --- /dev/null +++ b/.idea/libraries/play_services_identity_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_location_7_8_0.xml b/.idea/libraries/play_services_location_7_8_0.xml new file mode 100644 index 0000000..393b971 --- /dev/null +++ b/.idea/libraries/play_services_location_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_maps_7_8_0.xml b/.idea/libraries/play_services_maps_7_8_0.xml new file mode 100644 index 0000000..8c0e03b --- /dev/null +++ b/.idea/libraries/play_services_maps_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_nearby_7_8_0.xml b/.idea/libraries/play_services_nearby_7_8_0.xml new file mode 100644 index 0000000..d1f10b5 --- /dev/null +++ b/.idea/libraries/play_services_nearby_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_panorama_7_8_0.xml b/.idea/libraries/play_services_panorama_7_8_0.xml new file mode 100644 index 0000000..0778f52 --- /dev/null +++ b/.idea/libraries/play_services_panorama_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_plus_7_8_0.xml b/.idea/libraries/play_services_plus_7_8_0.xml new file mode 100644 index 0000000..0731dbe --- /dev/null +++ b/.idea/libraries/play_services_plus_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_safetynet_7_8_0.xml b/.idea/libraries/play_services_safetynet_7_8_0.xml new file mode 100644 index 0000000..637a600 --- /dev/null +++ b/.idea/libraries/play_services_safetynet_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_vision_7_8_0.xml b/.idea/libraries/play_services_vision_7_8_0.xml new file mode 100644 index 0000000..5cfb83b --- /dev/null +++ b/.idea/libraries/play_services_vision_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_wallet_7_8_0.xml b/.idea/libraries/play_services_wallet_7_8_0.xml new file mode 100644 index 0000000..2785146 --- /dev/null +++ b/.idea/libraries/play_services_wallet_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/play_services_wearable_7_8_0.xml b/.idea/libraries/play_services_wearable_7_8_0.xml new file mode 100644 index 0000000..40469df --- /dev/null +++ b/.idea/libraries/play_services_wearable_7_8_0.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/support_annotations_23_0_1.xml b/.idea/libraries/support_annotations_23_0_1.xml new file mode 100644 index 0000000..7259927 --- /dev/null +++ b/.idea/libraries/support_annotations_23_0_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/support_v4_23_0_1.xml b/.idea/libraries/support_v4_23_0_1.xml new file mode 100644 index 0000000..a353a01 --- /dev/null +++ b/.idea/libraries/support_v4_23_0_1.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7158618 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.8 + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..b4cef19 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..6564d52 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..7a4fcca --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,2124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1446078239845 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/EasyHarvestClient.iml b/EasyHarvestClient.iml new file mode 100644 index 0000000..28fb13a --- /dev/null +++ b/EasyHarvestClient.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/app.iml b/app/app.iml new file mode 100644 index 0000000..361318d --- /dev/null +++ b/app/app.iml @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..f1a76c5 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,33 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" + + defaultConfig { + applicationId "com.www.client" + minSdkVersion 16 + targetSdkVersion 23 + } + + buildTypes { + release { + minifyEnabled false + debuggable true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } + + packagingOptions { + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + } +} + +dependencies { + compile 'com.android.support:support-v4:+' + compile 'com.google.maps.android:android-maps-utils:+' + compile 'com.google.android.gms:play-services:+' + + compile fileTree(dir: 'libs', include: '*.jar') +} diff --git a/app/libs/commons-io-2.4.jar b/app/libs/commons-io-2.4.jar new file mode 100644 index 0000000..90035a4 Binary files /dev/null and b/app/libs/commons-io-2.4.jar differ diff --git a/app/libs/httpclient-4.2.5.jar b/app/libs/httpclient-4.2.5.jar new file mode 100644 index 0000000..5310588 Binary files /dev/null and b/app/libs/httpclient-4.2.5.jar differ diff --git a/app/libs/httpcore-4.2.4.jar b/app/libs/httpcore-4.2.4.jar new file mode 100644 index 0000000..9f45bd9 Binary files /dev/null and b/app/libs/httpcore-4.2.4.jar differ diff --git a/app/lint.xml b/app/lint.xml new file mode 100644 index 0000000..ee0eead --- /dev/null +++ b/app/lint.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..cac5ea8 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png new file mode 100644 index 0000000..070bb17 Binary files /dev/null and b/app/src/main/ic_launcher-web.png differ diff --git a/app/src/main/java/com/www/client/AppendingObjectOutputStream.java b/app/src/main/java/com/www/client/AppendingObjectOutputStream.java new file mode 100644 index 0000000..308a7ec --- /dev/null +++ b/app/src/main/java/com/www/client/AppendingObjectOutputStream.java @@ -0,0 +1,18 @@ +package com.www.client; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +public class AppendingObjectOutputStream extends ObjectOutputStream { + + public AppendingObjectOutputStream(OutputStream out) throws IOException { + super(out); + } + + @Override + protected void writeStreamHeader() throws IOException { + reset(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/www/client/BootReceiver.java b/app/src/main/java/com/www/client/BootReceiver.java new file mode 100644 index 0000000..b730646 --- /dev/null +++ b/app/src/main/java/com/www/client/BootReceiver.java @@ -0,0 +1,21 @@ +package com.www.client; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +public class BootReceiver extends BroadcastReceiver { + private static final String TAG = "BootReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + Log.i(TAG, "onReceive: " + "..."); + if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { + //context.startService(new Intent(context, TaskService.class)); + context.startService(new Intent(context, TaskService.class)); + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/www/client/ClientActivity.java b/app/src/main/java/com/www/client/ClientActivity.java new file mode 100644 index 0000000..1cb655f --- /dev/null +++ b/app/src/main/java/com/www/client/ClientActivity.java @@ -0,0 +1,329 @@ +package com.www.client; + +import android.app.Activity; +import android.app.ActivityManager; +import android.app.ActivityManager.RunningServiceInfo; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.graphics.Color; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Bundle; +import android.os.Environment; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.www.client.pm.EasyPrivacy; +import com.www.client.pm.PrivacyMechanism; + +import java.io.File; +import java.io.IOException; + +public class ClientActivity extends Activity implements SeekBar.OnSeekBarChangeListener { + private static final String SDCARD_DIR = Environment.getExternalStorageDirectory().getPath(); + public static final String CLIENT_DIR = SDCARD_DIR + "/Client"; + private static Context context; + private static ConnectivityManager connectivityManager; + public static boolean restartService = false; + SeekBar seekBar; + TextView statusText; + TextView levelText; + TextView commentText; + public static SharedPreferences sharedPref = null; + public static SharedPreferences.Editor editor = null; + + PrivacyMechanism pm; + + @Override + protected void onCreate(Bundle savedInstanceState) { + String TAG = getClass().getName() + "@onCreate: "; + + super.onCreate(savedInstanceState); + + Log.wtf(TAG, "..."); + + setContentView(R.layout.activity_client); + ClientActivity.context = getApplicationContext(); + connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + editor = sharedPref.edit(); + seekBar = (SeekBar) findViewById(R.id.levelService); + seekBar.setOnSeekBarChangeListener(this); + statusText = (TextView) findViewById(R.id.status); + levelText = (TextView) findViewById(R.id.level); + commentText = (TextView) findViewById(R.id.comment); + Button ok = (Button) findViewById(R.id.okButton); + Button cancel = (Button) findViewById(R.id.cancelButton); + ok.setOnClickListener(okListener); + cancel.setOnClickListener(cancelListener); + } + + @Override + protected void onStart() { + String TAG = getClass().getName() + "@onStart: "; + + super.onStart(); + Log.wtf(TAG, "onStart: " + "..."); + + if (sharedPref.getString("username", null) == null) { + mkdirs(); + editor.putInt("serviceLevel", 0); + editor.commit(); + statusText.setTextColor(Color.rgb(255, 0, 0)); + statusText.setText("OFF"); + commentText.setTextColor(Color.rgb(100, 100, 100)); + commentText.setText("Slide the bar right to turn the service on & set the desired level of activity..."); + } else { + seekBar.setProgress(sharedPref.getInt("serviceLevel", 0)); + seekBar.setSecondaryProgress(sharedPref.getInt("serviceLevel", 0)); + if (sharedPref.getInt("serviceLevel", 0) > 0) { + statusText.setTextColor(Color.rgb(0, 255, 0)); + statusText.setText("ON"); + commentText.setTextColor(Color.rgb(255, 255, 255)); + commentText.setText("The service will download tasks from the server, execute them & send the results back."); + if (!isServiceRunning()) { + Log.wtf(TAG, "onStart: Restarting..."); + startService(new Intent(ClientActivity.this, TaskService.class)); + } + } else { + statusText.setTextColor(Color.rgb(255, 0, 0)); + statusText.setText("OFF"); + commentText.setTextColor(Color.rgb(100, 100, 100)); + commentText.setText("Nothing to do."); + } + } + + /* + * Do not comment out! + */ + onTest(); + + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + onResume(); + } + + private void onTest() { + String TAG = getClass().getName() + "@onTest: "; + + editor.putString("username", "emkatsom"); + +// editor.putString("taskID", "1"); + + /**/ +// editor.putBoolean(Globals.easy_privacy, false); + editor.putBoolean(Globals.easy_privacy, true); + +// editor.putString("deviceID", "1234"); +// +// editor.putString(Globals.pm_id, "13"); +// editor.putInt(Globals.privacy_level, 24); + /**/ + + editor.commit(); + +// startActivity(new Intent(getBaseContext(), SettingsActivity.class)); + +// startActivity(new Intent(getBaseContext(), PrivacyRegionsActivity.class)); +// startActivity(new Intent(getBaseContext(), AddPrivacyRegionActivity.class)); + +// startActivity(new Intent(getBaseContext(), com.www.client.pm.PrivacyMechanismsActivity.class)); +// startActivity(new Intent(getBaseContext(), com.www.client.pm.ListPrivacyMechanismsActivity.class)); + + } + + private OnClickListener okListener = new OnClickListener() { + public void onClick(View v) { + /**/ + if (seekBar.getProgress() > 0 && sharedPref.getInt("serviceLevel", 0) == 0) { + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putInt("serviceLevel", seekBar.getProgress()); + editor.commit(); + seekBar.setSecondaryProgress(seekBar.getProgress()); + enableBootReceiver(); + startService(new Intent(ClientActivity.this, TaskService.class)); + } else if (seekBar.getProgress() == 0) { + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putInt("serviceLevel", seekBar.getProgress()); + editor.commit(); + seekBar.setSecondaryProgress(seekBar.getProgress()); + disableBootReceiver(); + stopService(new Intent(ClientActivity.this, TaskService.class)); + } else { + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putInt("serviceLevel", seekBar.getProgress()); + editor.commit(); + seekBar.setSecondaryProgress(seekBar.getProgress()); + } + /**/ + + /* + if(pm != null) { +// pm.onStart(); + } else { + pm = new PrivacyMechanism( + getApplicationContext(), + Integer.valueOf(sharedPref.getString(Globals.pm_id, "0")), + Integer.valueOf(sharedPref.getString(Globals.st_id, "0"))); +// pm.onStart(); + } + /**/ + } + }; + + private OnClickListener cancelListener = new OnClickListener() { + public void onClick(View v) { + seekBar.setProgress(sharedPref.getInt("serviceLevel", 0)); + seekBar.setSecondaryProgress(sharedPref.getInt("serviceLevel", 0)); + levelText.setText(null); + + /* + if(pm != null) { + pm.onStop(); + pm = null; + } + /**/ + } + }; + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.activity_client, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_settings: + Intent i = new Intent(this, SettingsActivity.class); + startActivity(i); + return true; + default: + return super.onOptionsItemSelected(item); + } + + } + + @Override + public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) { + int c = (int) (100 + arg0.getProgress() * 1.55); + levelText.setTextColor(Color.rgb(c, c, c)); + levelText.setText(arg0.getProgress() + "%"); + if (arg1 == 0) { + statusText.setTextColor(Color.rgb(255, 0, 0)); + statusText.setText("OFF"); + commentText.setTextColor(Color.rgb(100, 100, 100)); + commentText.setText("Nothing to do."); + } else { + statusText.setTextColor(Color.rgb(0, 255, 0)); + statusText.setText("ON"); + commentText.setTextColor(Color.rgb(255, 255, 255)); + commentText.setText("The service will download tasks from the server, execute them & send the results back."); + } + } + + @Override + public void onStartTrackingTouch(SeekBar arg0) { + int c = (int) (100 + arg0.getProgress() * 1.55); + levelText.setTextColor(Color.rgb(c, c, c)); + levelText.setText(arg0.getProgress() + "%"); + } + + @Override + public void onStopTrackingTouch(SeekBar arg0) { + levelText.setText(null); + } + + private void enableBootReceiver() { + ComponentName receiver = new ComponentName(context, BootReceiver.class); + PackageManager pm = context.getPackageManager(); + pm.setComponentEnabledSetting(receiver, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + } + + private void disableBootReceiver() { + ComponentName receiver = new ComponentName(context, BootReceiver.class); + PackageManager pm = context.getPackageManager(); + pm.setComponentEnabledSetting(receiver, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + } + + public static Context getContext() { + return ClientActivity.context; + } + + public static boolean isOnline() { + Boolean wifiConnected, mobileConnected; + NetworkInfo activeInfo = connectivityManager.getActiveNetworkInfo(); + if (activeInfo != null && activeInfo.isConnected()) { + wifiConnected = activeInfo.getType() == ConnectivityManager.TYPE_WIFI; + mobileConnected = activeInfo.getType() == ConnectivityManager.TYPE_MOBILE; + } else { + wifiConnected = false; + mobileConnected = false; + } + if (((ClientActivity.sharedPref.getString("listPref", "Wi-Fi").equals("Any")) && (wifiConnected || mobileConnected)) + || ((ClientActivity.sharedPref.getString("listPref", "Wi-Fi").equals("Wi-Fi")) && (wifiConnected))) { + return true; + } else { + return false; + } + } + + private boolean isServiceRunning() { + ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + if (TaskService.class.getName().equals(service.service.getClassName())) { + return true; + } + } + return false; + } + + private void mkdirs() { + String TAG = getClass().getName() + "@mkdirs: "; + + File clientDir = new File(CLIENT_DIR); + File settingsDir = new File(CLIENT_DIR + "/Settings"); + File pmsDir = new File(CLIENT_DIR + "/PMs"); + + Utils.delete(clientDir); + Utils.delete(settingsDir); + Utils.delete(pmsDir); + + if(clientDir.mkdir()) { + Log.wtf(TAG, "Created " + clientDir.getPath()); + } else { + Log.wtf(TAG, "Could not create Client directory."); + } + + if(settingsDir.mkdir()) { + Log.wtf(TAG, "Created " + settingsDir.getPath()); + } else { + Log.wtf(TAG, "Could not create Settings directory."); + } + + if(pmsDir.mkdir()) { + Log.wtf(TAG, "Created " + pmsDir.getPath()); + } else { + Log.wtf(TAG, "Could not create PMs directory."); + } + } +} diff --git a/app/src/main/java/com/www/client/Globals.java b/app/src/main/java/com/www/client/Globals.java new file mode 100644 index 0000000..ed394e8 --- /dev/null +++ b/app/src/main/java/com/www/client/Globals.java @@ -0,0 +1,82 @@ +package com.www.client; + +import android.os.Environment; + +public class Globals { + /** + * Evaluation + */ +// public static boolean eval_status = true; + public static boolean eval_status = false; + + // Beauty +// public static String eval_dev = "MID7188"; +// public static String eval_ip = "192.168.49.1"; + + // Nexus +// public static String eval_dev = "occam"; +// public static String eval_ip = "192.168.49.75"; + + /** + * Description: device URLS. + * Changelog : - . + */ + public static String sdcard_dir = Environment.getExternalStorageDirectory().getPath(); + public static String client_dir = sdcard_dir + "/Client"; + public static String pms_dir = client_dir + "/PMs"; + + /** + * Description: URLS. + * Changelog : - . + */ + public static String server_url = "http://83.212.109.118:8080/Server/webresources"; +// public static String server_url = "http://192.168.2.2:8084/Server/webresources"; +// public static String server_url = "http://10.64.83.194:8084/Server/webresources"; + + public static String devs_url = server_url + "/devs"; + public static String tasks_url = server_url + "/tasks"; + + public static String pms_url = server_url + "/pms"; + public static int pm_port = 4545; + + /** + * Description: Time latency in ms. + * Changelog : - . + */ + public static int task_latency = 10 * 100 * 1000; + public static int pm_latency = 1 * 100 * 1000; + + /** + * Description: EasyHarvest client shared preferences labels. + * Changelog : - . + */ + public static String shr_user = "username"; // string + public static String shr_dev_id = "deviceID"; // string + + /** + * Description: Sensing tasks shared preferences labels. + * Changelog : - . + */ + public static String st_id = "taskID"; // string + + + /** + * Description: Privacy mechanisms shared preferences labels. + * Changelog : - . + */ + public static String easy_privacy = "EasyPrivacy"; // boolean + + public static String privacy_level = "privacyLevel"; // integer + + public static String pm_name = "pmName"; // string + public static String pm_clss = "pmClss"; // + public static String pm_id = "pmID"; // + public static String pm_vers = "pmVersion"; // + public static String pm_st_id = "pmTaskId"; // + public static String pm_user = "pmUser"; // + public static String pm_desc = "pmDescription"; // + public static String pm_date = "pmDate"; // + public static String pm_time = "pmTime"; // + public static String pm_size = "pmSize"; // + +} diff --git a/app/src/main/java/com/www/client/Item.java b/app/src/main/java/com/www/client/Item.java new file mode 100644 index 0000000..848c25e --- /dev/null +++ b/app/src/main/java/com/www/client/Item.java @@ -0,0 +1,36 @@ +package com.www.client; + +public class Item { + String text = ""; + int image = 0; + + public Item(String text, int image) { + this.text = text; + this.image = image; + } + + public Item(String text) { + this.text = text; + } + + public int getImage() { + return image; + } + + public void setImage(int image) { + this.image = image; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public String toString() { + return text; + } +} diff --git a/app/src/main/java/com/www/client/ItemArrayAdapter.java b/app/src/main/java/com/www/client/ItemArrayAdapter.java new file mode 100644 index 0000000..72188a1 --- /dev/null +++ b/app/src/main/java/com/www/client/ItemArrayAdapter.java @@ -0,0 +1,56 @@ +package com.www.client; + +import android.app.Activity; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; + +public class ItemArrayAdapter extends ArrayAdapter { + + private static final String TAG = "ItemArrayAdapter"; + Context context; + + public ItemArrayAdapter(Context context, int resourceId, List items) { + super(context, resourceId, items); + this.context = context; + } + + /*private view holder class*/ + private class ViewHolder { + TextView textView; + ImageView imageView; + } + + public View getView(int position, View view, ViewGroup group) { + ViewHolder holder = null; + JSONObject item = getItem(position); + + LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); + if (view == null) { + view = inflater.inflate(R.layout.item, null); + holder = new ViewHolder(); + holder.textView = (TextView) view.findViewById(R.id.text); + view.setTag(holder); + } + else { + holder = (ViewHolder) view.getTag(); + } + + try { + holder.textView.setText(item.getString("label")); + } catch (JSONException e) { + e.printStackTrace(); + } + + return view; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/www/client/SettingsActivity.java b/app/src/main/java/com/www/client/SettingsActivity.java new file mode 100644 index 0000000..6992c7d --- /dev/null +++ b/app/src/main/java/com/www/client/SettingsActivity.java @@ -0,0 +1,244 @@ +package com.www.client; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningServiceInfo; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceActivity; +import android.preference.PreferenceManager; +import android.preference.PreferenceScreen; +import android.util.Log; +import android.widget.Toast; + +import com.www.client.pm.PrivacyMechanismsActivity; +import com.www.client.pr.PrivacyRegionsActivity; + +import org.apache.commons.io.FileUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; + +import java.io.File; +import java.io.IOException; + +public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener, OnPreferenceClickListener, Preference.OnPreferenceChangeListener { + private static final String TAG = "SettingsActivity"; + + public static PreferenceScreen prefScreen = null; + public static SharedPreferences sp = null; + public static SharedPreferences.Editor spEditor = null; + + SwitchPref privacyRegions = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + //Log.wtf(TAG, "onCreate"); + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.preferences); + + /* + * Privacy regions switch listener. + */ + privacyRegions = (SwitchPref) findPreference(getResources().getString((R.string.privacy_regions_status))); + privacyRegions.setOnPreferenceClickListener(this); + privacyRegions.setOnPreferenceChangeListener(this); + + /* + * Set preference item listeners. + */ + findPreference(getResources().getString((R.string.privacy_mechanisms_key))).setOnPreferenceClickListener(this); + + findPreference("device_unregister").setOnPreferenceClickListener(this); + + } + + @Override + protected void onResume() { + //Log.wtf(TAG, "onResume"); + super.onResume(); + if (sp == null) { + //Log.wtf(TAG, "onResume: " + "sp == null"); + sp = PreferenceManager.getDefaultSharedPreferences(this); + spEditor = sp.edit(); + sp.registerOnSharedPreferenceChangeListener(this); + } else { + //Log.wtf(TAG, "onResume: " + "sp != null"); + } + privacyRegions.setChecked(sp.getBoolean(getResources().getString((R.string.privacy_regions_status)), false)); + //this.onContentChanged(); + } + + @Override + protected void onPause() { + //Log.wtf(TAG, "onPause"); + super.onPause(); + if (sp != null) { + sp.unregisterOnSharedPreferenceChangeListener(this); + sp = null; + } + }/**/ + + @Override + protected void onStop() { + //Log.wtf(TAG, "onStop"); + super.onStop(); + if (sp != null) { + sp.unregisterOnSharedPreferenceChangeListener(this); + sp = null; + } + //finish(); + }/**/ + + /*@Override + protected void onDestroy() { + Log.wtf(TAG, "onDestroy"); + super.onDestroy(); + sp.unregisterOnSharedPreferenceChangeListener(this); + sp = null; + }/**/ + + /*@Override + public void onConfigurationChanged(Configuration newConfig) { + Log.wtf(TAG, "onConfigurationChanged"); + super.onConfigurationChanged(newConfig); + //onResume(); + }*/ + + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { +// Toast.makeText(getApplicationContext(), "onSharedPreferenceChanged: " + key, Toast.LENGTH_SHORT).show(); + Log.wtf(TAG, "onSharedPreferenceChanged: " + sharedPreferences.getAll()); + if (key.equals("listPref") || key.equals(getResources().getString((R.string.privacy_regions_status)))) { +// ClientActivity.restartService = true; + Toast.makeText(getApplicationContext(), "Restarting...", Toast.LENGTH_SHORT).show(); + if (isServiceRunning()) { + Log.wtf(TAG, "onSharedPreferenceChanged: " + "Restarting service..."); + stopService(new Intent(this, TaskService.class)); + startService(new Intent(this, TaskService.class)); + } + } + } + + /* + * Control action when a preference is clicked. + */ + @Override + public boolean onPreferenceClick(Preference preference) { +// Toast.makeText(getApplicationContext(), "onPreferenceClick: " + preference.getKey(), Toast.LENGTH_SHORT).show(); + + /* + * Launch Privacy Regions activity. + */ + if (getResources().getString((R.string.privacy_regions_status)).equals(preference.getKey())) { +// Toast.makeText(ClientActivity.getContext(), "onPreferenceClick: " + preference.getKey(), Toast.LENGTH_SHORT).show(); + Intent i = new Intent(this, PrivacyRegionsActivity.class); + startActivity(i); + } + + /* + * Launch Privacy Mechanisms activity. + */ + if (getResources().getString((R.string.privacy_mechanisms_key)).equals(preference.getKey())) { +// Toast.makeText(ClientActivity.getContext(), "onPreferenceClick: " + preference.getKey(), Toast.LENGTH_SHORT).show(); + Intent i = new Intent(this, PrivacyMechanismsActivity.class); + startActivity(i); + } + + /* + * Unregister the device. + */ + if ("device_unregister".equals(preference.getKey())) { + Toast.makeText(ClientActivity.getContext(), "Unregistering...", Toast.LENGTH_SHORT).show(); + String deviceID = ClientActivity.sharedPref.getString("deviceID", null); + if (deviceID != null) { + if (ClientActivity.isOnline()) { + Log.wtf(TAG, "deviceUnregister: " + "Online."); + String url = Globals.devs_url + "/" + deviceID + "/unregister"; + Log.wtf(TAG, "deviceUnregister: " + "" + deviceID + "/unregister"); + new DeviceUnregister().execute(url); + } else { + Log.wtf(TAG, "deviceUnregister: " + "Offline."); + Toast.makeText(ClientActivity.getContext(), "No internet connection", Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(ClientActivity.getContext(), "Not registered", Toast.LENGTH_SHORT).show(); + } + + } + return false; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object o) { + //Toast.makeText(getApplicationContext(), "onPreferenceChange: " + preference.getKey(), Toast.LENGTH_SHORT).show(); + if ("privacyRegionsStatus".equals(preference.getKey())) { + //Toast.makeText(getApplicationContext(), "onPreferenceChange: " + preference.getKey() + " = " + o.toString(), Toast.LENGTH_SHORT).show(); + } + return true; + } + + private class DeviceUnregister extends AsyncTask { + private static final String TAG = "DeviceUnregister"; + private HttpClient client; + + @Override + protected String doInBackground(String... urls) { + Log.wtf(TAG, "doInBackground: " + "..."); + client = new DefaultHttpClient(); + HttpGet request = new HttpGet(urls[0]); + HttpResponse response = null; + String result = "oops"; + try { + response = client.execute(request); + } catch (Exception e) { + //e.printStackTrace(); + } + if (response != null) { + try { + result = Utils.writeToString(response.getEntity().getContent()); + } catch (Exception e) { + } + } + return result; + } + + protected void onPostExecute(String result) { + Log.wtf(TAG, "onPostExecute: " + result + "."); + if (result.equals("OK") || result.equals("Not registered")) { + Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show(); + stopService(new Intent(getApplicationContext(), TaskService.class)); + spEditor.putInt("serviceLevel", 0); + spEditor.putString("deviceID", null); + spEditor.putString("username", null); + spEditor.putString("serviceStatus", "get"); + spEditor.putString("getStatus", "getTaskInfo"); + spEditor.commit(); + try { + FileUtils.cleanDirectory(new File(ClientActivity.CLIENT_DIR)); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + Toast.makeText(getApplicationContext(), "Oops!", Toast.LENGTH_SHORT).show(); + } + } + } + + private boolean isServiceRunning() { + ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + if (TaskService.class.getName().equals(service.service.getClassName())) { + return true; + } + } + return false; + } +} diff --git a/app/src/main/java/com/www/client/SwitchPref.java b/app/src/main/java/com/www/client/SwitchPref.java new file mode 100644 index 0000000..9adc08f --- /dev/null +++ b/app/src/main/java/com/www/client/SwitchPref.java @@ -0,0 +1,25 @@ +package com.www.client; + +import android.content.Context; +import android.preference.SwitchPreference; +import android.util.AttributeSet; + +public class SwitchPref extends SwitchPreference { + + public SwitchPref(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public SwitchPref(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SwitchPref(Context context) { + super(context); + } + + @Override + protected void onClick() { + //super.onClick(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/www/client/TaskService.java b/app/src/main/java/com/www/client/TaskService.java new file mode 100644 index 0000000..591d5a7 --- /dev/null +++ b/app/src/main/java/com/www/client/TaskService.java @@ -0,0 +1,2254 @@ +package com.www.client; + +import android.app.*; +import android.content.*; +import android.location.*; +import android.net.*; +import android.os.*; +import android.preference.*; +import android.util.*; +import android.widget.*; + +import com.www.client.pm.PrivacyMechanism; + +import org.apache.http.*; +import org.apache.http.client.*; +import org.apache.http.client.entity.*; +import org.apache.http.client.methods.*; +import org.apache.http.impl.client.*; +import org.apache.http.message.*; +import org.json.*; + +import java.io.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; +import java.util.regex.*; + +import dalvik.system.DexClassLoader; + + +public class TaskService extends Service implements LocationListener { + + private static Context context; + + private static final int API = android.os.Build.VERSION.SDK_INT; + public static final String WIFI = "Wi-Fi"; + public static final String ANY = "Any"; + + private static final String SDCARD = Environment.getExternalStorageDirectory().getPath(); + public static final String CLIENT = SDCARD + "/Client"; + + private static Class classToLoad = null; + private static Object instance = null; + private static Method method = null; + + private static boolean wifiConnected = false; + private static boolean mobileConnected = false; + public static boolean isConnected = false; + public static boolean firstRun = true; + + public static boolean isWithinBorders = false; + private static NetworkReceiver networkReceiver = null; + private static LocationManager locationManager = null; + + private static ArrayList privacyRegions = null; + + private static DeviceRegister deviceRegister = null; + private static GetTaskInfo getTaskInfo = null; + private static GetBin getBin = null; + private static GetProp getProp = null; + private static PutData putData = null; + private static CheckData checkData = null; + private static LogCat logCat = null; + + private static SharedPreferences sharedPref = null; + private static SharedPreferences.Editor editor = null; + + private static PrivacyMechanism pm; + + /********** SERVICE FUNCTIONS **********/ + + @Override + public void onCreate() { + String TAG = getClass().getName() + "@onStartCommand: "; + super.onCreate(); + + Log.wtf(TAG, "ON"); + TaskService.context = getApplicationContext(); + sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + editor = sharedPref.edit(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + String TAG = getClass().getName() + "@onStartCommand: "; + + Log.wtf(TAG, "Received start id " + startId + ": " + intent); + if(intent != null && intent.getExtras() != null) { + int request = intent.getExtras().getInt("request"); + Log.wtf(TAG, "request = " + request); + switch (request) { + case 0: + Log.wtf(TAG, "" + "Sleep..."); + stopExe(); + if(putData != null) { + putData.cancel(true); + putData.shutdownClient(); + } + if(checkData != null) { + checkData.cancel(true); + checkData.shutdownClient(); + } + unregisterLocationReceiver(); + setTimeFrom(spGetString("timeFrom"), spGetString("timeTo")); + return START_STICKY; + case 1: + Log.wtf(TAG, "" + "Wake up!"); + //registerNetworkReceiver(); + onStart(); + return START_STICKY; + default: + Log.wtf(TAG, "" + "default"); + return START_STICKY; + } + } + else { + Log.wtf(TAG, "" + "else"); + registerNetworkReceiver(); + onStart(); + return START_STICKY; + } + /*/**/ + } + + @Override + public void onDestroy() { + String TAG = getClass().getName() + "@onDestroy: "; + + super.onDestroy(); + Log.wtf(TAG, "Shutting down..."); + + // Disable BootReceiver + /*ComponentName receiver = new ComponentName(context, BootReceiver.class); + PackageManager pm = context.getPackageManager(); + pm.setComponentEnabledSetting(receiver, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP);/**/ + + onHalt(); + if(networkReceiver != null) unregisterNetworkReceiver(); + Log.wtf(TAG, "OFF"); + } + + public void onTest() { + String TAG = getClass().getName() + "@onTest: "; + Log.wtf(TAG, "..."); + /* + editor.putString("deviceID", "ea3f8e1825fb4c3abb0904aa4dfbab3e"); + + editor.putString("taskID", "1"); + editor.putString("className", "Demo"); + editor.putString("taskSize", "13130092"); + + editor.putBoolean("timeStatus", true); + editor.putString("timeFrom", "12:00"); + editor.putString("timeTo", "13:00"); + + editor.putString("serviceStatus", "post"); + editor.putString("taskStatus", "start"); + //editor.putString("postStatus", "log"); + /**/ + + editor.commit(); + + //exeTask(); + //setTimeFrom("21:00", "23:00"); + //setTimeTo("20:00", "02:00"); + //Log.wtf(TAG, "onTest: " + "isWithinTime = " + isWithinTime("01:00", "21:00")); + } + + public void onStart() { + String TAG = getClass().getName() + "@onStart: "; + + Log.wtf(TAG, "Starting/Resuming..."); + //fileInit(); + onTest(); + if (spGetString("deviceID").isEmpty()) { + deviceRegister(); + } + else { + if("get".equals(spGetString("serviceStatus"))) { + if("getBin".equals(spGetString("getStatus"))){ + getBin(); + } + else { + getTaskInfo(); + } + } + else if("post".equals(spGetString("serviceStatus"))) { + if("start".equals(spGetString("taskStatus"))) { + if(getProp != null) { + getProp.cancel(true); + getProp.shutdownClient(); + } + getProp(); + startExe(); + if(!"log".equals(spGetString("postStatus"))) { + if("put".equals(spGetString("postStatus"))) { + //if(putData == null) { + putData(); + //} + } + else { + //if(checkData == null) { + checkData(); + //} + } + } + } + else if("pause".equals(spGetString("taskStatus"))) { + onPause(); + } + else { + onStop(); + onStart(); + } + } + }/**/ + } + + public void onHalt() { + stopNetworking(); + stopExe(); + + unregisterLocationReceiver(); + } + + public void onPause() { + if(putData != null) { + putData.cancel(true); + putData.shutdownClient(); + } + if(checkData != null) { + checkData.cancel(true); + checkData.shutdownClient(); + } + unregisterLocationReceiver(); + cancelTime(); + stopExe(); + deletePendingData(spGetString("taskID")); + getProp(); + } + + public void onStop() { + stopNetworking(); + unregisterLocationReceiver(); + cancelTime(); + deletePendingData(spGetString("taskID")); + stopExe(); + +// +// Remove corresponding PM + if (sharedPref.getString(Globals.pm_id, null) != null) { + Utils.removePM(getApplicationContext(), Integer.valueOf(sharedPref.getString(Globals.pm_id, "0"))); + } +// + + editor.putString("serviceStatus", "get"); + editor.putString("getStatus", "getTaskInfo"); + editor.putString("postStatus", "log"); + editor.commit(); + taskFin(); + + onStart(); + } + + @Override + public IBinder onBind(Intent intent) { + // TODO Auto-generated method stub + return null; + } + + /********** SERVER FUNCTIONS **********/ + + public void deviceRegister() { + String TAG = getClass().getName() + "@deviceRegister: "; + + if(isOnline()) { + Log.wtf(TAG, "Online"); + deviceRegister = new DeviceRegister(); + deviceRegister.addNameValuePair("username", sharedPref.getString("username", null)); + deviceRegister.addNameValuePair("model", android.os.Build.MODEL); + deviceRegister.addNameValuePair("os", android.os.Build.VERSION.RELEASE); + deviceRegister.execute(Globals.devs_url + "/register"); + Log.wtf(TAG, "Online"); + } + else { + Log.wtf(TAG, "Offline"); + } + } + + public void getTaskInfo() { + String TAG = getClass().getName() + "@getTaskInfo: "; + + if(isOnline()) { + Log.wtf(TAG, "" + "Online."); + getTaskInfo = new GetTaskInfo(); + getTaskInfo.execute(); + } + else { + Log.wtf(TAG, "getTaskInfo: " + "Offline."); + } + } + + public void getBin() { + String TAG = getClass().getName() + "@getBin: "; + + if(isOnline()) { + Log.wtf(TAG, "" + "Online."); + String taskID = sharedPref.getString("taskID", null); + File task = new File(CLIENT + "/" + taskID + "/" + taskID + ".zip"); + String url = "/" + taskID + "/getbin"; + if (task.exists()) url += "/" + task.length() + "/" + sharedPref.getString("deviceID", null); + else url += "/" + sharedPref.getString("deviceID", null); + Log.wtf(TAG, "" + url); + getBin = new GetBin(); + getBin.execute(Globals.tasks_url + url); + } + else { + Log.wtf(TAG, "" + "Offline."); + } + } + + private void getProp() { + String TAG = getClass().getName() + "@getProp: "; + + if(isOnline()) { + Log.wtf(TAG, "Online"); + String taskID = sharedPref.getString("taskID", null); + String deviceID = sharedPref.getString("deviceID", null); + String url = "/" + taskID + "/getprop/" + deviceID; + Log.wtf(TAG, "" + url); + getProp = new GetProp(); + getProp.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Globals.tasks_url + url); + } + else { + Log.wtf(TAG, "Offline"); + } + } + + public void putData() { + String TAG = getClass().getName() + "@putData: "; + if(isOnline()) { + Log.wtf(TAG, "" + "Online."); + String taskID = sharedPref.getString("taskID", ""); + String deviceID = sharedPref.getString("deviceID", ""); + File data = Utils.returnFileFrom(CLIENT + "/" + taskID, ".dat"); + if(data != null) { + Log.wtf(TAG, "" + "Found data " + data); + +// String url = "/" + taskID + "/putdata/" + taskID + "/" + deviceID; + + String dataName = data.getName().substring(0, data.getName().indexOf(".")); + editor.putString("dataName", dataName); + editor.commit(); + + String url = "/" + taskID + "/putdata/" + dataName + "/" + deviceID; + + Log.wtf(TAG, "" + url); + + Log.wtf(TAG, "1/3"); + putData = new PutData(); + Log.wtf(TAG, "2/3"); + putData.execute(Globals.tasks_url + url); + Log.wtf(TAG, "3/3"); + } + else { + Log.wtf(TAG, "" + "No new data found."); + + editor.putString("postStatus", "log"); + editor.commit(); + } + } + else { + Log.wtf(TAG, "" + "Offline."); + } + } + + public void checkData() { + String TAG = getClass().getName() + "@checkData: "; + + if(isOnline()) { + Log.wtf(TAG, "" + "Online."); + String taskID = sharedPref.getString("taskID", null); + String deviceID = sharedPref.getString("deviceID", null); + +// File data = new File(CLIENT + "/" + taskID + "/" + taskID + ".dat"); + + String dataName = sharedPref.getString("dataName", null); + File data = new File(CLIENT + "/" + taskID + "/" + dataName + ".dat"); + + if(data.exists()) { + +// String url = "/" + taskID + "/checkdata/" + taskID + "_" + data.length() + "/" + deviceID; + + String url = "/" + taskID + "/checkdata/" + dataName + "_" + data.length() + "/" + deviceID; + + Log.wtf(TAG, "" + url); + checkData = new CheckData(); + checkData.execute(Globals.tasks_url + url); + } + else { + Log.wtf(TAG, "" + "Data " + dataName + " not found."); + } + } + else { + Log.wtf(TAG, "" + "Offline."); + } + } + + private void startExe() { + String TAG = getClass().getName() + "@startExe: "; + + Log.wtf(TAG, "" + "..."); + if (classToLoad == null) { + if((sharedPref.getBoolean("locStatus", false) || sharedPref.getBoolean("privacyRegionsStatus", false)) + && sharedPref.getBoolean("timeStatus", false)) { + Log.wtf(TAG, "" + "Time: ON"); + Log.wtf(TAG, "" + "Location: ON"); + registerLocationReceiver(); + if(isWithinBorders() && isWithinTime(spGetString("timeFrom"), spGetString("timeTo"))) { + Log.wtf(TAG, "" + "Within time."); + Log.wtf(TAG, "" + "Within borders."); + setTimeTo(spGetString("timeFrom"), spGetString("timeTo")); + exeTask(); + } + else if(isWithinBorders() && !isWithinTime(spGetString("timeFrom"), spGetString("timeTo"))) { + Log.wtf(TAG, "" + "Out of time."); + Log.wtf(TAG, "" + "Within borders."); + setTimeFrom(spGetString("timeFrom"), spGetString("timeTo")); + unregisterLocationReceiver(); + } + else if(!isWithinBorders() && isWithinTime(spGetString("timeFrom"), spGetString("timeTo"))) { + Log.wtf(TAG, "" + "Within time."); + Log.wtf(TAG, "" + "Out of borders."); + setTimeTo(spGetString("timeFrom"), spGetString("timeTo")); + } + else { + Log.wtf(TAG, "" + "Out of time."); + Log.wtf(TAG, "" + "Out of borders."); + setTimeFrom(spGetString("timeFrom"), spGetString("timeTo")); + unregisterLocationReceiver(); + } + } + else if((sharedPref.getBoolean("locStatus", false) || sharedPref.getBoolean("privacyRegionsStatus", false)) + && !sharedPref.getBoolean("timeStatus", false)) { + if(sharedPref.getBoolean("locStatus", false)) { + Log.wtf(TAG, "" + "Time: OFF"); + Log.wtf(TAG, "" + "Location: ON"); + registerLocationReceiver(); + if(isWithinBorders()) { + Log.wtf(TAG, "" + "Within borders."); + exeTask(); + } + else { + Log.wtf(TAG, "" + "Out of borders."); + } + } + } + else if((!sharedPref.getBoolean("locStatus", false) && !sharedPref.getBoolean("privacyRegionsStatus", false)) + && sharedPref.getBoolean("timeStatus", false)) { + Log.wtf(TAG, "" + "Time: ON"); + Log.wtf(TAG, "" + "Location: OFF"); + if(isWithinTime(spGetString("timeFrom"), spGetString("timeTo"))) { + Log.wtf(TAG, "" + "Within time."); + setTimeTo(spGetString("timeFrom"), spGetString("timeTo")); + exeTask(); + } + else { + Log.wtf(TAG, "" + "Out of time."); + setTimeFrom(spGetString("timeFrom"), spGetString("timeTo")); + } + } + else { + Log.wtf(TAG, "" + "Time: OFF"); + Log.wtf(TAG, "" + "Location: OFF"); + exeTask(); + } + } + else { + Log.wtf(TAG, "" + "Already executing."); + } + } + + private void stopExe() { + String TAG = getClass().getName() + "@stopExe: "; + + Log.wtf(TAG, "" + "..."); + + // Toggled in ClientActivity@onTest() + if (sharedPref.getBoolean(Globals.easy_privacy, false)) { + if (pm != null) { + Log.wtf(TAG, "Stopping PM " + "..."); + + pm.onStop(); + pm = null; + + Log.wtf(TAG, "Stopping PM " + "OK"); + } + } + + Log.wtf(TAG, "Stopping ST " + "..."); + if(logCat != null) logCat.cancel(true); + if(classToLoad != null) { + try { + String taskID = sharedPref.getString("taskID", ""); + method = classToLoad.getMethod("saveState", ObjectOutputStream.class); + ObjectOutputStream os = saveState(taskID); + if (os != null) { + if (!(Boolean) method.invoke(instance, saveState(taskID))) { + close(os); + new File(CLIENT + "/" + taskID + "/" + taskID + ".sav").delete(); + } else { + close(os); + } + } + classToLoad.getMethod("onStop").invoke(instance); + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + } + classToLoad = null; + Log.wtf(TAG, "Stopping ST " + "OK"); + } + + private void exeTask() { + String TAG = getClass().getName() + "@exeTask: "; + + String taskID = sharedPref.getString("taskID", ""); + String className = sharedPref.getString("className", ""); + Log.wtf(TAG, "" + "..."); + if(classToLoad == null) { + FileInputStream fis = null; + ObjectInputStream ois = null; + if(new File(CLIENT + "/" + taskID + "/" + taskID + ".sav").exists()) { + Log.wtf(TAG, "" + "Found saved state."); + try { + fis = new FileInputStream(CLIENT + "/" + taskID + "/" + taskID + ".sav"); + ois = new ObjectInputStream(fis); + //savedInstance = (Object) ois.readObject(); + } catch (Exception e) { + e.printStackTrace(); + } + } + try { + Log.wtf(TAG, "" + "Loading..."); + String url = CLIENT + "/" + taskID + "/" + taskID + ".zip"; + File dir = getDir("dex", 0); + DexClassLoader classLoader = new DexClassLoader(url, dir.getAbsolutePath(), null, this.getClass().getClassLoader()); + classToLoad = (Class) classLoader.loadClass(className); + instance = classToLoad.newInstance(); + method = classToLoad.getMethod("onStart", Context.class, ObjectInputStream.class); + method.invoke(instance, getApplicationContext(), ois); + + close(ois); + close(fis); + //oos.close(); + //fos.close(); + Log.wtf(TAG, "" + taskID + "|" + className + " loaded successfully."); + + + + } catch (Exception e) { + e.printStackTrace(); + } + logCat(); + } + else Log.wtf(TAG, "" + "Already executing."); + } + + private void logCat() { + String TAG = getClass().getName() + "@logCat: "; + + Log.wtf(TAG, "..."); + logCat = new LogCat(); + logCat.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + /********** **********/ + + private class DeviceRegister extends AsyncTask { + private static final String TAG = "DeviceRegister"; + private HttpClient client; + private ArrayList params = new ArrayList(); + + public void addNameValuePair(String name, String value) { + params.add(new BasicNameValuePair(name, value)); + } + + @Override + protected String doInBackground(String... urls) { + Log.wtf(TAG, "RegisterDeviceTask: doInBackground..."); + String result = "oops"; + client = new DefaultHttpClient(); + HttpResponse response = null; + try { + HttpPost request = new HttpPost(urls[0]); + request.setEntity(new UrlEncodedFormEntity(params)); + response = client.execute(request); + } catch (Exception e) { + //e.printStackTrace(); + } + if(response != null) { + try { + result = Utils.writeToString(response.getEntity().getContent()); + editor.putString("deviceID", result); + editor.putString("serviceStatus", "get"); + editor.putString("getStatus", "getTaskInfo"); + editor.commit(); + result = "device received id " + result; + } catch (Exception e) { + //e.printStackTrace(); + } + } + else result = "connection error"; + return result; + } + + protected void onPostExecute(String result) { + Log.wtf(TAG, "onPostExecute: " + result); + if(!isCancelled()) onStart(); + } + + protected void onCancelled(String result) { + Log.wtf(TAG, "onCancelled: " + "..."); + } + + public void shutdownClient () { + if (client != null) client.getConnectionManager().shutdown(); + } + } + + private class GetTaskInfo extends AsyncTask { + + private static final String TAG = "GetTaskInfo"; + private String deviceID = spGetString("deviceID"); + private HttpClient client; + private JSONObject task = null; + + @Override + protected String doInBackground(Void... arg0) { + Log.wtf(TAG, "doInBackground: " + "..."); + client = new DefaultHttpClient(); + HttpGet request = new HttpGet(Globals.tasks_url + "/gettaskinfo/" + deviceID); + HttpResponse response = null; + String result = "oops"; + while (!isCancelled() && "oops".equals(result) && isOnline()) { + try { + response = client.execute(request); + } catch (Exception e) { + //e.printStackTrace(); + } + if(response != null) { + try { + task = new JSONObject(Utils.writeToString(response.getEntity().getContent())); + if (!taskIsNull(task)) result = task.toString(); + } catch (Exception e) { + //e.printStackTrace(); + } + if ("oops".equals(result)) { + try { + int div = sharedPref.getInt("serviceLevel", 1); + if (div == 0) div = 1; + Thread.sleep(Globals.task_latency/div); + } catch (InterruptedException e) { + //e.printStackTrace(); + } + } + } + else result = "Connection error"; + } + return result; + } + + protected void onPostExecute(String result) { + Log.wtf(TAG, "onPostExecute: " + result + "."); + if (task != null) { + try { + TaskService.editor.putString("serviceStatus", "get"); + TaskService.editor.putString("getStatus", "getBin"); + TaskService.editor.putString("taskID", task.getString("taskID")); + TaskService.editor.putString("taskSize", task.getString("taskSize")); + TaskService.editor.putString("taskStatus", task.getString("taskStatus")); + TaskService.editor.putString("className", task.getString("className")); + TaskService.editor.putString("dataName", ""); + TaskService.editor.putString("dataChecked", "0"); + TaskService.editor.putBoolean("locStatus", false); + if(("on").equals(task.getString("locStatus"))) { + TaskService.editor.putBoolean("locStatus", true); + TaskService.editor.putString("locSWlat", task.getString("locSWlat")); + TaskService.editor.putString("locSWlng", task.getString("locSWlng")); + TaskService.editor.putString("locNElat", task.getString("locNElat")); + TaskService.editor.putString("locNElng", task.getString("locNElng")); + } + TaskService.editor.putBoolean("timeStatus", false); + if(("on").equals(task.getString("timeStatus"))) { + TaskService.editor.putBoolean("timeStatus", true); + TaskService.editor.putString("timeFrom", task.getString("timeFrom")); + TaskService.editor.putString("timeTo", task.getString("timeTo")); + } + TaskService.editor.commit(); + new File(TaskService.CLIENT + "/" + task.getString("taskID")).mkdir(); + } catch (JSONException e) { + e.printStackTrace(); + } + if(!isCancelled()) getBin(); + } + else { + if(!isCancelled()) onStart(); + } + } + + protected void onCancelled(String result) { + Log.wtf(TAG, "onCancelled: " + "..."); + } + + public void shutdownClient () { + if (client != null) client.getConnectionManager().shutdown(); + } + } + + private class GetBin extends AsyncTask { + private static final String TAG = "GetBin"; + private HttpClient client; + + @Override + protected String doInBackground(String... urls) { + Log.wtf(TAG, "doInBackground: " + "..."); + String result = "oops"; + String taskID = sharedPref.getString("taskID", null); + client = new DefaultHttpClient(); + HttpGet request = new HttpGet(urls[0]); + HttpResponse response = null; + try { + response = client.execute(request); + if(response != null) { + String taskUrl = CLIENT + "/" + taskID + "/" + taskID + ".zip"; + Utils.writeToFile(response.getEntity().getContent(), taskUrl); + result = "Bin received"; + } + else { + result = "Connection error"; + } + } catch (Exception e) {} + return result; + } + + protected void onCancelled(String result) { + Log.wtf(TAG, "onCancelled: " + "..."); + checkBin(); + } + + protected void onPostExecute(String result) { + Log.wtf(TAG, "onPostExecute: " + result + "."); + checkBin(); + if(!isCancelled()) onStart(); + } + + private void checkBin() { + String taskID = sharedPref.getString("taskID", null); + String taskUrl = CLIENT + "/" + taskID + "/" + taskID + ".zip"; + if (new File(taskUrl).length() == Long.valueOf(sharedPref.getString("taskSize", null))) { + Log.wtf(TAG, "checkBin: " + "OK" + "."); + TaskService.editor.putString("serviceStatus", "post"); + TaskService.editor.putString("postStatus", "log"); + TaskService.editor.commit(); + } + else if (new File(taskUrl).length() < Long.valueOf(sharedPref.getString("taskSize", null))) { + Log.wtf(TAG, "checkBin: " + new File(taskUrl).length() + "/" + spGetString("taskSize") + "."); + } + else { + onStop(); + onStart(); + } + } + + public void shutdownClient () { + if (client != null) client.getConnectionManager().shutdown(); + } + } + + private class GetProp extends AsyncTask { + + private static final String TAG = "GetProp"; + private HttpClient client; + private JSONObject prop = null; + + @Override + protected String doInBackground(String... urls) { + Log.wtf(TAG, "doInBackground: " + "..."); + client = new DefaultHttpClient(); + HttpGet request = new HttpGet(urls[0]); + HttpResponse response = null; + String result = "oops"; + String status = ""; + Boolean locationChanged = false; + Boolean timeChanged = false; + while(!isCancelled() && isOnline()) { + try { + response = client.execute(request); + } catch (Exception e) { + //e.printStackTrace(); + } + if(response != null) { + try { + prop = new JSONObject(Utils.writeToString(response.getEntity().getContent())); + } catch (Exception e) { + //e.printStackTrace(); + } + if (prop != null && !taskIsNull(prop)) { + try { + if(TaskService.sharedPref.getBoolean("locStatus", false)) { + locationChanged = locationChanged(prop, TaskService.sharedPref); + if(locationChanged) { + Log.wtf(TAG, "doInBackground: " + "Location changed."); + TaskService.editor.putString("locSWlat", prop.getString("locSWlat")); + TaskService.editor.putString("locSWlng", prop.getString("locSWlng")); + TaskService.editor.putString("locNElat", prop.getString("locNElat")); + TaskService.editor.putString("locNElng", prop.getString("locNElng")); + TaskService.editor.commit(); + } + } + if(TaskService.sharedPref.getBoolean("timeStatus", false)) { + timeChanged = timeChanged(prop, TaskService.sharedPref); + if(timeChanged) { + Log.wtf(TAG, "doInBackground: " + "Time changed."); + TaskService.editor.putString("timeFrom", prop.getString("timeFrom")); + TaskService.editor.putString("timeTo", prop.getString("timeTo")); + TaskService.editor.commit(); + } + } + if(!prop.isNull("taskStatus") && !prop.getString("taskStatus").equals(spGetString("taskStatus"))) { + TaskService.editor.putString("taskStatus", prop.getString("taskStatus")); + TaskService.editor.commit(); + return prop.getString("taskStatus"); + /**/ + } + else { + if(timeChanged) onTimeChanged(); + if(locationChanged) { + if (locationManager != null) { + onLocationChanged(getCurrentLocation()); + } + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + try { + int div = sharedPref.getInt("serviceLevel", 1); + if (div == 0) div = 1; + Thread.sleep(Globals.task_latency/div); + } catch (InterruptedException e) { + //e.printStackTrace(); + } + } + else { + result = "Connection error"; + } + } + return result; + } + + protected void onPostExecute(String result) { + Log.wtf(TAG, "onPostExecute: " + result + "."); + if("start".equals(result)) { + onStart(); + } + else if("pause".equals(result)) { + onPause(); + } + else if("stop".equals(result)) { + onStop(); + } + } + + public void shutdownClient () { + if (client != null) client.getConnectionManager().shutdown(); + } + + protected void onCancelled(String result) { + Log.wtf(TAG, "onCancelled: " + "..."); + } + + } + + private class PutData extends AsyncTask { + + private HttpURLConnection connection = null; + + @Override + protected String doInBackground(String... params) { + String TAG = getClass().getName() + "@doInBackground: "; + + Log.wtf(TAG, "1"); + + String taskID = TaskService.sharedPref.getString("taskID", null); + + Log.wtf(TAG, "2 " + taskID); + + String dataName = TaskService.sharedPref.getString("dataName", null); + + Log.wtf(TAG, "3 " + dataName); + + final String dataChecked = TaskService.sharedPref.getString("dataChecked", "0"); + + Log.wtf(TAG, "4 " + dataChecked); + +// final String dataUrl = TaskService.CLIENT + "/" + taskID + "/" + taskID + ".dat"; + + String dataUrl = TaskService.CLIENT + "/" + taskID + "/" + dataName + ".dat"; + + String result = "oops"; + + Log.wtf(TAG, "5 " + dataUrl); + + try { + Log.wtf(TAG, "Sending " + taskID + ".dat from " + dataChecked + "..."); + TaskService.editor.putString("postStatus", "check"); + TaskService.editor.commit(); + URL url = new URL(params[0]); + connection = (HttpURLConnection) url.openConnection(); + connection.setDoOutput(true); + connection.setChunkedStreamingMode(0); + connection.setRequestProperty("Connection", "close"); + Utils.returnPart(new RandomAccessFile(new File(dataUrl), "r"), connection.getOutputStream(), Long.valueOf(dataChecked)); + InputStream response = new BufferedInputStream(connection.getInputStream()); + result = Utils.writeToString(response); + } catch (Exception e) { + //e.printStackTrace(); + } + finally { + if(connection != null) { + connection.disconnect(); + connection = null; + return result; + } + } + return result; + } + + public void shutdownClient () { + if (connection != null) connection.disconnect(); + } + + protected void onCancelled(String result) { + String TAG = getClass().getName() + "@onCancelled: "; + + Log.wtf(TAG, "" + "..."); + } + + protected void onPostExecute(String result) { + String TAG = getClass().getName() + "@onPostExecute: "; + + Log.wtf(TAG, "" + result + "."); + checkData(); + + } + } + + private class CheckData extends AsyncTask { + private HttpClient client; + private JSONObject data = null; + + String taskID = TaskService.sharedPref.getString("taskID", null); + String deviceID = TaskService.sharedPref.getString("deviceID", null); + String dataName = TaskService.sharedPref.getString("dataName", null); + + @Override + protected Void doInBackground(String... urls) { + String TAG = getClass().getName() + "@doInBackground: "; + + Log.wtf(TAG, "..."); + client = new DefaultHttpClient(); + HttpGet request = new HttpGet(urls[0]); + HttpResponse HttpResponse = null; + String result = "oops"; + String response = ""; + String checked = "0"; + try { + HttpResponse = client.execute(request); + } catch (Exception e) { + //e.printStackTrace(); + } + if(HttpResponse != null) { + try { + data = new JSONObject(Utils.writeToString(HttpResponse.getEntity().getContent()).replace("[", "").replace("]", "").replace("\"", "")); + result = data.toString(); + response = data.getString("response"); + if ("put".equals(response)) { + checked = data.getString("checked"); + } + } catch (Exception e) { + //e.printStackTrace(); + } + Log.wtf(TAG, "" + result); + String dir = CLIENT + "/" + taskID; + if("OK".equals(response)) { + TaskService.editor.putString("dataChecked", "0"); + TaskService.editor.commit(); + + //new File(dir + "/" + dataName + ".dat.new").renameTo(new File(dir + "/" + dataName + ".dat")); + //mergeData(taskID, dataName); + +// new File(dir + "/" + taskID + ".dat").delete(); + + new File(dir + "/" + dataName + ".dat").delete(); + + TaskService.editor.putString("postStatus", "log"); + TaskService.editor.commit(); + + File data = Utils.returnFileFrom(dir, ".dat"); + + if(data != null) { + TaskService.editor.putString("postStatus", "put"); + TaskService.editor.commit(); + if(!isCancelled()) { + Log.wtf(TAG, "Recalling putData!"); + putData(); + } + } + else { + TaskService.editor.putString("postStatus", "log"); + TaskService.editor.commit(); + } + /**/ + } + else if("oops".equals(response)) { + TaskService.editor.putString("dataChecked", "0"); + TaskService.editor.putString("postStatus", "put"); + TaskService.editor.commit(); + if(!isCancelled()) putData(); + } + else if("put".equals(response)){ + TaskService.editor.putString("dataChecked", checked); + TaskService.editor.putString("postStatus", "put"); + TaskService.editor.commit(); + if(!isCancelled()) putData(); + } + else {} + } + else Log.wtf(TAG, "" + "Connection error."); + return null; + } + + public void shutdownClient () { + if (client != null) client.getConnectionManager().shutdown(); + } + + protected void onCancelled(String result) { + String TAG = getClass().getName() + "@onCancelled: "; + Log.wtf(TAG, "" + "..."); + } + } + + private class LogCat extends AsyncTask { + + String taskID = sharedPref.getString("taskID", ""); + + @Override + protected Void doInBackground(String... arg0) { + String TAG = getClass().getName() + "@doInBackground: "; + + Log.wtf(TAG, "..."); + + while(!isCancelled()) { + Log.wtf(TAG, "POST == " + sharedPref.getString("postStatus", "null")); + /* + * Check for new data + */ + List data = new ArrayList<>(); + try { + data = (List) classToLoad.getMethod("getData").invoke(instance); + + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + +// Check data integrity + if (data != null && !data.isEmpty() && checkDataKeys(data) && checkDataValues(data)) { +// Add extra information + Log.wtf(TAG, "New data."); + for (Object o : data) { + ((Map) o).put("device", sharedPref.getString("deviceID", "0")); + ((Map) o).put("task", sharedPref.getString("taskID", "0")); + } + +// EasyPrivacy staff +// EP status toggled in ClientActivity@onTest() + if (sharedPref.getBoolean(Globals.easy_privacy, false) + && sharedPref.getString(Globals.pm_id, null) != null) { + +// Detected installed PM + + if (pm == null) { + +// PM is inactive + + if(sharedPref.getString(Globals.pm_st_id, null) != null && + sharedPref.getString(Globals.st_id, null) != null && + sharedPref.getString(Globals.pm_st_id, "").equals(sharedPref.getString(Globals.st_id, ""))) { + +// PM is compatible with ST + +// Instantiate PM + Log.wtf(TAG, "Starting PM " + sharedPref.getString(Globals.pm_id, null) + "..."); + pm = new PrivacyMechanism( + getApplicationContext(), + Integer.valueOf(sharedPref.getString(Globals.pm_id, "0")), + Integer.valueOf(taskID)); + +// Start PM + pm.onStart(); + +// Pass data to PM + Log.wtf(TAG, "Passing data to PM..."); + pm.processData(data); + + } else { + +// PM is incompatible with ST + + Log.wtf(TAG, "Removing PM " + sharedPref.getString(Globals.pm_id, null) + "..."); + +// Remove PM + Utils.removePM(getApplicationContext(), Integer.valueOf(sharedPref.getString(Globals.pm_id, "0"))); + + Log.wtf(TAG, "Removed PM " + sharedPref.getString(Globals.pm_id, "*") + sharedPref.getString(Globals.pm_name, "") + "..."); + +// Save data to file + Log.wtf(TAG, "Saving data..."); + Utils.saveData(data, taskID); + + } + } else { + +// PM is active + + if(!sharedPref.getString(Globals.st_id, "").equals(String.valueOf(pm.getStId()))) { + +// PM is incompatible with ST + + Log.wtf(TAG, "Halting and removing active PM " + sharedPref.getString(Globals.pm_id, null) + "..."); + +// Stop + pm.onStop(); + pm = null; + +// Remove + Utils.removePM(getApplicationContext(), Integer.valueOf(sharedPref.getString(Globals.pm_id, "0"))); + + } else if (String.valueOf(pm.getId()).equals(sharedPref.getString(Globals.pm_id, null))) { + +// PM is compatible with ST + +// Pass data to PM + Log.wtf(TAG, "Passing data to PM..."); + pm.processData(data); + + } else { + +// PM changed, restart PM + + Log.wtf(TAG, "Stopping PM " + pm.getId() + "..."); + +// Stop old PM + pm.onStop(); + + Log.wtf(TAG, "Starting PM " + sharedPref.getString(Globals.pm_id, null) + "..."); + +// Instantiate new PM + pm = new PrivacyMechanism( + getApplicationContext(), + Integer.valueOf(sharedPref.getString(Globals.pm_id, "0")), + Integer.valueOf(taskID)); + +// Start new PM + pm.onStart(); + +// Pass data to PM + Log.wtf(TAG, "Passing data to PM..."); + pm.processData(data); + + } + } + } else { +// Save data to file + Log.wtf(TAG, "Saving data..."); + Utils.saveData(data, taskID); + } + + + /* + * Save Sensing Task state + */ + try { + ObjectOutputStream oos = saveState(taskID); + + method = classToLoad.getMethod("saveState", ObjectOutputStream.class); + boolean flag = (boolean) method.invoke(instance, oos); + + close(oos); + + if (!flag) { + new File(CLIENT + "/" + taskID + "/" + taskID + ".sav").delete(); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + /* + * send data to Server + */ + if ("log".equals(sharedPref.getString("postStatus", "log"))) { +// Log.wtf(TAG, "postStatus = put"); + + editor.putString("postStatus", "put"); + editor.commit(); + + if (!isCancelled()) { +// Log.wtf(TAG, "put data"); + putData(); + } + } + } else if(returnFileFrom(Globals.client_dir + "/" + taskID, ".dat") != null) { + Log.wtf(TAG, "Found data file @ " + taskID); + if ("log".equals(sharedPref.getString("postStatus", "log"))) { +// Log.wtf(TAG, "postStatus = put"); + + editor.putString("postStatus", "put"); + editor.commit(); + + if (!isCancelled()) { +// Log.wtf(TAG, "put data"); + putData(); + } + } + } + + /* + * Wait + */ + try { + int div = sharedPref.getInt("serviceLevel", 1); + if (div == 0) { + div = 1; + } + Thread.sleep(Globals.task_latency/div); + } catch (InterruptedException e) { + Log.wtf(TAG, e.getMessage()); + } + + + /* + ArrayList data = new ArrayList(); + try { + data = (ArrayList)classToLoad.getMethod("getData").invoke(instance); + } catch (Exception e) { + e.printStackTrace(); + } + + + if(!data.isEmpty()) { + Log.wtf(TAG, "doInBackground: " + "New data."); + try { +// for(Object object : data) { +// writeObjectToFile(object, taskID); +// } + saveData(data, taskID); + } catch (IOException e) { + e.printStackTrace(); + } + try { + method = classToLoad.getMethod("saveState", new Class[] { ObjectOutputStream.class }); + if (!(Boolean) method.invoke(instance, new Object[] { saveState(taskID) })) { + new File(CLIENT + "/" + taskID + "/" + taskID + ".sav").delete(); + } + } catch (Exception e) { + e.printStackTrace(); + } + if("log".equals(sharedPref.getString("postStatus", "log"))) { + editor.putString("postStatus", "put"); + editor.commit(); + if(!isCancelled()) putData(); + } + } + try { + int div = sharedPref.getInt("serviceLevel", 1); + if (div == 0) div = 1; + Thread.sleep(Globals.task_latency/div); + } catch (InterruptedException e) { +// e.printStackTrace(); + } + */ + + } + return null; + } + } + + /********** NETWORKING **********/ + + private boolean isOnline() { + ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeInfo = connMgr.getActiveNetworkInfo(); + if(activeInfo != null && activeInfo.isConnected()) { + wifiConnected = activeInfo.getType() == ConnectivityManager.TYPE_WIFI; + mobileConnected = activeInfo.getType() == ConnectivityManager.TYPE_MOBILE; + } + else { + wifiConnected = false; + mobileConnected = false; + } + if(((sharedPref.getString("listPref", "Wi-Fi").equals(ANY)) && (wifiConnected || mobileConnected)) || ((sharedPref.getString("listPref", "Wi-Fi").equals(WIFI)) && (wifiConnected))) { + isConnected = true; + return true; + } + else { + isConnected = false; + return false; + } + } + + private void stopNetworking() { + String TAG = getClass().getName() + "@stopNetworking: "; + + Log.wtf(TAG, "" + "..."); + if(deviceRegister != null) { + deviceRegister.cancel(true); + deviceRegister.shutdownClient(); + } + if(getTaskInfo != null) { + getTaskInfo.cancel(true); + getTaskInfo.shutdownClient(); + } + if(getBin != null) { + getBin.cancel(true); + getBin.shutdownClient(); + } + if(getProp != null) { + getProp.cancel(true); + getProp.shutdownClient(); + } + if(putData != null) { + putData.cancel(true); + putData.shutdownClient(); + } + if(checkData != null) { + checkData.cancel(true); + checkData.shutdownClient(); + } + } + + public class NetworkReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String TAG = getClass().getName() + "@onReceive: "; + + ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); + if ((WIFI.equals(sharedPref.getString("listPref", "Wi-Fi")) && networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) || + (ANY.equals(sharedPref.getString("listPref", "Wi-Fi")) && networkInfo != null)) { + if(!isConnected) { + Log.wtf(TAG, "" + "Connected."); + isConnected = true; + //if(!firstRun) { + //onHalt(); + onStart(); + //} + firstRun = false; + } + } + else { + Log.wtf(TAG, "" + "Disconnected."); + isConnected = false; + //stopNetworking(); + } + } + } + + public void registerNetworkReceiver() { + String TAG = getClass().getName() + "@registerNetworkReceiver: "; + + Log.wtf(TAG, "" + "..."); + if (networkReceiver == null) { + IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); + networkReceiver = new NetworkReceiver(); + this.registerReceiver(networkReceiver, filter); + } + else { + Log.wtf(TAG, "" + "Already registered."); + } + } + + public void unregisterNetworkReceiver() { + String TAG = getClass().getName() + "@unregisterNetworkReceiver: "; + + Log.wtf(TAG, "" + "..."); + if (networkReceiver != null) { + this.unregisterReceiver(networkReceiver); + networkReceiver = null; + } + else { + Log.wtf(TAG, "" + "Already unregistered."); + } + } + + /********** LOCATION **********/ + + private Location getCurrentLocation() { + Criteria criteria = new Criteria(); + String provider = locationManager.getBestProvider(criteria, true); + if(provider == null) provider = locationManager.getBestProvider(criteria, false); + Location location = locationManager.getLastKnownLocation(provider); + return location; + } + + private double getCoordinate(String string) { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); + return Double.parseDouble(sp.getString(string, "0")); + } + + private boolean isWithinBorders() { + //Log.wtf(TAG, "isWithinBorders: " + "..."); + Boolean result = false; + Criteria criteria = new Criteria(); + String provider = locationManager.getBestProvider(criteria, true); + if(provider == null) provider = locationManager.getBestProvider(criteria, false); + Location location = locationManager.getLastKnownLocation(provider); + if(location != null) { + result = isWithinBorders(location); + } + return result; + } + + private boolean isWithinBorders(Location loc) { + boolean result = false; + if (sharedPref.getBoolean("locStatus", false)) { + if (Double.compare(loc.getLatitude(), getCoordinate("locSWlat")) >= 0 && + Double.compare(loc.getLatitude(), getCoordinate("locNElat")) <= 0 && + Double.compare(loc.getLongitude(), getCoordinate("locSWlng")) >= 0 && + Double.compare(loc.getLongitude(), getCoordinate("locNElng")) <= 0) { + result = true; + } else return false; + } + if(sharedPref.getBoolean("privacyRegionsStatus", false)) { + ArrayList privacyRegions = Utils.fileToJSON(new File(CLIENT + "/" + "Settings" + "/" + "PrivacyRegions")); + for (JSONObject privacyRegion : privacyRegions) { + try { + if (Double.compare(loc.getLatitude(), privacyRegion.getDouble("locSWlat")) >= 0 && + Double.compare(loc.getLatitude(), privacyRegion.getDouble("locNElat")) <= 0 && + Double.compare(loc.getLongitude(), privacyRegion.getDouble("locSWlng")) >= 0 && + Double.compare(loc.getLongitude(), privacyRegion.getDouble("locNElng")) <= 0) { + return false; + } else result = true; + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + return result; + } + + private boolean locationChanged(JSONObject prop, SharedPreferences pref) { + try { + if (!prop.isNull("locSWlat") && !prop.isNull("locSWlng") && !prop.isNull("locNElat") && !prop.isNull("locNElng")) { + if (!prop.getString("locSWlat").equals(pref.getString("locSWlat", "0"))) { + return true; + } + else if (!prop.getString("locSWlng").equals(pref.getString("locSWlng", "0"))) { + return true; + } + else if (!prop.getString("locNElat").equals(pref.getString("locNElat", "0"))) { + return true; + } + else if (!prop.getString("locNElng").equals(pref.getString("locNElng", "0"))) { + return true; + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + return false; + } + + @Override + public void onLocationChanged(Location location) { + String TAG = getClass().getName() + "@onLocationChanged: "; + + double latitude = location.getLatitude(); + double longitude = location.getLongitude(); + Log.wtf(TAG, "" + "New location.\nLat: " + latitude + "\nLng: " + longitude); + if(isWithinBorders(location)) { + Log.wtf(TAG, "" + "Inside borders."); + startExe(); + } + else { + Log.wtf(TAG, "" + "Outside borders."); + stopExe(); + }/**/ + } + + @Override + public void onProviderDisabled(String provider) { + String TAG = getClass().getName() + "@onProviderDisabled: "; + + Log.wtf(TAG, "" + provider); + if(isWithinBorders()) { + Log.wtf(TAG, "" + "Within borders."); + //exe(); + } + else { + Log.wtf(TAG, "" + "Outside borders."); + //stopExe(); + }/**/ + } + + @Override + public void onProviderEnabled(String provider) { + String TAG = getClass().getName() + "@onProviderEnabled: "; + + Log.wtf(TAG, "" + provider); + if(isWithinBorders()) { + Log.wtf(TAG, "" + "Within borders."); + //exeTask(); + } + else { + Log.wtf(TAG, "" + "Outside borders."); + //stopExe(); + }/**/ + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + String TAG = getClass().getName() + "@onStatusChanged: "; + + Log.wtf(TAG, "" + provider); + Log.wtf(TAG, "" + status); + Log.wtf(TAG, "" + extras); + } + + public void registerLocationReceiver() { + String TAG = getClass().getName() + "@registerLocationReceiver: "; + + Log.wtf(TAG, "" + "..."); + + if(locationManager == null) { + locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + /*if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) && locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { + Log.wtf(TAG, "registerLocationReceiver: " + "all location providers are ON"); + } + else if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { + Log.wtf(TAG, "registerLocationReceiver: " + "gps provider is ON"); + } + else if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { + Log.wtf(TAG, "registerLocationReceiver: " + "network provider is ON"); + } + else { + Log.wtf(TAG, "registerLocationReceiver: " + "all location providers are OFF"); + }/**/ + + Criteria criteria = new Criteria(); + String provider = locationManager.getBestProvider(criteria, true); + if(provider == null) provider = locationManager.getBestProvider(criteria, false); + + Location location = locationManager.getLastKnownLocation(provider); + + int div = sharedPref.getInt("serviceLevel", 1); + if (div == 0) div = 1; + locationManager.requestLocationUpdates(provider, Globals.task_latency/div, 100/div, this);/**/ + + if (location != null) { + Log.wtf(TAG, "" + provider + " provider selected."); + //onLocationChanged(location); + /*if(isWithinBorders((double) (location.getLatitude()), (double) (location.getLongitude()))) { + Log.wtf(TAG, "registerLocationReceiver: " + "Inside borders."); + //if(classToLoad == null) exeTask(); + } + else { + Log.wtf(TAG, "registerLocationReceiver: " + "Outside borders."); + }/**/ + } + else Log.wtf(TAG, "registerLocationReceiver: " + "Location not available."); + } + } + + public void unregisterLocationReceiver() { + String TAG = getClass().getName() + "@unregisterLocationReceiver: "; + + Log.wtf(TAG, "" + "..."); + if(locationManager != null) { + locationManager.removeUpdates(this); + } + locationManager = null; + } + + /********** TIME **********/ + + private boolean timeChanged(JSONObject prop, SharedPreferences pref) { + try { + if (!prop.isNull("timeFrom") && !prop.isNull("timeFrom")) { + if (!prop.getString("timeFrom").equals(pref.getString("timeFrom", ""))) { + return true; + } + else if (!prop.getString("timeTo").equals(pref.getString("timeTo", ""))) { + return true; + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + return false; + } + + private boolean isWithinTime(String timeFrom, String timeTo) { + Calendar calCurr = Calendar.getInstance(); + /*calCurr.set(Calendar.HOUR_OF_DAY, 21); + calCurr.set(Calendar.MINUTE, 0);/**/ + calCurr.set(Calendar.SECOND, 0); + + Calendar calFrom = (Calendar) calCurr.clone(); + calFrom.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeFrom.split(":")[0])); + calFrom.set(Calendar.MINUTE, Integer.parseInt(timeFrom.split(":")[1])); + //calCurr.set(Calendar.SECOND, 1); + + Calendar calTo = (Calendar) calCurr.clone(); + calTo.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeTo.split(":")[0])); + calTo.set(Calendar.MINUTE, Integer.parseInt(timeTo.split(":")[1])); + //calCurr.set(Calendar.SECOND, -1); + + if(calFrom.before(calTo)) { + return calFrom.before(calCurr) && calTo.after(calCurr) || calFrom.equals(calCurr); + } + else if(calFrom.after(calTo)){ + return calFrom.before(calCurr) && calTo.before(calCurr) + || calFrom.after(calCurr) && calTo.after(calCurr) + || calFrom.equals(calCurr); + } + else return true; + } + + public void onTimeChanged() { + String TAG = getClass().getName() + "@onTimeChanged: "; + + String timeFrom = spGetString("timeFrom"); + String timeTo = spGetString("timeTo"); + Log.wtf(TAG, "" + "New time " + timeFrom + " - " + timeTo); + if(classToLoad != null){ + Log.wtf(TAG, "" + "Already executing."); + if(isWithinTime(timeFrom, timeTo)) { + Log.wtf(TAG, "" + "In time."); + setTimeTo(timeFrom, timeTo); + } + else { + Log.wtf(TAG, "" + "Out of time."); + stopExe(); + setTimeFrom(timeFrom, timeTo); + } + } + else { + Log.wtf(TAG, "" + "Not executing."); + setTimeFrom(timeFrom, timeTo); + }/**/ + } + + private void setTimeFrom(String timeFrom, String timeTo) { + String TAG = getClass().getName() + "@setTimeFrom: "; + + Calendar calCurr = Calendar.getInstance(); + /*calCurr.set(Calendar.HOUR_OF_DAY, 0); + calCurr.set(Calendar.MINUTE, 0);/**/ + calCurr.set(Calendar.SECOND, 0); + + + Calendar calFrom = (Calendar) calCurr.clone(); + calFrom.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeFrom.split(":")[0])); + calFrom.set(Calendar.MINUTE, Integer.parseInt(timeFrom.split(":")[1])); + //calCurr.set(Calendar.SECOND, 1); + + Calendar calTo = (Calendar) calCurr.clone(); + calTo.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeTo.split(":")[0])); + calTo.set(Calendar.MINUTE, Integer.parseInt(timeTo.split(":")[1])); + //calCurr.set(Calendar.SECOND, -1); + + Calendar cal = (Calendar) calFrom.clone(); + if(calFrom.before(calTo)) { + if(calCurr.after(calTo) || calCurr.equals(calTo)) { + cal.add(Calendar.DATE, 1); + } + } + else if(calFrom.after(calTo)){ + if(calCurr.before(calTo) && calCurr.before(calFrom)) { + cal.add(Calendar.DATE, -1); + } + } + + Log.wtf(TAG, "" + cal.getTime()); + + Intent intent = new Intent(TaskService.this, TaskService.class); + intent.putExtra("request", 1); + PendingIntent pendingIntent = PendingIntent.getService(TaskService.this, 13, intent, PendingIntent.FLAG_CANCEL_CURRENT); + AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE); + am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);/**/ + } + + private void setTimeTo(String timeFrom, String timeTo) { + String TAG = getClass().getName() + "@setTimeTo: "; + + Calendar calCurr = Calendar.getInstance(); + /*calCurr.set(Calendar.HOUR_OF_DAY, 21); + calCurr.set(Calendar.MINUTE, 0);/**/ + calCurr.set(Calendar.SECOND, 0); + + Calendar calFrom = (Calendar) calCurr.clone(); + calFrom.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeFrom.split(":")[0])); + calFrom.set(Calendar.MINUTE, Integer.parseInt(timeFrom.split(":")[1])); + //calCurr.set(Calendar.SECOND, 1); + + Calendar calTo = (Calendar) calCurr.clone(); + calTo.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeTo.split(":")[0])); + calTo.set(Calendar.MINUTE, Integer.parseInt(timeTo.split(":")[1])); + //calCurr.set(Calendar.SECOND, -1); + + Calendar cal = (Calendar) calTo.clone(); + if(calFrom.equals(calTo)) { + cal.add(Calendar.DATE, 1); + } + else if(calFrom.after(calTo)){ + if(calCurr.after(calFrom) && calCurr.after(calTo)) { + cal.add(Calendar.DATE, 1); + } + } + + Log.wtf(TAG, "" + cal.getTime()); + + Intent intent = new Intent(TaskService.this, TaskService.class); + intent.putExtra("request", 0); + PendingIntent pendingIntent = PendingIntent.getService(TaskService.this, 13, intent, PendingIntent.FLAG_CANCEL_CURRENT); + AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE); + am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);/**/ + } + + /*private void setTimeFrom(String time) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time.split(":")[0])); + cal.set(Calendar.MINUTE, Integer.parseInt(time.split(":")[1])); + cal.set(Calendar.SECOND, 0); + //cal.add(Calendar.SECOND, 10); + + Log.wtf(TAG, "setTimeFrom: " + cal.getTime()); + + Intent intent = new Intent(TaskService.this, TaskService.class); + intent.putExtra("request", 1); + PendingIntent pendingIntent = PendingIntent.getService(TaskService.this, 13, intent, PendingIntent.FLAG_CANCEL_CURRENT); + AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE); + am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent); + }/**/ + + /*private void setTimeTo(String time) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time.split(":")[0])); + cal.set(Calendar.MINUTE, Integer.parseInt(time.split(":")[1])); + cal.set(Calendar.SECOND, 0); + + Log.wtf(TAG, "setTimeTo: " + cal.getTime()); + + Intent intent = new Intent(TaskService.this, TaskService.class); + intent.putExtra("request", 0); + PendingIntent pendingIntent = PendingIntent.getService(TaskService.this, 13, intent, PendingIntent.FLAG_CANCEL_CURRENT); + AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE); + am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent); + }/**/ + + private void cancelTime() { + String TAG = getClass().getName() + "@cancelTime: "; + + Log.wtf(TAG, "" + "..."); + Intent intent = new Intent(TaskService.this, TaskService.class); + PendingIntent pendingIntent = PendingIntent.getService(TaskService.this, 13, intent, PendingIntent.FLAG_CANCEL_CURRENT); + AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE); + am.cancel(pendingIntent); + } + + /********** MISC **********/ + + private String capitalize(String s) { + if (s == null || s.length() == 0) { + return ""; + } + char first = s.charAt(0); + if (Character.isUpperCase(first)) { + return s; + } else { + return Character.toUpperCase(first) + s.substring(1); + } + } + + private static void close(Closeable resource) { + if (resource != null) { + try { + resource.close(); + } + catch (IOException ignore) {} + } + } + + public static void delete(File file) { + if(file.exists()) { + if(file.isDirectory()){ + if(file.list().length==0){ + file.delete(); + } + else { + String files[] = file.list(); + for (String temp : files) { + File fileDelete = new File(file, temp); + delete(fileDelete); + } + if(file.list().length==0){ + file.delete(); + } + } + } + else { + file.delete(); + } + } + } + + public void taskFin() { + String TAG = getClass().getName() + "@taskFin: "; + + Log.wtf(TAG, "" + "..."); + + delete(new File(CLIENT + "/" + spGetString("taskID"))); + editor.putString("taskID", null); + editor.putString("taskSize", null); + editor.putString("className", null); + editor.putString("dataName", null); + editor.putString("dataChecked", "0"); + if (sharedPref.getBoolean("locStatus", false)) { + editor.putBoolean("locStatus", false); + editor.putString("locSWlat", null); + editor.putString("locSWlng", null); + editor.putString("locNElat", null); + editor.putString("locNElng", null); + } + if (sharedPref.getBoolean("timeStatus", false)) { + editor.putBoolean("timeStatus", false); + editor.putString("timeFrom", null); + editor.putString("timeTo", null); + } + editor.commit(); + + + } + + public String spGetString(String key) { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); + return sp.getString(key, ""); + } + + public void deletePendingData(String taskID) { + String TAG = getClass().getName() + "@deletePendingData: "; + + Log.wtf(TAG, "" + "..."); + File file = returnFileFrom(CLIENT + "/" + taskID, ".dat.new"); + while (file != null) { + delete(file); + file = returnFileFrom(CLIENT + "/" + taskID, ".dat.new"); + } + file = returnFileFrom(CLIENT + "/" + taskID, ".dat.new.part"); + while (file != null) { + delete(file); + file = returnFileFrom(CLIENT + "/" + taskID, ".dat.new.part"); + } + } + + private String getDeviceName() { + String manufacturer = Build.MANUFACTURER; + String model = Build.MODEL; + if (model.startsWith(manufacturer)) { + return capitalize(model); + } else { + return capitalize(manufacturer) + " " + model; + } + } + + private String getParameter(String line, int element) { + String parameter = ""; + int counter = 0; + Pattern p = Pattern.compile("\"([^\"]*)\""); + Matcher m = p.matcher(line); + while (m.find()) { + if(element - counter == 1) { + parameter = parameter + m.group(1); + break; + } + else counter++; + } + return parameter; + } + + private boolean isExternalStorageReadable() { + String state = Environment.getExternalStorageState(); + return Environment.MEDIA_MOUNTED.equals(state) || + Environment.MEDIA_MOUNTED_READ_ONLY.equals(state); + } + + private boolean isExternalStorageWritable() { + String state = Environment.getExternalStorageState(); + return Environment.MEDIA_MOUNTED.equals(state); + } + + public void mergeParts(InputStream input, String taskID) throws IOException { + File file = new File(taskID); + Long length = file.length(); + int read = 0; + byte[] buffer = new byte[1024]; + RandomAccessFile output; + output = new RandomAccessFile(file, "rw"); + output.seek(length); + while((read = input.read(buffer)) > 0) { + output.write(buffer, 0, read); + } + close(output); + close(input); + } + + public void mergeParts(String fileName, String partName) throws IOException { + File file = new File(fileName); + File part = new File(partName); + Long length = file.length(); + InputStream input = new FileInputStream(partName); + int read = 0; + byte[] buffer = new byte[1024]; + RandomAccessFile output; + output = new RandomAccessFile(file, "rw"); + output.seek(length); + while((read = input.read(buffer)) > 0) { + output.write(buffer, 0, read); + } + close(output); + close(input); + part.delete(); + } + + public File returnFileFrom(String url, String type) { + File folder = new File(url); + if(!folder.exists()) return null; + String fileName; + File file = null; + File[] listOfFiles = folder.listFiles(); + Arrays.sort(listOfFiles, new Comparator() { + public int compare(File f1, File f2) { + return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified()); + } + }); + for (int i = 0; i < listOfFiles.length; i++) { + if (listOfFiles[i].isFile()) { + fileName = listOfFiles[i].getName(); + if (fileName.endsWith(type)) { + file = new File(folder + "/" + fileName); + break; + } + } + } + return file; + } + + public File returnPart(String url, long start) throws IOException { + File file = new File(url); + OutputStream output = new FileOutputStream(url + ".part"); + int read; + byte[] buffer = new byte[1024]; + RandomAccessFile input; + input = new RandomAccessFile(file, "r"); + input.seek(start); + while ((read = input.read(buffer)) > 0) { + output.write(buffer, 0, read); + } + close(output); + close(input); + File part = new File(url + ".part"); + return part; + } + + public boolean searchStringFor(String string, String phrase) { + int index = string.indexOf(phrase); + return index >= 0; + } + + private String writeToString(InputStream input) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(input)); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + sb.append(line); + } + String result = sb.toString(); + close(br); + close(input); + return result; + } + + private ObjectOutputStream saveState(String taskID) throws IOException { + String url = CLIENT + "/" + taskID + "/" + taskID + ".sav"; + if (new File(CLIENT + "/" + taskID).exists()) { + FileOutputStream fos = new FileOutputStream(url); + ObjectOutputStream oos = new ObjectOutputStream(fos); + return oos; + } + else return null; + } + + private void writeObjectToFile(Object object, String taskID) throws IOException { + String ext = ".dat.new"; + String url = CLIENT + "/" + taskID + "/" + taskID; + File file = new File(url + ext); + int i = 1; + while(file.exists() || new File(url + ".dat").exists()) { + url = CLIENT + "/" + taskID + "/" + taskID + "(" + i + ")"; + file = new File(url + ext); + i++; + } + FileOutputStream fos = new FileOutputStream(url + ext); + ObjectOutputStream oos = new ObjectOutputStream(fos); + + oos.writeObject(object); + + close(oos); + close(fos); + } + + + /* + * Data integrity + */ + + boolean checkDataKeys(List data) { + String TAG = getClass().getName() + "@checkDataKeys: "; + + for (Object o : data) { + Map m = (Map) o; + for (Object key : m.keySet()) { + try { + if ("sensor".equals(key) + || "timestamp".equals(key) + || "values".equals(key)) { + Log.wtf(TAG, key + " key" + " OK"); + } else { + Log.wtf(TAG, key + " key" + " ERROR"); + return false; + } + } catch (Exception e) { + Log.wtf(TAG, key + " key " + e.getMessage()); + return false; + } + } + } + return true; + } + + boolean checkDataValues(List data) { + String TAG = getClass().getName() + "@checkDataValues: "; + + for (Object o : data) { + Map m = (Map) o; + for (Object key : m.keySet()) { + if ("sensor".equals(key)) { + try { + int i = (int) m.get(key); + Log.wtf(TAG, key + " value " + "OK"); + } catch (Exception e) { + Log.wtf(TAG, key + " value " + e.getMessage()); + return false; + } + } else if ("timestamp".equals(key)) { + try { + long l = (long) m.get(key); + Log.wtf(TAG, key + " value " + "OK"); + } catch (Exception e) { + Log.wtf(TAG, key + " value " + e.getMessage()); + return false; + } + } else if ("values".equals(key)) { + try { + double[] d = (double[]) m.get(key); + Log.wtf(TAG, key + " value " + "OK"); + } catch (Exception e) { + Log.wtf(TAG, key + " value " + e.getMessage()); + return false; + } + } + } + } + return true; + } + + + /* + * Data I/O + */ + private void saveDataObj(ArrayList data, String taskID) throws IOException { + String ext = ".dat.new"; + String url = CLIENT + "/" + taskID + "/" + taskID; + String deviceID = spGetString("deviceID"); + FileOutputStream fos; + ObjectOutputStream oos; + if(new File(url + ext).exists()) { + fos = new FileOutputStream(url + ext, true); + oos = new AppendingObjectOutputStream(fos); + } + else { + fos = new FileOutputStream(url + ext); + oos = new ObjectOutputStream(fos); + } + for(Object object : data) { + oos.writeObject("[" + Calendar.getInstance().getTime() + "]" + " @ " + deviceID + ": " + object); + } + + close(oos); + close(fos); + } + + private void saveDataOLD(ArrayList data, String taskID) throws IOException { + String ext = ".dat"; + String url = CLIENT + "/" + taskID + "/" + taskID; + String deviceID = spGetString("deviceID"); + String dataName = taskID; + File file = new File(url + ext); + /*int i = 1; + while(file.exists() || new File(url + ".dat").exists()) { + dataName = taskID + "(" + i + ")"; + url = CLIENT + "/" + taskID + "/" + dataName; + file = new File(url + ext); + i++; + }/**/ + FileWriter fw = null; + if (file.exists()) fw = new FileWriter(file, true); + else fw = new FileWriter(file); + for(String string : data) { + fw.write("[" + Calendar.getInstance().getTime() + "]" + " @ " + deviceID + ": " + string + "\n"); + } + close(fw); + //mergeData(taskID, dataName); + //printData(url + ext); + } + + private void mergeData(String taskID, String dataName) { + String taskDir = CLIENT + "/" + taskID + "/"; + String dataUrl = taskDir + taskID + ".dat"; + String newDataUrl = taskDir + dataName + ".dat.new"; + BufferedReader br = null; + FileWriter fw = null; + try { + br = new BufferedReader(new FileReader(newDataUrl)); + fw = new FileWriter(new File(dataUrl), true); + //fw.write(FileUtils.readFileToString(new File(newDataUrl))); + String line; + while ((line = br.readLine()) != null) { + fw.write(line); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + close(fw); + close(br); + } + } + + private void printData(String url) { + String TAG = getClass().getName() + "@printData: "; + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(url)); + String line; + while ((line = br.readLine()) != null) { + Log.wtf(TAG, line); + //Log.wtf(line); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + close(br); + } + } + + /* + * + */ + + private void writeToFile(InputStream input, String url) throws IOException { + OutputStream output = new FileOutputStream(new File(url)); + int read; + byte[] buffer = new byte[1024]; + while((read = input.read(buffer)) > 0) { + output.write(buffer, 0, read); + } + close(output); + close(input); + } + + private void writeToFile(String filePath, String string) throws IOException { + File file = new File(filePath); + if(!file.exists()) file.createNewFile(); + FileWriter fileWriter = new FileWriter(file, true); + fileWriter.write(string); + //log = ""; + close(fileWriter); + if(searchStringFor(string, "{EOL}")) { + editor.putBoolean("logStatus", false); + editor.commit(); + } + } + + public static Context getContext() { + return TaskService.getContext(); + } + + public void test() { + String TAG = getClass().getName() + "@test: "; + + Log.wtf(TAG, "" + "..."); + + Toast.makeText(context, "test", Toast.LENGTH_SHORT).show(); + } + + public boolean taskIsNull(JSONObject task) { + if(!task.isNull("taskID") && !task.isNull("taskSize") && !task.isNull("taskStatus") && !task.isNull("className") && + !task.isNull("locStatus") && !task.isNull("timeStatus")) { + try { + if(("on").equals(task.getString("locStatus"))) { + if(task.isNull("locSWlat") || task.isNull("locSWlng") || task.isNull("locNElat") || task.isNull("locNElng")){ + return true; + } + } + if(("on").equals(task.getString("timeStatus"))) { + if(task.isNull("timeFrom") || task.isNull("timeTo")){ + return true; + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + return false; + } + else { + return true; + } + } +} diff --git a/app/src/main/java/com/www/client/TimeReceiver.java b/app/src/main/java/com/www/client/TimeReceiver.java new file mode 100644 index 0000000..2fede2d --- /dev/null +++ b/app/src/main/java/com/www/client/TimeReceiver.java @@ -0,0 +1,23 @@ +package com.www.client; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +public class TimeReceiver extends BroadcastReceiver { + private static final String TAG = "TimeReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + Log.i(TAG, "onReceive: " + "..."); + if (intent.getAction().equals("TASK_SERVICE_ON")) { + context.startService(new Intent(context, TaskService.class)); + } + else if (intent.getAction().equals("TASK_SERVICE_OFF")) { + context.startService(new Intent(context, TaskService.class)); + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/www/client/Utils.java b/app/src/main/java/com/www/client/Utils.java new file mode 100644 index 0000000..fe6bee4 --- /dev/null +++ b/app/src/main/java/com/www/client/Utils.java @@ -0,0 +1,533 @@ +package com.www.client; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + +import org.apache.commons.io.FileUtils; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; + +public class Utils { + private static final String TAG = "Utils"; + + public static HttpResponse response(String url, String task) { + HttpClient client = new DefaultHttpClient(); + HttpResponse response = null; + try { + if("get".equals(task)) { + response = client.execute(new HttpGet(url)); + } + } + catch (Exception e) { + Log.e(TAG, e.getLocalizedMessage(), e); + } + return response; + } + + public static HttpResponse httpResponse(String url, ArrayList params) { + Log.i(TAG, "response: " + params); + HttpClient httpClient = new DefaultHttpClient(); + HttpResponse httpResponse = null; + try { + HttpPost httppost = new HttpPost(url); + httppost.setEntity(new UrlEncodedFormEntity(params)); + httpResponse = httpClient.execute(httppost); + } + catch (Exception e) { + Log.e(TAG, e.getLocalizedMessage(), e); + } + return httpResponse; + } + + + public static File returnFileFrom(String url, String type) { + String TAG = "Utils.returnFileFrom: "; + + Log.wtf(TAG, url + " with type " + type); + + File folder = new File(url); + String fileName; + File file = null; + if (folder.exists()) { + File[] listOfFiles = folder.listFiles(); + for (int i = 0; i < listOfFiles.length; i++) { + if (listOfFiles[i].isFile()) { + fileName = listOfFiles[i].getName(); + if (fileName.endsWith(type)) { + file = new File(url + "/" + fileName); + Log.wtf(TAG, "found " + fileName); + break; + } + } + } + } + return file; + } + + public static void returnPart(RandomAccessFile input, OutputStream output, long start) throws IOException { + int read; + byte[] buffer = new byte[1024]; + input.seek(start); + while ((read = input.read(buffer)) > 0) { + output.write(buffer, 0, read); + } + close(output); + close(input); + } + + /** + * Description: Read an input stream and covert it to readable string. + * Parameters : - InputStream: The stream to convert to string. + * Changelog : - 150615: Remove throws clause and add appropriate log. + */ + public static String writeToString(InputStream input) { + String TAG = Utils.class.getName() + "@writeToString: "; + InputStreamReader isr = new InputStreamReader(input); + BufferedReader br = new BufferedReader(isr); + StringBuilder sb = new StringBuilder(); + String line; + try { + while ((line = br.readLine()) != null) { + sb.append(line); + } + } catch (IOException e) { + Log.e(TAG, e.getMessage()); + } + String result = sb.toString(); + close(br); + close(isr); + close(input); + return result; + } + + public static void writeToFile(InputStream input, String url) { + File file = new File(url); + long seek = file.length(); + RandomAccessFile output = null; + /*long skip = 0; + skip += input.skip(seek); + Log.i(TAG, "writeToFile: before " + skip + " - " + seek); + while(skip < seek) { + skip += input.skip(1); + } + Log.i(TAG, "writeToFile: after " + skip);/**/ + try { + output = new RandomAccessFile(file, "rw"); + output.seek(seek); + int read = 0; + byte[] buffer = new byte[1024]; + while((read = input.read(buffer)) > 0) { + output.write(buffer, 0, read); + } + } catch (Exception e) { + //e.printStackTrace(); + } + close(output); + close(input);/**/ + } + + public static void delete(File file) { + if(file.exists()) { + if(file.isDirectory()){ + if(file.list().length==0){ + file.delete(); + } + else { + String files[] = file.list(); + for (String temp : files) { + File fileDelete = new File(file, temp); + delete(fileDelete); + } + if(file.list().length==0){ + file.delete(); + } + } + } + else { + file.delete(); + } + } + } + + public static void writeJSONtoFile(JSONObject json, File file) { + FileWriter fw = null; + try { + if (file.exists()) { + fw = new FileWriter(file, true); + //json.put("id", countLines(file)); + } + else { + fw = new FileWriter(file); + //json.put("id", 0); + } + fw.write(json.toString() + "\n"); + close(fw); + } catch (IOException e) { + e.printStackTrace(); + } + //System.out.println("json: " + json); + //System.out.println("string: " + json.toString()); + //System.out.println("file: " + FileUtils.readFileToString(file)); + } + + public static void overwriteJSONtoFile(ArrayList arrayList, File file) { + FileWriter fw = null; + try { + fw = new FileWriter(file); + for (JSONObject jsonObject : arrayList) { + fw.write(jsonObject.toString() + "\n"); + } + close(fw); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static int countLines(File file) { + int lines = 0; + try { + lines = countLines(FileUtils.readFileToString(file)); + } catch (IOException e) { + e.printStackTrace(); + } + return lines; + } + + public static int countLines(String str){ + String[] lines = str.split("\r\n|\r|\n"); + return lines.length; + } + + public static ArrayList fileToJSON(File file) { + ArrayList arrayList = new ArrayList(); + if (file.exists()) { + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(file)); + String line; + while ((line = br.readLine()) != null) { + //System.out.println("line: " + line); + arrayList.add(new JSONObject(line)); + } + close(br); + //System.out.println("array: " + arrayList.toString()); + } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return arrayList; + } + + public static void removePM(Context c, int id) { + String TAG = Utils.class.getName() + "@removePM: "; + + Log.wtf(TAG, "Removing PM " + id + "..."); + + delete(new File(Globals.pms_dir + "/" + id)); + + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(c); + SharedPreferences.Editor ed = sp.edit(); + + ed.putString(Globals.pm_id, null); + ed.putString(Globals.pm_name, null); + ed.putString(Globals.pm_vers, null); +// +// class name + ed.putString(Globals.pm_clss, null); +// +// sensing task id + ed.putString(Globals.pm_st_id, null); +// + ed.putString(Globals.pm_desc, null); + ed.putString(Globals.pm_user, null); + ed.putString(Globals.pm_date, null); + ed.putString(Globals.pm_time, null); + ed.putString(Globals.pm_size, null); + + ed.commit(); + } + + public static void close(Closeable resource) { + if (resource != null) { + try { + resource.close(); + } catch (IOException ignore) { + } + } + } + + + + + + + + + + + + // Data related functions + // + // + public static boolean saveData(List data, String taskID) { + String TAG = "Utils@saveData: "; + + String ext = ".dat"; + String url = Globals.client_dir + "/" + taskID + "/" + taskID; + + int i = 1; + File file = new File(url + ext); +// while(file.exists() || new File(url + ".dat").exists()) { + // TODO: EVAL + /* + if (file.exists() || new File(url + ".dat").exists()) { + url = Globals.client_dir + "/" + taskID + "/" + taskID + "(" + i + ")"; + file = new File(url + ext); + i++; + } + */ + // /TODO: EVAL + url += ext; + + FileOutputStream fos; + ObjectOutputStream oos; + + try { + Log.wtf(TAG, "Saving data to " + url); + List oldData = Utils.getData(url); + if (!oldData.isEmpty()) { + oldData.addAll(data); + data = oldData; + } + fos = new FileOutputStream(url); + oos = new ObjectOutputStream(fos); + + oos.writeObject(data); + + close(oos); + close(fos); + + } catch (Exception ex) { + Log.wtf(TAG, ex.getMessage()); + return false; + } + Log.wtf(TAG, "OK"); + return true; + } + + // + public static void mergeData(String dataSrc, String dataDst) { + String TAG = "Utils@mergeData: "; + + if(new File(dataDst).exists()) { + Log.wtf(TAG, "Merging data with " + dataDst); + + List oldData = Utils.getData(dataDst); + List newData = Utils.getData(dataSrc); + oldData.addAll(newData); + + new File(dataSrc).delete(); + new File(dataDst).delete(); + + try { + FileOutputStream fos = new FileOutputStream(dataDst); + ObjectOutputStream oos = new ObjectOutputStream(fos); + + oos.writeObject(oldData); + + close(oos); + close(fos); + } catch (Exception ex) { + Log.wtf(TAG, ex.getMessage()); + } + } else { + Log.wtf(TAG, "Moving data to " + dataDst); + new File(dataSrc).renameTo(new File(dataDst)); + new File(dataSrc).delete(); + } + + } + + // + public static List getData(String url) { + String TAG = "Utils@getData: "; + + FileInputStream fis; + ObjectInputStream ois; + + List data = new ArrayList<>(); + + try { + Log.wtf(TAG, "Returning data " + url); + if (new File(url).exists()) { + fis = new FileInputStream(url); + ois = new ObjectInputStream(fis); + + data = (List) ois.readObject(); + + close(ois); + close(fis); + } else { + Log.wtf(TAG, "File does not exist"); + } + } catch (Exception ex) { + Log.wtf(TAG, ex.getMessage()); + } + Log.wtf(TAG, "OK"); + return data; + } + + public static ObjectInputStream getData(List data) { + String TAG = "Utils@getDataFrom: "; + + Log.wtf(TAG, "..."); + + ObjectInputStream ois = null; + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + + oos.writeObject(data); + + Utils.close(oos); + + InputStream is = new ByteArrayInputStream(baos.toByteArray()); + ois = new ObjectInputStream(is); + + } catch (IOException e) { + Log.wtf(TAG, e.getMessage()); + } + return ois; + } + + // + public static ObjectOutputStream putData (String url) { + String TAG = "Utils@putDataTo: "; + + Log.wtf(TAG, "..."); + + FileOutputStream fos; + ObjectOutputStream oos = null; + + try { +// Log.wtf(TAG, "Saving data to " + url); + + fos = new FileOutputStream(url); + oos = new ObjectOutputStream(fos); + } catch (Exception ex) { + Log.wtf(TAG, ex.getMessage()); + } + return oos; + } + + // TODO + public static String getNewDataPath (int stId) { + String TAG = "Utils@getNewDataPath: "; + + String ext = ".dat"; + String url = Globals.client_dir + "/" + stId + "/" + stId; + + int i = 1; + File file = new File(url + ext); + while(file.exists() || new File(url + ".dat").exists()) { + url = Globals.client_dir + "/" + stId + "/" + stId + "(" + i + ")"; + file = new File(url + ext); + i++; + } + + file = new File(url + ext + ".tmp"); + while(file.exists() || new File(url + ".dat" + ".tmp").exists()) { + url = Globals.client_dir + "/" + stId + "/" + stId + "(" + i + ")"; + file = new File(url + ext); + i++; + } + + url += ext + ".tmp"; + + return url; + } + + + + // State related functions + // + // getStateFrom the pm directory + public static ObjectInputStream getStateFrom (int id) { + final String TAG = "Utils@getStateFrom: "; + + FileInputStream fis; + ObjectInputStream ois = null; + + String url = Globals.pms_dir + "/" + id + "/" + id + ".sav"; + + Log.wtf(TAG, "" + url); + + if(new File(url).exists()) { + Log.wtf(TAG, "" + "OK"); + try { + fis = new FileInputStream(url); + ois = new ObjectInputStream(fis); + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + } else { + Log.wtf(TAG, "No saved state found"); + } + return ois; + } + + // putStateTo the pm directory + public static ObjectOutputStream putStateTo (String url) { + String TAG = "Utils@putStateTo: "; + + Log.wtf(TAG, url); + + FileOutputStream fos; + ObjectOutputStream oos = null; + + try { + fos = new FileOutputStream(url); + oos = new ObjectOutputStream(fos); + } catch (Exception ex) { + Log.wtf(TAG, ex.getMessage()); + } + return oos; + } + + + + +} diff --git a/app/src/main/java/com/www/client/pm/EasyPrivacy.java b/app/src/main/java/com/www/client/pm/EasyPrivacy.java new file mode 100644 index 0000000..2a2251a --- /dev/null +++ b/app/src/main/java/com/www/client/pm/EasyPrivacy.java @@ -0,0 +1,336 @@ +package com.www.client.pm; + +import com.www.client.Globals; +import com.www.client.R; + +import android.content.*; +import android.net.NetworkInfo; +import android.net.wifi.p2p.*; +import android.net.wifi.p2p.WifiP2pManager.*; +import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo; +import android.preference.PreferenceManager; +import android.util.*; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.util.*; + +public class EasyPrivacy + extends BroadcastReceiver + implements PeerListListener, ConnectionInfoListener { + + Context context; + + public static SharedPreferences shrPrf = null; + + private final IntentFilter intentFilter; + Channel channel; + WifiP2pManager manager; + private boolean wiFiP2pStatus; + private List peers; + + private ServerSocket serverSocket; + private ServerSocket clientSocket; + + public EasyPrivacy(Context c) { + String TAG = getClass().getName() + "@EasyPrivacy: "; + + Log.wtf(TAG, "..."); + + context = c; + shrPrf = PreferenceManager.getDefaultSharedPreferences(c); + + intentFilter = new IntentFilter(); + + // Indicates a change in the Wi-Fi P2P status. + intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); + + // Indicates a change in the list of available peers. + intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); + + // Indicates the state of Wi-Fi P2P connectivity has changed. + intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); + + // Indicates this device's details have changed. + intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); + + manager = (WifiP2pManager) c.getSystemService(Context.WIFI_P2P_SERVICE); + channel = manager.initialize(c, c.getMainLooper(), null); + + peers = new ArrayList<>(); + + Log.wtf(TAG, "OK"); + + } + + + + + public void onStart() { + String TAG = getClass().getName() + "@onStart: "; + + Log.wtf(TAG, "..."); + + context.registerReceiver(this, intentFilter); + + // Detect available peers that are in range. The call to this function is + // asynchronous and a success or failure is communicated to the application + // with onSuccess() and onFailure(). The onSuccess() method only notifies you + // that the discovery process succeeded and does not provide any information + // about the actual peers that it discovered, if any. + manager.discoverPeers(channel, new ActionListener() { + + @Override + public void onSuccess() { + // Command successful! Code isn't necessarily needed here, + // Unless you want to update the UI or add logging statements. + String TAG = getClass().getName() + "@onSuccess: "; + + Log.wtf(TAG, "OK"); + + } + + @Override + public void onFailure(int arg0) { + // Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY + String TAG = getClass().getName() + "@onFailure: "; + + Log.wtf(TAG, "Oops!"); + + } + + }); + + Log.wtf(TAG, "OK"); + + } + + public void onStop() { + String TAG = getClass().getName() + "@onStop: "; + + Log.wtf(TAG, "..."); + + context.unregisterReceiver(this); + + Log.wtf(TAG, "OK"); + + } + + + + // Register the PM service + // TODO to be called in PrivacyMecanism() if pm is collaborative + // Create a string map containing information about your service. + // Map record = new HashMap(); + // record.put("listenport", String.valueOf(SERVER_PORT)); + // record.put("buddyname", "John Doe" + (int) (Math.random() * 1000)); + // record.put("available", "visible"); +// public void startRegistration(Map record) { + public void startRegistration() { + + // Create a string map containing information about your service. + // TODO pass it as a parameter + Map record = new HashMap(); + +// record.put("listenport", String.valueOf(SERVER_PORT)); + + try { + serverSocket = new ServerSocket(0); + } catch (IOException e) { + e.printStackTrace(); + } + record.put("port", String.valueOf(serverSocket.getLocalPort())); + +// record.put("buddyname", "John Doe" + (int) (Math.random() * 1000)); + + record.put("usr", shrPrf.getString(Globals.shr_user, "user") + shrPrf.getString(Globals.shr_dev_id, "0")); + record.put("dev", shrPrf.getString(Globals.shr_dev_id, "0")); + record.put("pm", shrPrf.getString(Globals.pm_id, "0")); + record.put("prv", shrPrf.getString(Globals.privacy_level, "0")); + +// record.put("available", "visible"); + + // Service information. Pass it an instance name, service type + // _protocol._transportlayer , and the map containing + // information other devices will want once they connect to this one. + WifiP2pDnsSdServiceInfo serviceInfo = + WifiP2pDnsSdServiceInfo.newInstance("_test", "_presence._tcp", record); + + // Add the local service, sending the service info, network channel, + // and listener that will be used to indicate success or failure of + // the request. + manager.addLocalService(channel, serviceInfo, new ActionListener() { + + @Override + public void onSuccess() { + // Command successful! Code isn't necessarily needed here, + // Unless you want to update the UI or add logging statements. + String TAG = getClass().getName() + "@onSuccess: "; + + Log.wtf(TAG, "OK"); + + } + + @Override + public void onFailure(int arg0) { + // Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY + String TAG = getClass().getName() + "@onFailure: "; + + Log.wtf(TAG, "Oops!"); + + } + + }); + + } + + + + + + + + + + // Get notified about WifiP2P network changes. + // - Peers have changed + // -> Request the new peer list + // (get it at onPeersAvailable) + // - A connection has been established + // -> Request connection info + // (get it at onConnectionInfoAvailable) + @Override + public void onReceive(Context c, Intent intent) { + String TAG = getClass().getName() + "@onReceive: "; + + String action = intent.getAction(); + + if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { + // Determine if Wifi P2P mode is enabled or not, alert the Activity. + Log.wtf(TAG, "WifP2P state changed..."); + + int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1); + + if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { + Log.wtf(TAG, "WifiP2P enabled"); + + this.setWiFiP2pStatus(true); + + } else { + Log.wtf(TAG, "WifiP2P disabled"); + + this.setWiFiP2pStatus(false); + + } + + } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { + // The peer list has changed! We should probably do something about that. + Log.wtf(TAG, "WifiP2P peers changed..."); + + // Request available peers from the wifi p2p manager. This is an + // asynchronous call and the calling activity is notified with a + // callback on PeerListListener.onPeersAvailable() + if (manager != null) { + manager.requestPeers(channel, this); + } + + } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { + // Connection state changed! We should probably do something about that. + Log.wtf(TAG, "WifiP2P connection changed..."); + + if (manager != null) { + NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); + + if (networkInfo.isConnected()) { + // We are connected with the other device, request connection + // info to find group owner IP + Log.wtf(TAG, "Connected"); + + manager.requestConnectionInfo(channel, this); + } + + } + + } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { + Log.wtf(TAG, "WifiP2P this device changed..."); + + } + } + + // Tne WifiP2pManager.requestPeers(Channel, PeerListListener) returns the new + // WifiP2pDeviceList. + // + // Updates the: + // - Peers list + // - Service (PM) list + @Override + public void onPeersAvailable(WifiP2pDeviceList peers) { + String TAG = getClass().getName() + "@onPeersAvailable: "; + + Log.wtf(TAG, "..."); + + // Out with the old, in with the new. + this.peers.clear(); + + // TODO + // Update the peer list + this.peers.addAll(peers.getDeviceList()); + // TODO + + // If an AdapterView is backed by this data, notify it + // of the change. For instance, if you have a ListView of available + // peers, trigger an update. + + if (this.peers.size() == 0) { + Log.wtf(TAG, "No devices found"); + } else { + Log.wtf(TAG, this.peers.toString()); + } + + } + + // Tne WifiP2pManager.requestConnectionInfo(Channel, ConnectionInfoListener) + // returns connection info. + @Override + public void onConnectionInfoAvailable(WifiP2pInfo info) { + String TAG = getClass().getName() + "@onConnectionInfoAvailable: "; + + Log.wtf(TAG, "..."); + + // InetAddress from WifiP2pInfo struct. +// InetAddress groupOwnerAddress = info.groupOwnerAddress.getHostAddress(); + + // After the group negotiation, we can determine the group owner. + if (info.groupFormed && info.isGroupOwner) { + // Do whatever tasks are specific to the group owner. + // One common case is creating a server thread and accepting + // incoming connections. + } else if (info.groupFormed) { + // The other device acts as the client. In this case, + // you'll want to create a client thread that connects to the group + // owner. + } + } + + + + + + + + + + + + + + private void setWiFiP2pStatus(boolean status) { + wiFiP2pStatus = status; + } + + private boolean isWiFiP2pEnabled(boolean status) { + return wiFiP2pStatus; + } + +} diff --git a/app/src/main/java/com/www/client/pm/ListPrivacyMechanismsActivity.java b/app/src/main/java/com/www/client/pm/ListPrivacyMechanismsActivity.java new file mode 100644 index 0000000..bbed7cf --- /dev/null +++ b/app/src/main/java/com/www/client/pm/ListPrivacyMechanismsActivity.java @@ -0,0 +1,223 @@ +package com.www.client.pm; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.TextView; + +import com.www.client.ClientActivity; +import com.www.client.Globals; +import com.www.client.R; +import com.www.client.Utils; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; + +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONArray; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ListPrivacyMechanismsActivity extends Activity implements AdapterView.OnItemClickListener { + + SharedPreferences sp; + SharedPreferences.Editor spEditor; + + TextView textView; + + ListView listView; + List list; + + @Override + protected void onCreate(Bundle savedInstanceState) { + String TAG = ListPrivacyMechanismsActivity.class.getName() + "@onCreate: "; + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_list_privacy_mechanisms); + + sp = PreferenceManager.getDefaultSharedPreferences(this); + spEditor = sp.edit(); + +// getList(); + } + + @Override + protected void onResume() { + //Log.i(TAG, "onResume: ..."); + super.onResume(); + getList(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_list_privacy_mechanisms, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.get_privacy_mechanism_action_refresh) { +// Toast.makeText(getApplicationContext(), "refresh", Toast.LENGTH_SHORT).show(); + + getList(); + return true; + } + + return super.onOptionsItemSelected(item); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + String TAG = getClass().getName() + "@onItemClick: "; + JSONObject choice = null; + try { + choice = new JSONObject(list.get(position)); + +// Toast.makeText(getApplicationContext(), choice.toString(), Toast.LENGTH_SHORT).show(); +// Log.wtf(TAG, choice.toString()); + + Intent intent = new Intent(this, ViewPrivacyMechanismActivity.class); + intent.putExtra("intent", "get"); + + intent.putExtra("id", choice.getJSONArray("id").getString(0)); + intent.putExtra("name", choice.getJSONArray("name").getString(0)); +// class name + intent.putExtra("class", choice.getJSONArray("class").getString(0)); +// + intent.putExtra("version", choice.getJSONArray("version").getString(0)); + intent.putExtra("description", choice.getJSONArray("description").getString(0)); + intent.putExtra("user", choice.getJSONArray("user").getString(0)); + intent.putExtra("date", choice.getJSONArray("date").getString(0)); + intent.putExtra("time", choice.getJSONArray("time").getString(0)); + intent.putExtra("size", choice.getJSONArray("size").getString(0)); + + startActivity(intent); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private void getList() { + String TAG = getClass().getName() + "@getList: "; +// Toast.makeText(getApplicationContext(), "Getting list...", Toast.LENGTH_SHORT).show(); + + listView = (ListView) findViewById(R.id.listView); + listView.setVisibility(View.INVISIBLE); + list = new ArrayList<>(); + + textView = (TextView) findViewById(R.id.textView); + textView.setText("Please wait..."); + textView.setVisibility(View.VISIBLE); + + String stID = sp.getString("taskID", null); + String deviceID = sp.getString("deviceID", null); + + if (deviceID != null && stID != null) { + if (ClientActivity.isOnline()) { + String url = Globals.pms_url + "/getlist/" + stID + "/" + deviceID; + Log.wtf(TAG, url); +// Toast.makeText(getApplicationContext(), url, Toast.LENGTH_SHORT).show(); + new GetList().execute(url); + } else { + Log.wtf(TAG, "Offline."); +// Toast.makeText(getApplicationContext(), "Offline", Toast.LENGTH_SHORT).show(); + textView.setText("No network connection"); + } + } else { + Log.wtf(TAG, "Not registered yet"); +// Toast.makeText(getApplicationContext(), "Not registered yet", Toast.LENGTH_SHORT).show(); + textView.setText("Not registered yet"); + } + } + + private class GetList extends AsyncTask { + @Override + protected String doInBackground(String... params) { + String TAG = GetList.class.getName() + "@doInBackground: "; + + Log.wtf(TAG, "..."); + + HttpClient client = new DefaultHttpClient(); + HttpGet request = new HttpGet(params[0]); + HttpResponse response = null; + String result = "Oops!"; + + try { + response = client.execute(request); + if (response != null) { + result = Utils.writeToString(response.getEntity().getContent()); + } + } catch (IOException e) { + Log.e(TAG, e.getMessage()); + } + + return result; + } + + protected void onPostExecute(String result) { + String TAG = GetList.class.getName() + "@onPostExecute: "; + + try { + JSONArray jsonArray = new JSONArray(result); + for (int i = 0; i < jsonArray.length(); i++) { + list.add(jsonArray.getString(i)); + } + } catch (Exception ex) { + Log.e(TAG, ex.getMessage()); + } + + Log.wtf(TAG, result); + + boolean error = true; + try { + if (list.size() > 0) { + JSONObject o = new JSONObject(list.get(0)); + o.getJSONArray("Error").getString(0); + } + } catch (JSONException e) { + error = false; + } + + + if ("Oops!".equals(result)) { + textView.setText("Oops, something went wrong"); + } else if (list.size() == 0) { + textView.setText("There are no privacy mechanisms available"); + + } else if (error) { + textView.setText("Not registered yet"); + } else { + textView.setVisibility(View.INVISIBLE); + + /* + * List + */ + PrivacyMechanismArrayAdapter adapter = new PrivacyMechanismArrayAdapter(getApplicationContext(), R.layout.item, list); + listView.setAdapter(adapter); + listView.setOnItemClickListener(ListPrivacyMechanismsActivity.this); + listView.setVisibility(View.VISIBLE); + } + } + } + +} diff --git a/app/src/main/java/com/www/client/pm/PmBroadcastReceiver.java b/app/src/main/java/com/www/client/pm/PmBroadcastReceiver.java new file mode 100644 index 0000000..43af47e --- /dev/null +++ b/app/src/main/java/com/www/client/pm/PmBroadcastReceiver.java @@ -0,0 +1,88 @@ +package com.www.client.pm; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.NetworkInfo; +import android.net.wifi.p2p.*; +import android.net.wifi.p2p.WifiP2pManager.*; +import android.util.Log; + +public class PmBroadcastReceiver extends BroadcastReceiver { + + WifiP2pManager manager; + Channel channel; + PmP2p pmP2p; + + // + public PmBroadcastReceiver(WifiP2pManager manager, Channel channel, PmP2p pmP2p) { + this.manager = manager; + this.channel = channel; + this.pmP2p = pmP2p; + } + + // Get notified about WifiP2P network changes. + // - Peers have changed + // -> Request the new peer list + // (get it @PmP2p.onPeersAvailable) + // - A connection has been established + // -> Request connection info + // (get it @PmP2p.onConnectionInfoAvailable) + @Override + public void onReceive(Context context, Intent intent) { + String TAG = getClass().getName() + "@onReceive: "; + + String action = intent.getAction(); + + if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { + // Determine if Wifi P2P mode is enabled or not, alert the Activity. + Log.wtf(TAG, "WifP2P state changed..."); + + int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1); + + if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { + Log.wtf(TAG, "WifiP2P enabled"); + pmP2p.setWifiP2pStatus(true); + } else { + Log.wtf(TAG, "WifiP2P disabled"); + pmP2p.setWifiP2pStatus(false); + } + + } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { + // The peer list has changed! We should probably do something about that. + Log.wtf(TAG, "WifiP2P peers changed..."); + + // Request available peers from the wifi p2p manager. This is an + // asynchronous call and the calling activity is notified with a + // callback on PeerListListener.onPeersAvailable() + if (manager != null) { + manager.requestPeers(channel, pmP2p); + } + + } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { + // Connection state changed! We should probably do something about that. + Log.wtf(TAG, "WifiP2P connection changed..."); + + if (manager != null) { + NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); + + if (networkInfo.isConnected()) { + // We are connected with the other device, request connection + // info to find group owner IP + Log.wtf(TAG, "Connected"); + + manager.requestConnectionInfo(channel, pmP2p); + } else { + Log.wtf(TAG, "Disconnected"); + + pmP2p.disconnect(); + } + } + + } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { + Log.wtf(TAG, "WifiP2P this device changed..."); + } + + } + +} diff --git a/app/src/main/java/com/www/client/pm/PmClient.java b/app/src/main/java/com/www/client/pm/PmClient.java new file mode 100644 index 0000000..890a197 --- /dev/null +++ b/app/src/main/java/com/www/client/pm/PmClient.java @@ -0,0 +1,141 @@ +package com.www.client.pm; + +import android.os.AsyncTask; +import android.util.Log; + +import com.www.client.Globals; +import com.www.client.Utils; + +import java.io.*; +import java.net.*; +import java.util.Map; + +//public class PmClient extends AsyncTask { + +public class PmClient implements Runnable { + + + Map peer; + PrivacyMechanism pm; + + public PmClient(Map peer, PrivacyMechanism privacyMechanism) { + this.peer = peer; + this.pm = privacyMechanism; + } + + @Override + public void run() { + String TAG = getClass().getName() + "@doInBackground: "; + + Log.wtf(TAG, "..."); + + Socket socket = new Socket(); + + Log.wtf(TAG, peer.toString()); + + try { + socket.bind(null); + socket.connect((new InetSocketAddress(peer.get("ip"), +// Integer.valueOf(peer.get("port")))), 500); + Globals.pm_port)), 500); + + OutputStream os = socket.getOutputStream(); + + File data = new File(Globals.pms_dir + "/" + pm.getId() + "/" + peer.get("dev") + ".dat"); + + if(data.exists()) { + Log.wtf(TAG, "Sending " + data.getPath()); + + RandomAccessFile raf = new RandomAccessFile(data, "r"); + Utils.returnPart(raf, os, 0); + + Utils.close(os); + Utils.close(raf); + + data.delete(); + } else { + Log.wtf(TAG, "No data " + data.getPath()); + } + + } catch (FileNotFoundException e) { + Log.wtf(TAG, e.getMessage()); + } catch (IOException e) { + Log.wtf(TAG, e.getMessage()); + } finally { + if (socket != null) { + if (socket.isConnected()) { + try { + Log.wtf(TAG, "Closing socket..."); + socket.close(); + } catch (IOException e) { + Log.wtf(TAG, e.getMessage()); + } + } + } + } + } + +// @Override +// protected Object doInBackground(Object[] params) { +// String TAG = getClass().getName() + "@doInBackground: "; +// +// Log.wtf(TAG, "..."); +// +// Socket socket = new Socket(); +// +// Log.wtf(TAG, peer.toString()); +// +// try { +// socket.bind(null); +// socket.connect((new InetSocketAddress(peer.get("ip"), +// Integer.valueOf(peer.get("port")))), 500); +// +// OutputStream os = socket.getOutputStream(); +// +//// String dir = Globals.pms_dir + "/" + pm.getId(); +//// File data = null; +//// for(File file : new File(dir).listFiles()) { +//// if(file.getName().endsWith(".dat.tmp")) { +//// data = file; +//// break; +//// } +//// } +// +// File data = new File(Globals.pms_dir + "/" + pm.getId() + "/" + peer.get("dev") + ".dat"); +// +// if(data.exists()) { +// Log.wtf(TAG, "Sending " + data.getPath()); +// +// RandomAccessFile raf = new RandomAccessFile(data, "r"); +// Utils.returnPart(raf, os, 0); +// +// Utils.close(os); +// Utils.close(raf); +// +// data.delete(); +// } else { +// Log.wtf(TAG, "No data " + data.getPath()); +// } +// +// } catch (FileNotFoundException e) { +// Log.wtf(TAG, e.getMessage()); +// } catch (IOException e) { +// Log.wtf(TAG, e.getMessage()); +// } +// +// finally { +// if (socket != null) { +// if (socket.isConnected()) { +// try { +// socket.close(); +// } catch (IOException e) { +// Log.wtf(TAG, e.getMessage()); +// } +// } +// } +// } +// +// return null; +// } + +} diff --git a/app/src/main/java/com/www/client/pm/PmP2p.java b/app/src/main/java/com/www/client/pm/PmP2p.java new file mode 100644 index 0000000..c5ca536 --- /dev/null +++ b/app/src/main/java/com/www/client/pm/PmP2p.java @@ -0,0 +1,660 @@ +package com.www.client.pm; + +import android.content.Context; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.net.wifi.WpsInfo; +import android.net.wifi.p2p.*; +import android.net.wifi.p2p.WifiP2pManager.*; +import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo; +import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest; +import android.os.Build; +import android.preference.PreferenceManager; +import android.util.*; + +import com.www.client.Globals; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.util.*; +import java.util.concurrent.ThreadPoolExecutor; + +public class PmP2p implements PeerListListener, ConnectionInfoListener { + + Context context; + PrivacyMechanism pm; + + private SharedPreferences shrPrf; + + private PmBroadcastReceiver receiver; + private IntentFilter intentFilter; + private Channel channel; + private WifiP2pManager manager; + private WifiP2pDnsSdServiceInfo serviceInfo; + + private boolean wifiP2pStatus; + private boolean connectionStatus; + + private List> peers; + + // ServerSocket serverSocket; + Map serverPeer; + Thread server, client; + + // + public PmP2p(Context context, PrivacyMechanism pm) { + String TAG = getClass().getName() + "@PmP2p: "; + + Log.wtf(TAG, "..."); + + this.context = context; + this.pm = pm; + + Log.wtf(TAG, "1/8"); + + shrPrf = PreferenceManager.getDefaultSharedPreferences(context); + + Log.wtf(TAG, "2/8"); + + // Create the intent filter + intentFilter = new IntentFilter(); + // Indicates a change in the Wi-Fi P2P status. + intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); + // Indicates a change in the list of available peers. + intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); + // Indicates the state of Wi-Fi P2P connectivity has changed. + intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); + // Indicates this device's details have changed. + intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); + + Log.wtf(TAG, "3/8"); + + // WifiP2pManager + manager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE); + channel = manager.initialize(context, context.getMainLooper(), null); + + Log.wtf(TAG, "4/8"); + + // Detect available peers that are in range. + // get the list @onPeersAvailable + peers = new ArrayList<>(); + serverPeer = new HashMap<>(); + manager.discoverPeers(channel, new ActionListener() { + @Override + public void onSuccess() { + // Command successful! Code isn't necessarily needed here, + // Unless you want to update the UI or add logging statements. + String TAG = getClass().getName() + "discoverPeers@onSuccess: "; + + Log.wtf(TAG, "OK"); + + } + + @Override + public void onFailure(int arg0) { + // Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY + String TAG = getClass().getName() + "discoverPeers@onFailure: "; + + Log.wtf(TAG, "Oops!"); + + } + + }); + + Log.wtf(TAG, "5/8"); + + registerService(); + + Log.wtf(TAG, "6/8"); + + discoverService(); + + Log.wtf(TAG, "7/8"); + + // BroadcastReceiver + receiver = new PmBroadcastReceiver(manager, channel, this); + context.registerReceiver(receiver, intentFilter); + + Log.wtf(TAG, "8/8"); + +// TODO +// try { +// server = new Thread(new PmServer(this.pm)); +// server.start(); +// } catch (IOException e) { +// Log.wtf(TAG, e.getMessage()); +// } +// TODO + + Log.wtf(TAG, "OK"); + } + + // + public void onStop() { + String TAG = getClass().getName() + "@onStop: "; + + Log.wtf(TAG, "..."); + + disconnect(); +//// TODO +// if(server != null) { +// Log.wtf(TAG, "server"); +// server.cancel(true); +// server = null; +// +//// serverSocket = null; +// +// } + + manager.stopPeerDiscovery(channel, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "stopPeerDiscovery@onSuccess: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "stopPeerDiscovery@onFailure: "; + Log.wtf(TAG, "Oops!"); + } + }); + + manager.cancelConnect(channel, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "cancelConnect@onSuccess: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "cancelConnect@onFailure: "; + Log.wtf(TAG, "Oops!"); + } + }); + manager.removeGroup(channel, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "removeGroup@onSuccess: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "removeGroup@onFailure: "; + Log.wtf(TAG, "Oops!"); + } + }); + + if (serviceInfo != null) { + manager.removeLocalService(channel, serviceInfo, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "removeLocalService@onSuccess: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "removeLocalService@onFailure: "; + Log.wtf(TAG, "Oops!"); + } + }); + } + + manager.clearServiceRequests(channel, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "clearServiceRequests@onSuccess: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "clearServiceRequests@onFailure: "; + Log.wtf(TAG, "Oops!"); + } + }); + manager.clearLocalServices(channel, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "clearLocalServices@onSuccess: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "clearLocalServices@onFailure: "; + Log.wtf(TAG, "Oops!"); + } + }); + + context.unregisterReceiver(receiver); + + Log.wtf(TAG, "OK"); + } + + // Register the PM service + private void registerService() { + String TAG = getClass().getName() + "@registerService: "; + + Map record = new HashMap(); + + Log.wtf(TAG, "..."); + +// try { +// serverSocket = new ServerSocket(0); +// serverSocket = new ServerSocket(Globals.pm_port); + +// serverSocket = new ServerSocket(); // <-- create an unbound socket first +// serverSocket.setReuseAddress(true); +// serverSocket.bind(new InetSocketAddress(Globals.pm_port)); // <-- now bind it + +// Log.wtf(TAG, serverSocket.toString()); + +// record.put("port", String.valueOf(serverSocket.getLocalPort())); + record.put("usr", shrPrf.getString(Globals.shr_user, "user")); + record.put("dev", shrPrf.getString(Globals.shr_dev_id, "0")); + record.put("pm", String.valueOf(pm.getId())); + record.put("pref", String.valueOf(pm.getPreferences())); + + Log.wtf(TAG, record.toString()); + +// } catch (IOException e) { +// Log.wtf(TAG, e.getMessage()); +// } + + // Service information. Pass it an instance name, service type + // _protocol._transportlayer , and the map containing + // information other devices will want once they connect to this one. + serviceInfo = WifiP2pDnsSdServiceInfo.newInstance("_eh", "_ftp._tcp", record); + + + Log.wtf(TAG, "Adding service..."); + + // Add the local service, sending the service info, network channel, + // and listener that will be used to indicate success or failure of + // the request. + manager.addLocalService(channel, serviceInfo, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "addLocalService@onSuccess: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "addLocalService@onFailure: "; + Log.wtf(TAG, "Oops!"); + } + }); + + } + + // + private void discoverService() { + /** + * Register listeners for DNS-SD services. These are callbacks invoked + * by the system when a service is actually discovered. + */ + manager.setDnsSdResponseListeners(channel, + new DnsSdServiceResponseListener() { + @Override + public void onDnsSdServiceAvailable(String name, String type, WifiP2pDevice device) { + // A service has been discovered. Is this our app? + String TAG = getClass().getName() + "@onDnsSdServiceAvailable: "; + + Log.wtf(TAG, "..."); + + Log.wtf(TAG, name + "" + type + "" + device.toString()); + + } + }, new DnsSdTxtRecordListener() { + // A new TXT record is available. Pick up the advertised name. + @Override + public void onDnsSdTxtRecordAvailable(String domain, Map record, WifiP2pDevice device) { + String TAG = getClass().getName() + "@onDnsSdTxtRecordAvailable: "; + + Log.wtf(TAG, "..."); + + Log.wtf(TAG, "Found " + domain.toString() + record.toString() + device.toString()); + + if (record.containsKey("pm") && record.get("pm") != null && + String.valueOf(pm.getId()).equals(record.get("pm"))) { + + Map m = new HashMap<>(); + m.put("mac", device.deviceAddress); + m.putAll(record); + + Log.wtf(TAG, "Checking " + m); + + if (!peers.contains(m)) { + for (Map p : peers) { + if (p.get("dev").equals(m.get("dev"))) { + Log.wtf(TAG, "Updating " + m); + p.putAll(m); + return; + } + } + Log.wtf(TAG, "Adding " + m); + peers.add(m); + } + + pm.onPeersChanged(peers); + } + } + } + ); + + /** + * After attaching listeners, create a service request and initiate + * discovery. + */ + WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance(); + manager.addServiceRequest(channel, serviceRequest, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "addServiceRequest@onSuccess: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "addServiceRequest@onFailure: "; + Log.wtf(TAG, "Oops!"); + } + }); + manager.discoverServices(channel, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "discoverServices@onSuccess: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "discoverServices@onFailure: "; + Log.wtf(TAG, "Oops!"); + } + }); + + } + + /** + * Read an input stream and covert it to readable string. + * + * @param deviceAddress the MAC address of the peer. + */ + public void sendToPeer(String deviceAddress) { + String TAG = getClass().getName() + "@sendToPeer: "; + + Log.wtf(TAG, deviceAddress); + + Map peer = getPeer(deviceAddress); + + if (isConnected() && peer != null) { + Log.wtf(TAG, peer.toString()); + serverPeer.putAll(peer); + Log.wtf(TAG, serverPeer.toString()); + + // client = new PmClient(serverPeer, pm); + // client.execute(); + + client = new Thread(new PmClient(serverPeer, this.pm)); + client.start(); + } else { + connect(deviceAddress); + } + + } + + /** + * + */ + public void connect(String deviceAddress) { + String TAG = getClass().getName() + "@connect: "; + + Log.wtf(TAG, "Connecting to " + deviceAddress); + + WifiP2pConfig config = new WifiP2pConfig(); + config.deviceAddress = deviceAddress; + config.wps.setup = WpsInfo.PBC; + + Log.wtf(TAG, "Config " + config.toString()); + + Map peer = getPeer(deviceAddress); + + if (peer != null) { + serverPeer.putAll(peer); + + Log.wtf(TAG, "serverPeer == " + serverPeer.toString()); + manager.connect(channel, config, new ActionListener() { + @Override + public void onSuccess() { + String TAG = getClass().getName() + "@connect: "; + Log.wtf(TAG, "OK"); + } + + @Override + public void onFailure(int reason) { + String TAG = getClass().getName() + "@connect: "; + Log.wtf(TAG, "error" + reason); + } + }); + } + } + + /** + * + */ + public void disconnect() { + String TAG = getClass().getName() + "@disconnect: "; + + Log.wtf(TAG, "..."); + + setConnectionStatus(false); + + if (client != null) { + Log.wtf(TAG, "client"); + client.interrupt(); + client = null; + +// serverPeer = null; + + } + + if (server != null) { + Log.wtf(TAG, "server"); + server.interrupt(); + server = null; + +// serverSocket = null; + + } + + } + + /** + * + */ + public void setWifiP2pStatus(boolean status) { + wifiP2pStatus = status; + } + + /** + * + */ + public boolean isWifiP2pEnabled() { + return wifiP2pStatus; + } + + /** + * + */ + public void setConnectionStatus(boolean status) { + this.connectionStatus = status; + } + + /** + * + */ + public boolean isConnected() { + return this.connectionStatus; + } + + /** + * Tne WifiP2pManager.requestConnectionInfo(Channel, ConnectionInfoListener) + * returns connection info. + */ + @Override + public void onConnectionInfoAvailable(WifiP2pInfo info) { + String TAG = getClass().getName() + "@onConnectionInfoAvailable: "; + + Log.wtf(TAG, "..."); + + Log.wtf(TAG, info.toString()); + + setConnectionStatus(true); + + // TODO: EVAL + if (info.isGroupOwner) { + // if(Build.PRODUCT.equals(Globals.eval_dev)) { + // TODO: /EVAL + Log.wtf(TAG, "Connected as server"); + + /* + if (serverSocket != null) { + Log.wtf(TAG, "Executing server..."); + server = new PmServer(serverSocket, pm); + server = new PmServer(pm); + server.execute(); + } else { + Log.wtf(TAG, "No server socket"); + } + */ + + server = new Thread(new PmServer(this.pm)); + server.start(); + } else { + Log.wtf(TAG, "Connected as client"); + + /* + if (serverPeer != null) { + Log.wtf(TAG, "Executing client..."); + serverPeer.put("ip", info.groupOwnerAddress.getHostAddress()); + Log.wtf(TAG, "serverPeer " + serverPeer.toString()); + sendToPeer(info.groupOwnerAddress.getHostAddress()); + } else { + Log.wtf(TAG, "No server peer"); + } + */ + + if (serverPeer != null) { + Log.wtf(TAG, "Executing client..."); + // TODO: EVAL + serverPeer.put("ip", info.groupOwnerAddress.getHostAddress()); // + // serverPeer.put("ip", Globals.eval_ip); + Log.wtf(TAG, "serverPeer " + serverPeer.toString()); + sendToPeer(info.groupOwnerAddress.getHostAddress()); // + // sendToPeer(serverPeer.get("ip")); + // TODO: /EVAL + } else { + Log.wtf(TAG, "No server peer"); + } + + } + + } + + /** + * Tne WifiP2pManager.requestPeers(Channel, PeerListListener) returns the new + * WifiP2pDeviceList. + *

+ * Updates the: + * - Peers list + * - Service (PM) list + */ + @Override + public void onPeersAvailable(WifiP2pDeviceList peers) { + String TAG = getClass().getName() + "@onPeersAvailable: "; + + Log.wtf(TAG, "..."); + + boolean update = false; + + if (peers.getDeviceList().size() == 0) { + Log.wtf(TAG, "No devices found"); + this.peers = new ArrayList<>(); + update = true; + } else { + // Update the peers list + for (Map m : this.peers) { + boolean remove = true; + for (WifiP2pDevice d : peers.getDeviceList()) { + Log.wtf(TAG, m.get("mac") + " - " + d.deviceAddress); + if (m.get("mac").equals(d.deviceAddress)) { + Log.wtf(TAG, "Validated " + m); + remove = false; + break; + } + } + if (remove) { + Log.wtf(TAG, "Removing " + m); + this.peers.remove(m); + update = true; + } + } + } + + if (update) { + Log.wtf(TAG, "Going to update peers..."); + pm.onPeersChanged(this.peers); + } else { + Log.wtf(TAG, "Nothing changed"); + } + + + } + + // + public String getPeerAddress(int id) { + String TAG = getClass().getName() + "@getPeerAddress: "; + + Log.wtf(TAG, "..."); + + for (Map m : this.peers) { + + Log.wtf(TAG, m.get("dev") + " - " + id); + + if (Integer.parseInt((String) m.get("dev")) == id) { + + Log.wtf(TAG, m.get("mac").toString()); + + return m.get("mac").toString(); + } + } + return ""; + } + + // + public Map getPeer(String deviceAddress) { + String TAG = getClass().getName() + "@getPeer: "; + + Log.wtf(TAG, "..."); + Log.wtf(TAG, "Finding peer with address " + deviceAddress); + + for (Map m : this.peers) { + Log.wtf(TAG, "" + deviceAddress + " - " + m.get("mac")); + if (m.get("mac").equals(deviceAddress)) { + Log.wtf(TAG, "Returning " + m.toString()); + return m; + } + } + + Log.wtf(TAG, "Could not find peer with address " + deviceAddress); + return null; + } + +} diff --git a/app/src/main/java/com/www/client/pm/PmServer.java b/app/src/main/java/com/www/client/pm/PmServer.java new file mode 100644 index 0000000..d1c2dc3 --- /dev/null +++ b/app/src/main/java/com/www/client/pm/PmServer.java @@ -0,0 +1,92 @@ +package com.www.client.pm; + +import android.os.AsyncTask; +import android.os.Handler; +import android.util.Log; + +import com.www.client.Globals; +import com.www.client.Utils; + +import java.io.*; +import java.net.*; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +//public class PmServer extends AsyncTask { + +public class PmServer implements Runnable { + ServerSocket ss; + PrivacyMechanism pm; + + public PmServer(PrivacyMechanism pm) { + String TAG = getClass().getName() + ""; + this.pm = pm; + try { + this.ss = new ServerSocket(Globals.pm_port); + Log.wtf(TAG, "Socket opened"); + } catch (IOException e) { +// Log.wtf(TAG, e.getMessage()); + e.printStackTrace(); + } + + } + + + @Override + public void run() { + String TAG = getClass().getName() + "@run"; + + while (!Thread.currentThread().isInterrupted()) { + try { + Log.wtf(TAG, "Waiting for client..."); + + Socket s = ss.accept(); + + try { + // Read from the InputStream + Log.wtf(TAG, "1/6"); + + InputStream is = s.getInputStream(); + + Log.wtf(TAG, "2/6"); + + pm.aggregateData(is); + + Log.wtf(TAG, "3/6"); + + Utils.close(is); + + Log.wtf(TAG, "4/6"); + + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + s.close(); + + Log.wtf(TAG, "5/6"); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + } catch (IOException e) { + try { + + Log.wtf(TAG, "6/6"); + + if (ss != null && !ss.isClosed()) { + ss.close(); + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + e.printStackTrace(); + break; + } + } + } + +} diff --git a/app/src/main/java/com/www/client/pm/PrivacyMechanism.java b/app/src/main/java/com/www/client/pm/PrivacyMechanism.java new file mode 100644 index 0000000..d03025b --- /dev/null +++ b/app/src/main/java/com/www/client/pm/PrivacyMechanism.java @@ -0,0 +1,458 @@ +package com.www.client.pm; + +import com.www.client.Globals; +import com.www.client.Utils; + +import android.content.*; +import android.net.Uri; +import android.os.AsyncTask; +import android.preference.*; +import android.util.Log; + +import org.apache.commons.io.FilenameUtils; + +import java.io.*; +import java.lang.reflect.*; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.*; + +import dalvik.system.*; + +public class PrivacyMechanism implements SharedPreferences.OnSharedPreferenceChangeListener { + + private static Context context; + private static SharedPreferences sp; + private static SharedPreferences.OnSharedPreferenceChangeListener spLsnr; + + private int stId, pmId, pmPreferences; + + private String pmClssName; + private Class pmClss; + private Object pmInst; + private Method pmMthd; + + PmP2p pmP2p; + + public PrivacyMechanism (Context c, int pm, int st) { + final String TAG = getClass().getName() + "@PrivacyMechanism: "; + + context = c; + + sp = PreferenceManager.getDefaultSharedPreferences(c); + + pmId = pm; + stId = st; + + String pmDir = Globals.pms_dir + "/" + pmId; + String stDir = Globals.client_dir + "/" + stId; + + /**/ + pmClssName = sp.getString(Globals.pm_clss, null); + String pmZipUrl = pmDir + "/" + pmId + ".zip"; + File dex = c.getDir("dex", 0); + + DexClassLoader classLoader = new DexClassLoader(pmZipUrl, dex.getAbsolutePath(), null, this.getClass().getClassLoader()); + try { + if (pmClss == null) { + Log.wtf(TAG, "Instantiating PM " + pmId + " with class '" + pmClssName + "' for ST " + stId + " from " + pmZipUrl); + pmClss = (Class) classLoader.loadClass(pmClssName); + pmInst = pmClss.newInstance(); + } else { + Log.wtf(TAG, "PM " + pmId + " with class '" + pmClssName + "' for ST " + stId + " already instantiated."); + } + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + /**/ + } + + /** + * PrivacyMechanism functions + */ + + /** + * void onStart (Context, int, ObjectInputStream) + */ + public void onStart () { + final String TAG = getClass().getName() + "@onStart: "; + + Log.wtf(TAG, "..."); + + sp.registerOnSharedPreferenceChangeListener(this); + + pmPreferences = sp.getInt(Globals.privacy_level, 0); + + try { + + ObjectInputStream ois = Utils.getStateFrom(getId()); + + // void onStart (Context, int, ObjectInputStream) + pmMthd = pmClss.getMethod( + "onStart", + Context.class, + int.class, + ObjectInputStream.class); + + pmMthd.invoke( + pmInst, + context, + sp.getInt(Globals.privacy_level, 0), + ois); + + Utils.close(ois); + + // Collaborative staff + /**/ + try { + // void onPeersChanged (List> + pmClss.getMethod("onPeersChanged", + List.class); + + pmP2p = new PmP2p(context, this); + + } catch (NoSuchMethodException e) { + Log.wtf(TAG, "Could not find " + e.getMessage()); + } + + try { + // boolean aggregateData (ObjectInputStream, ObjectOutputStream) + pmClss.getMethod("aggregateData", + ObjectInputStream.class, + ObjectOutputStream.class); + + if(pmP2p == null) { + pmP2p = new PmP2p(context, this); + } + + } catch (NoSuchMethodException e) { + Log.wtf(TAG, "Could not find " + e.getMessage()); + } + /**/ + + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + } + + /** + * void onStop () + */ + public void onStop () { + final String TAG = getClass().getName() + "@onStop: "; + + Log.wtf(TAG, "..."); + + if(pmP2p != null) { + pmP2p.onStop(); + pmP2p = null; + } + + /**/ + sp.unregisterOnSharedPreferenceChangeListener(this); + + // save state + saveState(); + + // stop + try { + // void onStop () + pmMthd = pmClss.getMethod( + "onStop"); + pmMthd.invoke( + pmInst); + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + + pmClss = null; + /**/ + + } + + /** + * int processData (ObjectInputStream, ObjectOutputStream) + * @param data + */ + public void processData (List data) { + String TAG = getClass().getName() + "@processData: "; + + Log.wtf(TAG, "..."); + + /* + * process data + */ + int devId = 0; + String dataPath = Utils.getNewDataPath(getStId()); + + Log.wtf(TAG, "Saving data to " + dataPath); + + ObjectInputStream ois = Utils.getData(data); + ObjectOutputStream oos = Utils.putData(dataPath); + + try { + // int processData (ObjectInputStream, ObjectOutputStream) + pmMthd = pmClss.getMethod( + "processData", + ObjectInputStream.class, + ObjectOutputStream.class); + + devId = (int) pmMthd.invoke( + pmInst, + ois, + oos); + + Utils.close(oos); + Utils.close(ois); + + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + + // saveState(getId()); + + /** + * Send to server or aggregator + */ + Log.wtf(TAG, "devId == " + devId); + if (devId == 0) { + Log.wtf(TAG, "1"); + // Log.wtf(TAG, "Renaming data to " + new File(FilenameUtils.removeExtension(dataPath)).getPath()); + // new File(dataPath).renameTo(new File(FilenameUtils.removeExtension(dataPath))); + Utils.saveData(Utils.getData(dataPath), String.valueOf(getStId())); + new File(dataPath).delete(); + } else if (devId < 0) { + Log.wtf(TAG, "2"); + Log.wtf(TAG, "Deleting data " + dataPath); + new File(dataPath).delete(); + } else { + Log.wtf(TAG, "3"); + + String address = pmP2p.getPeerAddress(devId); + if(pmP2p.isWifiP2pEnabled() && !address.isEmpty()) { + Log.wtf(TAG, "Sending data to " + devId); + Utils.mergeData(dataPath, Globals.pms_dir + "/" + pmId + "/" + devId + ".dat"); + pmP2p.sendToPeer(address); + } else { + Log.wtf(TAG, pmP2p.isWifiP2pEnabled() + " | " + address); + Utils.saveData(Utils.getData(dataPath), String.valueOf(getStId())); + new File(dataPath).delete(); + } + + } + } + + /** + * boolean saveState (ObjectOutputStream) + * Called in: + * - onStop + * - processData + * - aggregateData + */ + private void saveState() { + String TAG = getClass().getName() + "@saveState: "; + + Log.wtf(TAG, "..."); + + String url = Globals.pms_dir + "/" + getId() + "/" + getId() + ".sav"; + + Log.wtf(TAG, url); + + try { + ObjectOutputStream oos = Utils.putStateTo(url); + // boolean saveState (ObjectOutputStream) + pmMthd = pmClss.getMethod( + "saveState", + ObjectOutputStream.class); + + boolean flag = (boolean) pmMthd.invoke( + pmInst, + oos); + + Utils.close(oos); + + if (flag) { + Log.wtf(TAG, "OK"); + } else { + Log.wtf(TAG, "No state saved"); + new File(url).delete(); + } + + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + + } + + /** + * void onPreferenceChanged (int) + * Monitor if user changes the privacy level and inform the PM + * @param sharedPreferences + * @param key + */ + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + final String TAG = getClass().getName() + "@onSharedPreferenceChanged: "; + + if (Globals.privacy_level.equals(key)) { + Log.wtf(TAG, "new privacy level " + sp.getInt(Globals.privacy_level, 0)); + + pmPreferences = sp.getInt(Globals.privacy_level, 0); + /* + * Call onPreferencesChanged + */ + try { +// void onPreferenceChanged (int) + pmMthd = pmClss.getMethod( + "onPreferenceChanged", + int.class); + + pmMthd.invoke( + pmInst, + sp.getInt(Globals.privacy_level, 0)); + + } catch (Exception e) { + Log.wtf(TAG, "" + e.getMessage()); + } + } + } + + /** + * void onPeersChanged (List>) + * @param peers + */ + void onPeersChanged (List> peers) { + String TAG = getClass().getName() + "@onPeersChanged: "; + + Log.wtf(TAG, "..."); + + List> list = new ArrayList<>(); + + for (Map p : peers) { + Map m = new HashMap<>(); + m.put("id", p.get("dev")); + m.put("pref", p.get("pref")); + list.add(m); + } + + Log.wtf(TAG, list.toString()); + + try { + // void onPeersChanged (List>) + pmMthd = pmClss.getMethod( + "onPeersChanged", + List.class); + + pmMthd.invoke( + pmInst, + list); + + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + + } + + /** + * boolean aggregateData (ObjectInputStream, ObjectOutputStream) + * Called by PmP2p > connect > onConnectionInfoAvailable > PmServer + * @param is + */ + public void aggregateData(InputStream is) { + String TAG = getClass().getName() + "@aggregateData: "; + + Log.wtf(TAG, "..."); + + try { + + Log.wtf(TAG, "1"); + + ObjectInputStream ois = new ObjectInputStream(is); + + Log.wtf(TAG, "2"); + + String dataPath = Utils.getNewDataPath(getStId()); + + Log.wtf(TAG, "3"); + + ObjectOutputStream oos = Utils.putData(dataPath); + + Log.wtf(TAG, "4"); + + boolean flag = false; + + try { + // boolean aggregateData (ObjectInputStream, ObjectOutputStream) + pmMthd = pmClss.getMethod( + "aggregateData", + ObjectInputStream.class, + ObjectOutputStream.class); + + Log.wtf(TAG, "5"); + + flag = (boolean) pmMthd.invoke( + pmInst, + ois, + oos); + + Log.wtf(TAG, "6"); + + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + + Log.wtf(TAG, "7"); + + Utils.close(oos); + Utils.close(ois); + Utils.close(is); + + Log.wtf(TAG, "8"); + + if (flag) { + Utils.saveData(Utils.getData(dataPath), String.valueOf(getStId())); + } + + Log.wtf(TAG, "9"); + + new File(dataPath).delete(); + + Log.wtf(TAG, "10"); + + saveState(); + + Log.wtf(TAG, "11"); + + } catch (Exception e) { + Log.wtf(TAG, e.getMessage()); + } + + Log.wtf(TAG, "OK"); + } + + /** + * Misc. + */ + + public int getId () { + final String TAG = getClass().getName() + "@getId: "; + return pmId; + } + + public int getVersion() { + //TODO + return 0; + } + + public int getPreferences() { + String TAG = getClass().getName() + "@getPreferences: "; + return pmPreferences; + } + + public int getStId () { + String TAG = getClass().getName() + "@getStId: "; + return stId; + } + +} diff --git a/app/src/main/java/com/www/client/pm/PrivacyMechanismArrayAdapter.java b/app/src/main/java/com/www/client/pm/PrivacyMechanismArrayAdapter.java new file mode 100644 index 0000000..6aa2c7f --- /dev/null +++ b/app/src/main/java/com/www/client/pm/PrivacyMechanismArrayAdapter.java @@ -0,0 +1,76 @@ +package com.www.client.pm; + +import android.app.Activity; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.www.client.ClientActivity; +import com.www.client.R; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; + +public class PrivacyMechanismArrayAdapter extends ArrayAdapter { + + private static final String TAG = "PrivacyMechanismArrayAdapter"; + Context context; + + public PrivacyMechanismArrayAdapter(Context context, int resourceId, List items) { + super(context, resourceId, items); + this.context = context; + } + + /*private view holder class*/ + private class ViewHolder { + TextView nameView; + TextView userView; + TextView statusView; + } + + public View getView(int position, View view, ViewGroup group) { + ViewHolder holder = null; + JSONObject item = null; + try { + item = new JSONObject(getItem(position)); + } catch (JSONException e) { + e.printStackTrace(); + } + + LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); + if (view == null) { + view = inflater.inflate(R.layout.privacy_mechanism_item, null); + holder = new ViewHolder(); + holder.nameView = (TextView) view.findViewById(R.id.name); + holder.userView = (TextView) view.findViewById(R.id.user); + holder.statusView = (TextView) view.findViewById(R.id.status); + view.setTag(holder); + } + else { + holder = (ViewHolder) view.getTag(); + } + + try { + if (item != null) { + holder.nameView.setText(item.getJSONArray("name").getString(0)); + holder.userView.setText("by " + item.getJSONArray("user").getString(0)); + if(ClientActivity.sharedPref.getString("pmID", null) != null && + item.getJSONArray("id").getString(0).equals(ClientActivity.sharedPref.getString("pmID", null))) { + holder.statusView.setText("INSTALLED"); + } else { + holder.statusView.setText(" "); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return view; + } +} diff --git a/app/src/main/java/com/www/client/pm/PrivacyMechanismsActivity.java b/app/src/main/java/com/www/client/pm/PrivacyMechanismsActivity.java new file mode 100644 index 0000000..e93d386 --- /dev/null +++ b/app/src/main/java/com/www/client/pm/PrivacyMechanismsActivity.java @@ -0,0 +1,184 @@ +package com.www.client.pm; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.net.ConnectivityManager; +import android.os.Bundle; +import android.os.Environment; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.www.client.Globals; +import com.www.client.R; + + +public class PrivacyMechanismsActivity extends Activity implements SeekBar.OnSeekBarChangeListener { + private static final String TAG = "PrivacyMechanismsActivity"; + + private static final String SDCARD = Environment.getExternalStorageDirectory().getPath(); + public static final String CLIENT = SDCARD + "/Client"; + + private static ConnectivityManager cm; + + public static SharedPreferences sp = null; + public static SharedPreferences.Editor spEditor = null; + + SeekBar seekBar; + TextView statusText; + TextView levelText; + TextView commentText; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_privacy_mechanisms); + + cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + + sp = PreferenceManager.getDefaultSharedPreferences(this); + spEditor = sp.edit(); + + statusText = (TextView) findViewById(R.id.status); + statusText.setText("LOW"); + statusText.setTextColor(Color.rgb(255, 0, 0)); + levelText = (TextView) findViewById(R.id.level); + commentText = (TextView) findViewById(R.id.comment); + + seekBar = (SeekBar) findViewById(R.id.level_bar); + seekBar.setOnSeekBarChangeListener(this); + seekBar.setProgress(sp.getInt(Globals.privacy_level, 0)); + seekBar.setSecondaryProgress(sp.getInt(Globals.privacy_level, 0)); + + levelText.setText(""); + + /* + * Buttons + */ + findViewById(R.id.ok_btn).setOnClickListener(okListener); + findViewById(R.id.cancel_btn).setOnClickListener(cancelListener);; + + // install +// Button getListBtn = (Button)findViewById(R.id.get_list_btn); +// getListBtn.setOnClickListener(new View.OnClickListener() { +// public void onClick(View v) { +//// startActivity(new Intent(getBaseContext(), AddPrivacyRegionActivity.class)); +// Toast.makeText(getApplicationContext(), "list", Toast.LENGTH_SHORT).show(); +// } +// }); + + // view installed +// Button viewBtn = (Button)findViewById(R.id.view_btn); +// viewBtn.setOnClickListener(new View.OnClickListener() { +// public void onClick(View v) { +//// startActivity(new Intent(getBaseContext(), AddPrivacyRegionActivity.class)); +// Toast.makeText(getApplicationContext(), "view", Toast.LENGTH_SHORT).show(); +// } +// }); + } + + /* + * Action bar menu methods + */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_privacy_mechanisms, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.privacy_mechanisms_get_list) { +// Toast.makeText(getApplicationContext(), "list", Toast.LENGTH_SHORT).show(); + Intent i = new Intent(this, ListPrivacyMechanismsActivity.class); + startActivity(i); + return true; + } + if (id == R.id.privacy_mechanisms_view_installed) { +// Toast.makeText(getApplicationContext(), "in", Toast.LENGTH_SHORT).show(); + Intent i = new Intent(this, ViewPrivacyMechanismActivity.class); + i.putExtra("intent", "view"); + startActivity(i); + return true; + } + + return super.onOptionsItemSelected(item); + } + + /* + * Seekbar methods + */ + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + int r = (255 * (100 - progress)) / 100; + int g = (255 * progress) / 100; + int b = 0; + + levelText.setTextColor(Color.rgb(r, g, b)); + levelText.setText(progress + "%"); + + statusText.setTextColor(Color.rgb(r, g, b)); + + if (progress < 33) { + statusText.setText("LOW"); + } else if (progress >= 33 && progress <66) { + statusText.setText("MEDIUM"); + } else { + statusText.setText("HIGH"); + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + levelText.setText(""); + } + + private void updateContentView(int i) { + + } + + /* + * Buttons + */ + private View.OnClickListener okListener = new View.OnClickListener() { + + // OK button + public void onClick(View v) { + String TAG = getClass().getName() + "@onClick: "; + + seekBar.setSecondaryProgress(seekBar.getProgress()); + spEditor.putInt(Globals.privacy_level, seekBar.getProgress()); + spEditor.commit(); + + Log.wtf(TAG, Globals.privacy_level + " -> " + seekBar.getProgress()); + } + }; + + private View.OnClickListener cancelListener = new View.OnClickListener() { + // Cancel button + public void onClick(View v) { + seekBar.setProgress(sp.getInt(Globals.privacy_level, 0)); + seekBar.setSecondaryProgress(sp.getInt(Globals.privacy_level, 0)); + levelText.setText(""); + } + }; +} diff --git a/app/src/main/java/com/www/client/pm/ViewPrivacyMechanismActivity.java b/app/src/main/java/com/www/client/pm/ViewPrivacyMechanismActivity.java new file mode 100644 index 0000000..ae27fa6 --- /dev/null +++ b/app/src/main/java/com/www/client/pm/ViewPrivacyMechanismActivity.java @@ -0,0 +1,333 @@ +package com.www.client.pm; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.AsyncTask; +import android.os.Environment; +import android.preference.PreferenceManager; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.ListView; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.Toast; + +import com.www.client.ClientActivity; +import com.www.client.Globals; +import com.www.client.R; +import com.www.client.Utils; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.io.IOException; +import java.text.DecimalFormat; +import java.util.ArrayList; + +public class ViewPrivacyMechanismActivity extends Activity { + + String sdcard = Environment.getExternalStorageDirectory().getPath(); + String clientDir = sdcard + "/Client"; + String pmsDir = clientDir + "/PMs"; + + SharedPreferences sp = null; + SharedPreferences.Editor spEditor = null; + + String parentActivity = ""; + + TextView textView; + Button button; + ScrollView scrollView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + String TAG = ViewPrivacyMechanismActivity.class.getName() + "@onCreate: "; + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_view_privacy_mechanism); + + sp = PreferenceManager.getDefaultSharedPreferences(this); + spEditor = sp.edit(); + + final Intent i = getIntent(); + + button = (Button)findViewById(R.id.button); + button.setText("Install"); + button.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + button.setEnabled(false); + if("Install".equals(button.getText())) { + button.setText("Installing..."); + + Toast.makeText(getApplicationContext(), "Installing...", Toast.LENGTH_SHORT).show(); + + /* + * Remove previous PM + */ + if(sp.getString("pmID", null) != null) { + removePM(sp.getString("pmID", null)); + } + + spEditor.putString("pmID", i.getStringExtra("id")); + spEditor.putString("pmName", i.getStringExtra("name")); + spEditor.putString("pmVersion", i.getStringExtra("version")); +// +// class name +// + spEditor.putString(Globals.pm_clss, i.getStringExtra("class")); +// +// st id +// + spEditor.putString(Globals.pm_st_id, sp.getString(Globals.st_id, "0")); +// +// +// + spEditor.putString("pmDescription", i.getStringExtra("description")); + spEditor.putString("pmUser", i.getStringExtra("user")); + spEditor.putString("pmDate", i.getStringExtra("date")); + spEditor.putString("pmTime", i.getStringExtra("time")); + spEditor.putString("pmSize", i.getStringExtra("size")); + spEditor.commit(); + + getPM(); + +// Toast.makeText(getApplicationContext(), "Done", Toast.LENGTH_SHORT).show(); +// button.setText("Uninstall"); + } else { + button.setText("Uninstalling..."); + Toast.makeText(getApplicationContext(), "Uninstalling...", Toast.LENGTH_SHORT).show(); + + removePM(sp.getString("pmID", null)); + + Toast.makeText(getApplicationContext(), "Done", Toast.LENGTH_SHORT).show(); +// button.setText("Install"); + +// returnToParent(); + finish(); + } +// button.setEnabled(true); + } + }); + + if("get".equals(i.getStringExtra("intent"))) { + // Came here from the list + + parentActivity = "ListPrivacyMechanismsActivity"; + + textView = (TextView) findViewById(R.id.message); + textView.setVisibility(View.INVISIBLE); + + if(i.getStringExtra("id").equals(sp.getString("pmID", null))) { + button.setText("Uninstall"); + } + + textView = (TextView) findViewById(R.id.name); + textView.setText(i.getStringExtra("name")); + setTitle(i.getStringExtra("name")); + + textView = (TextView) findViewById(R.id.version); + textView.setText("version " + i.getStringExtra("version") + ".0"); + + textView = (TextView) findViewById(R.id.user); + textView.setText("by " + i.getStringExtra("user")); + + textView = (TextView) findViewById(R.id.description); + textView.setText(i.getStringExtra("description")); + + textView = (TextView) findViewById(R.id.date_time); + textView.setText(i.getStringExtra("date") + "\n" + i.getStringExtra("time")); + + textView = (TextView) findViewById(R.id.size); +// textView.setText(i.getStringExtra("size") + "b"); + textView.setText(String.format( "%.2f", Float.valueOf(i.getStringExtra("size")) /1000) + " KB"); + + textView = (TextView) findViewById(R.id.id); + textView.setText(i.getStringExtra("id")); + } else { + // Came here from the PM settings + + parentActivity = "PrivacyMechanismsActivity"; + + if(sp.getString("pmID", null) != null) { + textView = (TextView) findViewById(R.id.message); + textView.setVisibility(View.INVISIBLE); + + button.setText("Uninstall"); + + textView = (TextView) findViewById(R.id.name); + textView.setText(sp.getString("pmName", "")); + setTitle(sp.getString("pmName", "")); + + textView = (TextView) findViewById(R.id.version); + textView.setText("version " + sp.getString("pmVersion", "") + ".0"); + + textView = (TextView) findViewById(R.id.user); + textView.setText("by " + sp.getString("pmUser", "")); + + textView = (TextView) findViewById(R.id.description); + textView.setText(sp.getString("pmDescription", "")); + + textView = (TextView) findViewById(R.id.date_time); + textView.setText(sp.getString("pmDate", "") + "\n" + sp.getString("pm_time", "")); + + textView = (TextView) findViewById(R.id.size); + textView.setText(String.format( "%.2f", Float.valueOf(sp.getString("pmSize", "0"))/1000) + " KB"); + + textView = (TextView) findViewById(R.id.id); + textView.setText(sp.getString("pmID", "")); + } else { + scrollView = (ScrollView) findViewById(R.id.content); + scrollView.setVisibility(View.INVISIBLE); + + textView = (TextView) findViewById(R.id.message); + textView.setText("No privacy mechanism installed"); + } + } + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. +// getMenuInflater().inflate(R.menu.menu_view_privacy_mechanism, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + // Respond to the action bar's Up/Home button + if (id == android.R.id.home) { + returnToParent(); + } + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + private boolean returnToParent() { + Intent i = null; + try { + i = new Intent(this, Class.forName("com.www.client.pm." + parentActivity)); + startActivity(i); + finish(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + return true; + } + + private void getPM() { + String TAG = ViewPrivacyMechanismActivity.class.getName() + "@getPM: "; +// Toast.makeText(getApplicationContext(), "Getting list...", Toast.LENGTH_SHORT).show(); + + String deviceID = sp.getString("deviceID", null); + String pmID = sp.getString("pmID", null); + + if (deviceID != null && pmID != null) { + if (ClientActivity.isOnline()) { + String url = Globals.pms_url + "/" + pmID + "/getbin/" + deviceID; + Log.wtf(TAG, url); +// Toast.makeText(getApplicationContext(), url, Toast.LENGTH_SHORT).show(); + new GetPM().execute(url); + } else { + Log.wtf(TAG, "Offline."); + Toast.makeText(getApplicationContext(), "No network connection", Toast.LENGTH_SHORT).show(); + } + } else { + Log.wtf(TAG, "Not registered yet"); + Toast.makeText(getApplicationContext(), "Not registered yet", Toast.LENGTH_SHORT).show(); + } + } + + private class GetPM extends AsyncTask { + @Override + protected String doInBackground(String... params) { + String TAG = GetPM.class.getName() + "@doInBackground: "; + + Log.wtf(TAG, "..."); + + HttpClient client = new DefaultHttpClient(); + HttpGet request = new HttpGet(params[0]); + HttpResponse response = null; + String result = "Oops!"; + + try { + response = client.execute(request); + if (response != null) { + String dir = pmsDir + "/" + sp.getString("pmID", null); + Log.wtf(TAG, dir); + new File(dir).mkdir(); + String url = dir + "/" + sp.getString("pmID", null) + ".zip"; + Log.wtf(TAG, url); + Utils.writeToFile(response.getEntity().getContent(), url); + Log.wtf(TAG, Long.toString(new File(url).length()) + " == " + sp.getString("pmSize", null)); + if(new File(url).length() == Long.valueOf(sp.getString("pmSize", null))) { + result = "OK"; + } + } + } catch (IOException e) { + Log.e(TAG, e.getMessage()); + } + + return result; + } + + protected void onPostExecute(String result) { + String TAG = GetPM.class.getName() + "@onPostExecute: "; + + Log.wtf(TAG, result); + + if(!"OK".equals(result)) { + Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show(); + removePM(sp.getString("pmID", null)); + button.setText("Install"); + button.setEnabled(true); + } else { + Toast.makeText(getApplicationContext(), "Done", Toast.LENGTH_SHORT).show(); +// returnToParent(); + finish(); + } + } + } + + private void removePM(String id) { + Utils.delete(new File(pmsDir + "/" + id.toString())); + + spEditor.putString("pmID", null); + spEditor.putString("pmName", null); + spEditor.putString("pmVersion", null); +// +// class name + spEditor.putString(Globals.pm_clss, null); +// +// sensing task id + spEditor.putString(Globals.pm_st_id, null); +// + spEditor.putString("pmDescription", null); + spEditor.putString("pmUser", null); + spEditor.putString("pmDate", null); + spEditor.putString("pmTime", null); + spEditor.putString("pmSize", null); + spEditor.commit(); + } + +} diff --git a/app/src/main/java/com/www/client/pr/AddPrivacyRegionActivity.java b/app/src/main/java/com/www/client/pr/AddPrivacyRegionActivity.java new file mode 100644 index 0000000..a2b1d60 --- /dev/null +++ b/app/src/main/java/com/www/client/pr/AddPrivacyRegionActivity.java @@ -0,0 +1,152 @@ +package com.www.client.pr; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Environment; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.GoogleMapOptions; +import com.google.android.gms.maps.MapFragment; +import com.google.android.gms.maps.model.LatLngBounds; +import com.www.client.R; +import com.www.client.Utils; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; + + +public class AddPrivacyRegionActivity extends Activity { + private static final String TAG = "AddPrivacyRegionActivity"; + + private GoogleMap regionMap = null; + private EditText region_label = null; + + private static final String SDCARD = Environment.getExternalStorageDirectory().getPath(); + public static final String CLIENT = SDCARD + "/Client"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_add_privacy_region); + + GoogleMapOptions mapOptions = new GoogleMapOptions(); + regionMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.region_map)).getMap(); + + region_label = (EditText) findViewById(R.id.region_label); + //region_label.setImeActionLabel("OK", EditorInfo.IME_ACTION_DONE); + region_label.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View arg0) { + region_label.setError(null); + } + });/**/ + /*region_label.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {} + @Override + public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { + region_label.setError(null); + } + @Override + public void afterTextChanged(Editable editable) {} + }); + /*region_label.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + addPrivacyRegion(); + } + return false; + } + });/**/ + //region_label.setImeActionLabel("OK", KeyEvent.KEYCODE_ENTER); + + final TextView info = (TextView) findViewById(R.id.info); + info.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View arg0) { + info.setVisibility(View.GONE); + } + });/**/ + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.add_privacy_region, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + if (id == R.id.action_ok) { + //Toast.makeText(getApplicationContext(), "onOptionsItemSelected: " + "OK", Toast.LENGTH_SHORT).show(); + addPrivacyRegion(); + + return true; + }/**/ + if (id == R.id.action_cancel) { + //Toast.makeText(getApplicationContext(), "onOptionsItemSelected: " + "CANCEL", Toast.LENGTH_SHORT).show(); + finish(); + return true; + }/**/ + return super.onOptionsItemSelected(item); + } + + public void addPrivacyRegion() { + if(region_label.getText().toString().trim().equals("")) { + region_label.setError("Region label is required!"); + } + else { + region_label.setError(null); + LatLngBounds bounds = regionMap.getProjection().getVisibleRegion().latLngBounds; + String label = region_label.getText().toString(); + + /*Toast.makeText(getApplicationContext(), region_label.getText().toString() + "\n" + + bounds.northeast.latitude + " - " + bounds.northeast.longitude + "\n" + + bounds.southwest.latitude + " - " + bounds.southwest.longitude, Toast.LENGTH_SHORT).show();/**/ + + JSONObject region = new JSONObject(); + try { + region.put("label", label); + SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd_HHmmss"); + region.put("id", sdf.format(new Date())); + region.put("ne_lat", bounds.northeast.latitude); + region.put("ne_lng", bounds.northeast.longitude); + region.put("sw_lat", bounds.southwest.latitude); + region.put("sw_lng", bounds.southwest.longitude); + Log.i(TAG, "addPrivacyRegion: " + region.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + Utils.writeJSONtoFile(region, new File(CLIENT + "/" + "Settings" + "/" + "PrivacyRegions")); + + try { + Toast.makeText(getApplicationContext(), "\"" + region.getString("label") + "\" " + " has been added.", Toast.LENGTH_SHORT).show(); + } catch (JSONException e) { + e.printStackTrace(); + } + + /**/ + startActivity(new Intent(getBaseContext(), PrivacyRegionsActivity.class)); + } + } + +} diff --git a/app/src/main/java/com/www/client/pr/Demo.java b/app/src/main/java/com/www/client/pr/Demo.java new file mode 100644 index 0000000..b1366d8 --- /dev/null +++ b/app/src/main/java/com/www/client/pr/Demo.java @@ -0,0 +1,142 @@ +package com.www.client.pr; + +import java.util.*; +import java.io.*; + +import android.content.Context; +import android.util.*; + +@SuppressWarnings("unchecked") +public class Demo { + + private Context context; + private int pref; + private List state; + private List> peers; + + public void onStart (Context c, int i, ObjectInputStream ois) throws Exception { + String TAG = getClass().getName() + "@onStart: "; + + Log.wtf(TAG, "..."); + +// get application context + context = c; + +// get privacy preferences + pref = i; + +// restore state + if (ois != null) { + Log.wtf(TAG, "Restoring state..."); + state = (List) ois.readObject(); + } else { + Log.wtf(TAG, "Initializing state..."); + state = new ArrayList<>(); + } + + peers = new ArrayList<>(); + + } + + public void onStop () { + String TAG = getClass().getName() + "@onStop: "; + + Log.wtf(TAG, "..."); + + } + + public void onPreferenceChanged (int i) { + String TAG = getClass().getName() + "@onPreferenceChanged: "; + + Log.wtf(TAG, "" + i); + + pref = i; + + } + + public boolean saveState (ObjectOutputStream oos) { + String TAG = getClass().getName() + "@saveState: "; + + Log.wtf(TAG, "..."); + +// s.writeObject(state); + + return false; + + } + + public int processData (ObjectInputStream ois, ObjectOutputStream oos) throws Exception { + String TAG = getClass().getName() + "@processData: "; + + Log.wtf(TAG, "..."); + +// get list of data + List list = (List) ois.readObject(); + +// edit each data entry of the data list + for (Object o : list) { + + Map data = (Map) o; + data.put("device", data.get("device")); + data.put("task", data.get("task")); + data.put("sensor", data.get("sensor")); + data.put("values", data.get("values")); + + float min = -1; + float max = 1; + + Random r = new Random(); + float d = min + (max - min) * r.nextFloat(); // -1 < d < 1 + + long var = (long) (((float) pref / 10) * d * 3600000000000L); // (pref/10) * random * (1hr) + + data.put("timestamp", (Long) data.get("timestamp") + var); + + } + + oos.writeObject(list); + + // If a peer is present + Log.wtf(TAG, "Returning..."); + if(!peers.isEmpty()) { + // Collaborate + Log.wtf(TAG, peers.get(0).get("id")); + return Integer.parseInt(peers.get(0).get("id")); + } + Log.wtf(TAG, "No peers"); + return 0; + + } + + /* + * Collaborative stuff + */ + /**/ + public void onPeersChanged (List> peers) { + String TAG = getClass().getName() + "@onPeersChanged: "; + + Log.wtf(TAG, "..."); + + this.peers = peers; + + Log.wtf(TAG, peers.toString()); + + } + + public boolean aggregateData (ObjectInputStream ois, ObjectOutputStream oos) throws Exception { + String TAG = getClass().getName() + "@aggregateData: "; + + Log.wtf(TAG, "..."); + + // Read input stream + List data = (List) ois.readObject(); + + // Write to output stream + oos.writeObject(data); + + return true; + + } + /**/ + +} diff --git a/app/src/main/java/com/www/client/pr/EditPrivacyRegionActivity.java b/app/src/main/java/com/www/client/pr/EditPrivacyRegionActivity.java new file mode 100644 index 0000000..03e4b24 --- /dev/null +++ b/app/src/main/java/com/www/client/pr/EditPrivacyRegionActivity.java @@ -0,0 +1,188 @@ +package com.www.client.pr; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.EditText; +import android.widget.Toast; + +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.MapFragment; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.LatLngBounds; +import com.www.client.R; +import com.www.client.Utils; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + + +public class EditPrivacyRegionActivity extends Activity { + private static final String TAG = "EditPrivacyRegionActivity"; + + private JSONObject privacyRegion = null; + + private GoogleMap regionMap = null; + private EditText region_label = null; + + private static final String SDCARD = Environment.getExternalStorageDirectory().getPath(); + public static final String CLIENT = SDCARD + "/Client"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_edit_privacy_region); + + try { + privacyRegion = new JSONObject((String) getIntent().getSerializableExtra("privacyRegion")); + //Log.i(TAG, privacyRegion.toString()); + setTitle(privacyRegion.getString("label")); + } catch (JSONException e) { + e.printStackTrace(); + } + + regionMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.region_map)).getMap(); + final View mapView = getFragmentManager().findFragmentById(R.id.region_map).getView(); + + LatLngBounds.Builder bounds; + bounds = new LatLngBounds.Builder(); + + if (mapView.getViewTreeObserver().isAlive()) { + mapView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @SuppressLint("NewApi") // We check which build version we are using. + @Override + public void onGlobalLayout() { + + LatLngBounds bounds = null; + try { + bounds = new LatLngBounds.Builder() + .include(new LatLng(privacyRegion.getDouble("ne_lat"), privacyRegion.getDouble("ne_lng"))) + .include(new LatLng(privacyRegion.getDouble("sw_lat"), privacyRegion.getDouble("sw_lng"))) + .build(); + } catch (JSONException e) { + e.printStackTrace(); + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } else { + mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } + regionMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)); + } + }); + } + + region_label = (EditText) findViewById(R.id.region_label); + try { + region_label.setText(privacyRegion.getString("label")); + } catch (JSONException e) { + e.printStackTrace(); + } + //region_label.setImeActionLabel("OK", EditorInfo.IME_ACTION_DONE); + region_label.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View arg0) { + region_label.setError(null); + } + });/**/ + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.edit_privacy_region, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + if (id == R.id.action_ok) { + //Toast.makeText(getApplicationContext(), "onOptionsItemSelected: " + "OK", Toast.LENGTH_SHORT).show(); + editPrivacyRegion(); + return true; + }/**/ + if (id == R.id.action_cancel) { + //Toast.makeText(getApplicationContext(), "onOptionsItemSelected: " + "CANCEL", Toast.LENGTH_SHORT).show(); + finish(); + return true; + }/**/ + return super.onOptionsItemSelected(item); + } + + public void editPrivacyRegion() { + if(region_label.getText().toString().trim().equals("")) { + region_label.setError("Region label is required!"); + } + else { + region_label.setError(null); + LatLngBounds bounds = regionMap.getProjection().getVisibleRegion().latLngBounds; + String label = region_label.getText().toString(); + + /*Toast.makeText(getApplicationContext(), region_label.getText().toString() + "\n" + + bounds.northeast.latitude + " - " + bounds.northeast.longitude + "\n" + + bounds.southwest.latitude + " - " + bounds.southwest.longitude, Toast.LENGTH_SHORT).show();/**/ + + JSONObject region = new JSONObject(); + try { + region.put("label", label); + SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd_HHmmss"); + region.put("id", sdf.format(new Date())); + region.put("ne_lat", bounds.northeast.latitude); + region.put("ne_lng", bounds.northeast.longitude); + region.put("sw_lat", bounds.southwest.latitude); + region.put("sw_lng", bounds.southwest.longitude); + //Log.i(TAG, "editPrivacyRegion: " + region.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + + ArrayList privacyRegions = new ArrayList(); + privacyRegions = Utils.fileToJSON(new File(CLIENT + "/" + "Settings" + "/" + "PrivacyRegions")); + + int i = 0; + for (JSONObject jsonObject : privacyRegions) { + try { + if (jsonObject.getString("id").equals(privacyRegion.getString("id")) + && jsonObject.getString("label").equals(privacyRegion.getString("label"))) { + //Toast.makeText(getApplicationContext(), jsonObject.getString("label"), Toast.LENGTH_SHORT).show(); + privacyRegions.set(i, region); + break; + } + } catch (JSONException e) { + e.printStackTrace(); + } + i++; + } + Utils.overwriteJSONtoFile(privacyRegions, new File(CLIENT + "/" + "Settings" + "/" + "PrivacyRegions")); + + try { + Toast.makeText(getApplicationContext(), "\"" + privacyRegion.getString("label") + "\" " + "has been edited.", Toast.LENGTH_SHORT).show(); + } catch (JSONException e) { + e.printStackTrace(); + } + + finish(); + /*Intent intent = new Intent(this, ViewPrivacyRegionActivity.class); + intent.putExtra("privacyRegion", region.toString()); + startActivity(intent);/**/ + } + } +} diff --git a/app/src/main/java/com/www/client/pr/PrivacyRegionsActivity.java b/app/src/main/java/com/www/client/pr/PrivacyRegionsActivity.java new file mode 100644 index 0000000..2f7e6d4 --- /dev/null +++ b/app/src/main/java/com/www/client/pr/PrivacyRegionsActivity.java @@ -0,0 +1,174 @@ +package com.www.client.pr; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Environment; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.ListView; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + +import com.www.client.ClientActivity; +import com.www.client.ItemArrayAdapter; +import com.www.client.R; +import com.www.client.TaskService; +import com.www.client.Utils; + +import org.json.JSONObject; + +import java.io.File; +import java.util.ArrayList; + +public class PrivacyRegionsActivity extends Activity implements CompoundButton.OnCheckedChangeListener, AdapterView.OnItemClickListener { + private static final String TAG = "PrivacyRegionsActivity"; + + private static final String SDCARD = Environment.getExternalStorageDirectory().getPath(); + public static final String CLIENT = SDCARD + "/Client"; + + public static SharedPreferences sp = null; + public static SharedPreferences.Editor spEditor = null; + + Switch actionBarSwitch; + + ArrayList privacyRegions = null; + + ListView listView; + TextView textView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_privacy_regions); + setTitle(getResources().getString((R.string.privacy_regions_title))); + + sp = PreferenceManager.getDefaultSharedPreferences(this); + spEditor = sp.edit(); + + Button addNewButton = (Button)findViewById(R.id.add_new); + addNewButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v){ + startActivity(new Intent(getBaseContext(), AddPrivacyRegionActivity.class)); + } + }); + } + + @Override + protected void onResume() { + //Log.i(TAG, "onResume: ..."); + super.onResume(); + loadList(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + onResume(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.activity_privacy_regions, menu); + + actionBarSwitch = (Switch)menu.findItem(R.id.action_bar_switch).getActionView().findViewById(R.id.switch_button); + actionBarSwitch.setChecked(sp.getBoolean(getResources().getString((R.string.privacy_regions_status)), false)); + actionBarSwitch.setOnCheckedChangeListener(this); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + switch (item.getItemId()) { + case R.id.switch_button: + Toast.makeText(ClientActivity.getContext(), "onOptionsItemSelected: " + item.toString(), Toast.LENGTH_SHORT).show(); + return true; + default:return super.onOptionsItemSelected(item); + } + } + + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + //Toast.makeText(getApplicationContext(), "onCheckedChanged: " + compoundButton, Toast.LENGTH_SHORT).show(); + if (compoundButton == actionBarSwitch) { + //Toast.makeText(getApplicationContext(), "onCheckedChanged: " + compoundButton + " = " + b, Toast.LENGTH_SHORT).show(); + spEditor.putBoolean(getResources().getString((R.string.privacy_regions_status)), b); + spEditor.commit(); + //Log.i(TAG, "onCheckedChanged: " + sp.getAll()); + //restart service + //Toast.makeText(getApplicationContext(), "Restarting...", Toast.LENGTH_SHORT).show(); + if(isServiceRunning()) { + Log.i(TAG, "onCheckedChanged: " + "Restarting service..."); + stopService(new Intent(this, TaskService.class)); + startService(new Intent(this, TaskService.class)); + }/**/ + } + } + + + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + JSONObject choice = privacyRegions.get(i); + //Toast.makeText(getApplicationContext(), choice.toString(), Toast.LENGTH_SHORT).show(); + //Log.i(TAG, choice.toString()); + Intent intent = new Intent(this, ViewPrivacyRegionActivity.class); + intent.putExtra("privacyRegion", choice.toString()); + startActivity(intent); + } + + private void loadList() { + //Log.i(TAG, "loadList: ... "); + privacyRegions = Utils.fileToJSON(new File(CLIENT + "/" + "Settings" + "/" + "PrivacyRegions")); + textView = (TextView) findViewById(R.id.info); + listView = (ListView) findViewById(R.id.list); + //Log.i(TAG, "loadList: " + privacyRegions.toString()); + + if (privacyRegions.isEmpty()) { + //Log.i(TAG, "privacyRegions is empty"); + listView.setVisibility(View.GONE); + textView.setVisibility(View.VISIBLE); + } + else { + //Log.i(TAG, "privacyRegions not empty"); + textView.setVisibility(View.GONE); + /*for (JSONObject privacyRegion : privacyRegions) { + Log.i(TAG, "loadList: " + privacyRegion.toString()); + }/**/ + + listView = (ListView) findViewById(R.id.list); + + ItemArrayAdapter adapter = new ItemArrayAdapter(this, R.layout.item, privacyRegions); + listView.setAdapter(adapter); + listView.setOnItemClickListener(this); + } + } + + private boolean isServiceRunning() { + ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + if (TaskService.class.getName().equals(service.service.getClassName())) { + return true; + } + } + return false; + } +} diff --git a/app/src/main/java/com/www/client/pr/ViewPrivacyRegionActivity.java b/app/src/main/java/com/www/client/pr/ViewPrivacyRegionActivity.java new file mode 100644 index 0000000..98cf08d --- /dev/null +++ b/app/src/main/java/com/www/client/pr/ViewPrivacyRegionActivity.java @@ -0,0 +1,142 @@ +package com.www.client.pr; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.Toast; + +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.MapFragment; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.LatLngBounds; +import com.www.client.R; +import com.www.client.Utils; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.util.ArrayList; + + +public class ViewPrivacyRegionActivity extends Activity { + private static final String TAG = "ViewPrivacyRegionActivity"; + + private JSONObject privacyRegion = null; + + private GoogleMap regionMap = null; + + private static final String SDCARD = Environment.getExternalStorageDirectory().getPath(); + public static final String CLIENT = SDCARD + "/Client"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_view_privacy_region); + + try { + privacyRegion = new JSONObject((String) getIntent().getSerializableExtra("privacyRegion")); + //Log.i(TAG, privacyRegion.toString()); + setTitle(privacyRegion.getString("label")); + } catch (JSONException e) { + e.printStackTrace(); + } + + regionMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.region_map)).getMap(); + final View mapView = getFragmentManager().findFragmentById(R.id.region_map).getView(); + + regionMap.getUiSettings().setZoomControlsEnabled(false); + regionMap.getUiSettings().setCompassEnabled(false); + regionMap.getUiSettings().setAllGesturesEnabled(false); + regionMap.getUiSettings().setMyLocationButtonEnabled(false);/**/ + + LatLngBounds.Builder bounds; + bounds = new LatLngBounds.Builder(); + + if (mapView.getViewTreeObserver().isAlive()) { + mapView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @SuppressLint("NewApi") // We check which build version we are using. + @Override + public void onGlobalLayout() { + + LatLngBounds bounds = null; + try { + bounds = new LatLngBounds.Builder() + .include(new LatLng(privacyRegion.getDouble("ne_lat"), privacyRegion.getDouble("ne_lng"))) + .include(new LatLng(privacyRegion.getDouble("sw_lat"), privacyRegion.getDouble("sw_lng"))) + .build(); + } catch (JSONException e) { + e.printStackTrace(); + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } else { + mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } + regionMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)); + } + }); + } + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.view_privacy_region, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + if (id == R.id.action_edit) { + Intent intent = new Intent(this, EditPrivacyRegionActivity.class); + intent.putExtra("privacyRegion", privacyRegion.toString()); + startActivity(intent); + return true; + } + if (id == R.id.action_delete) { + //Toast.makeText(getApplicationContext(), "onOptionsItemSelected: " + "DELETE", Toast.LENGTH_SHORT).show(); + ArrayList privacyRegions = new ArrayList(); + privacyRegions = Utils.fileToJSON(new File(CLIENT + "/" + "Settings" + "/" + "PrivacyRegions")); + + for (JSONObject jsonObject : privacyRegions) { + try { + if (jsonObject.getString("id").equals(privacyRegion.getString("id")) + && jsonObject.getString("label").equals(privacyRegion.getString("label"))) { + //Toast.makeText(getApplicationContext(), jsonObject.getString("label"), Toast.LENGTH_SHORT).show(); + privacyRegions.remove(jsonObject); + break; + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + Utils.overwriteJSONtoFile(privacyRegions, new File(CLIENT + "/" + "Settings" + "/" + "PrivacyRegions")); + + try { + Toast.makeText(getApplicationContext(), "\"" + privacyRegion.getString("label") + "\" " + " has been deleted.", Toast.LENGTH_SHORT).show(); + } catch (JSONException e) { + e.printStackTrace(); + } + + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_action_accept.png b/app/src/main/res/drawable-hdpi/ic_action_accept.png new file mode 100644 index 0000000..700fc81 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_accept.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_action_cancel.png b/app/src/main/res/drawable-hdpi/ic_action_cancel.png new file mode 100644 index 0000000..e206f29 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_cancel.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_action_discard.png b/app/src/main/res/drawable-hdpi/ic_action_discard.png new file mode 100644 index 0000000..703b31f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_discard.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_action_edit.png b/app/src/main/res/drawable-hdpi/ic_action_edit.png new file mode 100644 index 0000000..756db31 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_edit.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_refresh.png b/app/src/main/res/drawable-hdpi/ic_refresh.png new file mode 100644 index 0000000..363a7e4 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_refresh.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_settings.png b/app/src/main/res/drawable-hdpi/ic_settings.png new file mode 100644 index 0000000..c074181 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_settings.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_accept.png b/app/src/main/res/drawable-mdpi/ic_action_accept.png new file mode 100644 index 0000000..41107b8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_accept.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_cancel.png b/app/src/main/res/drawable-mdpi/ic_action_cancel.png new file mode 100644 index 0000000..70e6d2d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_cancel.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_discard.png b/app/src/main/res/drawable-mdpi/ic_action_discard.png new file mode 100644 index 0000000..248fb09 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_discard.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_edit.png b/app/src/main/res/drawable-mdpi/ic_action_edit.png new file mode 100644 index 0000000..68a4532 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_edit.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/app/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..1558034 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_refresh.png b/app/src/main/res/drawable-mdpi/ic_refresh.png new file mode 100644 index 0000000..cd58861 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_refresh.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_settings.png b/app/src/main/res/drawable-mdpi/ic_settings.png new file mode 100644 index 0000000..4d0d62d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_settings.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_accept.png b/app/src/main/res/drawable-xhdpi/ic_action_accept.png new file mode 100644 index 0000000..6ee32b6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_accept.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_discard.png b/app/src/main/res/drawable-xhdpi/ic_action_discard.png new file mode 100644 index 0000000..9eeeed1 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_discard.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_edit.png b/app/src/main/res/drawable-xhdpi/ic_action_edit.png new file mode 100644 index 0000000..67e056f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_edit.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/app/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..a13650d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_refresh.png b/app/src/main/res/drawable-xhdpi/ic_refresh.png new file mode 100644 index 0000000..3bb546f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_refresh.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_settings.png b/app/src/main/res/drawable-xhdpi/ic_settings.png new file mode 100644 index 0000000..5efb16b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_settings.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..c101603 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_refresh.png b/app/src/main/res/drawable-xxhdpi/ic_refresh.png new file mode 100644 index 0000000..542fb9a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_refresh.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_settings.png b/app/src/main/res/drawable-xxhdpi/ic_settings.png new file mode 100644 index 0000000..30187c4 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_settings.png differ diff --git a/app/src/main/res/layout/activity_add_privacy_region.xml b/app/src/main/res/layout/activity_add_privacy_region.xml new file mode 100644 index 0000000..209f07b --- /dev/null +++ b/app/src/main/res/layout/activity_add_privacy_region.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_client.xml b/app/src/main/res/layout/activity_client.xml new file mode 100644 index 0000000..78f55b3 --- /dev/null +++ b/app/src/main/res/layout/activity_client.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + +