blob: 0fe909552cb15e2a21482aef84a1beb88c072234 [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.qs;
import static com.android.systemui.qs.dagger.QSFragmentModule.QS_FGS_MANAGER_FOOTER_VIEW;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.dagger.QSScope;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
/**
* Footer entry point for the foreground service manager
*/
@QSScope
public class QSFgsManagerFooter implements View.OnClickListener,
FgsManagerController.OnDialogDismissedListener,
FgsManagerController.OnNumberOfPackagesChangedListener,
VisibilityChangedDispatcher {
private final View mRootView;
private final TextView mFooterText;
private final Context mContext;
private final Executor mMainExecutor;
private final Executor mExecutor;
private final FgsManagerController mFgsManagerController;
private boolean mIsInitialized = false;
private int mNumPackages;
private final View mTextContainer;
private final View mNumberContainer;
private final TextView mNumberView;
private final ImageView mDotView;
@Nullable
private VisibilityChangedDispatcher.OnVisibilityChangedListener mVisibilityChangedListener;
@Inject
QSFgsManagerFooter(@Named(QS_FGS_MANAGER_FOOTER_VIEW) View rootView,
@Main Executor mainExecutor, @Background Executor executor,
FgsManagerController fgsManagerController) {
mRootView = rootView;
mFooterText = mRootView.findViewById(R.id.footer_text);
mTextContainer = mRootView.findViewById(R.id.fgs_text_container);
mNumberContainer = mRootView.findViewById(R.id.fgs_number_container);
mNumberView = mRootView.findViewById(R.id.fgs_number);
mDotView = mRootView.findViewById(R.id.fgs_new);
mContext = rootView.getContext();
mMainExecutor = mainExecutor;
mExecutor = executor;
mFgsManagerController = fgsManagerController;
}
/**
* Whether to show the footer in collapsed mode (just a number) or not (text).
* @param collapsed
*/
public void setCollapsed(boolean collapsed) {
mTextContainer.setVisibility(collapsed ? View.GONE : View.VISIBLE);
mNumberContainer.setVisibility(collapsed ? View.VISIBLE : View.GONE);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mRootView.getLayoutParams();
lp.width = collapsed ? ViewGroup.LayoutParams.WRAP_CONTENT : 0;
lp.weight = collapsed ? 0f : 1f;
mRootView.setLayoutParams(lp);
}
public void init() {
if (mIsInitialized) {
return;
}
mFgsManagerController.init();
mRootView.setOnClickListener(this);
mIsInitialized = true;
}
public void setListening(boolean listening) {
if (listening) {
mFgsManagerController.addOnDialogDismissedListener(this);
mFgsManagerController.addOnNumberOfPackagesChangedListener(this);
mNumPackages = mFgsManagerController.getNumRunningPackages();
refreshState();
} else {
mFgsManagerController.removeOnDialogDismissedListener(this);
mFgsManagerController.removeOnNumberOfPackagesChangedListener(this);
}
}
@Override
public void setOnVisibilityChangedListener(
@Nullable OnVisibilityChangedListener onVisibilityChangedListener) {
mVisibilityChangedListener = onVisibilityChangedListener;
}
@Override
public void onClick(View view) {
mFgsManagerController.showDialog(mRootView);
}
public void refreshState() {
mExecutor.execute(this::handleRefreshState);
}
public View getView() {
return mRootView;
}
public void handleRefreshState() {
mMainExecutor.execute(() -> {
CharSequence text = mContext.getResources().getQuantityString(
R.plurals.fgs_manager_footer_label, mNumPackages, mNumPackages);
mFooterText.setText(text);
mNumberView.setText(Integer.toString(mNumPackages));
mNumberView.setContentDescription(text);
if (mFgsManagerController.shouldUpdateFooterVisibility()) {
mRootView.setVisibility(mNumPackages > 0
&& mFgsManagerController.isAvailable() ? View.VISIBLE : View.GONE);
mDotView.setVisibility(
mFgsManagerController.getChangesSinceDialog() ? View.VISIBLE : View.GONE);
if (mVisibilityChangedListener != null) {
mVisibilityChangedListener.onVisibilityChanged(mRootView.getVisibility());
}
}
});
}
@Override
public void onDialogDismissed() {
refreshState();
}
@Override
public void onNumberOfPackagesChanged(int numPackages) {
mNumPackages = numPackages;
refreshState();
}
}