1 /* 2 * Copyright (C) 2022 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.screenshot 18 19 import android.content.ComponentName 20 import android.content.Context 21 import android.content.pm.PackageManager 22 import android.content.pm.PackageManager.ComponentInfoFlags 23 import android.graphics.drawable.Drawable 24 import android.os.UserHandle 25 import android.os.UserManager 26 import android.util.Log 27 import android.view.View 28 import android.view.ViewGroup 29 import android.widget.ImageView 30 import android.widget.TextView 31 import com.android.systemui.R 32 import javax.inject.Inject 33 34 /** 35 * Handles work profile first run, determining whether a first run UI should be shown and populating 36 * that UI if needed. 37 */ 38 class WorkProfileMessageController 39 @Inject 40 constructor( 41 private val context: Context, 42 private val userManager: UserManager, 43 private val packageManager: PackageManager, 44 ) { 45 46 /** 47 * @return a populated WorkProfileFirstRunData object if a work profile first run message should 48 * be shown 49 */ 50 fun onScreenshotTaken(userHandle: UserHandle?): WorkProfileFirstRunData? { 51 if (userHandle == null) return null 52 53 if (userManager.isManagedProfile(userHandle.identifier) && !messageAlreadyDismissed()) { 54 var badgedIcon: Drawable? = null 55 var label: CharSequence? = null 56 val fileManager = fileManagerComponentName() 57 ?: return WorkProfileFirstRunData(defaultFileAppName(), null) 58 try { 59 val info = packageManager.getActivityInfo(fileManager, ComponentInfoFlags.of(0L)) 60 val icon = packageManager.getActivityIcon(fileManager) 61 badgedIcon = packageManager.getUserBadgedIcon(icon, userHandle) 62 label = info.loadLabel(packageManager) 63 } catch (e: PackageManager.NameNotFoundException) { 64 Log.w(TAG, "Component $fileManager not found") 65 } 66 67 // If label wasn't loaded, use a default 68 return WorkProfileFirstRunData(label ?: defaultFileAppName(), badgedIcon) 69 } 70 return null 71 } 72 73 /** 74 * Use the provided WorkProfileFirstRunData to populate the work profile first run UI in the 75 * given view. 76 */ 77 fun populateView(view: ViewGroup, data: WorkProfileFirstRunData, animateOut: () -> Unit) { 78 if (data.icon != null) { 79 // Replace the default icon if one is provided. 80 val imageView: ImageView = view.requireViewById<ImageView>(R.id.screenshot_message_icon) 81 imageView.setImageDrawable(data.icon) 82 } 83 val messageContent = view.requireViewById<TextView>(R.id.screenshot_message_content) 84 messageContent.text = 85 view.context.getString(R.string.screenshot_work_profile_notification, data.appName) 86 view.requireViewById<View>(R.id.message_dismiss_button).setOnClickListener { 87 animateOut() 88 onMessageDismissed() 89 } 90 } 91 92 private fun messageAlreadyDismissed(): Boolean { 93 return sharedPreference().getBoolean(PREFERENCE_KEY, false) 94 } 95 96 private fun onMessageDismissed() { 97 val editor = sharedPreference().edit() 98 editor.putBoolean(PREFERENCE_KEY, true) 99 editor.apply() 100 } 101 102 private fun sharedPreference() = 103 context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE) 104 105 private fun fileManagerComponentName() = 106 ComponentName.unflattenFromString( 107 context.getString(R.string.config_sceenshotWorkProfileFilesApp) 108 ) 109 110 private fun defaultFileAppName() = context.getString(R.string.screenshot_default_files_app_name) 111 112 data class WorkProfileFirstRunData constructor(val appName: CharSequence, val icon: Drawable?) 113 114 companion object { 115 const val TAG = "WorkProfileMessageCtrl" 116 const val SHARED_PREFERENCES_NAME = "com.android.systemui.screenshot" 117 const val PREFERENCE_KEY = "work_profile_first_run" 118 } 119 } 120