blob: f3d183ceb45f685aa45fdaecbe2cd54ea514f697 [file] [log] [blame]
/*
* Copyright (C) 2022 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.statusbar.policy;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.safetycenter.SafetyCenterManager;
import androidx.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.dagger.qualifiers.Background;
import java.util.ArrayList;
import java.util.Objects;
import javax.inject.Inject;
/**
* Controller which calls listeners when a PACKAGE_CHANGED broadcast is sent for the
* PermissionController. These broadcasts may be because the PermissionController enabled or
* disabled its TileService, and the tile should be added if the component was enabled, or removed
* if disabled.
*/
public class SafetyController implements
CallbackController<SafetyController.Listener> {
private boolean mSafetyCenterEnabled;
private final Handler mBgHandler;
private final ArrayList<Listener> mListeners = new ArrayList<>();
private static final IntentFilter PKG_CHANGE_INTENT_FILTER;
private final Context mContext;
private final SafetyCenterManager mSafetyCenterManager;
private final PackageManager mPackageManager;
static {
PKG_CHANGE_INTENT_FILTER = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
PKG_CHANGE_INTENT_FILTER.addDataScheme("package");
}
@Inject
public SafetyController(Context context, PackageManager pm, SafetyCenterManager scm,
@Background Handler bgHandler) {
mContext = context;
mSafetyCenterManager = scm;
mPackageManager = pm;
mBgHandler = bgHandler;
mSafetyCenterEnabled = mSafetyCenterManager.isSafetyCenterEnabled();
}
public boolean isSafetyCenterEnabled() {
return mSafetyCenterEnabled;
}
/**
* Adds a listener, registering the broadcast receiver if need be. Immediately calls the
* provided listener on the calling thread.
*/
@Override
public void addCallback(@NonNull Listener listener) {
synchronized (mListeners) {
mListeners.add(listener);
if (mListeners.size() == 1) {
mContext.registerReceiver(mPermControllerChangeReceiver, PKG_CHANGE_INTENT_FILTER);
mBgHandler.post(() -> {
mSafetyCenterEnabled = mSafetyCenterManager.isSafetyCenterEnabled();
listener.onSafetyCenterEnableChanged(isSafetyCenterEnabled());
});
} else {
listener.onSafetyCenterEnableChanged(isSafetyCenterEnabled());
}
}
}
@Override
public void removeCallback(@NonNull Listener listener) {
synchronized (mListeners) {
mListeners.remove(listener);
if (mListeners.isEmpty()) {
mContext.unregisterReceiver(mPermControllerChangeReceiver);
}
}
}
private void handleSafetyCenterEnableChange() {
synchronized (mListeners) {
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onSafetyCenterEnableChanged(mSafetyCenterEnabled);
}
}
}
/**
* Upon receiving a package changed broadcast for the PermissionController, checks if the
* safety center is enabled or disabled, and sends an update on the main thread if the state
* changed.
*/
@VisibleForTesting
final BroadcastReceiver mPermControllerChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String packageName = intent.getData() != null ? intent.getData().getSchemeSpecificPart()
: null;
if (!Objects.equals(packageName,
mPackageManager.getPermissionControllerPackageName())) {
return;
}
boolean wasSafetyCenterEnabled = mSafetyCenterEnabled;
mSafetyCenterEnabled = mSafetyCenterManager.isSafetyCenterEnabled();
if (wasSafetyCenterEnabled == mSafetyCenterEnabled) {
return;
}
mBgHandler.post(() -> handleSafetyCenterEnableChange());
}
};
/**
* Listener for safety center enabled changes
*/
public interface Listener {
/**
* Callback to be notified when the safety center is enabled or disabled
* @param isSafetyCenterEnabled If the safety center is enabled
*/
void onSafetyCenterEnableChanged(boolean isSafetyCenterEnabled);
}
}