Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android : Create a file in /data/local/tmp from an automated test

Goal: Taking a screenshot during an automated test on a device. Pull the screenshot file using adb once the test is done.

Context:

I'm currently trying to write automated tests to take snapshots of the device screen. Using UiDevice to navigate, I would like to take a screenshot in the middle of a test. UiDevice has a method takeScreenshot that I call when I would like to take a snapshot.

After some investigation, I realised that the class responsible to write the image into file UiAutomatorBridge catches an Exception :

java.io.FileNotFoundException: /data/local/tmp/screenshots/screen2.png: open failed: EACCES (Permission denied)

Using adb, I created the file and set all permissions to all users.

adb shell touch /data/local/tmp/screenshots/screen1.png
adb shell chmod 777 /data/local/tmp/screenshots

Once done, I can take a screenshot with :

@Test
public void takeSnapShot() {
    String filename = "/data/local/tmp/screenshots/screen1.png";
    File file = new File(filename);
    assertEquals(true, mDevice.takeScreenshot(file));
}

Problem :

I would like to be able to create a file directly while the test is executing, without the need of using adb. I tried to create a file directly from Java using createNewFile.

try {
     file.createNewFile();
} catch (IOException e) {
     e.printStackTrace();
}

But I get an IOException

java.io.IOException: open failed: EACCES (Permission denied)

Has anyone an idea of what is going on ? I'm quite new to Linux, so don't hesitate to suggest something even if it seems obvious to you ;)

Should I post this on superuser instead ?

EDIT

The directory /data has these permissions

drwxrwx--x system   system            2016-01-14 14:03 data

I can't list the content of /data, which makes me believe the user "shell" doesn't belong to the group "system". I can't list the content of /data/local neither.

However, the /data/local/tmp is owned by "shell".

drwxrwx--x shell    shell             2016-01-14 12:20 . (tmp)

/data/local/tmp gives +x permission to all users.

Finally, the directory "screenshots" belongs to shell with permissions 777.

drwxrwxrwx shell    shell             2016-01-14 11:46 screenshots

To my understanding, any user should be able to access /data/local/tmp/screenshots

like image 413
Gordak Avatar asked Nov 09 '22 21:11

Gordak


1 Answers

Instead of saving under /data/local/tmp/, use Environment.getExternalStorageDirectory(). You need a read/write permission to do that. You have to add these two lines into the Manifest of the application ! (I tried to add those lines into the /androidTest/Manifest.xml file, but it has no effects).

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

While it solves the problem of finding a common directory to save/read screenshots, it brings a new one as well.

Having to add these 2 permissions isn't a big deal if you already had them. But if you don't want to ask the user for those permissions, you have to add/remove these lines every time you test/sign your application, which is far from ideal.

EDIT :

In this post, someone proposed to make use of the build differentials (debug, release) to have two different Manifests.

In the end, I have 3 Manifests :

  • Release Manifest (without external read/write permissions)
  • Debug Manifest (with external read/write permissions)
  • AndroidTest Manifest for

tools:overrideLibrary="android.support.test.uiautomator.v18"

like image 63
Gordak Avatar answered Nov 14 '22 22:11

Gordak