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.permissionui.cts.usepermission 18 19 import android.Manifest 20 import android.app.Activity 21 import android.app.NotificationChannel 22 import android.app.NotificationManager 23 import android.content.BroadcastReceiver 24 import android.content.Context 25 import android.content.Intent 26 import android.content.IntentFilter 27 import android.content.pm.PackageManager 28 import android.os.Bundle 29 import android.os.Handler 30 import android.os.Looper 31 32 const val EXTRA_CREATE_CHANNELS = "extra_create" 33 const val EXTRA_REQUEST_NOTIF_PERMISSION = "extra_request_notif_permission" 34 const val EXTRA_REQUEST_OTHER_PERMISSIONS = "extra_request_permissions" 35 const val EXTRA_START_SECOND_ACTIVITY = "extra_start_second_activity" 36 const val EXTRA_START_SECOND_APP = "extra_start_second_app" 37 const val SECONDARY_APP_INTENT = "emptyactivity.main" 38 const val SECONDARY_APP_PKG = "android.permissionui.cts.usepermissionother" 39 const val TEST_PKG = "android.permissionui.cts" 40 const val CHANNEL_ID_31 = "test_channel_id" 41 const val BROADCAST_ACTION = "usepermission.createchannels.BROADCAST" 42 const val DELAY_MS = 1000L 43 const val LONG_DELAY_MS = 2000L 44 45 class CreateNotificationChannelsActivity : Activity() { 46 private lateinit var notificationManager: NotificationManager 47 private var launchActivityOnSecondResume = false 48 private var isFirstResume = true 49 private var windowHasFocus = false 50 private var pendingCreateChannel = false 51 private val handler = Handler(Looper.getMainLooper()) 52 onCreatenull53 override fun onCreate(savedInstanceState: Bundle?) { 54 super.onCreate(savedInstanceState) 55 56 if (savedInstanceState != null) { 57 throw RuntimeException( 58 "Activity was recreated (perhaps due to a configuration change?) " + 59 "and this activity doesn't currently know how to gracefully handle " + 60 "configuration changes." 61 ) 62 } 63 64 registerReceiver(receiver, IntentFilter(BROADCAST_ACTION), RECEIVER_EXPORTED) 65 handleIntent(intent) 66 } 67 handleIntentnull68 private fun handleIntent(providedIntent: Intent?, broacastAfterComplete: Boolean = false) { 69 if (providedIntent == null) { 70 return 71 } 72 val launchSecondActivity = 73 providedIntent.getBooleanExtra(EXTRA_START_SECOND_ACTIVITY, false) 74 notificationManager = baseContext.getSystemService(NotificationManager::class.java)!! 75 if (providedIntent.getBooleanExtra(EXTRA_START_SECOND_APP, false)) { 76 handler.postDelayed( 77 { 78 val intent2 = Intent(SECONDARY_APP_INTENT) 79 intent2.`package` = SECONDARY_APP_PKG 80 intent2.addCategory(Intent.CATEGORY_DEFAULT) 81 handler.postDelayed({ createChannel() }, DELAY_MS) 82 startActivity(intent2) 83 }, 84 LONG_DELAY_MS 85 ) 86 } else if (providedIntent.getBooleanExtra(EXTRA_CREATE_CHANNELS, false)) { 87 createChannel() 88 if (launchSecondActivity) { 89 launchActivityOnSecondResume = true 90 } 91 } else if (launchSecondActivity) { 92 launchSecondActivity() 93 } 94 95 if (providedIntent.getBooleanExtra(EXTRA_REQUEST_OTHER_PERMISSIONS, false)) { 96 requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), 0) 97 } 98 99 if (providedIntent.getBooleanExtra(EXTRA_REQUEST_NOTIF_PERMISSION, false)) { 100 requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 0) 101 } 102 103 if (broacastAfterComplete) { 104 sendBroadcast(Intent(BROADCAST_ACTION).setPackage(TEST_PKG)) 105 } 106 } 107 108 private val receiver = 109 object : BroadcastReceiver() { onReceivenull110 override fun onReceive(context: Context?, intent: Intent?) { 111 handleIntent(intent, true) 112 } 113 } 114 launchSecondActivitynull115 private fun launchSecondActivity() { 116 handler.postDelayed( 117 { 118 val intent2 = Intent(Intent.ACTION_MAIN) 119 intent2.`package` = packageName 120 intent2.addCategory(Intent.CATEGORY_DEFAULT) 121 intent2.putExtra(EXTRA_CREATE_CHANNELS, true) 122 startActivity(intent2) 123 }, 124 LONG_DELAY_MS 125 ) 126 } 127 onWindowFocusChangednull128 override fun onWindowFocusChanged(hasFocus: Boolean) { 129 windowHasFocus = hasFocus 130 if (windowHasFocus && pendingCreateChannel) { 131 pendingCreateChannel = false 132 createChannel() 133 } 134 } 135 createChannelnull136 private fun createChannel() { 137 // Wait until window has focus so the permission prompt can be displayed 138 if (!windowHasFocus) { 139 pendingCreateChannel = true 140 return 141 } 142 143 if (notificationManager.getNotificationChannel(CHANNEL_ID_31) == null) { 144 notificationManager.createNotificationChannel( 145 NotificationChannel( 146 CHANNEL_ID_31, 147 "Foreground Services", 148 NotificationManager.IMPORTANCE_HIGH 149 ) 150 ) 151 } 152 } 153 onResumenull154 override fun onResume() { 155 super.onResume() 156 if (!isFirstResume && launchActivityOnSecondResume) { 157 launchSecondActivity() 158 } 159 isFirstResume = false 160 } 161 onRequestPermissionsResultnull162 override fun onRequestPermissionsResult( 163 requestCode: Int, 164 permissions: Array<out String>, 165 grantResults: IntArray 166 ) { 167 super.onRequestPermissionsResult(requestCode, permissions, grantResults) 168 val grantedPerms = arrayListOf<String>() 169 for ((i, permName) in permissions.withIndex()) { 170 if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { 171 grantedPerms.add(permName) 172 } 173 } 174 sendBroadcast( 175 Intent(BROADCAST_ACTION) 176 .putStringArrayListExtra( 177 PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS, 178 grantedPerms 179 ) 180 .setPackage(TEST_PKG) 181 ) 182 } 183 184 companion object { 185 private val TAG = CreateNotificationChannelsActivity::class.simpleName 186 } 187 } 188