Using Monkey in a subactivity only (android debugging) - android

I'm trying to use Monkey debuggin tool (from adb) to stress test a part of my application.
As Monkey acts in a total random way, I'd like it to concentrate on the part of code that might contain an error I'm looking for (very rare bug, and I don't know how to replicate it).
So, in my Main activity I have 6 buttons, each fires up a new activity. I'd like to set monkey to look only in one of those activities, and every activity accesible from it. I cannot find a reasonable way to do it.
I've tried the
adb shell monkey -p my.package.name -c android.intent.category.MONKEY 1000
and in my manifest file I've put in some activities, that I'm interested in:
<intent-filter>
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
But it didn't work. Monkey still fires up activities that are not categorized by this tag.
It is crucial for Monkey to work in selected subactivities, because it wastes about 95% of time roaming through my app, outside of subactivities that I actually want to test.
Also I've tried some simple script to launch the desired subactivity, but with no success.
Looking for any help,
cheers,
kajman

I have also had a bit of problems with constraining the monkey with categories. I think it is not intended to work as you assume. How it works then? I have no clear idea, just experimenting with it. The documentation is quite poor.
For your problem you could consider the following approaches
Put your subactivities under one subpackage and permit access to only that subpackage with the -p option
Add some constraints to your code that prevents the navigation inside the app. For example set the onClickListeners to do nothing or disable back button for the activity under test when some specific condition is met.
P.S. You can use adb shell am start in order to start the desired subactivity. Again poor documentation, no example, but the action is the name of the action you have defined inside intent-filter for the activity in your AndroidManifest. Name is the Activity name, for example
adb shell am start -a my.package.app.ACTION1 -n my.package.app/.sub.MyActivity

I know it is bit late but here is more robust way - use code like this:
ActivityManager activityManager;
activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
if(!activityManager.isUserAMonkey()) {
//stuff you want to execute anywhere but monkey test
});

Related

How would I stop something that was started by an app for itself without stopping the app?

Note: I'm fairly new to linux/android when it comes to using the shell and commands/scripting, so if I've given some unrelevant information, or I'm trying to do something not possible, please tell me what's not relevant and why something is not possible and explain anything else to help me become better at this.
I'm trying to make a script that stop's Orbot's Tor network automatically when I exit from the Orfox app. So far, I have most of the coding down except for the stopping part for Tor. I believe there is something I can use in a shell script that would stop the Tor network right?
Currently, my script uses the command
# am force-stop org.torproject.android
to stop the app (to stop the Tor network), but I know that can't be the only way...
I know that when I press the Start button (within the Orbot app) or open up Orfox, it starts up the Tor network... When using
# ps | grep torproject
2 times (before and after starting Tor), I found that
u0_a291 11209 1 23092 15712 sys_epoll_ b68ecf18 S /data/data/org.torproject.android/app_bin/tor
shows up only when Tor is on.
I also found that after using
# ps | grep u0_a291
(the same way as the last command) that two shell's are started:
u0_a291 11150 8783 3780 1336 pipe_wait b6d9d0ac S sh
u0_a291 11212 8783 3780 1340 pipe_wait b6dec0ac S sh
only when tor is on.
I'm assuming some of the commands running through one or both of the shell's will give me a hint as to what commands I may need in order to stop the tor network in my script, but I have no idea how to view them or if I can. Is there a way to view them, or maybe I'm going about trying to find out how to stop Tor in the wrong way? So help me out guys, please.
I figured out what it was after all, and I didn't need any of the information that I provided... facepalm
I found out what the service and intent action I needed by looking at the base.apk (in /data/app/org.torproject.android) as an archive. I looked at the AndroidManifest.xml like a text file and found the service and it's intent action to be
.service.TorService
org.torproject.android.intent.action.Start
I concluded my script by using this to stop the tor service... I bet this might help someone else out in the future.
# am stopservice -n org.torproject.android/.service.TorService -a org.torproject.android.intent.action.START

Which process in android asks ActivityManager to broadcast BOOT_COMPLETED

I have searched this over the web, without an answer. Basically while testing a device, I observe that the display screen fires ON much earlier, while in the logcat the print
Consoleui:bootComplete follows after ~ 8 sec.
Now Device screen is displayed as part of starting Launcher application, so in the natural sequence of events, the system server will ask activitymanager to start launcher in a seperate thread and go on doing more work.
Thus it is only natural that display will come up, but still there might remain some services to be started by activitymanager/systemserver before a BOOT_COMPLETED broadcast can be made.
I have to prove this. In order to do so, I need to know which process tells the activitymanager that now it can broadcast the boot_complete message, if its the system server, please tell me the part of code where it does so. Thanks.
The activity manager service sends the boot complete intent on line 6320 of ActivityManagerService.java.
The activity manager service also starts the launcher using an intent with CATEGORY_HOME on line 3305 of ActivityManagerService.java.
It appears that your original question contains 2 sub-questions:
Q1. Where exactly in the AOSP code is system broadcast Intent BOOT_COMPLETED fired?
Q2. What are all the necessary conditions to trigger the firing of BOOT_COMPLETED?
For Q1, a broad location is in the Activity Manager. In this sense, #Alex Lockwood’s answer is correct. However, I have noticed that the exact location and the way this Intent is fired may change between Android versions. A source code search should be able to lead to the answer. Take AOSP branch “android-8.1.0_r32” as an example. First, find out where file “ActivityManagerService.java” is located using the following shell commands:
$ cd [your AOSP branch’s root directory]
$ find . -name ActivityManagerService.java
Once the file is found, go to its parent directory. For example, in our current case:
$ cd frameworks/base/services/core/java/com/android/server/am
Now perform the following search:
$ grep -rIn ACTION_BOOT_COMPLETED .
The output reveals that the exact location is not in file “ActivityManagerService.java”, but in file “UserController.java”. More exactly, it is in method “UserController.finishUserUnlockedCompleted()”.
For Q2, we can search backwards from the above method. Eventually we may reach method “ActivityManagerService.finishBooting()” where we can see that Boolean “mBootAnimationComplete” must be true. This implies that the boot animation process must be completed in order for BOOT_COMPLETED to be fired, and further implies that while the boot animation process is going on, a lot of system services are being started. For further details, you may refer to some dedicated books that explain which system services must be ready in order for the boot animation process to end.

