blob: 6d85d37537ea48b489a01091d9b73fc79e051901 [file] [log] [blame]
Satakshid2010f22019-10-29 10:57:43 -07001/*
2 * Copyright (C) 2019 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
17package com.android.systemui.screenshot;
18
Satakshiaaf69532019-11-07 17:54:24 -080019import static android.content.Context.NOTIFICATION_SERVICE;
20
Satakshid2010f22019-10-29 10:57:43 -070021import static org.mockito.ArgumentMatchers.any;
Satakshiaaf69532019-11-07 17:54:24 -080022import static org.mockito.ArgumentMatchers.anyLong;
Satakshid2010f22019-10-29 10:57:43 -070023import static org.mockito.ArgumentMatchers.eq;
Satakshiaaf69532019-11-07 17:54:24 -080024import static org.mockito.Mockito.doThrow;
Satakshid2010f22019-10-29 10:57:43 -070025import static org.mockito.Mockito.mock;
26import static org.mockito.Mockito.never;
27import static org.mockito.Mockito.times;
28import static org.mockito.Mockito.verify;
29import static org.mockito.Mockito.when;
30
31import android.app.Notification;
Satakshiaaf69532019-11-07 17:54:24 -080032import android.app.NotificationManager;
33import android.content.Intent;
Satakshid2010f22019-10-29 10:57:43 -070034import android.graphics.Bitmap;
Satakshiaaf69532019-11-07 17:54:24 -080035import android.net.Uri;
36import android.os.Bundle;
Satakshid2010f22019-10-29 10:57:43 -070037import android.os.Handler;
Satakshiaaf69532019-11-07 17:54:24 -080038import android.os.Looper;
Satakshid2010f22019-10-29 10:57:43 -070039import android.testing.AndroidTestingRunner;
40
41import androidx.test.filters.SmallTest;
42
43import com.android.systemui.SystemUIFactory;
44import com.android.systemui.SysuiTestCase;
Satakshiaaf69532019-11-07 17:54:24 -080045import com.android.systemui.util.NotificationChannels;
Satakshid2010f22019-10-29 10:57:43 -070046
47import org.junit.Assert;
48import org.junit.Before;
49import org.junit.Test;
50import org.junit.runner.RunWith;
51
52import java.util.Collections;
53import java.util.List;
54import java.util.concurrent.CompletableFuture;
55import java.util.concurrent.TimeUnit;
56
57@SmallTest
58@RunWith(AndroidTestingRunner.class)
59/**
60 * Tests for exception handling and bitmap configuration in adding smart actions to Screenshot
61 * Notification.
62 */
63public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
64 private ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
65 private Handler mHandler;
66
67 @Before
68 public void setup() {
69 mSmartActionsProvider = mock(
70 ScreenshotNotificationSmartActionsProvider.class);
71 mHandler = mock(Handler.class);
72 }
73
74 // Tests any exception thrown in getting smart actions future does not affect regular
75 // screenshot flow.
76 @Test
77 public void testExceptionHandlingInGetSmartActionsFuture()
78 throws Exception {
79 Bitmap bitmap = mock(Bitmap.class);
80 when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
81 ScreenshotNotificationSmartActionsProvider smartActionsProvider = mock(
82 ScreenshotNotificationSmartActionsProvider.class);
Satakshiaaf69532019-11-07 17:54:24 -080083 when(smartActionsProvider.getActions(any(), any(), any(),
Satakshid2010f22019-10-29 10:57:43 -070084 eq(false))).thenThrow(
85 RuntimeException.class);
86 CompletableFuture<List<Notification.Action>> smartActionsFuture =
Satakshiaaf69532019-11-07 17:54:24 -080087 GlobalScreenshot.getSmartActionsFuture("", bitmap,
88 smartActionsProvider, true, false);
Satakshid2010f22019-10-29 10:57:43 -070089 Assert.assertNotNull(smartActionsFuture);
90 List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
91 Assert.assertEquals(Collections.emptyList(), smartActions);
92 }
93
94 // Tests any exception thrown in waiting for smart actions future to complete does
95 // not affect regular screenshot flow.
96 @Test
97 public void testExceptionHandlingInGetSmartActions()
98 throws Exception {
99 CompletableFuture<List<Notification.Action>> smartActionsFuture = mock(
100 CompletableFuture.class);
101 int timeoutMs = 1000;
102 when(smartActionsFuture.get(timeoutMs, TimeUnit.MILLISECONDS)).thenThrow(
103 RuntimeException.class);
104 List<Notification.Action> actions = GlobalScreenshot.getSmartActions(
Satakshiaaf69532019-11-07 17:54:24 -0800105 "", smartActionsFuture, timeoutMs, mSmartActionsProvider);
Satakshid2010f22019-10-29 10:57:43 -0700106 Assert.assertEquals(Collections.emptyList(), actions);
107 }
108
Satakshiaaf69532019-11-07 17:54:24 -0800109 // Tests any exception thrown in notifying feedback does not affect regular screenshot flow.
110 @Test
111 public void testExceptionHandlingInNotifyingFeedback()
112 throws Exception {
113 doThrow(RuntimeException.class).when(mSmartActionsProvider).notifyOp(any(), any(), any(),
114 anyLong());
115 GlobalScreenshot.notifyScreenshotOp(null, mSmartActionsProvider, null, null, -1);
116 }
117
Satakshid2010f22019-10-29 10:57:43 -0700118 // Tests for a non-hardware bitmap, ScreenshotNotificationSmartActionsProvider is never invoked
119 // and a completed future is returned.
120 @Test
121 public void testUnsupportedBitmapConfiguration()
122 throws Exception {
123 Bitmap bitmap = mock(Bitmap.class);
124 when(bitmap.getConfig()).thenReturn(Bitmap.Config.RGB_565);
125 CompletableFuture<List<Notification.Action>> smartActionsFuture =
Satakshiaaf69532019-11-07 17:54:24 -0800126 GlobalScreenshot.getSmartActionsFuture("", bitmap,
127 mSmartActionsProvider, true, true);
128 verify(mSmartActionsProvider, never()).getActions(any(), any(), any(),
Satakshid2010f22019-10-29 10:57:43 -0700129 eq(false));
130 Assert.assertNotNull(smartActionsFuture);
131 List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
132 Assert.assertEquals(Collections.emptyList(), smartActions);
133 }
134
135 // Tests for a hardware bitmap, ScreenshotNotificationSmartActionsProvider is invoked once.
136 @Test
137 public void testScreenshotNotificationSmartActionsProviderInvokedOnce() {
138 Bitmap bitmap = mock(Bitmap.class);
139 when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
Satakshiaaf69532019-11-07 17:54:24 -0800140 GlobalScreenshot.getSmartActionsFuture("", bitmap, mSmartActionsProvider,
141 true, true);
Satakshid2010f22019-10-29 10:57:43 -0700142 verify(mSmartActionsProvider, times(1))
Satakshiaaf69532019-11-07 17:54:24 -0800143 .getActions(any(), any(), any(), eq(true));
Satakshid2010f22019-10-29 10:57:43 -0700144 }
145
146 // Tests for a hardware bitmap, a completed future is returned.
147 @Test
148 public void testSupportedBitmapConfiguration()
149 throws Exception {
150 Bitmap bitmap = mock(Bitmap.class);
151 when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
152 ScreenshotNotificationSmartActionsProvider actionsProvider =
Satakshiaaf69532019-11-07 17:54:24 -0800153 SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider(
154 mContext, null, mHandler);
Satakshid2010f22019-10-29 10:57:43 -0700155 CompletableFuture<List<Notification.Action>> smartActionsFuture =
Satakshiaaf69532019-11-07 17:54:24 -0800156 GlobalScreenshot.getSmartActionsFuture("", bitmap,
Satakshid2010f22019-10-29 10:57:43 -0700157 actionsProvider,
Satakshiaaf69532019-11-07 17:54:24 -0800158 true, true);
Satakshid2010f22019-10-29 10:57:43 -0700159 Assert.assertNotNull(smartActionsFuture);
160 List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
161 Assert.assertEquals(smartActions.size(), 0);
162 }
Satakshiaaf69532019-11-07 17:54:24 -0800163
164 // Tests for notification action extras.
165 @Test
166 public void testNotificationActionExtras() {
167 if (Looper.myLooper() == null) {
168 Looper.prepare();
169 }
170 NotificationManager notificationManager =
171 (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
172 GlobalScreenshot.SaveImageInBackgroundData
173 data = new GlobalScreenshot.SaveImageInBackgroundData();
174 data.context = mContext;
175 data.image = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
176 data.iconSize = 10;
177 data.finisher = null;
Miranda Kephart0148b282019-10-31 15:36:21 -0400178 data.mActionsReadyListener = null;
Satakshiaaf69532019-11-07 17:54:24 -0800179 data.previewWidth = 10;
180 data.previewheight = 10;
181 SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, data,
182 notificationManager);
183 Notification.Builder notificationBuilder = new Notification.Builder(mContext,
184 NotificationChannels.SCREENSHOTS_HEADSUP);
185 task.populateNotificationActions(mContext, mContext.getResources(),
186 Uri.parse("Screenshot_123.png"),
187 CompletableFuture.completedFuture(Collections.emptyList()), notificationBuilder);
188
189 Notification notification = notificationBuilder.build();
190 Assert.assertEquals(notification.actions.length, 3);
191 boolean isShareFound = false;
192 boolean isEditFound = false;
193 boolean isDeleteFound = false;
194 for (Notification.Action action : notification.actions) {
195 Intent intent = action.actionIntent.getIntent();
196 Assert.assertNotNull(intent);
197 Bundle bundle = intent.getExtras();
198 Assert.assertTrue(bundle.containsKey(GlobalScreenshot.EXTRA_ID));
199 Assert.assertTrue(bundle.containsKey(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED));
200
201 if (action.title.equals(GlobalScreenshot.ACTION_TYPE_DELETE)) {
202 isDeleteFound = intent.getAction() == null;
203 } else if (action.title.equals(GlobalScreenshot.ACTION_TYPE_EDIT)) {
204 isEditFound = Intent.ACTION_EDIT.equals(intent.getAction());
205 } else if (action.title.equals(GlobalScreenshot.ACTION_TYPE_SHARE)) {
206 isShareFound = Intent.ACTION_SEND.equals(intent.getAction());
207 }
208 }
209
210 Assert.assertTrue(isEditFound);
211 Assert.assertTrue(isDeleteFound);
212 Assert.assertTrue(isShareFound);
213 }
Satakshid2010f22019-10-29 10:57:43 -0700214}