1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16package com.android.launcher3.util.rule;
17
18import android.content.ComponentName;
19import android.content.pm.ActivityInfo;
20import android.os.ParcelFileDescriptor;
21import android.support.test.InstrumentationRegistry;
22
23import org.junit.rules.TestRule;
24import org.junit.runner.Description;
25import org.junit.runners.model.Statement;
26
27import java.io.FileInputStream;
28import java.io.IOException;
29
30/**
31 * Test rule which executes a shell command at the start of the test.
32 */
33public class ShellCommandRule implements TestRule {
34
35    private final String mCmd;
36
37    public ShellCommandRule(String cmd) {
38        mCmd = cmd;
39    }
40
41    @Override
42    public Statement apply(Statement base, Description description) {
43        return new MyStatement(base, mCmd);
44    }
45
46    public static void runShellCommand(String command) throws IOException {
47        ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation().getUiAutomation()
48                .executeShellCommand(command);
49
50        // Read the input stream fully.
51        FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
52        while (fis.read() != -1);
53        fis.close();
54    }
55
56    private static class MyStatement extends Statement {
57        private final Statement mBase;
58        private final String mCmd;
59
60        public MyStatement(Statement base, String cmd) {
61            mBase = base;
62            mCmd = cmd;
63        }
64
65        @Override
66        public void evaluate() throws Throwable {
67            runShellCommand(mCmd);
68            mBase.evaluate();
69        }
70    }
71
72    /**
73     * Grants the launcher permission to bind widgets.
74     */
75    public static ShellCommandRule grandWidgetBind() {
76        return new ShellCommandRule("appwidget grantbind --package "
77                + InstrumentationRegistry.getTargetContext().getPackageName());
78    }
79
80    /**
81     * Sets the target launcher as default launcher.
82     */
83    public static ShellCommandRule setDefaultLauncher() {
84        ActivityInfo launcher = InstrumentationRegistry.getTargetContext().getPackageManager()
85                .queryIntentActivities(LauncherActivityRule.getHomeIntent(), 0).get(0)
86                .activityInfo;
87        return new ShellCommandRule("cmd package set-home-activity " +
88                new ComponentName(launcher.packageName, launcher.name).flattenToString());
89    }
90}
91