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.systemui.controls.management 18 19 import android.app.ActivityManager 20 import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND 21 import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE 22 import android.content.BroadcastReceiver 23 import android.content.ComponentName 24 import android.content.Context 25 import android.content.Intent 26 import android.content.pm.PackageManager 27 import android.os.UserHandle 28 import android.service.controls.Control 29 import android.service.controls.ControlsProviderService 30 import android.util.Log 31 import java.lang.ClassCastException 32 33 /** 34 * Proxy to launch in user 0 35 */ 36 class ControlsRequestReceiver : BroadcastReceiver() { 37 38 companion object { 39 private const val TAG = "ControlsRequestReceiver" 40 41 fun isPackageInForeground(context: Context, packageName: String): Boolean { 42 val uid = try { 43 context.packageManager.getPackageUid(packageName, 0) 44 } catch (_: PackageManager.NameNotFoundException) { 45 Log.w(TAG, "Package $packageName not found") 46 return false 47 } 48 49 val am = context.getSystemService(ActivityManager::class.java) 50 if ((am?.getUidImportance(uid) ?: IMPORTANCE_GONE) != IMPORTANCE_FOREGROUND) { 51 Log.w(TAG, "Uid $uid not in foreground") 52 return false 53 } 54 return true 55 } 56 } 57 58 override fun onReceive(context: Context, intent: Intent) { 59 if (!context.packageManager.hasSystemFeature(PackageManager.FEATURE_CONTROLS)) { 60 return 61 } 62 63 val targetComponent = try { 64 intent.getParcelableExtra<ComponentName>(Intent.EXTRA_COMPONENT_NAME) 65 } catch (e: ClassCastException) { 66 Log.e(TAG, "Malformed intent extra ComponentName", e) 67 return 68 } 69 70 val control = try { 71 intent.getParcelableExtra<Control>(ControlsProviderService.EXTRA_CONTROL) 72 } catch (e: ClassCastException) { 73 Log.e(TAG, "Malformed intent extra Control", e) 74 return 75 } 76 77 val packageName = targetComponent?.packageName 78 79 if (packageName == null || !isPackageInForeground(context, packageName)) { 80 return 81 } 82 83 val activityIntent = Intent(context, ControlsRequestDialog::class.java).apply { 84 putExtra(Intent.EXTRA_COMPONENT_NAME, targetComponent) 85 putExtra(ControlsProviderService.EXTRA_CONTROL, control) 86 addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) 87 } 88 activityIntent.putExtra(Intent.EXTRA_USER_ID, context.userId) 89 90 context.startActivityAsUser(activityIntent, UserHandle.SYSTEM) 91 } 92 }