1 /*
2  * Copyright (C) 2023 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.permissioncontroller.privacysources.v34
18 
19 import android.app.PendingIntent
20 import android.app.PendingIntent.FLAG_IMMUTABLE
21 import android.app.PendingIntent.FLAG_UPDATE_CURRENT
22 import android.content.Context
23 import android.content.Intent
24 import android.content.Intent.ACTION_REVIEW_APP_DATA_SHARING_UPDATES
25 import android.os.Build
26 import android.safetycenter.SafetyCenterManager
27 import android.safetycenter.SafetyEvent
28 import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_DEVICE_REBOOTED
29 import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED
30 import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
31 import android.safetycenter.SafetySourceData
32 import android.safetycenter.SafetySourceData.SEVERITY_LEVEL_INFORMATION
33 import android.safetycenter.SafetySourceStatus
34 import androidx.annotation.RequiresApi
35 import com.android.permissioncontroller.R
36 import com.android.permissioncontroller.permission.utils.KotlinUtils
37 import com.android.permissioncontroller.permission.utils.Utils
38 import com.android.permissioncontroller.privacysources.PrivacySource
39 import com.android.permissioncontroller.privacysources.SafetyCenterReceiver.RefreshEvent
40 import com.android.permissioncontroller.privacysources.SafetyCenterReceiver.RefreshEvent.EVENT_DEVICE_REBOOTED
41 import com.android.permissioncontroller.privacysources.SafetyCenterReceiver.RefreshEvent.EVENT_REFRESH_REQUESTED
42 import com.android.permissioncontroller.privacysources.SafetyCenterReceiver.RefreshEvent.UNKNOWN
43 
44 /**
45  * Privacy source providing the App Data Sharing Updates page entry to Safety Center.
46  *
47  * The content of the App Data Sharing Updates page is static, however the entry should only be
48  * displayed if the Safety Label Change Notification feature is enabled.
49  */
50 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
51 class AppDataSharingUpdatesPrivacySource : PrivacySource {
52 
53     override val shouldProcessProfileRequest: Boolean = false
54 
safetyCenterEnabledChangednull55     override fun safetyCenterEnabledChanged(context: Context, enabled: Boolean) {
56         // Do nothing.
57     }
58 
rescanAndPushSafetyCenterDatanull59     override fun rescanAndPushSafetyCenterData(
60         context: Context,
61         intent: Intent,
62         refreshEvent: RefreshEvent
63     ) {
64         val safetyCenterManager: SafetyCenterManager =
65             Utils.getSystemServiceSafe(context, SafetyCenterManager::class.java)
66 
67         val safetySourceData =
68             if (KotlinUtils.isSafetyLabelChangeNotificationsEnabled(context)) {
69                 SafetySourceData.Builder()
70                     .setStatus(
71                         SafetySourceStatus.Builder(
72                                 context.getString(R.string.data_sharing_updates_title),
73                                 context.getString(R.string.data_sharing_updates_summary),
74                                 SEVERITY_LEVEL_INFORMATION
75                             )
76                             .setPendingIntent(
77                                 PendingIntent.getActivity(
78                                     context,
79                                     /* requestCode= */ 0,
80                                     Intent(ACTION_REVIEW_APP_DATA_SHARING_UPDATES),
81                                     FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE
82                                 )
83                             )
84                             .build(),
85                     )
86                     .build()
87             } else {
88                 null
89             }
90 
91         safetyCenterManager.setSafetySourceData(
92             APP_DATA_SHARING_UPDATES_SOURCE_ID,
93             safetySourceData,
94             createSafetyEventForDataSharingUpdates(refreshEvent, intent)
95         )
96     }
97 
createSafetyEventForDataSharingUpdatesnull98     private fun createSafetyEventForDataSharingUpdates(
99         refreshEvent: RefreshEvent,
100         intent: Intent
101     ): SafetyEvent {
102         return when (refreshEvent) {
103             EVENT_REFRESH_REQUESTED -> {
104                 val refreshBroadcastId =
105                     intent.getStringExtra(
106                         SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID
107                     )
108                 SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
109                     .setRefreshBroadcastId(refreshBroadcastId)
110                     .build()
111             }
112             EVENT_DEVICE_REBOOTED -> {
113                 SafetyEvent.Builder(SAFETY_EVENT_TYPE_DEVICE_REBOOTED).build()
114             }
115             UNKNOWN -> {
116                 SafetyEvent.Builder(SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build()
117             }
118         }
119     }
120 
121     /** Companion object for [AppDataSharingUpdatesPrivacySource]. */
122     companion object {
123         /** Source id for safety center source for app data sharing updates. */
124         const val APP_DATA_SHARING_UPDATES_SOURCE_ID = "AndroidPrivacyAppDataSharingUpdates"
125     }
126 }
127