• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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