blob: a0bc4d7da746663b7595fb24e82a44645b3feb33 [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.screenshot;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.FileObserver;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
import android.view.KeyEvent;
import java.io.File;
/**
* Functional tests for the global screenshot feature.
*/
@LargeTest
public class ScreenshotTest extends ActivityInstrumentationTestCase2<ScreenshotStubActivity> {
private static final String LOG_TAG = "ScreenshotTest";
private static final int SCREEN_WAIT_TIME_SEC = 5;
public ScreenshotTest() {
super(ScreenshotStubActivity.class);
}
/**
* A simple test for screenshots that launches an Activity, injects the key event combo
* to trigger the screenshot, and verifies the screenshot was taken successfully.
*/
public void testScreenshot() throws Exception {
Log.d(LOG_TAG, "starting testScreenshot");
// launch the activity.
ScreenshotStubActivity activity = getActivity();
assertNotNull(activity);
File screenshotDir = getScreenshotDir();
NewScreenshotObserver observer = new NewScreenshotObserver(
screenshotDir.getAbsolutePath());
observer.startWatching();
takeScreenshot();
// unlikely, but check if a new screenshot file was already created
if (observer.getCreatedPath() == null) {
// wait for screenshot to be created
synchronized(observer) {
observer.wait(SCREEN_WAIT_TIME_SEC*1000);
}
}
assertNotNull(String.format("Could not find screenshot after %d seconds",
SCREEN_WAIT_TIME_SEC), observer.getCreatedPath());
File screenshotFile = new File(screenshotDir, observer.getCreatedPath());
try {
assertTrue(String.format("Detected new screenshot %s but its not a file",
screenshotFile.getName()), screenshotFile.isFile());
assertTrue(String.format("Detected new screenshot %s but its not an image",
screenshotFile.getName()), isValidImage(screenshotFile));
} finally {
// delete the file to prevent external storage from filing up
screenshotFile.delete();
}
}
private static class NewScreenshotObserver extends FileObserver {
private String mAddedPath = null;
NewScreenshotObserver(String path) {
super(path, FileObserver.CREATE);
}
synchronized String getCreatedPath() {
return mAddedPath;
}
@Override
public void onEvent(int event, String path) {
Log.d(LOG_TAG, String.format("Detected new file added %s", path));
synchronized (this) {
mAddedPath = path;
notify();
}
}
}
/**
* Inject the key sequence to take a screenshot.
*/
private void takeScreenshot() {
getInstrumentation().sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_POWER));
getInstrumentation().sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_VOLUME_DOWN));
// the volume down key event will cause the 'volume adjustment' UI to appear in the
// foreground, and steal UI focus
// unfortunately this means the next key event will get directed to the
// 'volume adjustment' UI, instead of this test's activity
// for this reason this test must be signed with platform certificate, to grant this test
// permission to inject key events to another process
getInstrumentation().sendKeySync(new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_VOLUME_DOWN));
getInstrumentation().sendKeySync(new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_POWER));
}
/**
* Get the directory where screenshot images are stored.
*/
private File getScreenshotDir() {
// TODO: get this dir location from a constant
return new File(Environment.getExternalStorageDirectory(), "Pictures" + File.separator +
"Screenshots");
}
/**
* Return true if file is valid image file
*/
private boolean isValidImage(File screenshotFile) {
Bitmap b = BitmapFactory.decodeFile(screenshotFile.getAbsolutePath());
// TODO: do more checks on image
return b != null;
}
}