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 17 package com.android.cts.netpolicy.hostside.app2; 18 19 import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; 20 21 import static com.android.cts.netpolicy.hostside.app2.Common.ACTION_RECEIVER_READY; 22 import static com.android.cts.netpolicy.hostside.app2.Common.ACTION_SHOW_TOAST; 23 import static com.android.cts.netpolicy.hostside.app2.Common.ACTION_SNOOZE_WARNING; 24 import static com.android.cts.netpolicy.hostside.app2.Common.MANIFEST_RECEIVER; 25 import static com.android.cts.netpolicy.hostside.app2.Common.NOTIFICATION_TYPE_ACTION; 26 import static com.android.cts.netpolicy.hostside.app2.Common.NOTIFICATION_TYPE_ACTION_BUNDLE; 27 import static com.android.cts.netpolicy.hostside.app2.Common.NOTIFICATION_TYPE_ACTION_REMOTE_INPUT; 28 import static com.android.cts.netpolicy.hostside.app2.Common.NOTIFICATION_TYPE_BUNDLE; 29 import static com.android.cts.netpolicy.hostside.app2.Common.NOTIFICATION_TYPE_CONTENT; 30 import static com.android.cts.netpolicy.hostside.app2.Common.NOTIFICATION_TYPE_DELETE; 31 import static com.android.cts.netpolicy.hostside.app2.Common.NOTIFICATION_TYPE_FULL_SCREEN; 32 import static com.android.cts.netpolicy.hostside.app2.Common.TAG; 33 34 import android.app.Notification; 35 import android.app.Notification.Action; 36 import android.app.NotificationManager; 37 import android.app.PendingIntent; 38 import android.app.RemoteInput; 39 import android.content.BroadcastReceiver; 40 import android.content.Context; 41 import android.content.Intent; 42 import android.content.SharedPreferences; 43 import android.net.ConnectivityManager; 44 import android.os.Bundle; 45 import android.util.Log; 46 import android.widget.Toast; 47 48 /** 49 * Receiver used to: 50 * <ol> 51 * <li>Count number of {@code RESTRICT_BACKGROUND_CHANGED} broadcasts received. 52 * <li>Show a toast. 53 * </ol> 54 */ 55 public class MyBroadcastReceiver extends BroadcastReceiver { 56 57 private final String mName; 58 MyBroadcastReceiver()59 public MyBroadcastReceiver() { 60 this(MANIFEST_RECEIVER); 61 } 62 MyBroadcastReceiver(String name)63 MyBroadcastReceiver(String name) { 64 Log.d(TAG, "Constructing MyBroadcastReceiver named " + name); 65 mName = name; 66 } 67 68 @Override onReceive(Context context, Intent intent)69 public void onReceive(Context context, Intent intent) { 70 Log.d(TAG, "onReceive() for " + mName + ": " + intent); 71 final String action = intent.getAction(); 72 switch (action) { 73 case ACTION_SNOOZE_WARNING: 74 increaseCounter(context, action); 75 break; 76 case ACTION_RESTRICT_BACKGROUND_CHANGED: 77 increaseCounter(context, action); 78 break; 79 case ACTION_RECEIVER_READY: 80 final String message = mName + " is ready to rumble"; 81 Log.d(TAG, message); 82 setResultData(message); 83 break; 84 case ACTION_SHOW_TOAST: 85 showToast(context); 86 break; 87 default: 88 Log.e(TAG, "received unexpected action: " + action); 89 } 90 } 91 92 @Override toString()93 public String toString() { 94 return "[MyBroadcastReceiver: mName=" + mName + "]"; 95 } 96 increaseCounter(Context context, String action)97 private void increaseCounter(Context context, String action) { 98 final SharedPreferences prefs = context.getApplicationContext() 99 .getSharedPreferences(mName, Context.MODE_PRIVATE); 100 final int value = prefs.getInt(action, 0) + 1; 101 Log.d(TAG, "increaseCounter('" + action + "'): setting '" + mName + "' to " + value); 102 prefs.edit().putInt(action, value).apply(); 103 } 104 getCounter(Context context, String action, String receiverName)105 static int getCounter(Context context, String action, String receiverName) { 106 final SharedPreferences prefs = context.getSharedPreferences(receiverName, 107 Context.MODE_PRIVATE); 108 final int value = prefs.getInt(action, 0); 109 Log.d(TAG, "getCounter('" + action + "', '" + receiverName + "'): " + value); 110 return value; 111 } 112 getRestrictBackgroundStatus(Context context)113 static String getRestrictBackgroundStatus(Context context) { 114 final ConnectivityManager cm = (ConnectivityManager) context 115 .getSystemService(Context.CONNECTIVITY_SERVICE); 116 final int apiStatus = cm.getRestrictBackgroundStatus(); 117 Log.d(TAG, "getRestrictBackgroundStatus: returning " + apiStatus); 118 return String.valueOf(apiStatus); 119 } 120 121 /** 122 * Sends a system notification containing actions with pending intents to launch the app's 123 * main activitiy or service. 124 */ sendNotification(Context context, String channelId, int notificationId, String notificationType )125 static void sendNotification(Context context, String channelId, int notificationId, 126 String notificationType ) { 127 Log.d(TAG, "sendNotification: id=" + notificationId + ", type=" + notificationType); 128 final Intent serviceIntent = new Intent(context, MyService.class); 129 final PendingIntent pendingIntent = PendingIntent.getService(context, 0, serviceIntent, 130 PendingIntent.FLAG_MUTABLE); 131 final Bundle bundle = new Bundle(); 132 bundle.putCharSequence("parcelable", "I am not"); 133 134 final Notification.Builder builder = new Notification.Builder(context, channelId) 135 .setSmallIcon(R.drawable.ic_notification); 136 137 Action action = null; 138 switch (notificationType) { 139 case NOTIFICATION_TYPE_CONTENT: 140 builder 141 .setContentTitle("Light, Cameras...") 142 .setContentIntent(pendingIntent); 143 break; 144 case NOTIFICATION_TYPE_DELETE: 145 builder.setDeleteIntent(pendingIntent); 146 break; 147 case NOTIFICATION_TYPE_FULL_SCREEN: 148 builder.setFullScreenIntent(pendingIntent, true); 149 break; 150 case NOTIFICATION_TYPE_BUNDLE: 151 bundle.putParcelable("Magnum P.I. (Pending Intent)", pendingIntent); 152 builder.setExtras(bundle); 153 break; 154 case NOTIFICATION_TYPE_ACTION: 155 action = new Action.Builder( 156 R.drawable.ic_notification, "ACTION", pendingIntent) 157 .build(); 158 builder.addAction(action); 159 break; 160 case NOTIFICATION_TYPE_ACTION_BUNDLE: 161 bundle.putParcelable("Magnum A.P.I. (Action Pending Intent)", pendingIntent); 162 action = new Action.Builder( 163 R.drawable.ic_notification, "ACTION WITH BUNDLE", null) 164 .addExtras(bundle) 165 .build(); 166 builder.addAction(action); 167 break; 168 case NOTIFICATION_TYPE_ACTION_REMOTE_INPUT: 169 bundle.putParcelable("Magnum R.I. (Remote Input)", null); 170 final RemoteInput remoteInput = new RemoteInput.Builder("RI") 171 .addExtras(bundle) 172 .build(); 173 action = new Action.Builder( 174 R.drawable.ic_notification, "ACTION WITH REMOTE INPUT", pendingIntent) 175 .addRemoteInput(remoteInput) 176 .build(); 177 builder.addAction(action); 178 break; 179 default: 180 Log.e(TAG, "Unknown notification type: " + notificationType); 181 return; 182 } 183 184 final Notification notification = builder.build(); 185 ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)) 186 .notify(notificationId, notification); 187 } 188 showToast(Context context)189 private void showToast(Context context) { 190 Toast.makeText(context, "Toast from CTS test", Toast.LENGTH_SHORT).show(); 191 setResultData("Shown"); 192 } 193 } 194