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 package android.content.pm.cts.shortcutmanager.common;
17 
18 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.retryUntil;
19 
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.os.Bundle;
25 import android.util.Log;
26 
27 import junit.framework.Assert;
28 
29 import java.util.concurrent.atomic.AtomicReference;
30 import java.util.function.Consumer;
31 
32 public class ReplyUtil {
ReplyUtil()33     private ReplyUtil() {
34     }
35 
36     private static final String MAIN_CTS_PACKAGE = "android.content.pm.cts.shortcutmanager";
37 
runTestAndReply(Context context, String replyAction, Runnable test)38     public static void runTestAndReply(Context context, String replyAction, Runnable test) {
39         try {
40             test.run();
41 
42             sendReply(context, replyAction, null);
43         } catch (Throwable e) {
44             String error = "Test failed: " + e.getMessage() + "\n" + Log.getStackTraceString(e);
45             sendReply(context, replyAction, error);
46         }
47     }
48 
sendReply(Context context, String replyAction, String failureMessageOrNullForSuccess)49     public static void sendReply(Context context, String replyAction,
50             String failureMessageOrNullForSuccess) {
51         // Create the reply bundle.
52         final Bundle ret = new Bundle();
53         if (failureMessageOrNullForSuccess == null) {
54             ret.putBoolean("success", true);
55         } else {
56             ret.putString("error", failureMessageOrNullForSuccess);
57         }
58 
59         // Send reply
60         final Intent reply = new Intent(replyAction).setPackage(MAIN_CTS_PACKAGE);
61         reply.putExtras(ret);
62 
63         context.sendBroadcast(reply);
64     }
65 
sendSuccessReply(Context context, String replyAction)66     public static void sendSuccessReply(Context context, String replyAction) {
67         sendReply(context, replyAction, null);
68     }
69 
invokeAndWaitForReply(Context context, Consumer<String> r)70     public static void invokeAndWaitForReply(Context context, Consumer<String> r) {
71         final AtomicReference<Intent> ret = new AtomicReference<>();
72 
73         // Register the reply receiver
74 
75         // Use a random reply action every time.
76         final String replyAction = Constants.ACTION_REPLY + Constants.sRandom.nextLong();
77         final IntentFilter filter = new IntentFilter(replyAction);
78 
79         final BroadcastReceiver resultReceiver = new BroadcastReceiver() {
80             @Override
81             public void onReceive(Context context, Intent intent) {
82                 ret.set(intent);
83             }
84         };
85 
86         context.registerReceiver(resultReceiver, filter);
87 
88         try {
89             // Run the code.
90             r.accept(replyAction);
91 
92             // Wait for the response.
93             retryUntil(() -> ret.get() != null, "Didn't receive result broadcast", 120);
94 
95             if (ret.get().getExtras().getBoolean("success")) {
96                 return;
97             }
98             Assert.fail(ret.get().getExtras().getString("error"));
99         } finally {
100             context.unregisterReceiver(resultReceiver);
101         }
102     }
103 }
104