1 /*
2  * Copyright (C) 2020 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.nn.crashtest.app;
18 
19 import android.app.Activity;
20 import android.content.Intent;
21 import android.util.Log;
22 
23 import com.android.nn.crashtest.core.CrashTest;
24 import com.android.nn.crashtest.core.CrashTestCoordinator;
25 
26 import java.time.Duration;
27 import java.util.concurrent.TimeUnit;
28 
29 public abstract class NNCrashTestActivity extends Activity {
30   public static final Duration MAX_TEST_DELAY_BEFORE_HANG = Duration.ofSeconds(30);
31 
32   private final CrashTestStatus mTestStatus = new CrashTestStatus(this::logMessage);
33   private final CrashTestCoordinator mCoordinator = new CrashTestCoordinator(this);
34   private Duration mDuration;
35 
logMessage(String msg)36   protected void logMessage(String msg) {
37     Log.i(getTag(), msg);
38   }
39 
getTag()40   protected abstract String getTag();
41 
getTestName(Intent intent)42   protected abstract String getTestName(Intent intent);
43 
getTestDurationMillis(Intent intent)44   protected abstract long getTestDurationMillis(Intent intent);
45 
getIntentInitializer(Intent intent)46   protected abstract CrashTestCoordinator.CrashTestIntentInitializer getIntentInitializer(Intent intent);
47 
getTestClass()48   protected abstract Class<? extends CrashTest> getTestClass();
49 
50 
51   @Override
onResume()52   protected void onResume() {
53     super.onResume();
54 
55     final Intent intent = getIntent();
56 
57     mDuration = Duration.ofMillis(getTestDurationMillis(intent));
58     mCoordinator.startTest(getTestClass(),
59         getIntentInitializer(intent),
60         mTestStatus,
61         /*separateProcess=*/true, getTestName(intent));
62   }
63 
64   // This method blocks until the tests complete and returns true if all tests completed
65   // successfully
testResult()66   public CrashTestStatus.TestResult testResult() {
67     try {
68       final Duration testTimeout = mDuration.plus(MAX_TEST_DELAY_BEFORE_HANG);
69       boolean completed =
70               mTestStatus.waitForCompletion(testTimeout.toMillis(), TimeUnit.MILLISECONDS);
71       if (!completed) {
72         Log.w(getTag(), String.format("Test didn't complete within %s. Returning HANG", testTimeout));
73         return CrashTestStatus.TestResult.HANG;
74       }
75       return mTestStatus.result();
76     } catch (InterruptedException e) {
77       Log.w(getTag(), "Interrupted while waiting for test completion. Returning HANG");
78       return CrashTestStatus.TestResult.HANG;
79     }
80   }
81 }