Android: run an app several times

I would like to run a bunch of tests in my Android App.
The thing is: I want to define first a number of tests N, and make my App run that number of times, one after another.
It's a little tricky in Android, because of the Activities lifecycle, but the goal is to start a test (execute the app again) right after when the last one stoped.
Is that possible? I tried reading the Android Developers Testing section, but I'm having some doubts about if what I want is possible with that technique.
Plus, I want to make each test execute with different values for the variables (different inputs), but that's probably even more tricky, so... let's focus in the first problem :)
Any help?? Thanks
It sounds to me what you want is a mechanism to restart your Android application programatically (and gracefully). Many people may say it is impossible, but you can implement the mechanism.
The basic flow is:
(1) finish() your root activity.
(2) In onDestroy() of your root activity, call startActivity(createMainLauncherIntent()).
(3) And the implementation of createMainLauncherIntent() should look like the following.
private Intent createMainLauncherIntent()
{
Intent intent = new Intent();
// To launch this activity as if it started from the launcher.
intent.setClass(this, getClass());
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
return intent;
}
(4) Of course, the onDestroy() should have a mechanism to avoid infinite loop of 'restart'.
A sample of base root Activity class:
https://github.com/TakahikoKawasaki/nv-android-base/blob/master/src/main/java/com/neovisionaries/android/app/BaseRootActivity.java
A sample Android application that implements 'restart' mechanism:
https://github.com/TakahikoKawasaki/nv-android-base-sample
You can run any number of test for your app, you just need to specify the valid test runner. By default, the SDK provides a AndroidTestRunner that allows you to run tests for your app inside an emulator.
After that, you can also use another test runner like Robolectric that allows to run tests directly from your IDE.
You can run as may tests as you want with both solutions, there is no need to kill and restart the app between each test. Even though, it would very inefficient and time consuming to do so.
im not sure, but what about a script witch kills your app and start it again with new inputs, which could be stored in preinitialized db?
here a link to how to kill your aplication: Android ADB stop application command like "force-stop" for non rooted device
You can launch app with params using shell command start and parameter -e:
$ adb shell am start -n com.some.package/com.some.package.MainActivity -e key param
Params will come to the onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle extras = this.getIntent().getExtras();
if(extras != null){
String key = extras.getString("key");
}
}
To kill app on android you need to have rooted device. Next command will kill app:
$ adb shell ps | grep com.some.package | awk '{print $2}' | xargs adb shell kill
But I'm sure that standard testing methods will works better. So I recommend you carefully read all Android documentation about testing.

How can I dismiss the android keyguard using adb intent

I am looking for a way to use ADB to dismiss the keyguard in order to automate some tasks.
I would like to start an ACTIVITY (perhaps to call the public method disableKeyguard in android.app.KeyguardManager.KeyguardLock), because I assume that it will work on all (or most) Android devices, but I am unsure of the syntax.
I do not wish to use MonkeyRunner, because it is not present (or perhaps, callable) on all devices. I also cannot send a MENU keycode (adb shell input keycode 82), because this does not dismiss the keyguard on all devices.
Currently I am sending events (low-level touch events), but this needs to be customized for each device, so it is a time consuming task.
Does anyone have a suggestion?
The "Activity Testing" article has a section called Unlocking the emulator or device that addresses this situation.
In short, there isn't a way to do it directly with adb but using disableKeyguard() isn't complicated (see the three lines of example code in the article linked to above). You could easily put together a little app that does nothing but disable the keyguard. It would then just be a matter of
adb install <apk>
adb shell am start <package>/.<activity>
# Whatever you need to automate
adb uninstall <package>
(Where <apk>, <package>, and <activity> all refer to the tiny app that just disables the keyguard.)

Android: IntentFilters for components

What is a reasonable way to filter out specific cmp Strings with an Android IntentFilters which are declared in code in broadcast Receivers (rather than in android.xml)?
The case I'm searching for has:
action = android.intent.action.MAIN
category = android.intent.category.LAUNCHER
Any advice would be greatly appreciated.
I do a positive test for stuff I'm interested in and ignore everything that doesn't conform, as opposed to negatively trying to throw away all possible non-interesting things and keeping what's left. But maybe I've misunderstood your problem.
The issue was the intent filter only works over the application in which it occurs. This meant MAIN and LAUNCHER wasn't finding anything except for application relaunch events which weren't actually occurring. The system freeze up was caused by a separate error on the phone, not by the FILTER actually processing over too much information.
Still not sure how to search within an app by cmp or Component but the bigger issue was not finding stuff outside the application and that has alternative approaches.

Categories

Resources