Loading packages/SystemUI/res/values/strings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -2345,6 +2345,11 @@ <!-- Title for User Switch dialog. [CHAR LIMIT=20] --> <string name="qs_user_switch_dialog_title">Select user</string> <!-- Label for the entry point to open the dialog which shows currently running applications [CHAR LIMIT=NONE]--> <plurals name="fgs_manager_footer_label"> <item quantity="one"><xliff:g id="count" example="1">%s</xliff:g> app running in the background</item> <item quantity="other"><xliff:g id="count" example="2">%s</xliff:g> apps running in the background</item> </plurals> <!-- Title for dialog listing applications currently running in the backing [CHAR LIMIT=NONE]--> <string name="fgs_manager_dialog_title">Apps running in the background</string> <!-- Label of the button to stop the app from running in the background [CHAR LIMIT=12]--> Loading packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +6 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha private final QSPanelController mQsPanelController; private final QuickQSPanelController mQuickQSPanelController; private final QuickStatusBarHeader mQuickStatusBarHeader; private final QSFgsManagerFooter mFgsManagerFooter; private final QSSecurityFooter mSecurityFooter; private final QS mQs; private final View mQSFooterActions; Loading Loading @@ -151,7 +152,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha public QSAnimator(QS qs, QuickQSPanel quickPanel, QuickStatusBarHeader quickStatusBarHeader, QSPanelController qsPanelController, QuickQSPanelController quickQSPanelController, QSTileHost qsTileHost, QSSecurityFooter securityFooter, @Main Executor executor, TunerService tunerService, QSFgsManagerFooter fgsManagerFooter, QSSecurityFooter securityFooter, @Main Executor executor, TunerService tunerService, QSExpansionPathInterpolator qsExpansionPathInterpolator, @Named(QS_FOOTER) FooterActionsView qsFooterActionsView, @Named(QQS_FOOTER) FooterActionsView qqsFooterActionsView) { Loading @@ -162,6 +164,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mQuickStatusBarHeader = quickStatusBarHeader; mQQSFooterActions = qqsFooterActionsView; mQSFooterActions = qsFooterActionsView; mFgsManagerFooter = fgsManagerFooter; mSecurityFooter = securityFooter; mHost = qsTileHost; mExecutor = executor; Loading Loading @@ -481,6 +484,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha // Fade in the security footer and the divider as we reach the final position Builder builder = new Builder().setStartDelay(EXPANDED_TILE_DELAY); builder.addFloat(mFgsManagerFooter.getView(), "alpha", 0, 1); builder.addFloat(mSecurityFooter.getView(), "alpha", 0, 1); if (mQsPanelController.shouldUseHorizontalLayout() && mQsPanelController.mMediaHost.hostView != null) { Loading @@ -490,6 +494,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mQsPanelController.mMediaHost.hostView.setAlpha(1.0f); } mAllPagesDelayedAnimator = builder.build(); mAllViews.add(mFgsManagerFooter.getView()); mAllViews.add(mSecurityFooter.getView()); translationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator()); qqsTranslationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator()); Loading packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java 0 → 100644 +117 −0 Original line number Diff line number Diff line /* * 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 android.provider.DeviceConfig.NAMESPACE_SYSTEMUI; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED; import static com.android.systemui.qs.dagger.QSFragmentModule.QS_FGS_MANAGER_FOOTER_VIEW; import android.content.Context; import android.provider.DeviceConfig; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.fgsmanager.FgsManagerDialogFactory; import com.android.systemui.statusbar.policy.RunningFgsController; import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; /** * Footer entry point for the foreground service manager */ public class QSFgsManagerFooter implements View.OnClickListener { private final View mRootView; private final TextView mFooterText; private final Context mContext; private final Executor mMainExecutor; private final Executor mExecutor; private final RunningFgsController mRunningFgsController; private final FgsManagerDialogFactory mFgsManagerDialogFactory; private boolean mIsInitialized = false; private boolean mIsAvailable = false; @Inject QSFgsManagerFooter(@Named(QS_FGS_MANAGER_FOOTER_VIEW) View rootView, @Main Executor mainExecutor, RunningFgsController runningFgsController, @Background Executor executor, FgsManagerDialogFactory fgsManagerDialogFactory) { mRootView = rootView; mFooterText = mRootView.findViewById(R.id.footer_text); ImageView icon = mRootView.findViewById(R.id.primary_footer_icon); icon.setImageResource(R.drawable.ic_info_outline); mContext = rootView.getContext(); mMainExecutor = mainExecutor; mExecutor = executor; mRunningFgsController = runningFgsController; mFgsManagerDialogFactory = fgsManagerDialogFactory; } public void init() { if (mIsInitialized) { return; } mRootView.setOnClickListener(this); mRunningFgsController.addCallback(packages -> refreshState()); DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_SYSTEMUI, mExecutor, (DeviceConfig.OnPropertiesChangedListener) properties -> { mIsAvailable = properties.getBoolean(TASK_MANAGER_ENABLED, mIsAvailable); }); mIsAvailable = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, TASK_MANAGER_ENABLED, false); mIsInitialized = true; } @Override public void onClick(View view) { mFgsManagerDialogFactory.create(mRootView); } public void refreshState() { mExecutor.execute(this::handleRefreshState); } public View getView() { return mRootView; } private boolean isAvailable() { return mIsAvailable; } public void handleRefreshState() { int numPackages = mRunningFgsController.getPackagesWithFgs().size(); mMainExecutor.execute(() -> { mFooterText.setText(mContext.getResources().getQuantityString( R.plurals.fgs_manager_footer_label, numPackages, numPackages)); mRootView.setVisibility(numPackages > 0 && isAvailable() ? View.VISIBLE : View.GONE); }); } } packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +19 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ public class QSPanel extends LinearLayout implements Tunable { private final List<OnConfigurationChangedListener> mOnConfigurationChangedListeners = new ArrayList<>(); @Nullable protected View mFgsManagerFooter; @Nullable protected View mSecurityFooter; Loading Loading @@ -448,7 +450,12 @@ public class QSPanel extends LinearLayout implements Tunable { switchToParent(mSecurityFooter, mHeaderContainer, 0); } else { // Add after the footer int index = indexOfChild(mFooter); int index; if (mFgsManagerFooter != null) { index = indexOfChild(mFgsManagerFooter); } else { index = indexOfChild(mFooter); } switchToParent(mSecurityFooter, this, index + 1); } } Loading Loading @@ -722,6 +729,17 @@ public class QSPanel extends LinearLayout implements Tunable { switchSecurityFooter(shouldUseSplitNotificationShade); } /** * Set the fgs manager footer view and switch it into the right place * @param view the view in question */ public void setFgsManagerFooter(View view) { mFgsManagerFooter = view; // Add after the footer int index = indexOfChild(mFooter); switchToParent(mFgsManagerFooter, this, index + 1); } protected void setPageMargin(int pageMargin) { if (mTileLayout instanceof PagedTileLayout) { ((PagedTileLayout) mTileLayout).setPageMargin(pageMargin); Loading packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java +7 −1 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import javax.inject.Named; public class QSPanelController extends QSPanelControllerBase<QSPanel> { public static final String QS_REMOVE_LABELS = "sysui_remove_labels"; private final QSFgsManagerFooter mQSFgsManagerFooter; private final QSSecurityFooter mQsSecurityFooter; private final TunerService mTunerService; private final QSCustomizerController mQsCustomizerController; Loading Loading @@ -94,7 +95,8 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { }; @Inject QSPanelController(QSPanel view, QSSecurityFooter qsSecurityFooter, TunerService tunerService, QSPanelController(QSPanel view, QSFgsManagerFooter qsFgsManagerFooter, QSSecurityFooter qsSecurityFooter, TunerService tunerService, QSTileHost qstileHost, QSCustomizerController qsCustomizerController, @Named(QS_USING_MEDIA_PLAYER) boolean usingMediaPlayer, @Named(QS_PANEL) MediaHost mediaHost, Loading @@ -105,6 +107,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { FalsingManager falsingManager, CommandQueue commandQueue) { super(view, qstileHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger, uiEventLogger, qsLogger, dumpManager); mQSFgsManagerFooter = qsFgsManagerFooter; mQsSecurityFooter = qsSecurityFooter; mTunerService = tunerService; mQsCustomizerController = qsCustomizerController; Loading @@ -128,6 +131,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { mMediaHost.init(MediaHierarchyManager.LOCATION_QS); mQsCustomizerController.init(); mBrightnessSliderController.init(); mQSFgsManagerFooter.init(); } private void updateMediaExpansion() { Loading @@ -146,6 +150,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { refreshAllTiles(); } mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener); mView.setFgsManagerFooter(mQSFgsManagerFooter.getView()); mView.setSecurityFooter(mQsSecurityFooter.getView(), mShouldUseSplitNotificationShade); switchTileLayout(true); mBrightnessMirrorHandler.onQsPanelAttached(); Loading Loading @@ -230,6 +235,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { public void refreshAllTiles() { mBrightnessController.checkRestrictionAndSetEnabled(); super.refreshAllTiles(); mQSFgsManagerFooter.refreshState(); mQsSecurityFooter.refreshState(); } Loading Loading
packages/SystemUI/res/values/strings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -2345,6 +2345,11 @@ <!-- Title for User Switch dialog. [CHAR LIMIT=20] --> <string name="qs_user_switch_dialog_title">Select user</string> <!-- Label for the entry point to open the dialog which shows currently running applications [CHAR LIMIT=NONE]--> <plurals name="fgs_manager_footer_label"> <item quantity="one"><xliff:g id="count" example="1">%s</xliff:g> app running in the background</item> <item quantity="other"><xliff:g id="count" example="2">%s</xliff:g> apps running in the background</item> </plurals> <!-- Title for dialog listing applications currently running in the backing [CHAR LIMIT=NONE]--> <string name="fgs_manager_dialog_title">Apps running in the background</string> <!-- Label of the button to stop the app from running in the background [CHAR LIMIT=12]--> Loading
packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +6 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha private final QSPanelController mQsPanelController; private final QuickQSPanelController mQuickQSPanelController; private final QuickStatusBarHeader mQuickStatusBarHeader; private final QSFgsManagerFooter mFgsManagerFooter; private final QSSecurityFooter mSecurityFooter; private final QS mQs; private final View mQSFooterActions; Loading Loading @@ -151,7 +152,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha public QSAnimator(QS qs, QuickQSPanel quickPanel, QuickStatusBarHeader quickStatusBarHeader, QSPanelController qsPanelController, QuickQSPanelController quickQSPanelController, QSTileHost qsTileHost, QSSecurityFooter securityFooter, @Main Executor executor, TunerService tunerService, QSFgsManagerFooter fgsManagerFooter, QSSecurityFooter securityFooter, @Main Executor executor, TunerService tunerService, QSExpansionPathInterpolator qsExpansionPathInterpolator, @Named(QS_FOOTER) FooterActionsView qsFooterActionsView, @Named(QQS_FOOTER) FooterActionsView qqsFooterActionsView) { Loading @@ -162,6 +164,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mQuickStatusBarHeader = quickStatusBarHeader; mQQSFooterActions = qqsFooterActionsView; mQSFooterActions = qsFooterActionsView; mFgsManagerFooter = fgsManagerFooter; mSecurityFooter = securityFooter; mHost = qsTileHost; mExecutor = executor; Loading Loading @@ -481,6 +484,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha // Fade in the security footer and the divider as we reach the final position Builder builder = new Builder().setStartDelay(EXPANDED_TILE_DELAY); builder.addFloat(mFgsManagerFooter.getView(), "alpha", 0, 1); builder.addFloat(mSecurityFooter.getView(), "alpha", 0, 1); if (mQsPanelController.shouldUseHorizontalLayout() && mQsPanelController.mMediaHost.hostView != null) { Loading @@ -490,6 +494,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mQsPanelController.mMediaHost.hostView.setAlpha(1.0f); } mAllPagesDelayedAnimator = builder.build(); mAllViews.add(mFgsManagerFooter.getView()); mAllViews.add(mSecurityFooter.getView()); translationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator()); qqsTranslationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator()); Loading
packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java 0 → 100644 +117 −0 Original line number Diff line number Diff line /* * 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 android.provider.DeviceConfig.NAMESPACE_SYSTEMUI; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED; import static com.android.systemui.qs.dagger.QSFragmentModule.QS_FGS_MANAGER_FOOTER_VIEW; import android.content.Context; import android.provider.DeviceConfig; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.fgsmanager.FgsManagerDialogFactory; import com.android.systemui.statusbar.policy.RunningFgsController; import java.util.concurrent.Executor; import javax.inject.Inject; import javax.inject.Named; /** * Footer entry point for the foreground service manager */ public class QSFgsManagerFooter implements View.OnClickListener { private final View mRootView; private final TextView mFooterText; private final Context mContext; private final Executor mMainExecutor; private final Executor mExecutor; private final RunningFgsController mRunningFgsController; private final FgsManagerDialogFactory mFgsManagerDialogFactory; private boolean mIsInitialized = false; private boolean mIsAvailable = false; @Inject QSFgsManagerFooter(@Named(QS_FGS_MANAGER_FOOTER_VIEW) View rootView, @Main Executor mainExecutor, RunningFgsController runningFgsController, @Background Executor executor, FgsManagerDialogFactory fgsManagerDialogFactory) { mRootView = rootView; mFooterText = mRootView.findViewById(R.id.footer_text); ImageView icon = mRootView.findViewById(R.id.primary_footer_icon); icon.setImageResource(R.drawable.ic_info_outline); mContext = rootView.getContext(); mMainExecutor = mainExecutor; mExecutor = executor; mRunningFgsController = runningFgsController; mFgsManagerDialogFactory = fgsManagerDialogFactory; } public void init() { if (mIsInitialized) { return; } mRootView.setOnClickListener(this); mRunningFgsController.addCallback(packages -> refreshState()); DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_SYSTEMUI, mExecutor, (DeviceConfig.OnPropertiesChangedListener) properties -> { mIsAvailable = properties.getBoolean(TASK_MANAGER_ENABLED, mIsAvailable); }); mIsAvailable = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, TASK_MANAGER_ENABLED, false); mIsInitialized = true; } @Override public void onClick(View view) { mFgsManagerDialogFactory.create(mRootView); } public void refreshState() { mExecutor.execute(this::handleRefreshState); } public View getView() { return mRootView; } private boolean isAvailable() { return mIsAvailable; } public void handleRefreshState() { int numPackages = mRunningFgsController.getPackagesWithFgs().size(); mMainExecutor.execute(() -> { mFooterText.setText(mContext.getResources().getQuantityString( R.plurals.fgs_manager_footer_label, numPackages, numPackages)); mRootView.setVisibility(numPackages > 0 && isAvailable() ? View.VISIBLE : View.GONE); }); } }
packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +19 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ public class QSPanel extends LinearLayout implements Tunable { private final List<OnConfigurationChangedListener> mOnConfigurationChangedListeners = new ArrayList<>(); @Nullable protected View mFgsManagerFooter; @Nullable protected View mSecurityFooter; Loading Loading @@ -448,7 +450,12 @@ public class QSPanel extends LinearLayout implements Tunable { switchToParent(mSecurityFooter, mHeaderContainer, 0); } else { // Add after the footer int index = indexOfChild(mFooter); int index; if (mFgsManagerFooter != null) { index = indexOfChild(mFgsManagerFooter); } else { index = indexOfChild(mFooter); } switchToParent(mSecurityFooter, this, index + 1); } } Loading Loading @@ -722,6 +729,17 @@ public class QSPanel extends LinearLayout implements Tunable { switchSecurityFooter(shouldUseSplitNotificationShade); } /** * Set the fgs manager footer view and switch it into the right place * @param view the view in question */ public void setFgsManagerFooter(View view) { mFgsManagerFooter = view; // Add after the footer int index = indexOfChild(mFooter); switchToParent(mFgsManagerFooter, this, index + 1); } protected void setPageMargin(int pageMargin) { if (mTileLayout instanceof PagedTileLayout) { ((PagedTileLayout) mTileLayout).setPageMargin(pageMargin); Loading
packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java +7 −1 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import javax.inject.Named; public class QSPanelController extends QSPanelControllerBase<QSPanel> { public static final String QS_REMOVE_LABELS = "sysui_remove_labels"; private final QSFgsManagerFooter mQSFgsManagerFooter; private final QSSecurityFooter mQsSecurityFooter; private final TunerService mTunerService; private final QSCustomizerController mQsCustomizerController; Loading Loading @@ -94,7 +95,8 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { }; @Inject QSPanelController(QSPanel view, QSSecurityFooter qsSecurityFooter, TunerService tunerService, QSPanelController(QSPanel view, QSFgsManagerFooter qsFgsManagerFooter, QSSecurityFooter qsSecurityFooter, TunerService tunerService, QSTileHost qstileHost, QSCustomizerController qsCustomizerController, @Named(QS_USING_MEDIA_PLAYER) boolean usingMediaPlayer, @Named(QS_PANEL) MediaHost mediaHost, Loading @@ -105,6 +107,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { FalsingManager falsingManager, CommandQueue commandQueue) { super(view, qstileHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger, uiEventLogger, qsLogger, dumpManager); mQSFgsManagerFooter = qsFgsManagerFooter; mQsSecurityFooter = qsSecurityFooter; mTunerService = tunerService; mQsCustomizerController = qsCustomizerController; Loading @@ -128,6 +131,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { mMediaHost.init(MediaHierarchyManager.LOCATION_QS); mQsCustomizerController.init(); mBrightnessSliderController.init(); mQSFgsManagerFooter.init(); } private void updateMediaExpansion() { Loading @@ -146,6 +150,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { refreshAllTiles(); } mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener); mView.setFgsManagerFooter(mQSFgsManagerFooter.getView()); mView.setSecurityFooter(mQsSecurityFooter.getView(), mShouldUseSplitNotificationShade); switchTileLayout(true); mBrightnessMirrorHandler.onQsPanelAttached(); Loading Loading @@ -230,6 +235,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { public void refreshAllTiles() { mBrightnessController.checkRestrictionAndSetEnabled(); super.refreshAllTiles(); mQSFgsManagerFooter.refreshState(); mQsSecurityFooter.refreshState(); } Loading