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.res.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 */ onScreenshotTakennull50 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 = 57 fileManagerComponentName() 58 ?: return WorkProfileFirstRunData(defaultFileAppName(), null) 59 try { 60 val info = packageManager.getActivityInfo(fileManager, ComponentInfoFlags.of(0L)) 61 val icon = packageManager.getActivityIcon(fileManager) 62 badgedIcon = packageManager.getUserBadgedIcon(icon, userHandle) 63 label = info.loadLabel(packageManager) 64 } catch (e: PackageManager.NameNotFoundException) { 65 Log.w(TAG, "Component $fileManager not found") 66 } 67 68 // If label wasn't loaded, use a default 69 return WorkProfileFirstRunData(label ?: defaultFileAppName(), badgedIcon) 70 } 71 return null 72 } 73 74 /** 75 * Use the provided WorkProfileFirstRunData to populate the work profile first run UI in the 76 * given view. 77 */ populateViewnull78 fun populateView(view: ViewGroup, data: WorkProfileFirstRunData, animateOut: () -> Unit) { 79 if (data.icon != null) { 80 // Replace the default icon if one is provided. 81 val imageView: ImageView = view.requireViewById<ImageView>(R.id.screenshot_message_icon) 82 imageView.setImageDrawable(data.icon) 83 } 84 val messageContent = view.requireViewById<TextView>(R.id.screenshot_message_content) 85 messageContent.text = 86 view.context.getString(R.string.screenshot_work_profile_notification, data.appName) 87 view.requireViewById<View>(R.id.message_dismiss_button).setOnClickListener { 88 animateOut() 89 onMessageDismissed() 90 } 91 } 92 messageAlreadyDismissednull93 private fun messageAlreadyDismissed(): Boolean { 94 return sharedPreference().getBoolean(PREFERENCE_KEY, false) 95 } 96 onMessageDismissednull97 private fun onMessageDismissed() { 98 val editor = sharedPreference().edit() 99 editor.putBoolean(PREFERENCE_KEY, true) 100 editor.apply() 101 } 102 sharedPreferencenull103 private fun sharedPreference() = 104 context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE) 105 106 private fun fileManagerComponentName() = 107 ComponentName.unflattenFromString(context.getString(R.string.config_screenshotFilesApp)) 108 109 private fun defaultFileAppName() = context.getString(R.string.screenshot_default_files_app_name) 110 111 data class WorkProfileFirstRunData constructor(val appName: CharSequence, val icon: Drawable?) 112 113 companion object { 114 const val TAG = "WorkProfileMessageCtrl" 115 const val SHARED_PREFERENCES_NAME = "com.android.systemui.screenshot" 116 const val PREFERENCE_KEY = "work_profile_first_run" 117 } 118 } 119