1 /*
2  * Copyright 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  */
16 package com.android.managedprovisioning.parser;
17 
18 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE;
20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
21 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
22 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE;
23 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
24 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
25 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
26 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
27 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED;
28 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE;
29 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME;
30 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_MAIN_COLOR;
31 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION;
32 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_USER_SETUP;
33 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE;
34 import static com.android.managedprovisioning.common.Globals.ACTION_RESUME_PROVISIONING;
35 import static com.android.managedprovisioning.model.ProvisioningParams.DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED;
36 import static com.android.managedprovisioning.model.ProvisioningParams.DEFAULT_STARTED_BY_TRUSTED_SOURCE;
37 import static com.android.managedprovisioning.model.ProvisioningParams.DEFAULT_SKIP_USER_SETUP;
38 import static com.android.managedprovisioning.parser.MessageParser.EXTRA_PROVISIONING_ACTION;
39 import static com.android.managedprovisioning.parser.MessageParser.EXTRA_PROVISIONING_STARTED_BY_TRUSTED_SOURCE;
40 import static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC;
41 import static com.android.managedprovisioning.model.ProvisioningParams.DEFAULT_LOCAL_TIME;
42 import static org.mockito.Mockito.doReturn;
43 import static org.mockito.Mockito.spy;
44 import static org.mockito.Mockito.verify;
45 
46 import android.accounts.Account;
47 import android.app.admin.DevicePolicyManager;
48 import android.content.ComponentName;
49 import android.content.Context;
50 import android.content.Intent;
51 import android.nfc.NdefMessage;
52 import android.nfc.NdefRecord;
53 import android.nfc.NfcAdapter;
54 import android.os.PersistableBundle;
55 import android.test.AndroidTestCase;
56 import android.test.suitebuilder.annotation.SmallTest;
57 
58 import com.android.managedprovisioning.TestUtils;
59 import com.android.managedprovisioning.common.Utils;
60 import com.android.managedprovisioning.model.ProvisioningParams;
61 
62 import org.mockito.Mock;
63 import org.mockito.MockitoAnnotations;
64 
65 import java.io.ByteArrayOutputStream;
66 import java.lang.Exception;
67 import java.util.Locale;
68 import java.util.Properties;
69 
70 /** Tests {@link MessageParser} */
71 @SmallTest
72 public class MessageParserTest extends AndroidTestCase {
73     private static final String TEST_PACKAGE_NAME = "com.afwsamples.testdpc";
74     private static final ComponentName TEST_COMPONENT_NAME =
75             ComponentName.unflattenFromString(
76                     "com.afwsamples.testdpc/com.afwsamples.testdpc.DeviceAdminReceiver");
77     private static final long TEST_LOCAL_TIME = 1456939524713L;
78     private static final Locale TEST_LOCALE = Locale.UK;
79     private static final String TEST_TIME_ZONE = "GMT";
80     private static final Integer TEST_MAIN_COLOR = 65280;
81     private static final boolean TEST_SKIP_ENCRYPTION = true;
82     private static final Account TEST_ACCOUNT_TO_MIGRATE =
83             new Account("user@gmail.com", "com.google");
84 
85     @Mock
86     private Context mContext;
87 
88     private Utils mUtils;
89 
90     private MessageParser mMessageParser;
91 
92     @Override
setUp()93     public void setUp() {
94         // this is necessary for mockito to work
95         System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
96 
97         MockitoAnnotations.initMocks(this);
98 
99         mMessageParser = new MessageParser(mUtils = spy(new Utils()));
100     }
101 
testParseAndRecoverIntent()102     public void testParseAndRecoverIntent() throws Exception {
103         // GIVEN the device admin app is installed.
104         doReturn(TEST_COMPONENT_NAME)
105                 .when(mUtils)
106                 .findDeviceAdmin(TEST_PACKAGE_NAME, null, mContext);
107 
108         // GIVEN a managed provisioning intent with some extras was being parsed.
109         Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE)
110                 .putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, TEST_PACKAGE_NAME)
111                 .putExtra(EXTRA_PROVISIONING_SKIP_ENCRYPTION, TEST_SKIP_ENCRYPTION)
112                 .putExtra(EXTRA_PROVISIONING_MAIN_COLOR, TEST_MAIN_COLOR)
113                 .putExtra(EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE, TEST_ACCOUNT_TO_MIGRATE);
114         ProvisioningParams params = mMessageParser.parse(intent, mContext);
115 
116         // WHEN the provisioning data was converted to an intent by getIntentFromProvisioningParams.
117         Intent restoredIntent = mMessageParser.getIntentFromProvisioningParams(params);
118 
119         // THEN the intent matches
120         TestUtils.assertIntentEquals(new Intent(ACTION_RESUME_PROVISIONING)
121                         .putExtra(EXTRA_PROVISIONING_ACTION, ACTION_PROVISION_MANAGED_PROFILE)
122                         // Package name is deprecated and replaced by component name only.
123                         .putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, (String) null)
124                         .putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
125                                 TEST_COMPONENT_NAME)
126                         .putExtra(EXTRA_PROVISIONING_LOCAL_TIME, DEFAULT_LOCAL_TIME)
127                         .putExtra(EXTRA_PROVISIONING_TIME_ZONE, (String) null)
128                         .putExtra(EXTRA_PROVISIONING_LOCALE, (Locale) null)
129                         .putExtra(EXTRA_PROVISIONING_SKIP_ENCRYPTION, TEST_SKIP_ENCRYPTION)
130                         .putExtra(EXTRA_PROVISIONING_SKIP_USER_SETUP, DEFAULT_SKIP_USER_SETUP)
131                         .putExtra(EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
132                                 DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED)
133                         .putExtra(EXTRA_PROVISIONING_MAIN_COLOR, TEST_MAIN_COLOR)
134                         .putExtra(EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE, TEST_ACCOUNT_TO_MIGRATE)
135                         .putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, (PersistableBundle) null)
136                         .putExtra(EXTRA_PROVISIONING_STARTED_BY_TRUSTED_SOURCE,
137                                 DEFAULT_STARTED_BY_TRUSTED_SOURCE),
138                 restoredIntent);
139     }
140 
test_correctParserUsedToParseNfcIntent()141     public void test_correctParserUsedToParseNfcIntent() throws Exception {
142         // GIVEN a NFC provisioning intent with some supported data.
143         Properties props = new Properties();
144         ByteArrayOutputStream stream = new ByteArrayOutputStream();
145         props.setProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, TEST_PACKAGE_NAME);
146         props.setProperty(
147                 EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
148                 TEST_COMPONENT_NAME.flattenToString());
149         props.store(stream, "NFC provisioning intent" /* data description */);
150         NdefRecord record = NdefRecord.createMime(
151                 DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC,
152                 stream.toByteArray());
153         NdefMessage ndfMsg = new NdefMessage(new NdefRecord[]{record});
154 
155         Intent intent = new Intent(NfcAdapter.ACTION_NDEF_DISCOVERED)
156                 .setType(MIME_TYPE_PROVISIONING_NFC)
157                 .putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, new NdefMessage[]{ndfMsg});
158 
159         // WHEN the mMessageParser.getParser is invoked.
160         ProvisioningDataParser parser = mMessageParser.getParser(intent);
161 
162         // THEN the properties parser is returned.
163         assertTrue(parser instanceof PropertiesProvisioningDataParser);
164     }
165 
test_correctParserUsedToParseOtherSupportedProvisioningIntent()166     public void test_correctParserUsedToParseOtherSupportedProvisioningIntent() throws Exception {
167         // GIVEN the device admin app is installed.
168         doReturn(TEST_COMPONENT_NAME)
169                 .when(mUtils)
170                 .findDeviceAdmin(null, TEST_COMPONENT_NAME, mContext);
171         // GIVEN a list of supported provisioning actions, except NFC.
172         String[] supportedProvisioningActions = new String[] {
173                 ACTION_PROVISION_MANAGED_DEVICE,
174                 ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE,
175                 ACTION_PROVISION_MANAGED_USER,
176                 ACTION_PROVISION_MANAGED_PROFILE,
177                 ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE
178         };
179 
180         for (String provisioningAction : supportedProvisioningActions) {
181             Intent intent = new Intent(provisioningAction)
182                     .putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, TEST_COMPONENT_NAME);
183 
184             // WHEN the mMessageParser.getParser is invoked.
185             ProvisioningDataParser parser = mMessageParser.getParser(intent);
186 
187             // THEN the extras parser is returned.
188             assertTrue(parser instanceof ExtrasProvisioningDataParser);
189         }
190     }
191 }
192