/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui; import android.util.ArrayMap; import android.util.ArraySet; import java.util.Arrays; /** * Struct to track relevant packages and notifications for a userid's foreground services. */ class ForegroundServicesUserState { // shelf life of foreground services before they go bad private static final long FG_SERVICE_GRACE_MILLIS = 5000; private String[] mRunning = null; private long mServiceStartTime = 0; // package -> sufficiently important posted notification keys private ArrayMap> mImportantNotifications = new ArrayMap<>(1); // package -> standard layout posted notification keys private ArrayMap> mStandardLayoutNotifications = new ArrayMap<>(1); // package -> app ops private ArrayMap> mAppOps = new ArrayMap<>(1); public void setRunningServices(String[] pkgs, long serviceStartTime) { mRunning = pkgs != null ? Arrays.copyOf(pkgs, pkgs.length) : null; mServiceStartTime = serviceStartTime; } public void addOp(String pkg, int op) { if (mAppOps.get(pkg) == null) { mAppOps.put(pkg, new ArraySet<>(3)); } mAppOps.get(pkg).add(op); } public boolean removeOp(String pkg, int op) { final boolean found; final ArraySet keys = mAppOps.get(pkg); if (keys == null) { found = false; } else { found = keys.remove(op); if (keys.size() == 0) { mAppOps.remove(pkg); } } return found; } public void addImportantNotification(String pkg, String key) { addNotification(mImportantNotifications, pkg, key); } public boolean removeImportantNotification(String pkg, String key) { return removeNotification(mImportantNotifications, pkg, key); } public void addStandardLayoutNotification(String pkg, String key) { addNotification(mStandardLayoutNotifications, pkg, key); } public boolean removeStandardLayoutNotification(String pkg, String key) { return removeNotification(mStandardLayoutNotifications, pkg, key); } public boolean removeNotification(String pkg, String key) { boolean removed = false; removed |= removeImportantNotification(pkg, key); removed |= removeStandardLayoutNotification(pkg, key); return removed; } public void addNotification(ArrayMap> map, String pkg, String key) { if (map.get(pkg) == null) { map.put(pkg, new ArraySet<>()); } map.get(pkg).add(key); } public boolean removeNotification(ArrayMap> map, String pkg, String key) { final boolean found; final ArraySet keys = map.get(pkg); if (keys == null) { found = false; } else { found = keys.remove(key); if (keys.size() == 0) { map.remove(pkg); } } return found; } public boolean isDisclosureNeeded() { if (mRunning != null && System.currentTimeMillis() - mServiceStartTime >= FG_SERVICE_GRACE_MILLIS) { for (String pkg : mRunning) { final ArraySet set = mImportantNotifications.get(pkg); if (set == null || set.size() == 0) { return true; } } } return false; } public ArraySet getFeatures(String pkg) { return mAppOps.get(pkg); } public String getStandardLayoutKey(String pkg) { final ArraySet set = mStandardLayoutNotifications.get(pkg); if (set == null || set.size() == 0) { return null; } return set.valueAt(0); } @Override public String toString() { return "UserServices{" + "mRunning=" + Arrays.toString(mRunning) + ", mServiceStartTime=" + mServiceStartTime + ", mImportantNotifications=" + mImportantNotifications + ", mStandardLayoutNotifications=" + mStandardLayoutNotifications + '}'; } }