1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of 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,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.managedprovisioning.e2eui;
17
18import android.content.pm.UserInfo;
19import android.os.UserManager;
20import android.support.test.espresso.ViewInteraction;
21import android.support.test.espresso.base.DefaultFailureHandler;
22import android.support.test.filters.LargeTest;
23import android.support.test.rule.ActivityTestRule;
24import android.test.AndroidTestCase;
25import android.util.Log;
26
27import android.view.View;
28import com.android.managedprovisioning.R;
29import com.android.managedprovisioning.TestInstrumentationRunner;
30import com.android.managedprovisioning.preprovisioning.PreProvisioningActivity;
31import org.hamcrest.Matcher;
32
33import java.util.List;
34
35import static android.support.test.espresso.Espresso.onView;
36import static android.support.test.espresso.action.ViewActions.click;
37import static android.support.test.espresso.action.ViewActions.scrollTo;
38import static android.support.test.espresso.matcher.ViewMatchers.withId;
39
40@LargeTest
41public class ManagedProfileTest extends AndroidTestCase {
42    private static final String TAG = "ManagedProfileTest";
43
44    private static final long TIMEOUT = 120L;
45
46    public ActivityTestRule mActivityRule;
47    private ProvisioningResultListener mResultListener;
48
49    @Override
50    protected void setUp() throws Exception {
51        super.setUp();
52        mActivityRule = new ActivityTestRule<>(
53                PreProvisioningActivity.class,
54                true /* initialTouchMode */,
55                false);  // launchActivity. False to set intent per method
56        mResultListener = new ProvisioningResultListener(getContext());
57        TestInstrumentationRunner.registerReplacedActivity(PreProvisioningActivity.class,
58                (cl, className, intent) -> new TestPreProvisioningActivity(mResultListener));
59    }
60
61    @Override
62    protected void tearDown() throws Exception {
63        super.tearDown();
64        TestInstrumentationRunner.unregisterReplacedActivity(PreProvisioningActivity.class);
65        mResultListener.unregister();
66
67        // Remove any managed profiles in case that
68        removeAllManagedProfiles();
69    }
70
71    private void removeAllManagedProfiles() {
72        UserManager um = getContext().getSystemService(UserManager.class);
73        List<UserInfo> users = um.getUsers();
74        for (UserInfo user : users) {
75            if (user.isManagedProfile()) {
76                int userId = user.getUserHandle().getIdentifier();
77                um.removeUserEvenWhenDisallowed(userId);
78                Log.e(TAG, "remove managed profile user: " + userId);
79            }
80        }
81    }
82
83    public void testManagedProfile() throws Exception {
84        mActivityRule.launchActivity(ManagedProfileAdminReceiver.INTENT_PROVISION_MANAGED_PROFILE);
85
86        mResultListener.register();
87
88        // Retry the sequence of 2 actions 3 times to avoid flakiness of the test
89        new EspressoClickRetryActions(3) {
90            @Override
91            public ViewInteraction newViewInteraction1() {
92                return onView(withId(R.id.next_button));
93            }
94        }.run();
95
96        if (mResultListener.await(TIMEOUT)) {
97            assertTrue(mResultListener.getResult());
98        } else {
99            fail("timeout: " + TIMEOUT + " seconds");
100        }
101    }
102
103    private abstract class EspressoClickRetryActions {
104        private final int mRetries;
105        private int i = 0;
106
107        EspressoClickRetryActions(int retries) {
108            mRetries = retries;
109        }
110
111        public abstract ViewInteraction newViewInteraction1();
112
113        public void run() {
114            i++;
115            newViewInteraction1()
116                    .withFailureHandler(this::handleFailure)
117                    .perform(scrollTo(), click());
118            Log.i(TAG, "newViewInteraction1 succeeds.");
119        }
120
121        private void handleFailure(Throwable e, Matcher<View> matcher) {
122            Log.i(TAG, "espresso handleFailure count: " + i, e);
123            if (i < mRetries) {
124                run();
125            } else {
126                new DefaultFailureHandler(getContext()).handle(e, matcher);
127            }
128        }
129    }
130}
131
132