1 /*
2  * Copyright (C) 2021 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 android.voiceinteraction.cts.testcore;
18 
19 import android.app.DirectAction;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.os.RemoteCallback;
24 import android.util.Log;
25 import android.voiceinteraction.common.Utils;
26 
27 import androidx.annotation.NonNull;
28 import androidx.annotation.Nullable;
29 
30 import com.android.compatibility.common.util.ThrowingRunnable;
31 
32 import java.util.concurrent.CountDownLatch;
33 import java.util.concurrent.TimeUnit;
34 import java.util.concurrent.TimeoutException;
35 
36 /**
37  * A control class to help to perform operations between test case and testing
38  * VoiceInteractionSession.
39  */
40 public class VoiceInteractionSessionControl {
41     private static final String TAG = VoiceInteractionSessionControl.class.getSimpleName();
42 
43     private @NonNull Context mContext;
44     private @Nullable RemoteCallback mControl;
45 
VoiceInteractionSessionControl(Context context)46     protected VoiceInteractionSessionControl(Context context) {
47         mContext = context;
48     }
49 
startVoiceInteractionSession(Intent intent)50     protected void startVoiceInteractionSession(Intent intent) throws Exception {
51         final CountDownLatch latch = new CountDownLatch(1);
52 
53         final RemoteCallback callback = new RemoteCallback((result) -> {
54             mControl = result.getParcelable(Utils.VOICE_INTERACTION_KEY_CONTROL);
55             latch.countDown();
56         });
57 
58         intent.putExtra(Utils.VOICE_INTERACTION_KEY_CALLBACK, callback);
59 
60         Log.v(TAG, "startVoiceInteractionSession(): " + intent);
61         mContext.startActivity(intent);
62 
63         final long timeoutMs = Utils.getAdjustedOperationTimeoutMs();
64         if (!latch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
65             throw new TimeoutException("activity not started in " + timeoutMs
66                     + "ms");
67         }
68     }
69 
stopVoiceInteractionSession()70     public void stopVoiceInteractionSession() throws Exception {
71         executeCommand(Utils.VOICE_INTERACTION_SESSION_CMD_FINISH,
72                 null /*directAction*/, null /*arguments*/, null /*postActionCommand*/);
73     }
74 
75     @NonNull
executeCommand(@onNull String action, @Nullable DirectAction directAction, @Nullable Bundle arguments, @Nullable ThrowingRunnable postActionCommand)76     protected Bundle executeCommand(@NonNull String action, @Nullable DirectAction directAction,
77             @Nullable Bundle arguments, @Nullable ThrowingRunnable postActionCommand)
78             throws Exception {
79         final CountDownLatch latch = new CountDownLatch(1);
80 
81         final Bundle result = new Bundle();
82 
83         final RemoteCallback callback = new RemoteCallback((b) -> {
84             result.putAll(b);
85             latch.countDown();
86         });
87 
88         final Bundle command = new Bundle();
89         command.putString(Utils.VOICE_INTERACTION_KEY_COMMAND, action);
90         command.putParcelable(Utils.VOICE_INTERACTION_DIRECT_ACTIONS_KEY_ACTION, directAction);
91         command.putBundle(Utils.VOICE_INTERACTION_KEY_ARGUMENTS, arguments);
92         command.putParcelable(Utils.VOICE_INTERACTION_KEY_CALLBACK, callback);
93 
94         Log.v(TAG, "executeCommand(): action=" + action + " command="
95                 + Utils.toBundleString(command));
96         mControl.sendResult(command);
97 
98         if (postActionCommand != null) {
99             Log.v(TAG, "Executing post-action command for " + action);
100             postActionCommand.run();
101         }
102 
103         final long timeoutMs = Utils.getAdjustedOperationTimeoutMs();
104         if (!latch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
105             throw new TimeoutException(
106                     "result not received in " + timeoutMs + "ms");
107         }
108         Log.v(TAG, "returning " + Utils.toBundleString(result));
109         return result;
110     }
111 }
112