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