blob: 5c2950f1365de103838a6fd6de562c69f5ee8199 [file] [log] [blame]
Gus Prevaseb4e2e12018-12-28 14:57:59 -05001/*
2 * Copyright (C) 2018 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
17package com.android.systemui;
18
19import android.util.ArrayMap;
20import android.util.ArraySet;
21
22import java.util.Arrays;
23
24/**
25 * Struct to track relevant packages and notifications for a userid's foreground services.
26 */
Beverly8c80e0c2019-12-03 11:25:39 -050027public class ForegroundServicesUserState {
Gus Prevaseb4e2e12018-12-28 14:57:59 -050028 // shelf life of foreground services before they go bad
29 private static final long FG_SERVICE_GRACE_MILLIS = 5000;
30
31 private String[] mRunning = null;
32 private long mServiceStartTime = 0;
Beverly546aa102020-06-15 15:25:47 -040033
34 // package -> sufficiently important posted notification keys that signal an app is
35 // running a foreground service
Gus Prevaseb4e2e12018-12-28 14:57:59 -050036 private ArrayMap<String, ArraySet<String>> mImportantNotifications = new ArrayMap<>(1);
Beverly546aa102020-06-15 15:25:47 -040037 // package -> standard layout posted notification keys that can display appOps
Gus Prevaseb4e2e12018-12-28 14:57:59 -050038 private ArrayMap<String, ArraySet<String>> mStandardLayoutNotifications = new ArrayMap<>(1);
39
40 // package -> app ops
41 private ArrayMap<String, ArraySet<Integer>> mAppOps = new ArrayMap<>(1);
42
43 public void setRunningServices(String[] pkgs, long serviceStartTime) {
44 mRunning = pkgs != null ? Arrays.copyOf(pkgs, pkgs.length) : null;
45 mServiceStartTime = serviceStartTime;
46 }
47
48 public void addOp(String pkg, int op) {
49 if (mAppOps.get(pkg) == null) {
50 mAppOps.put(pkg, new ArraySet<>(3));
51 }
52 mAppOps.get(pkg).add(op);
53 }
54
55 public boolean removeOp(String pkg, int op) {
56 final boolean found;
57 final ArraySet<Integer> keys = mAppOps.get(pkg);
58 if (keys == null) {
59 found = false;
60 } else {
61 found = keys.remove(op);
62 if (keys.size() == 0) {
63 mAppOps.remove(pkg);
64 }
65 }
66 return found;
67 }
68
69 public void addImportantNotification(String pkg, String key) {
70 addNotification(mImportantNotifications, pkg, key);
71 }
72
73 public boolean removeImportantNotification(String pkg, String key) {
74 return removeNotification(mImportantNotifications, pkg, key);
75 }
76
77 public void addStandardLayoutNotification(String pkg, String key) {
78 addNotification(mStandardLayoutNotifications, pkg, key);
79 }
80
81 public boolean removeStandardLayoutNotification(String pkg, String key) {
82 return removeNotification(mStandardLayoutNotifications, pkg, key);
83 }
84
85 public boolean removeNotification(String pkg, String key) {
86 boolean removed = false;
87 removed |= removeImportantNotification(pkg, key);
88 removed |= removeStandardLayoutNotification(pkg, key);
89 return removed;
90 }
91
92 public void addNotification(ArrayMap<String, ArraySet<String>> map, String pkg,
93 String key) {
94 if (map.get(pkg) == null) {
95 map.put(pkg, new ArraySet<>());
96 }
97 map.get(pkg).add(key);
98 }
99
100 public boolean removeNotification(ArrayMap<String, ArraySet<String>> map,
101 String pkg, String key) {
102 final boolean found;
103 final ArraySet<String> keys = map.get(pkg);
104 if (keys == null) {
105 found = false;
106 } else {
107 found = keys.remove(key);
108 if (keys.size() == 0) {
109 map.remove(pkg);
110 }
111 }
112 return found;
113 }
114
Beverly546aa102020-06-15 15:25:47 -0400115 /**
116 * System disclosures for foreground services are required if an app has a foreground service
117 * running AND the app hasn't posted its own notification signalling it is running a
118 * foreground service
119 */
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500120 public boolean isDisclosureNeeded() {
121 if (mRunning != null
122 && System.currentTimeMillis() - mServiceStartTime
123 >= FG_SERVICE_GRACE_MILLIS) {
124
125 for (String pkg : mRunning) {
126 final ArraySet<String> set = mImportantNotifications.get(pkg);
127 if (set == null || set.size() == 0) {
128 return true;
129 }
130 }
131 }
132 return false;
133 }
134
135 public ArraySet<Integer> getFeatures(String pkg) {
136 return mAppOps.get(pkg);
137 }
138
Beverly546aa102020-06-15 15:25:47 -0400139 /**
140 * Gets the notifications with standard layouts associated with this package
141 */
142 public ArraySet<String> getStandardLayoutKeys(String pkg) {
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500143 final ArraySet<String> set = mStandardLayoutNotifications.get(pkg);
144 if (set == null || set.size() == 0) {
145 return null;
146 }
Beverly546aa102020-06-15 15:25:47 -0400147 return set;
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500148 }
149
150 @Override
151 public String toString() {
152 return "UserServices{"
153 + "mRunning=" + Arrays.toString(mRunning)
154 + ", mServiceStartTime=" + mServiceStartTime
155 + ", mImportantNotifications=" + mImportantNotifications
156 + ", mStandardLayoutNotifications=" + mStandardLayoutNotifications
157 + '}';
158 }
159}