Move print workflow tests to own apk

Test: Ran new tests
This commit is contained in:
Philip P. Moltmann
2016-10-05 15:36:20 -07:00
parent 838277059f
commit cc021c9a20
16 changed files with 659 additions and 49 deletions

View File

@@ -1323,17 +1323,6 @@
</meta-data>
</service>
<activity
android:name="android.print.mockservice.SettingsActivity"
android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
android:exported="true">
</activity>
<activity
android:name="android.print.mockservice.AddPrintersActivity"
android:exported="true">
</activity>
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"

View File

@@ -16,6 +16,4 @@
limitations under the License.
-->
<print-service xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="android.print.mockservice.SettingsActivity"
android:addPrintersActivity="android.print.mockservice.AddPrintersActivity" />
<print-service xmlns:android="http://schemas.android.com/apk/res/android" />

View File

@@ -1,28 +0,0 @@
/*
* Copyright (C) 2016 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 android.print.mockservice;
import android.app.Activity;
import android.os.Bundle;
public class SettingsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}

View File

@@ -0,0 +1,19 @@
# Copyright (C) 2016 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.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
include $(call all-makefiles-under, $(LOCAL_PATH))

View File

@@ -0,0 +1,28 @@
# Copyright (C) 2016 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ub-uiautomator mockito-target-minus-junit4
LOCAL_PACKAGE_NAME := PrintSpoolerOutOfProcessTests
include $(BUILD_PACKAGE)

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.printspooler.outofprocess.tests">
<application>
<uses-library android:name="android.test.runner" />
<activity android:name=".PrintTestActivity"/>
<service
android:name=".mockservice.MockPrintService"
android:permission="android.permission.BIND_PRINT_SERVICE">
<intent-filter>
<action android:name="android.printservice.PrintService" />
</intent-filter>
<meta-data
android:name="android.printservice"
android:resource="@xml/printservice">
</meta-data>
</service>
<activity
android:name=".mockservice.SettingsActivity"
android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
android:exported="true">
</activity>
<activity
android:name=".mockservice.AddPrintersActivity"
android:exported="true">
</activity>
</application>
<!-- This runs in its own process, hence it instruments itself -->
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.printspooler.outofprocess.tests"
android:label="PrintSpooler Out of Process Test Cases">
</instrumentation>
</manifest>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 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.
-->
<print-service xmlns:android="http://schemas.android.com/apk/res/android"
android:addPrintersActivity="com.android.printspooler.outofprocess.tests.mockservice.AddPrintersActivity" />

View File

@@ -0,0 +1,211 @@
/*
* Copyright (C) 2016 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.printspooler.outofprocess.tests;
import android.annotation.NonNull;
import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintManager;
import android.print.PrinterId;
import com.android.printspooler.outofprocess.tests.mockservice.PrintServiceCallbacks;
import com.android.printspooler.outofprocess.tests.mockservice.PrinterDiscoverySessionCallbacks;
import com.android.printspooler.outofprocess.tests.mockservice.StubbablePrinterDiscoverySession;
import android.printservice.CustomPrinterIconCallback;
import android.printservice.PrintJob;
import android.printservice.PrintService;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.uiautomator.UiDevice;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.mockito.stubbing.Answer;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* This is the base class for print tests.
*/
abstract class BasePrintTest {
protected static final long OPERATION_TIMEOUT = 30000;
private static final String PM_CLEAR_SUCCESS_OUTPUT = "Success";
private static final int CURRENT_USER_ID = -2; // Mirrors UserHandle.USER_CURRENT
private android.print.PrintJob mPrintJob;
private static Instrumentation sInstrumentation;
private static UiDevice sUiDevice;
@Rule
public ActivityTestRule<PrintTestActivity> mActivityRule =
new ActivityTestRule<>(PrintTestActivity.class, false, true);
/**
* Return the UI device
*
* @return the UI device
*/
public UiDevice getUiDevice() {
return sUiDevice;
}
protected static Instrumentation getInstrumentation() {
return sInstrumentation;
}
@BeforeClass
public static void setUpClass() throws Exception {
sInstrumentation = InstrumentationRegistry.getInstrumentation();
assumeTrue(sInstrumentation.getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_PRINTING));
sUiDevice = UiDevice.getInstance(sInstrumentation);
// Make sure we start with a clean slate.
clearPrintSpoolerData();
// Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
// Dexmaker is used by mockito.
System.setProperty("dexmaker.dexcache", getInstrumentation()
.getTargetContext().getCacheDir().getPath());
}
@After
public void exitActivities() throws Exception {
// Exit print spooler
getUiDevice().pressBack();
getUiDevice().pressBack();
}
protected android.print.PrintJob print(@NonNull final PrintDocumentAdapter adapter,
final PrintAttributes attributes) {
// Initiate printing as if coming from the app.
getInstrumentation().runOnMainSync(() -> {
PrintManager printManager = (PrintManager) getActivity()
.getSystemService(Context.PRINT_SERVICE);
mPrintJob = printManager.print("Print job", adapter, attributes);
});
return mPrintJob;
}
protected PrintTestActivity getActivity() {
return mActivityRule.getActivity();
}
public static String runShellCommand(Instrumentation instrumentation, String cmd)
throws IOException {
ParcelFileDescriptor pfd = instrumentation.getUiAutomation().executeShellCommand(cmd);
byte[] buf = new byte[512];
int bytesRead;
FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
StringBuilder stdout = new StringBuilder();
while ((bytesRead = fis.read(buf)) != -1) {
stdout.append(new String(buf, 0, bytesRead));
}
fis.close();
return stdout.toString();
}
protected static void clearPrintSpoolerData() throws Exception {
assertTrue("failed to clear print spooler data",
runShellCommand(getInstrumentation(), String.format(
"pm clear --user %d %s", CURRENT_USER_ID,
PrintManager.PRINT_SPOOLER_PACKAGE_NAME))
.contains(PM_CLEAR_SUCCESS_OUTPUT));
}
@SuppressWarnings("unchecked")
protected PrinterDiscoverySessionCallbacks createMockPrinterDiscoverySessionCallbacks(
Answer<Void> onStartPrinterDiscovery, Answer<Void> onStopPrinterDiscovery,
Answer<Void> onValidatePrinters, Answer<Void> onStartPrinterStateTracking,
Answer<Void> onRequestCustomPrinterIcon, Answer<Void> onStopPrinterStateTracking,
Answer<Void> onDestroy) {
PrinterDiscoverySessionCallbacks callbacks = mock(PrinterDiscoverySessionCallbacks.class);
doCallRealMethod().when(callbacks).setSession(any(StubbablePrinterDiscoverySession.class));
when(callbacks.getSession()).thenCallRealMethod();
if (onStartPrinterDiscovery != null) {
doAnswer(onStartPrinterDiscovery).when(callbacks).onStartPrinterDiscovery(
any(List.class));
}
if (onStopPrinterDiscovery != null) {
doAnswer(onStopPrinterDiscovery).when(callbacks).onStopPrinterDiscovery();
}
if (onValidatePrinters != null) {
doAnswer(onValidatePrinters).when(callbacks).onValidatePrinters(
any(List.class));
}
if (onStartPrinterStateTracking != null) {
doAnswer(onStartPrinterStateTracking).when(callbacks).onStartPrinterStateTracking(
any(PrinterId.class));
}
if (onRequestCustomPrinterIcon != null) {
doAnswer(onRequestCustomPrinterIcon).when(callbacks).onRequestCustomPrinterIcon(
any(PrinterId.class), any(CancellationSignal.class),
any(CustomPrinterIconCallback.class));
}
if (onStopPrinterStateTracking != null) {
doAnswer(onStopPrinterStateTracking).when(callbacks).onStopPrinterStateTracking(
any(PrinterId.class));
}
if (onDestroy != null) {
doAnswer(onDestroy).when(callbacks).onDestroy();
}
return callbacks;
}
protected PrintServiceCallbacks createMockPrintServiceCallbacks(
Answer<PrinterDiscoverySessionCallbacks> onCreatePrinterDiscoverySessionCallbacks,
Answer<Void> onPrintJobQueued, Answer<Void> onRequestCancelPrintJob) {
final PrintServiceCallbacks service = mock(PrintServiceCallbacks.class);
doCallRealMethod().when(service).setService(any(PrintService.class));
when(service.getService()).thenCallRealMethod();
if (onCreatePrinterDiscoverySessionCallbacks != null) {
doAnswer(onCreatePrinterDiscoverySessionCallbacks).when(service)
.onCreatePrinterDiscoverySessionCallbacks();
}
if (onPrintJobQueued != null) {
doAnswer(onPrintJobQueued).when(service).onPrintJobQueued(any(PrintJob.class));
}
if (onRequestCancelPrintJob != null) {
doAnswer(onRequestCancelPrintJob).when(service).onRequestCancelPrintJob(
any(PrintJob.class));
}
return service;
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2016 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.printspooler.outofprocess.tests;
import android.app.Activity;
import android.os.Bundle;
import android.view.WindowManager;
public class PrintTestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
}

