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  */
16 
17 package com.android.cts.deviceandprofileowner;
18 
19 import java.lang.Character;
20 
21 public class SupportMessageTest extends BaseDeviceAdminTest {
22 
23     /**
24      * Longest allowed length of a short support message before the system may truncate it.
25      *
26      * Taken from documentation for
27      * {@link DevicePolicyManager#setShortSupportMessage(android.content.ComponentName, String)}.
28      */
29     private static final int MAX_SHORT_MSG_LENGTH = 200;
30 
31     private static final int REASONABLE_LONG_MSG_LENGTH = 4000;
32 
33     // Declare a different string of the same type for both long and short messages, so we can be
34     // sure they aren't mixed up by any API calls.
35     private static class ShortMessage {
36         static final CharSequence EMPTY = "";
37         static final CharSequence SIMPLE = "short-message-short";
38         static final CharSequence MAX_LENGTH =
39                 new String(new char[MAX_SHORT_MSG_LENGTH]).replace('\0', 'X');
40         static final CharSequence TOO_LONG =
41                 new String(new char[MAX_SHORT_MSG_LENGTH + 10]).replace('\0', 'A');
42         static final CharSequence UNICODE = new String(Character.toChars(0x1F634)) + " zzz";
43         static final CharSequence CONTAINS_NULL = "short\0null";
44     }
45     private static class LongMessage {
46         static final CharSequence EMPTY = "";
47         static final CharSequence SIMPLE = "long-message-long";
48         static final CharSequence LONG =
49                 new String(new char[REASONABLE_LONG_MSG_LENGTH]).replace('\0', 'B');
50         static final CharSequence UNICODE = new String(Character.toChars(0x1F609)) + " ;)";
51         static final CharSequence CONTAINS_NULL = "long\0null";
52     }
53 
54     @Override
tearDown()55     protected void tearDown() throws Exception {
56         clearSupportMessages();
57         super.tearDown();
58     }
59 
testShortSupportMessageSetGetAndClear()60     public void testShortSupportMessageSetGetAndClear() {
61         setShortMessage(ShortMessage.SIMPLE);
62         setShortMessage(null);
63     }
64 
testLongSupportMessageSetGetAndClear()65     public void testLongSupportMessageSetGetAndClear() {
66         setLongMessage(LongMessage.SIMPLE);
67         setLongMessage(null);
68     }
69 
testLongAndShortMessagesDoNotClobber()70     public void testLongAndShortMessagesDoNotClobber() {
71         setShortMessage(ShortMessage.SIMPLE);
72         setLongMessage(LongMessage.SIMPLE);
73 
74         assertEquals(ShortMessage.SIMPLE, getShortMessage());
75         assertEquals(LongMessage.SIMPLE, getLongMessage());
76     }
77 
testMaximumLengthPrefixIsSaved()78     public void testMaximumLengthPrefixIsSaved() {
79         // Save and restore a string of exactly the maximum length
80         setShortMessage(ShortMessage.MAX_LENGTH);
81 
82         /*
83          * Save and restore a "short message" string that is too large -- this may only store the
84          * first N characters, not the whole thing, so we need to use {@link String#startsWith}
85          * here.
86          */
87         mDevicePolicyManager.setShortSupportMessage(ADMIN_RECEIVER_COMPONENT,
88                 ShortMessage.TOO_LONG);
89         assertStartsWith(ShortMessage.TOO_LONG.subSequence(0, MAX_SHORT_MSG_LENGTH),
90                 getShortMessage());
91 
92         // Long support messages should not be affected; verify that.
93         mDevicePolicyManager.setLongSupportMessage(ADMIN_RECEIVER_COMPONENT, LongMessage.LONG);
94         assertEquals(LongMessage.LONG, getLongMessage());
95     }
96 
testEmptySupportMessage()97     public void testEmptySupportMessage() {
98         setShortMessage(ShortMessage.EMPTY);
99         setLongMessage(LongMessage.EMPTY);
100     }
101 
testUnicodeCharactersInMessage()102     public void testUnicodeCharactersInMessage() {
103         setShortMessage(ShortMessage.UNICODE);
104         setLongMessage(LongMessage.UNICODE);
105     }
106 
testNullCharacterInMessage()107     public void testNullCharacterInMessage() {
108         setShortMessage(ShortMessage.CONTAINS_NULL);
109         setLongMessage(LongMessage.CONTAINS_NULL);
110     }
111 
testSetOrGetSupportMessageWithNullAdminFails()112     public void testSetOrGetSupportMessageWithNullAdminFails() {
113         // Short support message
114         try {
115             mDevicePolicyManager.setShortSupportMessage(null, ShortMessage.SIMPLE);
116             fail("Exception should have been thrown for null admin ComponentName");
117         } catch (NullPointerException expected) {
118         }
119         try {
120             CharSequence message = mDevicePolicyManager.getShortSupportMessage(null);
121             fail("Exception should have been thrown for null admin ComponentName");
122         } catch (NullPointerException expected) {
123         }
124 
125         // Long support message
126         try {
127             mDevicePolicyManager.setLongSupportMessage(null, LongMessage.SIMPLE);
128             fail("Exception should have been thrown for null admin ComponentName");
129         } catch (NullPointerException expected) {
130         }
131 
132         try {
133             CharSequence message = mDevicePolicyManager.getLongSupportMessage(null);
134             fail("Exception should have been thrown for null admin ComponentName");
135         } catch (NullPointerException expected) {
136         }
137     }
138 
139     /**
140      * Delete all admin-set support messsages.
141      */
clearSupportMessages()142     private void clearSupportMessages() {
143         setShortMessage(null);
144         setLongMessage(null);
145     }
146 
147     /**
148      * Update the short support message.
149      *
150      * @throws AssertionError in the case that the message could not be set.
151      */
setShortMessage(CharSequence message)152     private void setShortMessage(CharSequence message) {
153         mDevicePolicyManager.setShortSupportMessage(ADMIN_RECEIVER_COMPONENT, message);
154         assertEquals(message, getShortMessage());
155     }
156 
157     /**
158      * Update the long support message.
159      *
160      * @throws AssertionError in the case that the message could not be set.
161      */
setLongMessage(CharSequence message)162     private void setLongMessage(CharSequence message) {
163         mDevicePolicyManager.setLongSupportMessage(ADMIN_RECEIVER_COMPONENT, message);
164         assertEquals(message, getLongMessage());
165     }
166 
getShortMessage()167     private CharSequence getShortMessage() {
168         return mDevicePolicyManager.getShortSupportMessage(ADMIN_RECEIVER_COMPONENT);
169     }
170 
getLongMessage()171     private CharSequence getLongMessage() {
172         return mDevicePolicyManager.getLongSupportMessage(ADMIN_RECEIVER_COMPONENT);
173     }
174 
assertStartsWith(CharSequence expectPrefix, CharSequence actual)175     private static void assertStartsWith(CharSequence expectPrefix, CharSequence actual) {
176         assertNotNull(expectPrefix);
177         assertNotNull(actual);
178         if (!actual.toString().startsWith(expectPrefix.toString())) {
179             fail("Expected prefix: '" + expectPrefix + "'\n" +
180                  "            got: '" + actual + "'");
181         }
182     }
183 }
184