Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test as service #382

Merged
merged 89 commits into from
Nov 30, 2020
Merged
Show file tree
Hide file tree
Changes from 83 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
1359032
Started the implementation of automatic testing
lorenzoPrimi Sep 30, 2019
06b43c1
Merge branch 'master' into automated_testing
lorenzoPrimi Mar 24, 2020
977705a
Update strings.xml
lorenzoPrimi Mar 24, 2020
7a88e74
Added preference
lorenzoPrimi Mar 25, 2020
24e1b87
Adding time preference
lorenzoPrimi Mar 26, 2020
3287d53
First raw implementation of alarm service
lorenzoPrimi Mar 26, 2020
99cfbd5
Commented code
lorenzoPrimi Mar 26, 2020
60dec58
Start RunningActivity from background
lorenzoPrimi Mar 27, 2020
42f086e
How to backgroun an activity
lorenzoPrimi Mar 27, 2020
2dcbe06
Merge branch 'master' into automated_testing
lorenzoPrimi Mar 31, 2020
a2f4fc4
Clean code
lorenzoPrimi Apr 1, 2020
cc14a6c
Send activity to background
lorenzoPrimi Apr 2, 2020
5bdbeeb
Always send the local notification
lorenzoPrimi Apr 2, 2020
9801ac5
versionCode
lorenzoPrimi Apr 3, 2020
a5e0505
Change software_name
lorenzoPrimi Apr 3, 2020
16af9f9
Update build.gradle
lorenzoPrimi Apr 3, 2020
27d9ffc
Merge branch 'master' into automated_testing
lorenzoPrimi Apr 9, 2020
10100b9
Update build.gradle
lorenzoPrimi Apr 9, 2020
bc0e1e4
Merge branch 'master' into automated_testing
lorenzoPrimi Apr 16, 2020
bce0aad
Update preferences_global.xml
lorenzoPrimi Apr 16, 2020
be2aa9e
Merge branch 'master' into automated_testing
lorenzoPrimi May 11, 2020
b70d251
Adapting code
lorenzoPrimi May 11, 2020
2d2f5ef
Merge branch 'master' into automated_testing
lorenzoPrimi May 19, 2020
3061104
Update PreferenceFragment.java
lorenzoPrimi May 19, 2020
9d4c425
Solve intent crash
lorenzoPrimi May 20, 2020
9f39686
Merge branch 'master' into automated_testing
lorenzoPrimi Jun 25, 2020
2b9f518
Default values (revert this commit in the future)
lorenzoPrimi Jun 25, 2020
3843b12
Merge branch 'master' into automated_testing
lorenzoPrimi Jun 26, 2020
bcf2681
Update PreferenceManager.java
lorenzoPrimi Jun 26, 2020
ac2a810
Merge branch 'master' into automated_testing
lorenzoPrimi Jul 9, 2020
58b23ca
Merge branch 'master' into automated_testing
lorenzoPrimi Aug 12, 2020
ce1416d
Update PreferenceFragment.java
lorenzoPrimi Aug 12, 2020
b4446a2
Merge branch 'master' into automated_testing
lorenzoPrimi Sep 16, 2020
9054eea
Merge branch 'master' into automated_testing
lorenzoPrimi Oct 13, 2020
aed2de3
Merge branch 'master' into automated_testing
lorenzoPrimi Oct 14, 2020
19d6201
Update strings.xml
lorenzoPrimi Oct 14, 2020
4446a18
Update RunningActivity.java
lorenzoPrimi Oct 14, 2020
7964139
Merge branch 'master' into automated_testing
lorenzoPrimi Oct 14, 2020
10a949d
Merge branch 'master' into automated_testing
lorenzoPrimi Oct 14, 2020
472cb11
Merge branch 'master' into automated_testing
lorenzoPrimi Oct 15, 2020
4306456
Adding preferences
lorenzoPrimi Oct 16, 2020
d2b8957
New alarm service
lorenzoPrimi Oct 16, 2020
1e54489
Trying refactor TestAsync
lorenzoPrimi Oct 19, 2020
4125712
Update TestAsyncTask.java
lorenzoPrimi Oct 19, 2020
bae53b8
fix
lorenzoPrimi Oct 19, 2020
ba5e674
Update AbstractTest.java
lorenzoPrimi Oct 19, 2020
8f79fbd
Change TestAsync class
lorenzoPrimi Oct 20, 2020
4048718
Update AlarmReceiver.java
lorenzoPrimi Oct 21, 2020
d1328d1
Merge branch 'master' into automated_testing
lorenzoPrimi Oct 21, 2020
fa7a790
add TODO
lorenzoPrimi Oct 22, 2020
9e6ad3b
Add no internet check
lorenzoPrimi Oct 26, 2020
101fd83
Start implementation of a ServiceJob
lorenzoPrimi Oct 26, 2020
a09c3a1
First working(ish) implementation of the test as a service
lorenzoPrimi Oct 28, 2020
7d445f0
Start code cleanup
lorenzoPrimi Oct 30, 2020
feb0d0a
Stop test
lorenzoPrimi Oct 30, 2020
034b58e
Check test running
lorenzoPrimi Nov 2, 2020
6a50119
Managing test start stop and post Execution
lorenzoPrimi Nov 2, 2020
fff5912
Fix unexpected end of stream on Connection in android
lorenzoPrimi Nov 2, 2020
b81b382
Update TestAsyncTask.java
lorenzoPrimi Nov 2, 2020
d463f82
Notification final fixes
lorenzoPrimi Nov 3, 2020
57318c0
Adjusting services classes
lorenzoPrimi Nov 4, 2020
db3fad6
open RunningActivity and handling testSuite
lorenzoPrimi Nov 4, 2020
bd7966f
Unused code
lorenzoPrimi Nov 4, 2020
07100d8
Test new scheduling
lorenzoPrimi Nov 4, 2020
9440c99
Last testing
lorenzoPrimi Nov 5, 2020
c80cbfb
Null checking
lorenzoPrimi Nov 5, 2020
8c30d79
last todo
lorenzoPrimi Nov 5, 2020
a5516f9
Removing background service classes
lorenzoPrimi Nov 9, 2020
1e28cc3
Separate runTest and downloadURLs
lorenzoPrimi Nov 9, 2020
90ef7a3
Fix crash
lorenzoPrimi Nov 10, 2020
64297c0
Merge branch 'master' into test_as_service
lorenzoPrimi Nov 13, 2020
3153776
Merge branch 'master' into test_as_service
lorenzoPrimi Nov 13, 2020
920d9ec
Merge branch 'master' into test_as_service
lorenzoPrimi Nov 16, 2020
08bdf6c
Removed comments
lorenzoPrimi Nov 16, 2020
8b56417
Merge branch 'master' into test_as_service
lorenzoPrimi Nov 19, 2020
a69edff
Update preferences_global.xml
lorenzoPrimi Nov 20, 2020
903a468
Update AndroidManifest.xml
lorenzoPrimi Nov 20, 2020
93d3815
Update MainActivity.java
lorenzoPrimi Nov 20, 2020
e53e097
Update preferences_global.xml
lorenzoPrimi Nov 20, 2020
1642f92
Fixing interrupt problem
lorenzoPrimi Nov 24, 2020
7c530b4
Remove vibration and sounds
lorenzoPrimi Nov 24, 2020
6844b57
removing icon
lorenzoPrimi Nov 25, 2020
dee3319
Merge branch 'master' into test_as_service
lorenzoPrimi Nov 26, 2020
c77fc66
Merge branch 'master' into test_as_service
lorenzoPrimi Nov 30, 2020
568f508
Localize string
lorenzoPrimi Nov 30, 2020
7bb15a8
Adding comments
lorenzoPrimi Nov 30, 2020
1aff254
Update build.gradle
lorenzoPrimi Nov 30, 2020
ccb5d30
Update build.gradle
lorenzoPrimi Nov 30, 2020
f98c1ed
Cancel notification on app open
lorenzoPrimi Nov 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ android {

defaultConfig {
applicationId 'org.openobservatory.ooniprobe'
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 29
versionName '2.7.1'
versionCode 66
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<permission android:name="org.openobservatory.ooniprobe.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="org.openobservatory.ooniprobe.permission.C2D_MESSAGE" />

Expand Down Expand Up @@ -122,5 +123,11 @@
android:scheme="ooni" />
</intent-filter>
</activity>

<service
android:name=".common.service.RunTestService"
android:icon="@drawable/notification_icon"
android:label="@string/Dashboard_Card_Run">
</service>
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ boolean isTestRunning() {
return ((Application) getApplication()).isTestRunning();
}

void setTestRunning(boolean testRunning) {
((Application) getApplication()).setTestRunning(testRunning);
}

public OONIOrchestraClient getOrchestraClient() {
return ((Application) getApplication()).getOrchestraClient();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ else if (getPreferenceManager().getAppOpenCount() == PreferenceManager.NOTIFICAT

@Override protected void onResume() {
super.onResume();
//TODO-SERVICE show RunningActivity
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package org.openobservatory.ooniprobe.activity;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.animation.Animation;
import android.widget.ImageButton;
Expand All @@ -12,17 +18,17 @@
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.airbnb.lottie.LottieAnimationView;

import org.openobservatory.ooniprobe.R;
import org.openobservatory.ooniprobe.common.CountlyManager;
import org.openobservatory.ooniprobe.common.ReachabilityManager;
import org.openobservatory.ooniprobe.common.NotificationService;
import org.openobservatory.ooniprobe.model.database.Result;
import org.openobservatory.ooniprobe.common.service.RunTestService;
import org.openobservatory.ooniprobe.test.TestAsyncTask;
import org.openobservatory.ooniprobe.test.suite.AbstractSuite;
import org.openobservatory.ooniprobe.test.suite.WebsitesSuite;

import java.util.ArrayList;

Expand All @@ -33,8 +39,7 @@
import localhost.toolkit.app.fragment.ConfirmDialogFragment;
import localhost.toolkit.app.fragment.MessageDialogFragment;

public class RunningActivity extends AbstractActivity implements ConfirmDialogFragment.OnConfirmedListener {
private static final String TEST = "test";
public class RunningActivity extends AbstractActivity implements ConfirmDialogFragment.OnConfirmedListener, ServiceConnection {
@BindView(R.id.running)
TextView running;
@BindView(R.id.name)
Expand All @@ -49,11 +54,10 @@ public class RunningActivity extends AbstractActivity implements ConfirmDialogFr
ImageButton close;
@BindView(R.id.animation)
LottieAnimationView animation;
private ArrayList<AbstractSuite> testSuites;
private AbstractSuite testSuite;
private boolean background;
private Integer runtime;
private TestAsyncTask task;
private RunTestService service;
private TestRunBroadRequestReceiver receiver;
boolean isBound = false;

public static Intent newIntent(AbstractActivity context, ArrayList<AbstractSuite> testSuites) {
if (ReachabilityManager.getNetworkType(context).equals(ReachabilityManager.NO_INTERNET)) {
Expand All @@ -63,9 +67,10 @@ public static Intent newIntent(AbstractActivity context, ArrayList<AbstractSuite
.build().show(context.getSupportFragmentManager(), null);
return null;
} else {
Bundle extra = new Bundle();
extra.putSerializable(TEST, testSuites);
return new Intent(context, RunningActivity.class).putExtra(TEST, extra);
Intent serviceIntent = new Intent(context, RunTestService.class);
serviceIntent.putExtra("testSuites", testSuites);
ContextCompat.startForegroundService(context, serviceIntent);
return new Intent(context, RunningActivity.class);
}
}

Expand All @@ -75,40 +80,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
setTheme(R.style.Theme_MaterialComponents_NoActionBar_App);
setContentView(R.layout.activity_running);
ButterKnife.bind(this);
Bundle extra = getIntent().getBundleExtra(TEST);
testSuites = (ArrayList<AbstractSuite>) extra.getSerializable(TEST);
if (testSuites == null) {
finish();
return;
}
CountlyManager.recordView("TestRunning");
runTest();
}

private void runTest() {
if (testSuites.size() > 0) {
testSuite = testSuites.get(0);
testStart();
setTestRunning(true);
task = (TestAsyncTaskImpl) new TestAsyncTaskImpl(this, testSuite.getResult()).execute(testSuite.getTestList(getPreferenceManager()));
}
}

private void testStart(){
runtime = testSuite.getRuntime(getPreferenceManager());
getWindow().setBackgroundDrawableResource(testSuite.getColor());
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setStatusBarColor(testSuite.getColor());
}
animation.setImageAssetsFolder("anim/");
animation.setAnimation(testSuite.getAnim());
animation.setRepeatCount(Animation.INFINITE);
animation.playAnimation();
progress.setIndeterminate(true);
eta.setText(R.string.Dashboard_Running_CalculatingETA);
progress.setMax(testSuite.getTestList(getPreferenceManager()).length * 100);
//TODO remove this line when web_connectiviity will be in go
close.setVisibility(testSuite.getName().equals(WebsitesSuite.NAME) ? View.GONE : View.VISIBLE);
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Expand All @@ -122,92 +94,128 @@ public void onClick(View view) {
});
}

private void applyUIChanges(){
if (service == null || service.task == null ||
service.task.currentSuite == null || service.task.currentTest == null) {
return;
}
animation.setImageAssetsFolder("anim/");
animation.setRepeatCount(Animation.INFINITE);
animation.playAnimation();
progress.setIndeterminate(true);
eta.setText(R.string.Dashboard_Running_CalculatingETA);

name.setText(getString(service.task.currentTest.getLabelResId()));
runtime = service.task.currentSuite.getRuntime(getPreferenceManager());
getWindow().setBackgroundDrawableResource(service.task.currentSuite.getColor());
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setStatusBarColor(service.task.currentSuite.getColor());
}
animation.setAnimation(service.task.currentSuite.getAnim());
progress.setMax(service.task.currentSuite.getTestList(getPreferenceManager()).length * 100);
}

@Override
protected void onResume() {
super.onResume();
background = false;
if (!isTestRunning()) {
testEnded(this);
return;
}
IntentFilter filter = new IntentFilter("org.openobservatory.ooniprobe.activity.RunningActivity");
receiver = new TestRunBroadRequestReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
//Bind the RunTestService
Intent intent = new Intent(this, RunTestService.class);
bindService(intent, this, Context.BIND_AUTO_CREATE);
}

@Override
protected void onPause() {
background = true;
super.onPause();
if (isBound) {
unbindService(this);
isBound = false;
}
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}

@Override
protected void onDestroy() {
setTestRunning(false);
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}

@Override
public void onBackPressed() {
Toast.makeText(this, getString(R.string.Modal_Error_CantCloseScreen), Toast.LENGTH_SHORT).show();
}

private static class TestAsyncTaskImpl extends TestAsyncTask<RunningActivity> {
TestAsyncTaskImpl(RunningActivity activity, Result result) {
super(activity, result);
}
@Override
public void onServiceConnected(ComponentName cname, IBinder binder) {
RunTestService.TestBinder b = (RunTestService.TestBinder) binder;
service = b.getService();
isBound = true;
applyUIChanges();
}

@Override
protected void onProgressUpdate(String... values) {
RunningActivity act = ref.get();
if (act != null && !act.isFinishing())
switch (values[0]) {
case RUN:
act.name.setText(values[1]);
break;
case PRG:
act.progress.setIndeterminate(false);
int prgs = Integer.parseInt(values[1]);
act.progress.setProgress(prgs);
act.eta.setText(act.getString(R.string.Dashboard_Running_Seconds, String.valueOf(Math.round(act.runtime - ((double) prgs) / act.progress.getMax() * act.runtime))));
break;
case LOG:
if (!act.task.isInterrupted())
act.log.setText(values[1]);
break;
case ERR:
Toast.makeText(act, values[1], Toast.LENGTH_SHORT).show();
act.finish();
break;
case URL:
act.progress.setIndeterminate(false);
act.runtime = act.testSuite.getRuntime(act.getPreferenceManager());
break;
}
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
RunningActivity act = ref.get();
act.testSuites.remove(act.testSuite);
if (act.testSuites.size() == 0)
endTest(act);
else
act.runTest();
}
@Override
public void onServiceDisconnected(ComponentName name) {
service = null;
}

private void endTest(RunningActivity act){
if (act != null && !act.isFinishing()) {
if (act.background) {
NotificationService.notifyTestEnded(act, act.testSuite);
} else
act.startActivity(MainActivity.newIntent(act, R.id.testResults));
act.finish();
public class TestRunBroadRequestReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String key = intent.getStringExtra("key");
String value = intent.getStringExtra("value");
switch (key) {
case TestAsyncTask.START:
applyUIChanges();
break;
case TestAsyncTask.RUN:
name.setText(value);
break;
case TestAsyncTask.PRG:
int prgs = Integer.parseInt(value);
progress.setIndeterminate(false);
progress.setProgress(prgs);
if (runtime != null)
eta.setText(getString(R.string.Dashboard_Running_Seconds,
String.valueOf(Math.round(runtime - ((double) prgs) / progress.getMax() * runtime))));
break;
case TestAsyncTask.LOG:
log.setText(value);
break;
case TestAsyncTask.ERR:
Toast.makeText(context, value, Toast.LENGTH_SHORT).show();
break;
case TestAsyncTask.URL:
progress.setIndeterminate(false);
runtime = service.task.currentSuite.getRuntime(getPreferenceManager());
break;
case TestAsyncTask.INT:
running.setText(getString(R.string.Dashboard_Running_Stopping_Title));
log.setText(getString(R.string.Dashboard_Running_Stopping_Notice));
break;
case TestAsyncTask.END:
testEnded(context);
break;
}

}
}

private void testEnded(Context context) {
startActivity(MainActivity.newIntent(context, R.id.testResults));
finish();
}

@Override
public void onConfirmation(Serializable serializable, int i) {
if (i == DialogInterface.BUTTON_POSITIVE) {
running.setText(getString(R.string.Dashboard_Running_Stopping_Title));
log.setText(getString(R.string.Dashboard_Running_Stopping_Notice));
task.interrupt();
if (service != null)
service.task.interrupt();
}
}
}
Loading