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