blob: 3dc41e64f4fecee549f664bdd0ea3c41187ad2ab [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.verifier.notifications;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.provider.Settings;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
import java.util.ArrayList;
/**
* Bubble notification tests: This test checks the behaviour of notifications that have a bubble.
*/
public class BubblesVerifierActivity extends PassFailButtons.Activity {
private static final String CHANNEL_ID = "BubblesVerifierChannel";
private static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
private TextView mTestTitle;
private TextView mTestDescription;
private Button mTestAction;
private ViewGroup mTestStepButtonLayout;
private Button mTestStepPassed;
private Button mTestStepFailed;
private ArrayList<BubblesTestStep> mTests = new ArrayList<>();
private int mCurrentTestIndex = -1; // gets incremented first time
private int mStepFailureCount = 0;
private abstract class BubblesTestStep {
/** The title of the test step. */
public abstract int getTestTitle();
/** What the tester should do & look for to verify this step was successful. */
public abstract int getTestDescription();
/**
* Text of the button that performs the action for this test (e.g. send bubble). If no
* button is necessary this will return 0.
*/
public int getButtonText() {
return 0;
}
/** Code to run when the button is activated; only used if {@link #getButtonText()} != 0 */
public void performTestAction() {
// optional
}
}
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.bubbles_main);
mTestTitle = findViewById(R.id.bubble_test_title);
mTestDescription = findViewById(R.id.bubble_test_description);
mTestAction = findViewById(R.id.bubble_test_button);
mTestStepButtonLayout = findViewById(R.id.button_layout);
mTestStepPassed = findViewById(R.id.test_step_passed);
mTestStepFailed = findViewById(R.id.test_step_failed);
mTestStepPassed.setOnClickListener((v) -> runNextTestOrShowSummary());
mTestStepFailed.setOnClickListener((v) -> {
mStepFailureCount++;
runNextTestOrShowSummary();
});
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
if (!am.isLowRamDevice()) {
mTests.add(new EnableBubbleTest());
mTests.add(new SendBubbleTest());
mTests.add(new SuppressNotifTest());
mTests.add(new AddNotifTest());
mTests.add(new RemoveMetadataTest());
mTests.add(new AddMetadataTest());
mTests.add(new ExpandBubbleTest());
mTests.add(new DismissBubbleTest());
mTests.add(new DismissNotificationTest());
mTests.add(new AutoExpandBubbleTest());
} else {
Toast.makeText(getApplicationContext(),
getResources().getString(R.string.bubbles_notification_no_bubbles_low_mem),
Toast.LENGTH_LONG).show();
}
setPassFailButtonClickListeners();
// Pass is are enabled when all the steps are done & succeeded
getPassButton().setEnabled(false);
// Sets the text in the dialog
setInfoResources(R.string.bubbles_notification_title,
R.string.bubbles_notification_description, -1);
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(
new NotificationChannel(CHANNEL_ID, CHANNEL_ID, IMPORTANCE_DEFAULT));
runNextTestOrShowSummary();
}
private void runNextTestOrShowSummary() {
if (mCurrentTestIndex + 1 >= mTests.size()) {
updateViewForCompletionSummary();
} else {
mCurrentTestIndex++;
BubblesTestStep currentTest = mTests.get(mCurrentTestIndex);
updateViewForTest(currentTest);
}
}
/** Populates the UI based on the provided test step */
private void updateViewForTest(BubblesTestStep test) {
mTestStepButtonLayout.setVisibility(VISIBLE);
mTestTitle.setText(test.getTestTitle());
mTestDescription.setText(test.getTestDescription());
if (test.getButtonText() != 0) {
// Can't pass until test action has run
mTestStepPassed.setEnabled(false);
// Set up test action
mTestAction.setOnClickListener((v) -> {
test.performTestAction();
mTestStepPassed.setEnabled(true);
});
mTestAction.setText(test.getButtonText());
mTestAction.setVisibility(VISIBLE);
} else {
// No test action required
mTestAction.setOnClickListener(null);
mTestAction.setVisibility(INVISIBLE);
mTestStepPassed.setEnabled(true);
}
}
/** Populates the UI indicating results of test & updates test buttons as needed */
private void updateViewForCompletionSummary() {
// No longer need any of these buttons
mTestStepButtonLayout.setVisibility(INVISIBLE);
mTestAction.setVisibility(INVISIBLE);
boolean didEverythingSucceed = mStepFailureCount == 0;
int totalTests = mTests.size();
int totalPasses = totalTests - mStepFailureCount;
mTestTitle.setText(R.string.bubbles_test_summary_title);
mTestDescription.setText(getString(R.string.bubbles_test_summary, totalPasses, totalTests));
if (didEverythingSucceed) {
getPassButton().setEnabled(true);
}
}
private class EnableBubbleTest extends BubblesTestStep {
@Override
public int getButtonText() {
return R.string.bubbles_notification_enable_bubbles_button;
}
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_enable_bubbles_title;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_enable_bubbles_verify;
}
@Override
public void performTestAction() {
final String packageName = getApplicationContext().getPackageName();
final int appUid = getApplicationInfo().uid;
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
intent.putExtra(Settings.EXTRA_APP_UID, appUid);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
}
private class SendBubbleTest extends BubblesTestStep {
@Override
public int getButtonText() {
return R.string.bubbles_notification_test_button_1;
}
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_title_1;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_verify_1;
}
@Override
public void performTestAction() {
Notification.Builder builder =
getBasicNotifBuilder("Bubble notification", "1: SendBubbleTest");
builder.setBubbleMetadata(getBasicBubbleBuilder().build());
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
private class SuppressNotifTest extends BubblesTestStep {
@Override
public int getButtonText() {
return R.string.bubbles_notification_test_button_2;
}
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_title_2;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_verify_2;
}
@Override
public void performTestAction() {
Notification.Builder builder =
getBasicNotifBuilder("Bubble notification", "2: SuppressNotifTest");
Notification.BubbleMetadata metadata = getBasicBubbleBuilder()
.setSuppressNotification(true)
.build();
builder.setBubbleMetadata(metadata);
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
private class AddNotifTest extends BubblesTestStep {
@Override
public int getButtonText() {
return R.string.bubbles_notification_test_button_3;
}
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_title_3;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_verify_3;
}
@Override
public void performTestAction() {
Notification.Builder builder =
getBasicNotifBuilder("Bubble notification", "3: AddNotifTest");
Notification.BubbleMetadata metadata = getBasicBubbleBuilder()
.setSuppressNotification(false)
.build();
builder.setBubbleMetadata(metadata);
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
private class RemoveMetadataTest extends BubblesTestStep {
@Override
public int getButtonText() {
return R.string.bubbles_notification_test_button_4;
}
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_title_4;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_verify_4;
}
@Override
public void performTestAction() {
Notification.Builder builder =
getBasicNotifBuilder("Bubble notification", "4: RemoveMetadataTest");
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
private class AddMetadataTest extends BubblesTestStep {
@Override
public int getButtonText() {
return R.string.bubbles_notification_test_button_5;
}
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_title_5;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_verify_5;
}
@Override
public void performTestAction() {
Notification.Builder builder =
getBasicNotifBuilder("Bubble notification", "5: AddMetadataTest");
Notification.BubbleMetadata metadata = getBasicBubbleBuilder().build();
builder.setBubbleMetadata(metadata);
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
private class ExpandBubbleTest extends BubblesTestStep {
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_title_6;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_verify_6;
}
}
private class DismissBubbleTest extends BubblesTestStep {
@Override
public int getButtonText() {
return R.string.bubbles_notification_test_button_7;
}
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_title_7;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_verify_7;
}
@Override
public void performTestAction() {
Notification.Builder builder =
getBasicNotifBuilder("Bubble notification", "7: DismissBubbleTest");
Notification.BubbleMetadata metadata = getBasicBubbleBuilder().build();
builder.setBubbleMetadata(metadata);
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
private class DismissNotificationTest extends BubblesTestStep {
@Override
public int getButtonText() {
return R.string.bubbles_notification_test_button_8;
}
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_title_8;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_verify_8;
}
@Override
public void performTestAction() {
Notification.Builder builder =
getBasicNotifBuilder("Bubble notification",
"8: DismissNotificationTest: Dismiss me!!");
Notification.BubbleMetadata metadata = getBasicBubbleBuilder().build();
builder.setBubbleMetadata(metadata);
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
private class AutoExpandBubbleTest extends BubblesTestStep {
@Override
public int getButtonText() {
return R.string.bubbles_notification_test_button_9;
}
@Override
public int getTestTitle() {
return R.string.bubbles_notification_test_title_9;
}
@Override
public int getTestDescription() {
return R.string.bubbles_notification_test_verify_9;
}
@Override
public void performTestAction() {
Notification.Builder builder =
getBasicNotifBuilder("Bubble notification", "9: Auto expanded bubble");
Notification.BubbleMetadata metadata =
getBasicBubbleBuilder().setAutoExpandBubble(true).build();
builder.setBubbleMetadata(metadata);
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
/** Creates a minimally filled out {@link android.app.Notification.BubbleMetadata.Builder} */
private Notification.BubbleMetadata.Builder getBasicBubbleBuilder() {
Context context = getApplicationContext();
Intent intent = new Intent(context, BubbleActivity.class);
final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
return new Notification.BubbleMetadata.Builder()
.setIcon(Icon.createWithResource(getApplicationContext(),
R.drawable.ic_android))
.setIntent(pendingIntent);
}
/** Creates a minimally filled out {@link Notification.Builder} with provided text. */
private Notification.Builder getBasicNotifBuilder(@NonNull CharSequence title,
@NonNull CharSequence content) {
Context context = getApplicationContext();
Intent intent = new Intent(context, BubbleActivity.class);
final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
return new Notification.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_android)
.setContentTitle(title)
.setContentText(content)
.setColor(Color.GREEN)
.setContentIntent(pendingIntent);
}
}