View File

@@ -14,17 +14,23 @@
* limitations under the License.
*/
package android.print;
package com.android.printspooler.outofprocess.tests;
import android.graphics.pdf.PdfDocument;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.mockservice.AddPrintersActivity;
import android.print.mockservice.MockPrintService;
import android.print.mockservice.PrinterDiscoverySessionCallbacks;
import android.print.mockservice.StubbablePrinterDiscoverySession;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.print.PrinterCapabilitiesInfo;
import android.print.PrinterId;
import android.print.PrinterInfo;
import com.android.printspooler.outofprocess.tests.mockservice.AddPrintersActivity;
import com.android.printspooler.outofprocess.tests.mockservice.MockPrintService;
import com.android.printspooler.outofprocess.tests.mockservice.PrinterDiscoverySessionCallbacks;
import com.android.printspooler.outofprocess.tests.mockservice.StubbablePrinterDiscoverySession;
import android.print.pdf.PrintedPdfDocument;
import android.support.test.filters.LargeTest;
import android.support.test.uiautomator.By;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package android.print.mockservice;
package com.android.printspooler.outofprocess.tests.mockservice;
import android.app.Activity;
import android.os.Bundle;

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
public class MockPrintService extends StubbablePrintService {
private static final Object sLock = new Object();
private static PrintServiceCallbacks sCallbacks;
public static void setCallbacks(PrintServiceCallbacks callbacks) {
synchronized (sLock) {
sCallbacks = callbacks;
}
}
@Override
protected PrintServiceCallbacks getCallbacks() {
synchronized (sLock) {
if (sCallbacks != null) {
sCallbacks.setService(this);
}
return sCallbacks;
}
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
import android.printservice.PrintJob;
import android.printservice.PrintService;
public abstract class PrintServiceCallbacks {
private PrintService mService;
public PrintService getService() {
return mService;
}
public void setService(PrintService service) {
mService = service;
}
public abstract PrinterDiscoverySessionCallbacks onCreatePrinterDiscoverySessionCallbacks();
public abstract void onRequestCancelPrintJob(PrintJob printJob);
public abstract void onPrintJobQueued(PrintJob printJob);
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
import android.os.CancellationSignal;
import android.print.PrinterId;
import android.printservice.CustomPrinterIconCallback;
import java.util.List;
public abstract class PrinterDiscoverySessionCallbacks {
private StubbablePrinterDiscoverySession mSession;
public void setSession(StubbablePrinterDiscoverySession session) {
mSession = session;
}
public StubbablePrinterDiscoverySession getSession() {
return mSession;
}
public abstract void onStartPrinterDiscovery(List<PrinterId> priorityList);
public abstract void onStopPrinterDiscovery();
public abstract void onValidatePrinters(List<PrinterId> printerIds);
public abstract void onStartPrinterStateTracking(PrinterId printerId);
public abstract void onRequestCustomPrinterIcon(PrinterId printerId,
CancellationSignal cancellationSignal, CustomPrinterIconCallback callback);
public abstract void onStopPrinterStateTracking(PrinterId printerId);
public abstract void onDestroy();
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
import android.printservice.PrintJob;
import android.printservice.PrintService;
import android.printservice.PrinterDiscoverySession;
public abstract class StubbablePrintService extends PrintService {
@Override
public PrinterDiscoverySession onCreatePrinterDiscoverySession() {
PrintServiceCallbacks callbacks = getCallbacks();
if (callbacks != null) {
return new StubbablePrinterDiscoverySession(this,
getCallbacks().onCreatePrinterDiscoverySessionCallbacks());
}
return null;
}
@Override
public void onRequestCancelPrintJob(PrintJob printJob) {
PrintServiceCallbacks callbacks = getCallbacks();
if (callbacks != null) {
callbacks.onRequestCancelPrintJob(printJob);
}
}
@Override
public void onPrintJobQueued(PrintJob printJob) {
PrintServiceCallbacks callbacks = getCallbacks();
if (callbacks != null) {
callbacks.onPrintJobQueued(printJob);
}
}
protected abstract PrintServiceCallbacks getCallbacks();
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2016 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.printspooler.outofprocess.tests.mockservice;
import android.os.CancellationSignal;
import android.print.PrinterId;
import android.printservice.CustomPrinterIconCallback;
import android.printservice.PrintService;
import android.printservice.PrinterDiscoverySession;
import android.support.annotation.NonNull;
import java.util.List;
public class StubbablePrinterDiscoverySession extends PrinterDiscoverySession {
private final PrintService mService;
private final PrinterDiscoverySessionCallbacks mCallbacks;
public StubbablePrinterDiscoverySession(PrintService service,
PrinterDiscoverySessionCallbacks callbacks) {
mService = service;
mCallbacks = callbacks;
if (mCallbacks != null) {
mCallbacks.setSession(this);
}
}
public PrintService getService() {
return mService;
}
@Override
public void onStartPrinterDiscovery(@NonNull List<PrinterId> priorityList) {
if (mCallbacks != null) {
mCallbacks.onStartPrinterDiscovery(priorityList);
}
}
@Override
public void onStopPrinterDiscovery() {
if (mCallbacks != null) {
mCallbacks.onStopPrinterDiscovery();
}
}
@Override
public void onValidatePrinters(@NonNull List<PrinterId> printerIds) {
if (mCallbacks != null) {
mCallbacks.onValidatePrinters(printerIds);
}
}
@Override
public void onStartPrinterStateTracking(@NonNull PrinterId printerId) {
if (mCallbacks != null) {
mCallbacks.onStartPrinterStateTracking(printerId);
}
}
@Override
public void onRequestCustomPrinterIcon(@NonNull PrinterId printerId,
@NonNull CancellationSignal cancellationSignal,
@NonNull CustomPrinterIconCallback callback) {
if (mCallbacks != null) {
mCallbacks.onRequestCustomPrinterIcon(printerId, cancellationSignal, callback);
}
}
@Override
public void onStopPrinterStateTracking(@NonNull PrinterId printerId) {
if (mCallbacks != null) {
mCallbacks.onStopPrinterStateTracking(printerId);
}
}
@Override
public void onDestroy() {
if (mCallbacks != null) {
mCallbacks.onDestroy();
}
}
}