Merge "Work on separating out the status bar management"
This commit is contained in:
committed by
Android (Google) Code Review
commit
47c4c94100
@@ -21,6 +21,8 @@
|
||||
<com.android.systemui.statusbar.phone.PhoneStatusBarView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/status_bar_height"
|
||||
android:id="@+id/status_bar"
|
||||
android:background="@drawable/system_bar_background"
|
||||
android:orientation="vertical"
|
||||
|
||||
@@ -59,9 +59,10 @@
|
||||
sysui:ignoreRightInset="true"
|
||||
android:importantForAccessibility="no"/>
|
||||
|
||||
<include layout="@layout/status_bar"
|
||||
<FrameLayout
|
||||
android:id="@+id/status_bar_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/status_bar_height" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<include layout="@layout/brightness_mirror" />
|
||||
|
||||
|
||||
@@ -16,18 +16,29 @@
|
||||
package com.android.systemui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Rect;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
|
||||
public class BatteryMeterView extends ImageView implements
|
||||
BatteryController.BatteryStateChangeCallback, TunerService.Tunable {
|
||||
BatteryStateChangeCallback, Tunable, DarkReceiver, ConfigurationListener {
|
||||
|
||||
private final BatteryMeterDrawable mDrawable;
|
||||
private final String mSlotBattery;
|
||||
@@ -77,6 +88,7 @@ public class BatteryMeterView extends ImageView implements
|
||||
mBatteryController.addCallback(this);
|
||||
mDrawable.startListening();
|
||||
Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
|
||||
Dependency.get(ConfigurationController.class).addCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,6 +97,7 @@ public class BatteryMeterView extends ImageView implements
|
||||
mBatteryController.removeCallback(this);
|
||||
mDrawable.stopListening();
|
||||
Dependency.get(TunerService.class).removeTunable(this);
|
||||
Dependency.get(ConfigurationController.class).removeCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,8 +112,35 @@ public class BatteryMeterView extends ImageView implements
|
||||
|
||||
}
|
||||
|
||||
public void setDarkIntensity(float f) {
|
||||
mDrawable.setDarkIntensity(f);
|
||||
@Override
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
scaleBatteryMeterViews();
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the scale factor for status bar icons and scales the battery view by that amount.
|
||||
*/
|
||||
private void scaleBatteryMeterViews() {
|
||||
Resources res = getContext().getResources();
|
||||
TypedValue typedValue = new TypedValue();
|
||||
|
||||
res.getValue(R.dimen.status_bar_icon_scale_factor, typedValue, true);
|
||||
float iconScaleFactor = typedValue.getFloat();
|
||||
|
||||
int batteryHeight = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_height);
|
||||
int batteryWidth = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_width);
|
||||
int marginBottom = res.getDimensionPixelSize(R.dimen.battery_margin_bottom);
|
||||
|
||||
LinearLayout.LayoutParams scaledLayoutParams = new LinearLayout.LayoutParams(
|
||||
(int) (batteryWidth * iconScaleFactor), (int) (batteryHeight * iconScaleFactor));
|
||||
scaledLayoutParams.setMarginsRelative(0, 0, 0, marginBottom);
|
||||
|
||||
setLayoutParams(scaledLayoutParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDarkChanged(Rect area, float darkIntensity, int tint) {
|
||||
mDrawable.setDarkIntensity(DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0);
|
||||
}
|
||||
|
||||
public void setRawColors(int fgColor, int bgColor) {
|
||||
|
||||
@@ -25,9 +25,13 @@ import android.util.ArrayMap;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.assist.AssistManager;
|
||||
import com.android.systemui.plugins.PluginManager;
|
||||
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
|
||||
import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
|
||||
import com.android.systemui.statusbar.phone.ManagedProfileController;
|
||||
import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
|
||||
import com.android.systemui.statusbar.phone.StatusBarWindowManager;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
|
||||
import com.android.systemui.statusbar.policy.AccessibilityController;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
import com.android.systemui.statusbar.policy.BatteryControllerImpl;
|
||||
@@ -35,6 +39,8 @@ import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
|
||||
import com.android.systemui.statusbar.policy.CastController;
|
||||
import com.android.systemui.statusbar.policy.CastControllerImpl;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
import com.android.systemui.statusbar.policy.DataSaverController;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
|
||||
@@ -187,6 +193,15 @@ public class Dependency extends SystemUI {
|
||||
mProviders.put(StatusBarWindowManager.class.getName(), () ->
|
||||
new StatusBarWindowManager(mContext));
|
||||
|
||||
mProviders.put(DarkIconDispatcher.class.getName(), () ->
|
||||
new DarkIconDispatcherImpl(mContext));
|
||||
|
||||
mProviders.put(ConfigurationController.class.getName(), () ->
|
||||
new ConfigurationControllerImpl(mContext));
|
||||
|
||||
mProviders.put(StatusBarIconController.class.getName(), () ->
|
||||
new StatusBarIconControllerImpl(mContext));
|
||||
|
||||
// Put all dependencies above here so the factory can override them if it wants.
|
||||
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class FragmentHostManager {
|
||||
return p;
|
||||
}
|
||||
|
||||
public void addTagListener(String tag, FragmentListener listener) {
|
||||
public FragmentHostManager addTagListener(String tag, FragmentListener listener) {
|
||||
ArrayList<FragmentListener> listeners = mListeners.get(tag);
|
||||
if (listeners == null) {
|
||||
listeners = new ArrayList<>();
|
||||
@@ -108,6 +108,7 @@ public class FragmentHostManager {
|
||||
if (current != null && current.getView() != null) {
|
||||
listener.onFragmentViewCreated(tag, current);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// Shouldn't generally be needed, included for completeness sake.
|
||||
|
||||
@@ -179,7 +179,7 @@ public class CastTile extends QSTile<QSTile.BooleanState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyguardChanged() {
|
||||
public void onKeyguardShowingChanged() {
|
||||
refreshState();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -141,7 +141,7 @@ public class LocationTile extends QSTile<QSTile.BooleanState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyguardChanged() {
|
||||
public void onKeyguardShowingChanged() {
|
||||
refreshState();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.Pair;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.statusbar.IStatusBar;
|
||||
@@ -92,6 +91,8 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
private final Object mLock = new Object();
|
||||
private ArrayList<Callbacks> mCallbacks = new ArrayList<>();
|
||||
private Handler mHandler = new H(Looper.getMainLooper());
|
||||
private int mDisable1;
|
||||
private int mDisable2;
|
||||
|
||||
/**
|
||||
* These methods are called back on the main thread.
|
||||
@@ -119,9 +120,9 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
default void cancelPreloadRecentApps() { }
|
||||
default void setWindowState(int window, int state) { }
|
||||
default void showScreenPinningRequest(int taskId) { }
|
||||
default void appTransitionPending() { }
|
||||
default void appTransitionPending(boolean forced) { }
|
||||
default void appTransitionCancelled() { }
|
||||
default void appTransitionStarting(long startTime, long duration) { }
|
||||
default void appTransitionStarting(long startTime, long duration, boolean forced) { }
|
||||
default void appTransitionFinished() { }
|
||||
default void showAssistDisclosure() { }
|
||||
default void startAssist(Bundle args) { }
|
||||
@@ -141,6 +142,7 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
|
||||
public void addCallbacks(Callbacks callbacks) {
|
||||
mCallbacks.add(callbacks);
|
||||
callbacks.disable(mDisable1, mDisable2, false /* animate */);
|
||||
}
|
||||
|
||||
public void removeCallbacks(Callbacks callbacks) {
|
||||
@@ -164,6 +166,8 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
|
||||
public void disable(int state1, int state2) {
|
||||
synchronized (mLock) {
|
||||
mDisable1 = state1;
|
||||
mDisable2 = state2;
|
||||
mHandler.removeMessages(MSG_DISABLE);
|
||||
mHandler.obtainMessage(MSG_DISABLE, state1, state2, null).sendToTarget();
|
||||
}
|
||||
@@ -315,9 +319,13 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
}
|
||||
|
||||
public void appTransitionPending() {
|
||||
appTransitionPending(false /* forced */);
|
||||
}
|
||||
|
||||
public void appTransitionPending(boolean forced) {
|
||||
synchronized (mLock) {
|
||||
mHandler.removeMessages(MSG_APP_TRANSITION_PENDING);
|
||||
mHandler.sendEmptyMessage(MSG_APP_TRANSITION_PENDING);
|
||||
mHandler.obtainMessage(MSG_APP_TRANSITION_PENDING, forced ? 1 : 0, 0).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,10 +337,14 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
}
|
||||
|
||||
public void appTransitionStarting(long startTime, long duration) {
|
||||
appTransitionStarting(startTime, duration, false /* forced */);
|
||||
}
|
||||
|
||||
public void appTransitionStarting(long startTime, long duration, boolean forced) {
|
||||
synchronized (mLock) {
|
||||
mHandler.removeMessages(MSG_APP_TRANSITION_STARTING);
|
||||
mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, Pair.create(startTime, duration))
|
||||
.sendToTarget();
|
||||
mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, forced ? 1 : 0, 0,
|
||||
Pair.create(startTime, duration)).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,7 +517,7 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
break;
|
||||
case MSG_APP_TRANSITION_PENDING:
|
||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||
mCallbacks.get(i).appTransitionPending();
|
||||
mCallbacks.get(i).appTransitionPending(msg.arg1 != 0);
|
||||
}
|
||||
break;
|
||||
case MSG_APP_TRANSITION_CANCELLED:
|
||||
@@ -516,7 +528,8 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
case MSG_APP_TRANSITION_STARTING:
|
||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||
Pair<Long, Long> data = (Pair<Long, Long>) msg.obj;
|
||||
mCallbacks.get(i).appTransitionStarting(data.first, data.second);
|
||||
mCallbacks.get(i).appTransitionStarting(data.first, data.second,
|
||||
msg.arg1 != 0);
|
||||
}
|
||||
break;
|
||||
case MSG_APP_TRANSITION_FINISHED:
|
||||
|
||||
@@ -43,6 +43,8 @@ import android.widget.LinearLayout;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.IconState;
|
||||
import com.android.systemui.statusbar.policy.NetworkControllerImpl;
|
||||
@@ -54,10 +56,9 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// Intimately tied to the design of res/layout/signal_cluster_view.xml
|
||||
public class SignalClusterView
|
||||
extends LinearLayout
|
||||
implements NetworkControllerImpl.SignalCallback,
|
||||
SecurityController.SecurityControllerCallback, Tunable {
|
||||
public class SignalClusterView extends LinearLayout implements NetworkControllerImpl.SignalCallback,
|
||||
SecurityController.SecurityControllerCallback, Tunable,
|
||||
DarkReceiver {
|
||||
|
||||
static final String TAG = "SignalClusterView";
|
||||
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
@@ -581,7 +582,8 @@ public class SignalClusterView
|
||||
return colorAccent;
|
||||
}
|
||||
|
||||
public void setIconTint(int tint, float darkIntensity, Rect tintArea) {
|
||||
@Override
|
||||
public void onDarkChanged(Rect tintArea, float darkIntensity, int tint) {
|
||||
boolean changed = tint != mIconTint || darkIntensity != mDarkIntensity
|
||||
|| !mTintArea.equals(tintArea);
|
||||
mIconTint = tint;
|
||||
@@ -593,16 +595,16 @@ public class SignalClusterView
|
||||
}
|
||||
|
||||
private void applyIconTint() {
|
||||
setTint(mVpn, StatusBarIconController.getTint(mTintArea, mVpn, mIconTint));
|
||||
setTint(mAirplane, StatusBarIconController.getTint(mTintArea, mAirplane, mIconTint));
|
||||
setTint(mVpn, DarkIconDispatcher.getTint(mTintArea, mVpn, mIconTint));
|
||||
setTint(mAirplane, DarkIconDispatcher.getTint(mTintArea, mAirplane, mIconTint));
|
||||
applyDarkIntensity(
|
||||
StatusBarIconController.getDarkIntensity(mTintArea, mNoSims, mDarkIntensity),
|
||||
DarkIconDispatcher.getDarkIntensity(mTintArea, mNoSims, mDarkIntensity),
|
||||
mNoSims, mNoSimsDark);
|
||||
applyDarkIntensity(
|
||||
StatusBarIconController.getDarkIntensity(mTintArea, mWifi, mDarkIntensity),
|
||||
DarkIconDispatcher.getDarkIntensity(mTintArea, mWifi, mDarkIntensity),
|
||||
mWifi, mWifiDark);
|
||||
applyDarkIntensity(
|
||||
StatusBarIconController.getDarkIntensity(mTintArea, mEthernet, mDarkIntensity),
|
||||
DarkIconDispatcher.getDarkIntensity(mTintArea, mEthernet, mDarkIntensity),
|
||||
mEthernet, mEthernetDark);
|
||||
for (int i = 0; i < mPhoneStates.size(); i++) {
|
||||
mPhoneStates.get(i).setIconTint(mIconTint, mDarkIntensity, mTintArea);
|
||||
@@ -740,10 +742,10 @@ public class SignalClusterView
|
||||
|
||||
public void setIconTint(int tint, float darkIntensity, Rect tintArea) {
|
||||
applyDarkIntensity(
|
||||
StatusBarIconController.getDarkIntensity(tintArea, mMobile, darkIntensity),
|
||||
DarkIconDispatcher.getDarkIntensity(tintArea, mMobile, darkIntensity),
|
||||
mMobile, mMobileDark);
|
||||
setTint(mMobileType, StatusBarIconController.getTint(tintArea, mMobileType, tint));
|
||||
setTint(mMobileRoaming, StatusBarIconController.getTint(tintArea, mMobileRoaming,
|
||||
setTint(mMobileType, DarkIconDispatcher.getTint(tintArea, mMobileType, tint));
|
||||
setTint(mMobileRoaming, DarkIconDispatcher.getTint(tintArea, mMobileRoaming,
|
||||
tint));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,17 +32,19 @@ import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.ViewStub;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.BatteryMeterView;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SwipeHelper;
|
||||
import com.android.systemui.fragments.FragmentHostManager;
|
||||
import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.recents.misc.SystemServicesProxy;
|
||||
import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
|
||||
import com.android.systemui.statusbar.phone.NavigationBarView;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
|
||||
@@ -75,7 +77,6 @@ public class CarStatusBar extends StatusBar implements
|
||||
|
||||
createBatteryController();
|
||||
mCarBatteryController.startListening();
|
||||
mConnectedDeviceSignalController.startListening();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,32 +88,40 @@ public class CarStatusBar extends StatusBar implements
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PhoneStatusBarView makeStatusBarView() {
|
||||
PhoneStatusBarView statusBarView = super.makeStatusBarView();
|
||||
protected void makeStatusBarView() {
|
||||
super.makeStatusBarView();
|
||||
|
||||
mBatteryMeterView = ((BatteryMeterView) statusBarView.findViewById(R.id.battery));
|
||||
FragmentHostManager manager = FragmentHostManager.get(mStatusBarWindow);
|
||||
manager.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
|
||||
mBatteryMeterView = ((BatteryMeterView) fragment.getView().findViewById(
|
||||
R.id.battery));
|
||||
|
||||
// By default, the BatteryMeterView should not be visible. It will be toggled visible
|
||||
// when a device has connected by bluetooth.
|
||||
mBatteryMeterView.setVisibility(View.GONE);
|
||||
// By default, the BatteryMeterView should not be visible. It will be toggled
|
||||
// when a device has connected by bluetooth.
|
||||
mBatteryMeterView.setVisibility(View.GONE);
|
||||
|
||||
ViewStub stub = (ViewStub) statusBarView.findViewById(R.id.connected_device_signals_stub);
|
||||
View signalsView = stub.inflate();
|
||||
ViewStub stub = (ViewStub) fragment.getView().findViewById(
|
||||
R.id.connected_device_signals_stub);
|
||||
View signalsView = stub.inflate();
|
||||
|
||||
// When a ViewStub if inflated, it does not respect the margins on the inflated view.
|
||||
// As a result, manually add the ending margin.
|
||||
((LinearLayout.LayoutParams) signalsView.getLayoutParams()).setMarginEnd(
|
||||
mContext.getResources().getDimensionPixelOffset(
|
||||
R.dimen.status_bar_connected_device_signal_margin_end));
|
||||
// When a ViewStub if inflated, it does not respect the margins on the
|
||||
// inflated view.
|
||||
// As a result, manually add the ending margin.
|
||||
((LinearLayout.LayoutParams) signalsView.getLayoutParams()).setMarginEnd(
|
||||
mContext.getResources().getDimensionPixelOffset(
|
||||
R.dimen.status_bar_connected_device_signal_margin_end));
|
||||
|
||||
mConnectedDeviceSignalController = new ConnectedDeviceSignalController(mContext,
|
||||
signalsView);
|
||||
if (mConnectedDeviceSignalController != null) {
|
||||
mConnectedDeviceSignalController.stopListening();
|
||||
}
|
||||
mConnectedDeviceSignalController = new ConnectedDeviceSignalController(mContext,
|
||||
signalsView);
|
||||
mConnectedDeviceSignalController.startListening();
|
||||
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "makeStatusBarView(). mBatteryMeterView: " + mBatteryMeterView);
|
||||
}
|
||||
|
||||
return statusBarView;
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "makeStatusBarView(). mBatteryMeterView: " + mBatteryMeterView);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private BatteryController createBatteryController() {
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.phone;
|
||||
|
||||
import static com.android.systemui.statusbar.phone.StatusBar.reinflateSignalCluster;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Fragment;
|
||||
import android.app.StatusBarManager;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.SignalClusterView;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
import com.android.systemui.statusbar.policy.EncryptionHelper;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitor;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
|
||||
/**
|
||||
* Contains the collapsed status bar and handles hiding/showing based on disable flags
|
||||
* and keyguard state. Also manages lifecycle to make sure the views it contains are being
|
||||
* updated by the StatusBarIconController and DarkIconManager while it is attached.
|
||||
*/
|
||||
public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks {
|
||||
|
||||
public static final String TAG = "CollapsedStatusBarFragment";
|
||||
private PhoneStatusBarView mStatusBar;
|
||||
private KeyguardMonitor mKeyguardMonitor;
|
||||
private NetworkController mNetworkController;
|
||||
private LinearLayout mSystemIconArea;
|
||||
private View mNotificationIconAreaInner;
|
||||
private int mDisabled1;
|
||||
private StatusBar mStatusBarComponent;
|
||||
private DarkIconManager mDarkIconManager;
|
||||
private SignalClusterView mSignalClusterView;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
|
||||
mNetworkController = Dependency.get(NetworkController.class);
|
||||
mStatusBarComponent = SysUiServiceProvider.getComponent(getContext(), StatusBar.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.status_bar, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mStatusBar = (PhoneStatusBarView) view;
|
||||
mDarkIconManager = new DarkIconManager((LinearLayout) view.findViewById(R.id.statusIcons));
|
||||
Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
|
||||
mSystemIconArea = (LinearLayout) mStatusBar.findViewById(R.id.system_icon_area);
|
||||
mSignalClusterView = reinflateSignalCluster(mStatusBar);
|
||||
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mSignalClusterView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mSignalClusterView);
|
||||
Dependency.get(StatusBarIconController.class).removeIconGroup(mDarkIconManager);
|
||||
}
|
||||
|
||||
public void initNotificationIconArea(NotificationIconAreaController
|
||||
notificationIconAreaController) {
|
||||
ViewGroup notificationIconArea = (ViewGroup) mStatusBar
|
||||
.findViewById(R.id.notification_icon_area);
|
||||
mNotificationIconAreaInner =
|
||||
notificationIconAreaController.getNotificationInnerAreaView();
|
||||
if (mNotificationIconAreaInner.getParent() != null) {
|
||||
((ViewGroup) mNotificationIconAreaInner.getParent())
|
||||
.removeView(mNotificationIconAreaInner);
|
||||
}
|
||||
notificationIconArea.addView(mNotificationIconAreaInner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(int state1, int state2, boolean animate) {
|
||||
state1 = adjustDisableFlags(state1);
|
||||
final int old1 = mDisabled1;
|
||||
final int diff1 = state1 ^ old1;
|
||||
mDisabled1 = state1;
|
||||
if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
|
||||
if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
|
||||
hideSystemIconArea(animate);
|
||||
} else {
|
||||
showSystemIconArea(animate);
|
||||
}
|
||||
}
|
||||
if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
|
||||
if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
|
||||
hideNotificationIconArea(animate);
|
||||
} else {
|
||||
showNotificationIconArea(animate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int adjustDisableFlags(int state) {
|
||||
if (!mStatusBarComponent.isLaunchTransitionFadingAway()
|
||||
&& !mKeyguardMonitor.isKeyguardFadingAway()
|
||||
&& shouldHideNotificationIcons()) {
|
||||
state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
|
||||
state |= StatusBarManager.DISABLE_SYSTEM_INFO;
|
||||
}
|
||||
if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
|
||||
if (mNetworkController.hasEmergencyCryptKeeperText()) {
|
||||
state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
|
||||
}
|
||||
if (!mNetworkController.isRadioOn()) {
|
||||
state |= StatusBarManager.DISABLE_SYSTEM_INFO;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
private boolean shouldHideNotificationIcons() {
|
||||
return !mStatusBar.isClosed() && mStatusBarComponent.shouldHideNotificationIcons();
|
||||
}
|
||||
|
||||
public void hideSystemIconArea(boolean animate) {
|
||||
animateHide(mSystemIconArea, animate);
|
||||
}
|
||||
|
||||
public void showSystemIconArea(boolean animate) {
|
||||
animateShow(mSystemIconArea, animate);
|
||||
}
|
||||
|
||||
public void hideNotificationIconArea(boolean animate) {
|
||||
animateHide(mNotificationIconAreaInner, animate);
|
||||
}
|
||||
|
||||
public void showNotificationIconArea(boolean animate) {
|
||||
animateShow(mNotificationIconAreaInner, animate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides a view.
|
||||
*/
|
||||
private void animateHide(final View v, boolean animate) {
|
||||
v.animate().cancel();
|
||||
if (!animate) {
|
||||
v.setAlpha(0f);
|
||||
v.setVisibility(View.INVISIBLE);
|
||||
return;
|
||||
}
|
||||
v.animate()
|
||||
.alpha(0f)
|
||||
.setDuration(160)
|
||||
.setStartDelay(0)
|
||||
.setInterpolator(Interpolators.ALPHA_OUT)
|
||||
.withEndAction(() -> v.setVisibility(View.INVISIBLE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a view, and synchronizes the animation with Keyguard exit animations, if applicable.
|
||||
*/
|
||||
private void animateShow(View v, boolean animate) {
|
||||
v.animate().cancel();
|
||||
v.setVisibility(View.VISIBLE);
|
||||
if (!animate) {
|
||||
v.setAlpha(1f);
|
||||
return;
|
||||
}
|
||||
v.animate()
|
||||
.alpha(1f)
|
||||
.setDuration(320)
|
||||
.setInterpolator(Interpolators.ALPHA_IN)
|
||||
.setStartDelay(50)
|
||||
|
||||
// We need to clean up any pending end action from animateHide if we call
|
||||
// both hide and show in the same frame before the animation actually gets started.
|
||||
// cancel() doesn't really remove the end action.
|
||||
.withEndAction(null);
|
||||
|
||||
// Synchronize the motion with the Keyguard fading if necessary.
|
||||
if (mKeyguardMonitor.isKeyguardFadingAway()) {
|
||||
v.animate()
|
||||
.setDuration(mKeyguardMonitor.getKeyguardFadingAwayDuration())
|
||||
.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
|
||||
.setStartDelay(mKeyguardMonitor.getKeyguardFadingAwayDelay())
|
||||
.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.phone;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
|
||||
import com.android.systemui.ConfigurationChangedReceiver;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ConfigurationControllerImpl implements ConfigurationController,
|
||||
ConfigurationChangedReceiver {
|
||||
|
||||
private final ArrayList<ConfigurationListener> mListeners = new ArrayList<>();
|
||||
private int mDensity;
|
||||
private float mFontScale;
|
||||
|
||||
public ConfigurationControllerImpl(Context context) {
|
||||
Configuration currentConfig = context.getResources().getConfiguration();
|
||||
mFontScale = currentConfig.fontScale;
|
||||
mDensity = currentConfig.densityDpi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
mListeners.forEach(l -> l.onConfigChanged(newConfig));
|
||||
final float fontScale = newConfig.fontScale;
|
||||
final int density = newConfig.densityDpi;
|
||||
if (density != mDensity || mFontScale != fontScale) {
|
||||
mListeners.forEach(l -> l.onDensityOrFontScaleChanged());
|
||||
mDensity = density;
|
||||
mFontScale = fontScale;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCallback(ConfigurationListener listener) {
|
||||
mListeners.add(listener);
|
||||
listener.onDensityOrFontScaleChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCallback(ConfigurationListener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.phone;
|
||||
|
||||
import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint;
|
||||
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Rect;
|
||||
import android.util.ArrayMap;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
|
||||
public class DarkIconDispatcherImpl implements DarkIconDispatcher {
|
||||
|
||||
private final LightBarTransitionsController mTransitionsController;
|
||||
private final Rect mTintArea = new Rect();
|
||||
private final ArrayMap<Object, DarkReceiver> mReceivers = new ArrayMap<>();
|
||||
|
||||
private int mIconTint = DEFAULT_ICON_TINT;
|
||||
private float mDarkIntensity;
|
||||
private int mDarkModeIconColorSingleTone;
|
||||
private int mLightModeIconColorSingleTone;
|
||||
|
||||
public DarkIconDispatcherImpl(Context context) {
|
||||
mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone);
|
||||
mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone);
|
||||
|
||||
mTransitionsController = new LightBarTransitionsController(context,
|
||||
this::setIconTintInternal);
|
||||
}
|
||||
|
||||
public LightBarTransitionsController getTransitionsController() {
|
||||
return mTransitionsController;
|
||||
}
|
||||
|
||||
public void addDarkReceiver(DarkReceiver receiver) {
|
||||
mReceivers.put(receiver, receiver);
|
||||
receiver.onDarkChanged(mTintArea, mDarkIntensity, mIconTint);
|
||||
}
|
||||
|
||||
public void addDarkReceiver(ImageView imageView) {
|
||||
DarkReceiver receiver = (area, darkIntensity, tint) -> imageView.setImageTintList(
|
||||
ColorStateList.valueOf(getTint(mTintArea, imageView, mIconTint)));
|
||||
mReceivers.put(imageView, receiver);
|
||||
receiver.onDarkChanged(mTintArea, mDarkIntensity, mIconTint);
|
||||
}
|
||||
|
||||
public void removeDarkReceiver(DarkReceiver object) {
|
||||
mReceivers.remove(object);
|
||||
}
|
||||
|
||||
public void removeDarkReceiver(ImageView object) {
|
||||
mReceivers.remove(object);
|
||||
}
|
||||
|
||||
public void applyDark(ImageView object) {
|
||||
mReceivers.get(object).onDarkChanged(mTintArea, mDarkIntensity, mIconTint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dark area so {@link #setIconsDark} only affects the icons in the specified area.
|
||||
*
|
||||
* @param darkArea the area in which icons should change it's tint, in logical screen
|
||||
* coordinates
|
||||
*/
|
||||
public void setIconsDarkArea(Rect darkArea) {
|
||||
if (darkArea == null && mTintArea.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (darkArea == null) {
|
||||
mTintArea.setEmpty();
|
||||
} else {
|
||||
mTintArea.set(darkArea);
|
||||
}
|
||||
applyIconTint();
|
||||
}
|
||||
|
||||
private void setIconTintInternal(float darkIntensity) {
|
||||
mDarkIntensity = darkIntensity;
|
||||
mIconTint = (int) ArgbEvaluator.getInstance().evaluate(darkIntensity,
|
||||
mLightModeIconColorSingleTone, mDarkModeIconColorSingleTone);
|
||||
applyIconTint();
|
||||
}
|
||||
|
||||
private void applyIconTint() {
|
||||
for (int i = 0; i < mReceivers.size(); i++) {
|
||||
mReceivers.valueAt(i).onDarkChanged(mTintArea, mDarkIntensity, mIconTint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.view.View;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -36,7 +37,7 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
|
||||
|
||||
private static final float NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD = 0.1f;
|
||||
|
||||
private final StatusBarIconController mStatusBarIconController;
|
||||
private final DarkIconDispatcher mStatusBarIconController;
|
||||
private final BatteryController mBatteryController;
|
||||
private FingerprintUnlockController mFingerprintUnlockController;
|
||||
|
||||
@@ -65,8 +66,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
|
||||
private final Rect mLastFullscreenBounds = new Rect();
|
||||
private final Rect mLastDockedBounds = new Rect();
|
||||
|
||||
public LightBarController(StatusBarIconController statusBarIconController) {
|
||||
mStatusBarIconController = statusBarIconController;
|
||||
public LightBarController() {
|
||||
mStatusBarIconController = Dependency.get(DarkIconDispatcher.class);
|
||||
mBatteryController = Dependency.get(BatteryController.class);
|
||||
mBatteryController.addCallback(this);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,19 @@
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.util.TimeUtils;
|
||||
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.CommandQueue.Callbacks;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitor;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -31,13 +37,14 @@ import java.io.PrintWriter;
|
||||
/**
|
||||
* Class to control all aspects about light bar changes.
|
||||
*/
|
||||
public class LightBarTransitionsController implements Dumpable {
|
||||
public class LightBarTransitionsController implements Dumpable, Callbacks {
|
||||
|
||||
public static final long DEFAULT_TINT_ANIMATION_DURATION = 120;
|
||||
private static final String EXTRA_DARK_INTENSITY = "dark_intensity";
|
||||
|
||||
private final Handler mHandler;
|
||||
private final DarkIntensityApplier mApplier;
|
||||
private final KeyguardMonitor mKeyguardMonitor;
|
||||
|
||||
private boolean mTransitionDeferring;
|
||||
private long mTransitionDeferringStartTime;
|
||||
@@ -56,9 +63,17 @@ public class LightBarTransitionsController implements Dumpable {
|
||||
}
|
||||
};
|
||||
|
||||
public LightBarTransitionsController(DarkIntensityApplier applier) {
|
||||
public LightBarTransitionsController(Context context, DarkIntensityApplier applier) {
|
||||
mApplier = applier;
|
||||
mHandler = new Handler();
|
||||
mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
|
||||
SysUiServiceProvider.getComponent(context, CommandQueue.class)
|
||||
.addCallbacks(this);
|
||||
}
|
||||
|
||||
public void destroy(Context context) {
|
||||
SysUiServiceProvider.getComponent(context, CommandQueue.class)
|
||||
.removeCallbacks(this);
|
||||
}
|
||||
|
||||
public void saveState(Bundle outState) {
|
||||
@@ -71,10 +86,15 @@ public class LightBarTransitionsController implements Dumpable {
|
||||
setIconTintInternal(savedInstanceState.getFloat(EXTRA_DARK_INTENSITY, 0));
|
||||
}
|
||||
|
||||
public void appTransitionPending() {
|
||||
@Override
|
||||
public void appTransitionPending(boolean forced) {
|
||||
if (mKeyguardMonitor.isKeyguardGoingAway() && !forced) {
|
||||
return;
|
||||
}
|
||||
mTransitionPending = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appTransitionCancelled() {
|
||||
if (mTransitionPending && mTintChangePending) {
|
||||
mTintChangePending = false;
|
||||
@@ -83,7 +103,11 @@ public class LightBarTransitionsController implements Dumpable {
|
||||
mTransitionPending = false;
|
||||
}
|
||||
|
||||
public void appTransitionStarting(long startTime, long duration) {
|
||||
@Override
|
||||
public void appTransitionStarting(long startTime, long duration, boolean forced) {
|
||||
if (mKeyguardMonitor.isKeyguardGoingAway() && !forced) {
|
||||
return;
|
||||
}
|
||||
if (mTransitionPending && mTintChangePending) {
|
||||
mTintChangePending = false;
|
||||
animateIconTint(mPendingDarkIntensity,
|
||||
|
||||
@@ -118,7 +118,6 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
|
||||
private int mSystemUiVisibility;
|
||||
private LightBarController mLightBarController;
|
||||
private boolean mKeyguardGoingAway;
|
||||
|
||||
public boolean mHomeBlockedThisTouch;
|
||||
|
||||
@@ -195,6 +194,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
mNavigationBarView.getLightTransitionsController().destroy(getContext());
|
||||
getContext().unregisterReceiver(mBroadcastReceiver);
|
||||
}
|
||||
|
||||
@@ -287,31 +287,6 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appTransitionPending() {
|
||||
mNavigationBarView.getLightTransitionsController().appTransitionPending();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appTransitionCancelled() {
|
||||
mNavigationBarView.getLightTransitionsController().appTransitionCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appTransitionStarting(long startTime, long duration) {
|
||||
if (mKeyguardGoingAway) return;
|
||||
doAppTransitionStarting(startTime, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls appTransitionStarting for the nav bar regardless of whether keyguard is going away.
|
||||
* public so StatusBar can force this when needed.
|
||||
*/
|
||||
public void doAppTransitionStarting(long startTime, long duration) {
|
||||
mNavigationBarView.getLightTransitionsController().appTransitionStarting(startTime,
|
||||
duration);
|
||||
}
|
||||
|
||||
// Injected from StatusBar at creation.
|
||||
public void setCurrentSysuiVisibility(int systemUiVisibility) {
|
||||
mSystemUiVisibility = systemUiVisibility;
|
||||
@@ -612,10 +587,6 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
|
||||
}
|
||||
|
||||
public void setKeyguardGoingAway(boolean keyguardGoingAway) {
|
||||
mKeyguardGoingAway = keyguardGoingAway;
|
||||
}
|
||||
|
||||
public BarTransitions getBarTransitions() {
|
||||
return mNavigationBarView.getBarTransitions();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ public final class NavigationBarTransitions extends BarTransitions {
|
||||
mView = view;
|
||||
mBarService = IStatusBarService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
||||
mLightTransitionsController = new LightBarTransitionsController(this::applyDarkIntensity);
|
||||
mLightTransitionsController = new LightBarTransitionsController(view.getContext(),
|
||||
this::applyDarkIntensity);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
|
||||
@@ -17,6 +17,8 @@ import com.android.systemui.statusbar.NotificationData;
|
||||
import com.android.systemui.statusbar.NotificationShelf;
|
||||
import com.android.systemui.statusbar.StatusBarIconView;
|
||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
|
||||
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -26,7 +28,7 @@ import java.util.function.Function;
|
||||
* A controller for the space in the status bar to the left of the system icons. This area is
|
||||
* normally reserved for notifications.
|
||||
*/
|
||||
public class NotificationIconAreaController {
|
||||
public class NotificationIconAreaController implements DarkReceiver {
|
||||
private final NotificationColorUtil mNotificationColorUtil;
|
||||
|
||||
private int mIconSize;
|
||||
@@ -64,11 +66,12 @@ public class NotificationIconAreaController {
|
||||
mNotificationIcons = (NotificationIconContainer) mNotificationIconArea.findViewById(
|
||||
R.id.notificationIcons);
|
||||
|
||||
NotificationShelf shelf = mStatusBar.getNotificationShelf();
|
||||
mNotificationScrollLayout = mStatusBar.getNotificationScrollLayout();
|
||||
}
|
||||
|
||||
public void setupShelf(NotificationShelf shelf) {
|
||||
mShelfIcons = shelf.getShelfIcons();
|
||||
shelf.setCollapsedIcons(mNotificationIcons);
|
||||
|
||||
mNotificationScrollLayout = mStatusBar.getNotificationScrollLayout();
|
||||
}
|
||||
|
||||
public void onDensityOrFontScaleChanged(Context context) {
|
||||
@@ -102,23 +105,18 @@ public class NotificationIconAreaController {
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link StatusBarIconController#setIconsDarkArea}.
|
||||
* See {@link com.android.systemui.statusbar.policy.DarkIconDispatcher#setIconsDarkArea}.
|
||||
* Sets the color that should be used to tint any icons in the notification area.
|
||||
*
|
||||
* @param tintArea the area in which to tint the icons, specified in screen coordinates
|
||||
* @param darkIntensity
|
||||
*/
|
||||
public void setTintArea(Rect tintArea) {
|
||||
public void onDarkChanged(Rect tintArea, float darkIntensity, int iconTint) {
|
||||
if (tintArea == null) {
|
||||
mTintArea.setEmpty();
|
||||
} else {
|
||||
mTintArea.set(tintArea);
|
||||
}
|
||||
applyNotificationIconsTint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color that should be used to tint any icons in the notification area.
|
||||
*/
|
||||
public void setIconTint(int iconTint) {
|
||||
mIconTint = iconTint;
|
||||
applyNotificationIconsTint();
|
||||
}
|
||||
@@ -231,7 +229,7 @@ public class NotificationIconAreaController {
|
||||
boolean colorize = !isPreL || NotificationUtils.isGrayscale(v, mNotificationColorUtil);
|
||||
if (colorize) {
|
||||
v.setImageTintList(ColorStateList.valueOf(
|
||||
StatusBarIconController.getTint(mTintArea, v, mIconTint)));
|
||||
DarkIconDispatcher.getTint(mTintArea, v, mIconTint)));
|
||||
}
|
||||
v.setIconTint(mIconTint);
|
||||
}
|
||||
|
||||
@@ -166,6 +166,10 @@ public abstract class PanelBar extends FrameLayout {
|
||||
if (DEBUG) LOG("onPanelPeeked");
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return mState == STATE_CLOSED;
|
||||
}
|
||||
|
||||
public void onPanelCollapsed() {
|
||||
if (DEBUG) LOG("onPanelCollapsed");
|
||||
}
|
||||
|
||||
@@ -38,24 +38,35 @@ import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.telephony.TelephonyIntents;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.qs.tiles.DndTile;
|
||||
import com.android.systemui.qs.tiles.RotationLockTile;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.CommandQueue.Callbacks;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController.Callback;
|
||||
import com.android.systemui.statusbar.policy.CastController;
|
||||
import com.android.systemui.statusbar.policy.CastController.CastDevice;
|
||||
import com.android.systemui.statusbar.policy.DataSaverController;
|
||||
import com.android.systemui.statusbar.policy.DataSaverController.Listener;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
|
||||
import com.android.systemui.statusbar.policy.HotspotController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitor;
|
||||
import com.android.systemui.statusbar.policy.NextAlarmController;
|
||||
import com.android.systemui.statusbar.policy.RotationLockController;
|
||||
import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
|
||||
import com.android.systemui.statusbar.policy.UserInfoController;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
|
||||
/**
|
||||
* This class contains all of the policy about which icons are installed in the status
|
||||
* bar at boot time. It goes through the normal API for icons, even though it probably
|
||||
* strictly doesn't need to.
|
||||
*/
|
||||
public class PhoneStatusBarPolicy implements Callback, RotationLockController.RotationLockControllerCallback, DataSaverController.Listener {
|
||||
public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
RotationLockControllerCallback, Listener,
|
||||
ZenModeController.Callback, DeviceProvisionedListener, KeyguardMonitor.Callback {
|
||||
private static final String TAG = "PhoneStatusBarPolicy";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
@@ -82,7 +93,9 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro
|
||||
private final StatusBarIconController mIconController;
|
||||
private final RotationLockController mRotationLockController;
|
||||
private final DataSaverController mDataSaver;
|
||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
private final ZenModeController mZenController;
|
||||
private final DeviceProvisionedController mProvisionedController;
|
||||
private final KeyguardMonitor mKeyguardMonitor;
|
||||
|
||||
// Assume it's all good unless we hear otherwise. We don't always seem
|
||||
// to get broadcasts that it *is* there.
|
||||
@@ -106,13 +119,15 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro
|
||||
mCast = Dependency.get(CastController.class);
|
||||
mHotspot = Dependency.get(HotspotController.class);
|
||||
mBluetooth = Dependency.get(BluetoothController.class);
|
||||
mBluetooth.addCallback(this);
|
||||
mNextAlarm = Dependency.get(NextAlarmController.class);
|
||||
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
mUserInfoController = Dependency.get(UserInfoController.class);
|
||||
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
mRotationLockController = Dependency.get(RotationLockController.class);
|
||||
mDataSaver = Dependency.get(DataSaverController.class);
|
||||
mZenController = Dependency.get(ZenModeController.class);
|
||||
mProvisionedController = Dependency.get(DeviceProvisionedController.class);
|
||||
mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
|
||||
|
||||
mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
|
||||
mSlotHotspot = context.getString(com.android.internal.R.string.status_bar_hotspot);
|
||||
@@ -127,7 +142,6 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro
|
||||
mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset);
|
||||
mSlotDataSaver = context.getString(com.android.internal.R.string.status_bar_data_saver);
|
||||
|
||||
mRotationLockController.addCallback(this);
|
||||
|
||||
// listen for broadcasts
|
||||
IntentFilter filter = new IntentFilter();
|
||||
@@ -158,7 +172,6 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro
|
||||
// Alarm clock
|
||||
mIconController.setIcon(mSlotAlarmClock, R.drawable.stat_sys_alarm, null);
|
||||
mIconController.setIconVisibility(mSlotAlarmClock, false);
|
||||
mNextAlarm.addCallback(mNextAlarmCallback);
|
||||
|
||||
// zen
|
||||
mIconController.setIcon(mSlotZen, R.drawable.stat_sys_zen_important, null);
|
||||
@@ -172,13 +185,11 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro
|
||||
// cast
|
||||
mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast, null);
|
||||
mIconController.setIconVisibility(mSlotCast, false);
|
||||
mCast.addCallback(mCastCallback);
|
||||
|
||||
// hotspot
|
||||
mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot,
|
||||
mContext.getString(R.string.accessibility_status_bar_hotspot));
|
||||
mIconController.setIconVisibility(mSlotHotspot, mHotspot.isHotspotEnabled());
|
||||
mHotspot.addCallback(mHotspotCallback);
|
||||
|
||||
// managed profile
|
||||
mIconController.setIcon(mSlotManagedProfile, R.drawable.stat_sys_managed_profile_status,
|
||||
@@ -189,15 +200,36 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro
|
||||
mIconController.setIcon(mSlotDataSaver, R.drawable.stat_sys_data_saver,
|
||||
context.getString(R.string.accessibility_data_saver_on));
|
||||
mIconController.setIconVisibility(mSlotDataSaver, false);
|
||||
|
||||
mRotationLockController.addCallback(this);
|
||||
mBluetooth.addCallback(this);
|
||||
mProvisionedController.addCallback(this);
|
||||
mZenController.addCallback(this);
|
||||
mCast.addCallback(mCastCallback);
|
||||
mHotspot.addCallback(mHotspotCallback);
|
||||
mNextAlarm.addCallback(mNextAlarmCallback);
|
||||
mDataSaver.addCallback(this);
|
||||
mKeyguardMonitor.addCallback(this);
|
||||
|
||||
SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
|
||||
}
|
||||
|
||||
public void setStatusBarKeyguardViewManager(
|
||||
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
|
||||
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
|
||||
public void destroy() {
|
||||
mRotationLockController.removeCallback(this);
|
||||
mBluetooth.removeCallback(this);
|
||||
mProvisionedController.removeCallback(this);
|
||||
mZenController.removeCallback(this);
|
||||
mCast.removeCallback(mCastCallback);
|
||||
mHotspot.removeCallback(mHotspotCallback);
|
||||
mNextAlarm.removeCallback(mNextAlarmCallback);
|
||||
mDataSaver.removeCallback(this);
|
||||
mKeyguardMonitor.removeCallback(this);
|
||||
SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
|
||||
mContext.unregisterReceiver(mIntentReceiver);
|
||||
}
|
||||
|
||||
public void setZenMode(int zen) {
|
||||
@Override
|
||||
public void onZenChanged(int zen) {
|
||||
mZen = zen;
|
||||
updateVolumeZen();
|
||||
}
|
||||
@@ -394,7 +426,7 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro
|
||||
if (DEBUG) Log.v(TAG, "updateManagedProfile: mManagedProfileFocused: "
|
||||
+ mManagedProfileFocused);
|
||||
final boolean showIcon;
|
||||
if (mManagedProfileFocused && !mStatusBarKeyguardViewManager.isShowing()) {
|
||||
if (mManagedProfileFocused && !mKeyguardMonitor.isShowing()) {
|
||||
showIcon = true;
|
||||
mIconController.setIcon(mSlotManagedProfile,
|
||||
R.drawable.stat_sys_managed_profile_status,
|
||||
@@ -471,15 +503,20 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro
|
||||
}
|
||||
};
|
||||
|
||||
public void appTransitionStarting(long startTime, long duration) {
|
||||
@Override
|
||||
public void appTransitionStarting(long startTime, long duration, boolean forced) {
|
||||
updateManagedProfile();
|
||||
}
|
||||
|
||||
public void notifyKeyguardShowingChanged() {
|
||||
@Override
|
||||
public void onKeyguardShowingChanged() {
|
||||
updateManagedProfile();
|
||||
}
|
||||
|
||||
public void setCurrentUserSetup(boolean userSetup) {
|
||||
@Override
|
||||
public void onUserSetupChanged() {
|
||||
boolean userSetup = mProvisionedController.isUserSetup(
|
||||
mProvisionedController.getCurrentUser());
|
||||
if (mCurrentUserSetup == userSetup) return;
|
||||
mCurrentUserSetup = userSetup;
|
||||
updateAlarm();
|
||||
|
||||
@@ -24,9 +24,13 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import com.android.systemui.BatteryMeterView;
|
||||
import com.android.systemui.DejankUtils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.EventLogTags;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
|
||||
|
||||
public class PhoneStatusBarView extends PanelBar {
|
||||
private static final String TAG = "PhoneStatusBarView";
|
||||
@@ -48,6 +52,7 @@ public class PhoneStatusBarView extends PanelBar {
|
||||
}
|
||||
}
|
||||
};
|
||||
private DarkReceiver mBattery;
|
||||
|
||||
public PhoneStatusBarView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -70,6 +75,20 @@ public class PhoneStatusBarView extends PanelBar {
|
||||
@Override
|
||||
public void onFinishInflate() {
|
||||
mBarTransitions.init();
|
||||
mBattery = (DarkReceiver) findViewById(R.id.battery);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
// Always have Battery meters in the status bar observe the dark/light modes.
|
||||
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mBattery);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mBattery);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -178,7 +178,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements
|
||||
SignalClusterView cluster = (SignalClusterView) findViewById(R.id.signal_cluster);
|
||||
int colorForeground = Utils.getColorAttr(getContext(), android.R.attr.colorForeground);
|
||||
float intensity = colorForeground == Color.WHITE ? 0 : 1;
|
||||
cluster.setIconTint(colorForeground, intensity, new Rect(0, 0, 0, 0));
|
||||
cluster.onDarkChanged(new Rect(0, 0, 0, 0), intensity, colorForeground);
|
||||
BatteryMeterView battery = (BatteryMeterView) findViewById(R.id.battery);
|
||||
int colorSecondary = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary);
|
||||
battery.setRawColors(colorForeground, colorSecondary);
|
||||
|
||||
@@ -173,13 +173,16 @@ import com.android.systemui.statusbar.ScrimView;
|
||||
import com.android.systemui.statusbar.SignalClusterView;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.notification.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
|
||||
import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
|
||||
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
|
||||
import com.android.systemui.statusbar.policy.EncryptionHelper;
|
||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitor;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
|
||||
@@ -504,9 +507,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
updateQsExpansionEnabled();
|
||||
}
|
||||
if (mIconPolicy != null) {
|
||||
mIconPolicy.setCurrentUserSetup(mUserSetup);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -712,6 +712,8 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
private BatteryController mBatteryController;
|
||||
private LogMaker mStatusBarStateLog;
|
||||
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
|
||||
private NotificationIconAreaController mNotificationIconAreaController;
|
||||
private ConfigurationListener mDensityChangeListener;
|
||||
|
||||
private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
|
||||
final int N = array.size();
|
||||
@@ -809,8 +811,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
final Configuration currentConfig = mContext.getResources().getConfiguration();
|
||||
mLocale = currentConfig.locale;
|
||||
mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
|
||||
mFontScale = currentConfig.fontScale;
|
||||
mDensity = currentConfig.densityDpi;
|
||||
|
||||
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
@@ -847,7 +847,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
int N = iconSlots.size();
|
||||
int viewIndex = 0;
|
||||
for (int i=0; i < N; i++) {
|
||||
setIcon(iconSlots.get(i), icons.get(i));
|
||||
mCommandQueue.setIcon(iconSlots.get(i), icons.get(i));
|
||||
}
|
||||
|
||||
// Set up the initial notification state.
|
||||
@@ -914,7 +914,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
|
||||
// Lastly, call to the icon policy to install/update all the icons.
|
||||
mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController);
|
||||
mIconPolicy.setCurrentUserSetup(mUserSetup);
|
||||
mSettingsObserver.onChange(false); // set up
|
||||
|
||||
mHeadsUpObserver.onChange(true); // set up
|
||||
@@ -938,18 +937,25 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
|
||||
mScreenPinningRequest = new ScreenPinningRequest(mContext);
|
||||
mFalsingManager = FalsingManager.getInstance(mContext);
|
||||
|
||||
Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
|
||||
|
||||
mDensityChangeListener = new ConfigurationListener() {
|
||||
@Override
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
StatusBar.this.onDensityOrFontScaleChanged();
|
||||
}
|
||||
};
|
||||
Dependency.get(ConfigurationController.class).addCallback(mDensityChangeListener);
|
||||
}
|
||||
|
||||
protected void createIconController() {
|
||||
mIconController = new StatusBarIconController(
|
||||
mContext, mStatusBarView, mKeyguardStatusBar, this);
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
// Constructing the view
|
||||
// ================================================================================
|
||||
protected PhoneStatusBarView makeStatusBarView() {
|
||||
protected void makeStatusBarView() {
|
||||
final Context context = mContext;
|
||||
updateDisplaySize(); // populates mDisplayMetrics
|
||||
updateResources();
|
||||
@@ -958,14 +964,37 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mStatusBarWindow.setService(this);
|
||||
mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
|
||||
|
||||
// TODO: Deal with the ugliness that comes from having some of the statusbar broken out
|
||||
// into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
|
||||
mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
|
||||
R.id.notification_panel);
|
||||
mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
|
||||
R.id.notification_stack_scroller);
|
||||
mNotificationPanel.setStatusBar(this);
|
||||
mNotificationPanel.setGroupManager(mGroupManager);
|
||||
mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
|
||||
|
||||
mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
|
||||
mStatusBarView.setBar(this);
|
||||
mStatusBarView.setPanel(mNotificationPanel);
|
||||
mNotificationIconAreaController = SystemUIFactory.getInstance()
|
||||
.createNotificationIconAreaController(context, this);
|
||||
inflateShelf();
|
||||
mNotificationIconAreaController.setupShelf(mNotificationShelf);
|
||||
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController);
|
||||
FragmentHostManager.get(mStatusBarWindow)
|
||||
.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
|
||||
CollapsedStatusBarFragment statusBarFragment = (CollapsedStatusBarFragment) fragment;
|
||||
statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
|
||||
mStatusBarView = (PhoneStatusBarView) fragment.getView();
|
||||
mStatusBarView.setBar(this);
|
||||
mStatusBarView.setPanel(mNotificationPanel);
|
||||
mStatusBarView.setScrimController(mScrimController);
|
||||
setAreThereNotifications();
|
||||
}).getFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.status_bar_container, new CollapsedStatusBarFragment(), CollapsedStatusBarFragment.TAG)
|
||||
.commit();
|
||||
Dependency.get(StatusBarIconController.class).addIconGroup(
|
||||
new IconManager((ViewGroup) mKeyguardStatusBar.findViewById(R.id.statusIcons)));
|
||||
mIconController = Dependency.get(StatusBarIconController.class);
|
||||
|
||||
if (!ActivityManager.isHighEndGfx()) {
|
||||
mStatusBarWindow.setBackground(null);
|
||||
@@ -1003,8 +1032,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
// figure out which pixel-format to use for the status bar.
|
||||
mPixelFormat = PixelFormat.OPAQUE;
|
||||
|
||||
mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
|
||||
R.id.notification_stack_scroller);
|
||||
mStackScroller.setLongPressListener(getNotificationLongClicker());
|
||||
mStackScroller.setStatusBar(this);
|
||||
mStackScroller.setGroupManager(mGroupManager);
|
||||
@@ -1012,7 +1039,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mGroupManager.setOnGroupChangeListener(mStackScroller);
|
||||
mVisualStabilityManager.setVisibilityLocationProvider(mStackScroller);
|
||||
|
||||
inflateShelf();
|
||||
inflateEmptyShadeView();
|
||||
inflateDismissView();
|
||||
mExpandedContents = mStackScroller;
|
||||
@@ -1025,7 +1051,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
|
||||
}
|
||||
|
||||
mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
|
||||
mKeyguardStatusView =
|
||||
(KeyguardStatusView) mStatusBarWindow.findViewById(R.id.keyguard_status_view);
|
||||
mKeyguardBottomArea =
|
||||
@@ -1039,8 +1064,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
// set the initial view visibility
|
||||
setAreThereNotifications();
|
||||
|
||||
createIconController();
|
||||
|
||||
// TODO: Find better place for this callback.
|
||||
mBatteryController.addCallback(new BatteryStateChangeCallback() {
|
||||
@Override
|
||||
@@ -1057,7 +1080,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
});
|
||||
|
||||
mLightBarController = new LightBarController(mIconController);
|
||||
mLightBarController = new LightBarController();
|
||||
if (mNavigationBar != null) {
|
||||
mNavigationBar.setLightBarController(mLightBarController);
|
||||
}
|
||||
@@ -1081,7 +1104,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
mHeadsUpManager.addListener(mScrimController);
|
||||
mStackScroller.setScrimController(mScrimController);
|
||||
mStatusBarView.setScrimController(mScrimController);
|
||||
mDozeScrimController = new DozeScrimController(mScrimController, context, mStackScroller,
|
||||
mNotificationPanel);
|
||||
|
||||
@@ -1187,8 +1209,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
|
||||
// Private API call to make the shadows look better for Recents
|
||||
ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
|
||||
|
||||
return mStatusBarView;
|
||||
}
|
||||
|
||||
protected void createNavigationBar() {
|
||||
@@ -1262,12 +1282,13 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
// end old BaseStatusBar.onDensityOrFontScaleChanged().
|
||||
mScrimController.onDensityOrFontScaleChanged();
|
||||
mStatusBarView.onDensityOrFontScaleChanged();
|
||||
// TODO: Remove this.
|
||||
if (mStatusBarView != null) mStatusBarView.onDensityOrFontScaleChanged();
|
||||
if (mBrightnessMirrorController != null) {
|
||||
mBrightnessMirrorController.onDensityOrFontScaleChanged();
|
||||
}
|
||||
inflateSignalClusters();
|
||||
mIconController.onDensityOrFontScaleChanged();
|
||||
mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
|
||||
inflateDismissView();
|
||||
updateClearAll();
|
||||
inflateEmptyShadeView();
|
||||
@@ -1283,12 +1304,11 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
|
||||
private void inflateSignalClusters() {
|
||||
SignalClusterView signalClusterView = reinflateSignalCluster(mStatusBarView);
|
||||
mIconController.setSignalCluster(signalClusterView);
|
||||
reinflateSignalCluster(mKeyguardStatusBar);
|
||||
}
|
||||
|
||||
private SignalClusterView reinflateSignalCluster(View view) {
|
||||
public static SignalClusterView reinflateSignalCluster(View view) {
|
||||
Context context = view.getContext();
|
||||
SignalClusterView signalCluster =
|
||||
(SignalClusterView) view.findViewById(R.id.signal_cluster);
|
||||
if (signalCluster != null) {
|
||||
@@ -1297,12 +1317,12 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
ViewGroup viewParent = (ViewGroup) parent;
|
||||
int index = viewParent.indexOfChild(signalCluster);
|
||||
viewParent.removeView(signalCluster);
|
||||
SignalClusterView newCluster = (SignalClusterView) LayoutInflater.from(mContext)
|
||||
SignalClusterView newCluster = (SignalClusterView) LayoutInflater.from(context)
|
||||
.inflate(R.layout.signal_cluster_view, viewParent, false);
|
||||
ViewGroup.MarginLayoutParams layoutParams =
|
||||
(ViewGroup.MarginLayoutParams) viewParent.getLayoutParams();
|
||||
layoutParams.setMarginsRelative(
|
||||
mContext.getResources().getDimensionPixelSize(
|
||||
context.getResources().getDimensionPixelSize(
|
||||
R.dimen.signal_cluster_margin_start),
|
||||
0, 0, 0);
|
||||
newCluster.setLayoutParams(layoutParams);
|
||||
@@ -1426,9 +1446,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
updateNotifications();
|
||||
}
|
||||
// end old BaseStatusBar.setZenMode().
|
||||
if (mIconPolicy != null) {
|
||||
mIconPolicy.setZenMode(mode);
|
||||
}
|
||||
}
|
||||
|
||||
protected void startKeyguard() {
|
||||
@@ -1445,7 +1462,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mKeyguardIndicationController.setUserInfoController(
|
||||
Dependency.get(UserInfoController.class));
|
||||
mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
mIconPolicy.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
|
||||
|
||||
mRemoteInputController.addCallback(new RemoteInputController.Callback() {
|
||||
@@ -1526,16 +1542,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(String slot, StatusBarIcon icon) {
|
||||
mIconController.setIcon(slot, icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIcon(String slot) {
|
||||
mIconController.removeIcon(slot);
|
||||
}
|
||||
|
||||
public UserHandle getCurrentUserHandle() {
|
||||
return new UserHandle(mCurrentUserId);
|
||||
}
|
||||
@@ -1898,7 +1904,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
updateQsExpansionEnabled();
|
||||
|
||||
// Let's also update the icons
|
||||
mIconController.updateNotificationIcons(mNotificationData);
|
||||
mNotificationIconAreaController.updateNotificationIcons(mNotificationData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2079,24 +2085,26 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
hasActiveNotifications() + " clearable=" + clearable);
|
||||
}
|
||||
|
||||
final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
|
||||
final boolean showDot = hasActiveNotifications() && !areLightsOn();
|
||||
if (showDot != (nlo.getAlpha() == 1.0f)) {
|
||||
if (showDot) {
|
||||
nlo.setAlpha(0f);
|
||||
nlo.setVisibility(View.VISIBLE);
|
||||
if (mStatusBarView != null) {
|
||||
final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
|
||||
final boolean showDot = hasActiveNotifications() && !areLightsOn();
|
||||
if (showDot != (nlo.getAlpha() == 1.0f)) {
|
||||
if (showDot) {
|
||||
nlo.setAlpha(0f);
|
||||
nlo.setVisibility(View.VISIBLE);
|
||||
}
|
||||
nlo.animate()
|
||||
.alpha(showDot ? 1 : 0)
|
||||
.setDuration(showDot ? 750 : 250)
|
||||
.setInterpolator(new AccelerateInterpolator(2.0f))
|
||||
.setListener(showDot ? null : new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator _a) {
|
||||
nlo.setVisibility(View.GONE);
|
||||
}
|
||||
})
|
||||
.start();
|
||||
}
|
||||
nlo.animate()
|
||||
.alpha(showDot?1:0)
|
||||
.setDuration(showDot?750:250)
|
||||
.setInterpolator(new AccelerateInterpolator(2.0f))
|
||||
.setListener(showDot ? null : new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator _a) {
|
||||
nlo.setVisibility(View.GONE);
|
||||
}
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
findAndUpdateMediaNotifications();
|
||||
@@ -2420,26 +2428,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
&& mFalsingManager.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE);
|
||||
}
|
||||
|
||||
protected int adjustDisableFlags(int state) {
|
||||
if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway && shouldHideNotificationIcons()) {
|
||||
state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
|
||||
state |= StatusBarManager.DISABLE_SYSTEM_INFO;
|
||||
}
|
||||
if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
|
||||
if (mNetworkController.hasEmergencyCryptKeeperText()) {
|
||||
state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
|
||||
}
|
||||
if (!mNetworkController.isRadioOn()) {
|
||||
state |= StatusBarManager.DISABLE_SYSTEM_INFO;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
private boolean shouldHideNotificationIcons() {
|
||||
return mExpandedVisible && mNotificationPanel.shouldHideNotificationIcons();
|
||||
}
|
||||
|
||||
/**
|
||||
* State is one or more of the DISABLE constants from StatusBarManager.
|
||||
*/
|
||||
@@ -2448,7 +2436,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;
|
||||
mDisabledUnmodified1 = state1;
|
||||
mDisabledUnmodified2 = state2;
|
||||
state1 = adjustDisableFlags(state1);
|
||||
final int old1 = mDisabled1;
|
||||
final int diff1 = state1 ^ old1;
|
||||
mDisabled1 = state1;
|
||||
@@ -2490,28 +2477,13 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
flagdbg.append(">");
|
||||
Log.d(TAG, flagdbg.toString());
|
||||
|
||||
if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
|
||||
if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
|
||||
mIconController.hideSystemIconArea(animate);
|
||||
} else {
|
||||
mIconController.showSystemIconArea(animate);
|
||||
}
|
||||
}
|
||||
|
||||
if ((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) {
|
||||
boolean visible = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
|
||||
mIconController.setClockVisibilityByPolicy(visible);
|
||||
}
|
||||
if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
|
||||
if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
|
||||
animateCollapsePanels();
|
||||
}
|
||||
}
|
||||
|
||||
if ((diff1 & (StatusBarManager.DISABLE_HOME
|
||||
| StatusBarManager.DISABLE_RECENT
|
||||
| StatusBarManager.DISABLE_BACK
|
||||
| StatusBarManager.DISABLE_SEARCH)) != 0) {
|
||||
if ((diff1 & StatusBarManager.DISABLE_RECENT) != 0) {
|
||||
if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
|
||||
// close recents if it's visible
|
||||
mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
|
||||
@@ -2519,14 +2491,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
}
|
||||
|
||||
if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
|
||||
if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
|
||||
mIconController.hideNotificationIconArea(animate);
|
||||
} else {
|
||||
mIconController.showNotificationIconArea(animate);
|
||||
}
|
||||
}
|
||||
|
||||
if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
|
||||
mDisableNotificationAlerts =
|
||||
(state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
|
||||
@@ -2740,10 +2704,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mFalsingManager.onScreenOff();
|
||||
}
|
||||
|
||||
public NotificationShelf getNotificationShelf() {
|
||||
return mNotificationShelf;
|
||||
}
|
||||
|
||||
public NotificationStackScrollLayout getNotificationScrollLayout() {
|
||||
return mStackScroller;
|
||||
}
|
||||
@@ -2757,6 +2717,14 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
updateNotifications();
|
||||
}
|
||||
|
||||
public boolean isLaunchTransitionFadingAway() {
|
||||
return mLaunchTransitionFadingAway;
|
||||
}
|
||||
|
||||
public boolean shouldHideNotificationIcons() {
|
||||
return mNotificationPanel.shouldHideNotificationIcons();
|
||||
}
|
||||
|
||||
/**
|
||||
* All changes to the status bar and notifications funnel through here and are batched.
|
||||
*/
|
||||
@@ -3162,7 +3130,8 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
|
||||
void checkBarModes() {
|
||||
if (mDemoMode) return;
|
||||
checkBarMode(mStatusBarMode, mStatusBarWindowState, getStatusBarTransitions());
|
||||
if (mStatusBarView != null) checkBarMode(mStatusBarMode, mStatusBarWindowState,
|
||||
getStatusBarTransitions());
|
||||
if (mNavigationBar != null) mNavigationBar.checkNavBarModes();
|
||||
mNoAnimationOnNextBarModeChange = false;
|
||||
}
|
||||
@@ -3183,7 +3152,9 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
|
||||
private void finishBarAnimations() {
|
||||
mStatusBarView.getBarTransitions().finishAnimations();
|
||||
if (mStatusBarView != null) {
|
||||
mStatusBarView.getBarTransitions().finishAnimations();
|
||||
}
|
||||
if (mNavigationBar != null) {
|
||||
mNavigationBar.finishBarAnimations();
|
||||
}
|
||||
@@ -3363,8 +3334,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mNotificationData.dump(pw, " ");
|
||||
}
|
||||
|
||||
mIconController.dump(pw);
|
||||
|
||||
if (false) {
|
||||
pw.println("see the logcat for a dump of the views we have created.");
|
||||
// must happen on ui thread
|
||||
@@ -3617,15 +3586,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
updateResources();
|
||||
updateDisplaySize(); // populates mDisplayMetrics
|
||||
// Begin old BaseStatusBar.onConfigurationChanged
|
||||
final float fontScale = newConfig.fontScale;
|
||||
final int density = newConfig.densityDpi;
|
||||
if (density != mDensity || mFontScale != fontScale) {
|
||||
onDensityOrFontScaleChanged();
|
||||
mDensity = density;
|
||||
mFontScale = fontScale;
|
||||
}
|
||||
// End old BaseStatusBar.onConfigurationChanged
|
||||
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
|
||||
@@ -3946,17 +3906,12 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mContext.unregisterReceiver(mDemoReceiver);
|
||||
mAssistManager.destroy();
|
||||
|
||||
final SignalClusterView signalCluster =
|
||||
(SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
|
||||
final SignalClusterView signalClusterKeyguard =
|
||||
(SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
|
||||
final SignalClusterView signalClusterQs =
|
||||
(SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
|
||||
if (mQSPanel != null && mQSPanel.getHost() != null) {
|
||||
mQSPanel.getHost().destroy();
|
||||
}
|
||||
Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(null);
|
||||
mDeviceProvisionedController.removeCallback(mUserSetupObserver);
|
||||
Dependency.get(ConfigurationController.class).removeCallback(mDensityChangeListener);
|
||||
}
|
||||
|
||||
private boolean mDemoModeAllowed;
|
||||
@@ -3989,7 +3944,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mBatteryController.dispatchDemoCommand(command, args);
|
||||
}
|
||||
if (modeChange || command.equals(COMMAND_STATUS)) {
|
||||
mIconController.dispatchDemoCommand(command, args);
|
||||
((StatusBarIconControllerImpl) mIconController).dispatchDemoCommand(command, args);
|
||||
}
|
||||
if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
|
||||
mNetworkController.dispatchDemoCommand(command, args);
|
||||
@@ -4132,14 +4087,8 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
onLaunchTransitionFadingEnded();
|
||||
}
|
||||
});
|
||||
mIconController.getTransitionsController().appTransitionStarting(
|
||||
SystemClock.uptimeMillis(),
|
||||
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION);
|
||||
if (mNavigationBar != null) {
|
||||
mNavigationBar.doAppTransitionStarting(
|
||||
SystemClock.uptimeMillis(),
|
||||
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION);
|
||||
}
|
||||
mCommandQueue.appTransitionStarting(SystemClock.uptimeMillis(),
|
||||
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
|
||||
}
|
||||
};
|
||||
if (mNotificationPanel.isLaunchTransitionRunning()) {
|
||||
@@ -4264,11 +4213,8 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
// Treat Keyguard exit animation as an app transition to achieve nice transition for status
|
||||
// bar.
|
||||
mKeyguardGoingAway = true;
|
||||
mIconController.getTransitionsController().appTransitionPending();
|
||||
if (mNavigationBar != null) {
|
||||
mNavigationBar.setKeyguardGoingAway(true);
|
||||
mNavigationBar.appTransitionPending();
|
||||
}
|
||||
mKeyguardMonitor.notifyKeyguardGoingAway(true);
|
||||
mCommandQueue.appTransitionPending(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4283,16 +4229,14 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mKeyguardFadingAwayDelay = delay;
|
||||
mKeyguardFadingAwayDuration = fadeoutDuration;
|
||||
mWaitingForKeyguardExit = false;
|
||||
mIconController.getTransitionsController().appTransitionStarting(
|
||||
startTime + fadeoutDuration
|
||||
mCommandQueue.appTransitionStarting(startTime + fadeoutDuration
|
||||
- LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
|
||||
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION);
|
||||
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
|
||||
recomputeDisableFlags(fadeoutDuration > 0 /* animate */);
|
||||
if (mNavigationBar != null) {
|
||||
mNavigationBar.doAppTransitionStarting(
|
||||
mCommandQueue.appTransitionStarting(
|
||||
startTime - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
|
||||
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION);
|
||||
}
|
||||
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
|
||||
mKeyguardMonitor.notifyKeyguardFadingAway(delay, fadeoutDuration);
|
||||
}
|
||||
|
||||
public boolean isKeyguardFadingAway() {
|
||||
@@ -4305,9 +4249,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
public void finishKeyguardFadingAway() {
|
||||
mKeyguardFadingAway = false;
|
||||
mKeyguardGoingAway = false;
|
||||
if (mNavigationBar != null) {
|
||||
mNavigationBar.setKeyguardGoingAway(false);
|
||||
}
|
||||
mKeyguardMonitor.notifyKeyguardDoneFading();
|
||||
}
|
||||
|
||||
public void stopWaitingForKeyguardExit() {
|
||||
@@ -4357,7 +4299,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
} else {
|
||||
mScrimController.setKeyguardShowing(false);
|
||||
}
|
||||
mIconPolicy.notifyKeyguardShowingChanged();
|
||||
mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
|
||||
updateDozingState();
|
||||
updatePublicMode();
|
||||
@@ -4944,33 +4885,11 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appTransitionPending() {
|
||||
// Use own timings when Keyguard is going away, see keyguardGoingAway and
|
||||
// setKeyguardFadingAway
|
||||
if (!mKeyguardFadingAway) {
|
||||
mIconController.getTransitionsController().appTransitionPending();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appTransitionCancelled() {
|
||||
mIconController.getTransitionsController().appTransitionCancelled();
|
||||
EventBus.getDefault().send(new AppTransitionFinishedEvent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appTransitionStarting(long startTime, long duration) {
|
||||
// Use own timings when Keyguard is going away, see keyguardGoingAway and
|
||||
// setKeyguardFadingAway.
|
||||
if (!mKeyguardGoingAway) {
|
||||
mIconController.getTransitionsController().appTransitionStarting(startTime, duration);
|
||||
}
|
||||
if (mIconPolicy != null) {
|
||||
mIconPolicy.appTransitionStarting(startTime, duration);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appTransitionFinished() {
|
||||
EventBus.getDefault().send(new AppTransitionFinishedEvent());
|
||||
@@ -5180,7 +5099,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
private boolean mVisibleToUser;
|
||||
|
||||
private Locale mLocale;
|
||||
private float mFontScale;
|
||||
|
||||
protected boolean mUseHeadsUp = false;
|
||||
protected boolean mHeadsUpTicker = false;
|
||||
@@ -5197,7 +5115,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
|
||||
|
||||
private UserManager mUserManager;
|
||||
private int mDensity;
|
||||
|
||||
protected KeyguardManager mKeyguardManager;
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
|
||||
@@ -1,502 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2017 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
|
||||
* 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
|
||||
* 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.phone;
|
||||
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.statusbar.StatusBarIcon;
|
||||
import com.android.systemui.BatteryMeterView;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.FontSizeUtils;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SystemUIFactory;
|
||||
import com.android.systemui.statusbar.NotificationData;
|
||||
import com.android.systemui.statusbar.NotificationShelf;
|
||||
import com.android.systemui.statusbar.SignalClusterView;
|
||||
import com.android.systemui.statusbar.StatusBarIconView;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
public interface StatusBarIconController {
|
||||
|
||||
/**
|
||||
* Controls everything regarding the icons in the status bar and on Keyguard, including, but not
|
||||
* limited to: notification icons, signal cluster, additional status icons, and clock in the status
|
||||
* bar.
|
||||
*/
|
||||
public class StatusBarIconController extends StatusBarIconList implements Tunable {
|
||||
public void addIconGroup(IconManager iconManager);
|
||||
public void removeIconGroup(IconManager iconManager);
|
||||
public void setExternalIcon(String slot);
|
||||
public void setIcon(String slot, int resourceId, CharSequence contentDescription);
|
||||
public void setIcon(String slot, StatusBarIcon icon);
|
||||
public void setIconVisibility(String slotTty, boolean b);
|
||||
public void removeIcon(String slot);
|
||||
|
||||
public static final String ICON_BLACKLIST = "icon_blacklist";
|
||||
public static final int DEFAULT_ICON_TINT = Color.WHITE;
|
||||
|
||||
private Context mContext;
|
||||
private StatusBar mStatusBar;
|
||||
private DemoStatusIcons mDemoStatusIcons;
|
||||
|
||||
private LinearLayout mSystemIconArea;
|
||||
private LinearLayout mStatusIcons;
|
||||
private SignalClusterView mSignalCluster;
|
||||
private LinearLayout mStatusIconsKeyguard;
|
||||
|
||||
private NotificationIconAreaController mNotificationIconAreaController;
|
||||
private View mNotificationIconAreaInner;
|
||||
private NotificationShelf mNotificationShelf;
|
||||
|
||||
private BatteryMeterView mBatteryMeterView;
|
||||
private BatteryMeterView mBatteryMeterViewKeyguard;
|
||||
private TextView mClock;
|
||||
|
||||
private int mIconSize;
|
||||
private int mIconHPadding;
|
||||
|
||||
private int mIconTint = DEFAULT_ICON_TINT;
|
||||
private float mDarkIntensity;
|
||||
private final Rect mTintArea = new Rect();
|
||||
private static final Rect sTmpRect = new Rect();
|
||||
private static final int[] sTmpInt2 = new int[2];
|
||||
|
||||
private int mDarkModeIconColorSingleTone;
|
||||
private int mLightModeIconColorSingleTone;
|
||||
|
||||
private final LightBarTransitionsController mTransitionsController;
|
||||
|
||||
private boolean mClockVisibleByPolicy = true;
|
||||
private boolean mClockVisibleByUser = true;
|
||||
|
||||
private final ArraySet<String> mIconBlacklist = new ArraySet<>();
|
||||
|
||||
public StatusBarIconController(Context context, View statusBar, View keyguardStatusBar,
|
||||
StatusBar phoneStatusBar) {
|
||||
super(context.getResources().getStringArray(
|
||||
com.android.internal.R.array.config_statusBarIcons));
|
||||
mContext = context;
|
||||
mStatusBar = phoneStatusBar;
|
||||
mSystemIconArea = (LinearLayout) statusBar.findViewById(R.id.system_icon_area);
|
||||
mStatusIcons = (LinearLayout) statusBar.findViewById(R.id.statusIcons);
|
||||
mSignalCluster = (SignalClusterView) statusBar.findViewById(R.id.signal_cluster);
|
||||
|
||||
mNotificationShelf = phoneStatusBar.getNotificationShelf();
|
||||
mNotificationIconAreaController = SystemUIFactory.getInstance()
|
||||
.createNotificationIconAreaController(context, phoneStatusBar);
|
||||
mNotificationIconAreaInner =
|
||||
mNotificationIconAreaController.getNotificationInnerAreaView();
|
||||
|
||||
ViewGroup notificationIconArea =
|
||||
(ViewGroup) statusBar.findViewById(R.id.notification_icon_area);
|
||||
notificationIconArea.addView(mNotificationIconAreaInner);
|
||||
|
||||
mStatusIconsKeyguard = (LinearLayout) keyguardStatusBar.findViewById(R.id.statusIcons);
|
||||
|
||||
mBatteryMeterView = (BatteryMeterView) statusBar.findViewById(R.id.battery);
|
||||
mBatteryMeterViewKeyguard = (BatteryMeterView) keyguardStatusBar.findViewById(R.id.battery);
|
||||
scaleBatteryMeterViews(context);
|
||||
|
||||
mClock = (TextView) statusBar.findViewById(R.id.clock);
|
||||
mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone);
|
||||
mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone);
|
||||
loadDimens();
|
||||
|
||||
Dependency.get(TunerService.class).addTunable(this, ICON_BLACKLIST);
|
||||
|
||||
mTransitionsController = new LightBarTransitionsController(this::setIconTintInternal);
|
||||
}
|
||||
|
||||
public void setSignalCluster(SignalClusterView signalCluster) {
|
||||
mSignalCluster = signalCluster;
|
||||
}
|
||||
|
||||
public LightBarTransitionsController getTransitionsController() {
|
||||
return mTransitionsController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the scale factor for status bar icons and scales the battery view by that amount.
|
||||
*/
|
||||
private void scaleBatteryMeterViews(Context context) {
|
||||
Resources res = context.getResources();
|
||||
TypedValue typedValue = new TypedValue();
|
||||
|
||||
res.getValue(R.dimen.status_bar_icon_scale_factor, typedValue, true);
|
||||
float iconScaleFactor = typedValue.getFloat();
|
||||
|
||||
int batteryHeight = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_height);
|
||||
int batteryWidth = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_width);
|
||||
int marginBottom = res.getDimensionPixelSize(R.dimen.battery_margin_bottom);
|
||||
|
||||
LinearLayout.LayoutParams scaledLayoutParams = new LinearLayout.LayoutParams(
|
||||
(int) (batteryWidth * iconScaleFactor), (int) (batteryHeight * iconScaleFactor));
|
||||
scaledLayoutParams.setMarginsRelative(0, 0, 0, marginBottom);
|
||||
|
||||
mBatteryMeterView.setLayoutParams(scaledLayoutParams);
|
||||
mBatteryMeterViewKeyguard.setLayoutParams(scaledLayoutParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (!ICON_BLACKLIST.equals(key)) {
|
||||
return;
|
||||
}
|
||||
mIconBlacklist.clear();
|
||||
mIconBlacklist.addAll(getIconBlacklist(newValue));
|
||||
ArrayList<StatusBarIconView> views = new ArrayList<StatusBarIconView>();
|
||||
// Get all the current views.
|
||||
for (int i = 0; i < mStatusIcons.getChildCount(); i++) {
|
||||
views.add((StatusBarIconView) mStatusIcons.getChildAt(i));
|
||||
}
|
||||
// Remove all the icons.
|
||||
for (int i = views.size() - 1; i >= 0; i--) {
|
||||
removeIcon(views.get(i).getSlot());
|
||||
}
|
||||
// Add them all back
|
||||
for (int i = 0; i < views.size(); i++) {
|
||||
setIcon(views.get(i).getSlot(), views.get(i).getStatusBarIcon());
|
||||
}
|
||||
|
||||
setClockVisibleByUser(!StatusBarIconController.getIconBlacklist(newValue)
|
||||
.contains("clock"));
|
||||
updateClockVisibility();
|
||||
}
|
||||
private void loadDimens() {
|
||||
mIconSize = mContext.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.status_bar_icon_size);
|
||||
mIconHPadding = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.status_bar_icon_padding);
|
||||
}
|
||||
|
||||
private void addSystemIcon(int index, StatusBarIcon icon) {
|
||||
String slot = getSlot(index);
|
||||
int viewIndex = getViewIndex(index);
|
||||
boolean blocked = mIconBlacklist.contains(slot);
|
||||
StatusBarIconView view = new StatusBarIconView(mContext, slot, null, blocked);
|
||||
view.set(icon);
|
||||
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
|
||||
lp.setMargins(mIconHPadding, 0, mIconHPadding, 0);
|
||||
mStatusIcons.addView(view, viewIndex, lp);
|
||||
|
||||
view = new StatusBarIconView(mContext, slot, null, blocked);
|
||||
view.set(icon);
|
||||
mStatusIconsKeyguard.addView(view, viewIndex, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
|
||||
applyIconTint();
|
||||
}
|
||||
|
||||
public void setIcon(String slot, int resourceId, CharSequence contentDescription) {
|
||||
int index = getSlotIndex(slot);
|
||||
StatusBarIcon icon = getIcon(index);
|
||||
if (icon == null) {
|
||||
icon = new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
|
||||
Icon.createWithResource(mContext, resourceId), 0, 0, contentDescription);
|
||||
setIcon(slot, icon);
|
||||
} else {
|
||||
icon.icon = Icon.createWithResource(mContext, resourceId);
|
||||
icon.contentDescription = contentDescription;
|
||||
handleSet(index, icon);
|
||||
}
|
||||
}
|
||||
|
||||
public void setExternalIcon(String slot) {
|
||||
int viewIndex = getViewIndex(getSlotIndex(slot));
|
||||
int height = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.status_bar_icon_drawing_size);
|
||||
ImageView imageView = (ImageView) mStatusIcons.getChildAt(viewIndex);
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
imageView.setAdjustViewBounds(true);
|
||||
setHeightAndCenter(imageView, height);
|
||||
imageView = (ImageView) mStatusIconsKeyguard.getChildAt(viewIndex);
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
imageView.setAdjustViewBounds(true);
|
||||
setHeightAndCenter(imageView, height);
|
||||
}
|
||||
|
||||
private void setHeightAndCenter(ImageView imageView, int height) {
|
||||
ViewGroup.LayoutParams params = imageView.getLayoutParams();
|
||||
params.height = height;
|
||||
if (params instanceof LinearLayout.LayoutParams) {
|
||||
((LinearLayout.LayoutParams) params).gravity = Gravity.CENTER_VERTICAL;
|
||||
}
|
||||
imageView.setLayoutParams(params);
|
||||
}
|
||||
|
||||
public void setIcon(String slot, StatusBarIcon icon) {
|
||||
setIcon(getSlotIndex(slot), icon);
|
||||
}
|
||||
|
||||
public void removeIcon(String slot) {
|
||||
int index = getSlotIndex(slot);
|
||||
removeIcon(index);
|
||||
}
|
||||
|
||||
public void setIconVisibility(String slot, boolean visibility) {
|
||||
int index = getSlotIndex(slot);
|
||||
StatusBarIcon icon = getIcon(index);
|
||||
if (icon == null || icon.visible == visibility) {
|
||||
return;
|
||||
}
|
||||
icon.visible = visibility;
|
||||
handleSet(index, icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIcon(int index) {
|
||||
if (getIcon(index) == null) {
|
||||
return;
|
||||
}
|
||||
super.removeIcon(index);
|
||||
int viewIndex = getViewIndex(index);
|
||||
mStatusIcons.removeViewAt(viewIndex);
|
||||
mStatusIconsKeyguard.removeViewAt(viewIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(int index, StatusBarIcon icon) {
|
||||
if (icon == null) {
|
||||
removeIcon(index);
|
||||
return;
|
||||
}
|
||||
boolean isNew = getIcon(index) == null;
|
||||
super.setIcon(index, icon);
|
||||
if (isNew) {
|
||||
addSystemIcon(index, icon);
|
||||
} else {
|
||||
handleSet(index, icon);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSet(int index, StatusBarIcon icon) {
|
||||
int viewIndex = getViewIndex(index);
|
||||
StatusBarIconView view = (StatusBarIconView) mStatusIcons.getChildAt(viewIndex);
|
||||
view.set(icon);
|
||||
view = (StatusBarIconView) mStatusIconsKeyguard.getChildAt(viewIndex);
|
||||
view.set(icon);
|
||||
applyIconTint();
|
||||
}
|
||||
|
||||
public void updateNotificationIcons(NotificationData notificationData) {
|
||||
mNotificationIconAreaController.updateNotificationIcons(notificationData);
|
||||
}
|
||||
|
||||
public void hideSystemIconArea(boolean animate) {
|
||||
animateHide(mSystemIconArea, animate);
|
||||
}
|
||||
|
||||
public void showSystemIconArea(boolean animate) {
|
||||
animateShow(mSystemIconArea, animate);
|
||||
}
|
||||
|
||||
public void hideNotificationIconArea(boolean animate) {
|
||||
animateHide(mNotificationIconAreaInner, animate);
|
||||
}
|
||||
|
||||
public void showNotificationIconArea(boolean animate) {
|
||||
animateShow(mNotificationIconAreaInner, animate);
|
||||
}
|
||||
|
||||
public void setClockVisibleByUser(boolean visible) {
|
||||
mClockVisibleByUser = visible;
|
||||
updateClockVisibility();
|
||||
}
|
||||
|
||||
public void setClockVisibilityByPolicy(boolean visible) {
|
||||
mClockVisibleByPolicy = visible;
|
||||
updateClockVisibility();
|
||||
}
|
||||
|
||||
private void updateClockVisibility() {
|
||||
int visibility = (mClockVisibleByPolicy && mClockVisibleByUser)
|
||||
? View.VISIBLE : View.GONE;
|
||||
mClock.setVisibility(visibility);
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
int N = mStatusIcons.getChildCount();
|
||||
pw.println(" icon views: " + N);
|
||||
for (int i=0; i<N; i++) {
|
||||
StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
|
||||
pw.println(" [" + i + "] icon=" + ic);
|
||||
}
|
||||
super.dump(pw);
|
||||
}
|
||||
|
||||
public void dispatchDemoCommand(String command, Bundle args) {
|
||||
if (mDemoStatusIcons == null) {
|
||||
mDemoStatusIcons = new DemoStatusIcons(mStatusIcons, mIconSize);
|
||||
}
|
||||
mDemoStatusIcons.dispatchDemoCommand(command, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides a view.
|
||||
*/
|
||||
private void animateHide(final View v, boolean animate) {
|
||||
v.animate().cancel();
|
||||
if (!animate) {
|
||||
v.setAlpha(0f);
|
||||
v.setVisibility(View.INVISIBLE);
|
||||
return;
|
||||
}
|
||||
v.animate()
|
||||
.alpha(0f)
|
||||
.setDuration(160)
|
||||
.setStartDelay(0)
|
||||
.setInterpolator(Interpolators.ALPHA_OUT)
|
||||
.withEndAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
v.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a view, and synchronizes the animation with Keyguard exit animations, if applicable.
|
||||
*/
|
||||
private void animateShow(View v, boolean animate) {
|
||||
v.animate().cancel();
|
||||
v.setVisibility(View.VISIBLE);
|
||||
if (!animate) {
|
||||
v.setAlpha(1f);
|
||||
return;
|
||||
}
|
||||
v.animate()
|
||||
.alpha(1f)
|
||||
.setDuration(320)
|
||||
.setInterpolator(Interpolators.ALPHA_IN)
|
||||
.setStartDelay(50)
|
||||
|
||||
// We need to clean up any pending end action from animateHide if we call
|
||||
// both hide and show in the same frame before the animation actually gets started.
|
||||
// cancel() doesn't really remove the end action.
|
||||
.withEndAction(null);
|
||||
|
||||
// Synchronize the motion with the Keyguard fading if necessary.
|
||||
if (mStatusBar.isKeyguardFadingAway()) {
|
||||
v.animate()
|
||||
.setDuration(mStatusBar.getKeyguardFadingAwayDuration())
|
||||
.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
|
||||
.setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dark area so {@link #setIconsDark} only affects the icons in the specified area.
|
||||
*
|
||||
* @param darkArea the area in which icons should change it's tint, in logical screen
|
||||
* coordinates
|
||||
*/
|
||||
public void setIconsDarkArea(Rect darkArea) {
|
||||
if (darkArea == null && mTintArea.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (darkArea == null) {
|
||||
mTintArea.setEmpty();
|
||||
} else {
|
||||
mTintArea.set(darkArea);
|
||||
}
|
||||
applyIconTint();
|
||||
mNotificationIconAreaController.setTintArea(darkArea);
|
||||
}
|
||||
|
||||
private void setIconTintInternal(float darkIntensity) {
|
||||
mDarkIntensity = darkIntensity;
|
||||
mIconTint = (int) ArgbEvaluator.getInstance().evaluate(darkIntensity,
|
||||
mLightModeIconColorSingleTone, mDarkModeIconColorSingleTone);
|
||||
mNotificationIconAreaController.setIconTint(mIconTint);
|
||||
applyIconTint();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tint to apply to {@param view} depending on the desired tint {@param color} and
|
||||
* the screen {@param tintArea} in which to apply that tint
|
||||
*/
|
||||
public static int getTint(Rect tintArea, View view, int color) {
|
||||
if (isInArea(tintArea, view)) {
|
||||
return color;
|
||||
} else {
|
||||
return DEFAULT_ICON_TINT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dark intensity to apply to {@param view} depending on the desired dark
|
||||
* {@param intensity} and the screen {@param tintArea} in which to apply that intensity
|
||||
*/
|
||||
public static float getDarkIntensity(Rect tintArea, View view, float intensity) {
|
||||
if (isInArea(tintArea, view)) {
|
||||
return intensity;
|
||||
} else {
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if more than half of the {@param view} area are in {@param area}, false
|
||||
* otherwise
|
||||
*/
|
||||
private static boolean isInArea(Rect area, View view) {
|
||||
if (area.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
sTmpRect.set(area);
|
||||
view.getLocationOnScreen(sTmpInt2);
|
||||
int left = sTmpInt2[0];
|
||||
|
||||
int intersectStart = Math.max(left, area.left);
|
||||
int intersectEnd = Math.min(left + view.getWidth(), area.right);
|
||||
int intersectAmount = Math.max(0, intersectEnd - intersectStart);
|
||||
|
||||
boolean coversFullStatusBar = area.top <= 0;
|
||||
boolean majorityOfWidth = 2 * intersectAmount > view.getWidth();
|
||||
return majorityOfWidth && coversFullStatusBar;
|
||||
}
|
||||
|
||||
private void applyIconTint() {
|
||||
for (int i = 0; i < mStatusIcons.getChildCount(); i++) {
|
||||
StatusBarIconView v = (StatusBarIconView) mStatusIcons.getChildAt(i);
|
||||
v.setImageTintList(ColorStateList.valueOf(getTint(mTintArea, v, mIconTint)));
|
||||
}
|
||||
mSignalCluster.setIconTint(mIconTint, mDarkIntensity, mTintArea);
|
||||
mBatteryMeterView.setDarkIntensity(
|
||||
isInArea(mTintArea, mBatteryMeterView) ? mDarkIntensity : 0);
|
||||
mClock.setTextColor(getTint(mTintArea, mClock, mIconTint));
|
||||
}
|
||||
|
||||
public static ArraySet<String> getIconBlacklist(String blackListStr) {
|
||||
ArraySet<String> ret = new ArraySet<String>();
|
||||
ArraySet<String> ret = new ArraySet<>();
|
||||
if (blackListStr == null) {
|
||||
blackListStr = "rotate,headset";
|
||||
}
|
||||
@@ -509,34 +55,110 @@ public class StatusBarIconController extends StatusBarIconList implements Tunabl
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
loadDimens();
|
||||
mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
|
||||
updateClock();
|
||||
for (int i = 0; i < mStatusIcons.getChildCount(); i++) {
|
||||
View child = mStatusIcons.getChildAt(i);
|
||||
|
||||
/**
|
||||
* Version of ViewGroup that observers state from the DarkIconDispatcher.
|
||||
*/
|
||||
public static class DarkIconManager extends IconManager {
|
||||
private final DarkIconDispatcher mDarkIconDispatcher;
|
||||
private int mIconHPadding;
|
||||
|
||||
public DarkIconManager(LinearLayout linearLayout) {
|
||||
super(linearLayout);
|
||||
mIconHPadding = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.status_bar_icon_padding);
|
||||
mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onIconAdded(int index, String slot, boolean blocked, StatusBarIcon icon) {
|
||||
StatusBarIconView view = new StatusBarIconView(mContext, slot, null, blocked);
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
|
||||
lp.setMargins(mIconHPadding, 0, mIconHPadding, 0);
|
||||
child.setLayoutParams(lp);
|
||||
mGroup.addView(view, index, lp);
|
||||
mDarkIconDispatcher.addDarkReceiver(view);
|
||||
}
|
||||
for (int i = 0; i < mStatusIconsKeyguard.getChildCount(); i++) {
|
||||
View child = mStatusIconsKeyguard.getChildAt(i);
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
|
||||
child.setLayoutParams(lp);
|
||||
|
||||
@Override
|
||||
protected void destroy() {
|
||||
for (int i = 0; i < mGroup.getChildCount(); i++) {
|
||||
mDarkIconDispatcher.removeDarkReceiver((ImageView) mGroup.getChildAt(i));
|
||||
}
|
||||
mGroup.removeAllViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemoveIcon(int viewIndex) {
|
||||
mDarkIconDispatcher.removeDarkReceiver((ImageView) mGroup.getChildAt(viewIndex));
|
||||
super.onRemoveIcon(viewIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetIcon(int viewIndex, StatusBarIcon icon) {
|
||||
super.onSetIcon(viewIndex, icon);
|
||||
mDarkIconDispatcher.applyDark((ImageView) mGroup.getChildAt(viewIndex));
|
||||
}
|
||||
scaleBatteryMeterViews(mContext);
|
||||
}
|
||||
|
||||
private void updateClock() {
|
||||
FontSizeUtils.updateFontSize(mClock, R.dimen.status_bar_clock_size);
|
||||
mClock.setPaddingRelative(
|
||||
mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.status_bar_clock_starting_padding),
|
||||
0,
|
||||
mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.status_bar_clock_end_padding),
|
||||
0);
|
||||
/**
|
||||
* Turns info from StatusBarIconController into ImageViews in a ViewGroup.
|
||||
*/
|
||||
public static class IconManager {
|
||||
protected final ViewGroup mGroup;
|
||||
protected final Context mContext;
|
||||
protected final int mIconSize;
|
||||
|
||||
public IconManager(ViewGroup group) {
|
||||
mGroup = group;
|
||||
mContext = group.getContext();
|
||||
mIconSize = mContext.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.status_bar_icon_size);
|
||||
}
|
||||
|
||||
protected void onIconAdded(int index, String slot, boolean blocked, StatusBarIcon icon) {
|
||||
StatusBarIconView view = new StatusBarIconView(mContext, slot, null, blocked);
|
||||
view.set(icon);
|
||||
mGroup.addView(view, index, new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
|
||||
}
|
||||
|
||||
protected void destroy() {
|
||||
mGroup.removeAllViews();
|
||||
}
|
||||
|
||||
protected void onIconExternal(int viewIndex, int height) {
|
||||
ImageView imageView = (ImageView) mGroup.getChildAt(viewIndex);
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
imageView.setAdjustViewBounds(true);
|
||||
setHeightAndCenter(imageView, height);
|
||||
}
|
||||
|
||||
protected void onDensityOrFontScaleChanged() {
|
||||
for (int i = 0; i < mGroup.getChildCount(); i++) {
|
||||
View child = mGroup.getChildAt(i);
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
|
||||
child.setLayoutParams(lp);
|
||||
}
|
||||
}
|
||||
|
||||
private void setHeightAndCenter(ImageView imageView, int height) {
|
||||
ViewGroup.LayoutParams params = imageView.getLayoutParams();
|
||||
params.height = height;
|
||||
if (params instanceof LinearLayout.LayoutParams) {
|
||||
((LinearLayout.LayoutParams) params).gravity = Gravity.CENTER_VERTICAL;
|
||||
}
|
||||
imageView.setLayoutParams(params);
|
||||
}
|
||||
|
||||
protected void onRemoveIcon(int viewIndex) {
|
||||
mGroup.removeViewAt(viewIndex);
|
||||
}
|
||||
|
||||
public void onSetIcon(int viewIndex, StatusBarIcon icon) {
|
||||
StatusBarIconView view = (StatusBarIconView) mGroup.getChildAt(viewIndex);
|
||||
view.set(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.phone;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.internal.statusbar.StatusBarIcon;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.StatusBarIconView;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Receives the callbacks from CommandQueue related to icons and tracks the state of
|
||||
* all the icons. Dispatches this state to any IconManagers that are currently
|
||||
* registered with it.
|
||||
*/
|
||||
public class StatusBarIconControllerImpl extends StatusBarIconList implements Tunable,
|
||||
ConfigurationListener, Dumpable, CommandQueue.Callbacks, StatusBarIconController {
|
||||
|
||||
private final DarkIconDispatcher mDarkIconDispatcher;
|
||||
|
||||
private Context mContext;
|
||||
private DemoStatusIcons mDemoStatusIcons;
|
||||
|
||||
private final ArrayList<IconManager> mIconGroups = new ArrayList<>();
|
||||
|
||||
private final ArraySet<String> mIconBlacklist = new ArraySet<>();
|
||||
|
||||
public StatusBarIconControllerImpl(Context context) {
|
||||
super(context.getResources().getStringArray(
|
||||
com.android.internal.R.array.config_statusBarIcons));
|
||||
Dependency.get(ConfigurationController.class).addCallback(this);
|
||||
mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
|
||||
mContext = context;
|
||||
|
||||
loadDimens();
|
||||
|
||||
SysUiServiceProvider.getComponent(context, CommandQueue.class)
|
||||
.addCallbacks(this);
|
||||
Dependency.get(TunerService.class).addTunable(this, ICON_BLACKLIST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIconGroup(IconManager group) {
|
||||
mIconGroups.add(group);
|
||||
for (int i = 0; i < mIcons.size(); i++) {
|
||||
StatusBarIcon icon = mIcons.get(i);
|
||||
if (icon != null) {
|
||||
String slot = mSlots.get(i);
|
||||
boolean blocked = mIconBlacklist.contains(slot);
|
||||
group.onIconAdded(getViewIndex(getSlotIndex(slot)), slot, blocked, icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIconGroup(IconManager group) {
|
||||
group.destroy();
|
||||
mIconGroups.remove(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (!ICON_BLACKLIST.equals(key)) {
|
||||
return;
|
||||
}
|
||||
mIconBlacklist.clear();
|
||||
mIconBlacklist.addAll(StatusBarIconController.getIconBlacklist(newValue));
|
||||
ArrayList<StatusBarIcon> current = new ArrayList<>(mIcons);
|
||||
ArrayList<String> currentSlots = new ArrayList<>(mSlots);
|
||||
// Remove all the icons.
|
||||
for (int i = current.size() - 1; i >= 0; i--) {
|
||||
removeIcon(currentSlots.get(i));
|
||||
}
|
||||
// Add them all back
|
||||
for (int i = 0; i < current.size(); i++) {
|
||||
setIcon(currentSlots.get(i), current.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
private void loadDimens() {
|
||||
}
|
||||
|
||||
private void addSystemIcon(int index, StatusBarIcon icon) {
|
||||
String slot = getSlot(index);
|
||||
int viewIndex = getViewIndex(index);
|
||||
boolean blocked = mIconBlacklist.contains(slot);
|
||||
|
||||
mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, blocked, icon));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(String slot, int resourceId, CharSequence contentDescription) {
|
||||
int index = getSlotIndex(slot);
|
||||
StatusBarIcon icon = getIcon(index);
|
||||
if (icon == null) {
|
||||
icon = new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
|
||||
Icon.createWithResource(mContext, resourceId), 0, 0, contentDescription);
|
||||
setIcon(slot, icon);
|
||||
} else {
|
||||
icon.icon = Icon.createWithResource(mContext, resourceId);
|
||||
icon.contentDescription = contentDescription;
|
||||
handleSet(index, icon);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExternalIcon(String slot) {
|
||||
int viewIndex = getViewIndex(getSlotIndex(slot));
|
||||
int height = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.status_bar_icon_drawing_size);
|
||||
mIconGroups.forEach(l -> l.onIconExternal(viewIndex, height));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(String slot, StatusBarIcon icon) {
|
||||
setIcon(getSlotIndex(slot), icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIcon(String slot) {
|
||||
int index = getSlotIndex(slot);
|
||||
removeIcon(index);
|
||||
}
|
||||
|
||||
public void setIconVisibility(String slot, boolean visibility) {
|
||||
int index = getSlotIndex(slot);
|
||||
StatusBarIcon icon = getIcon(index);
|
||||
if (icon == null || icon.visible == visibility) {
|
||||
return;
|
||||
}
|
||||
icon.visible = visibility;
|
||||
handleSet(index, icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIcon(int index) {
|
||||
if (getIcon(index) == null) {
|
||||
return;
|
||||
}
|
||||
super.removeIcon(index);
|
||||
int viewIndex = getViewIndex(index);
|
||||
mIconGroups.forEach(l -> l.onRemoveIcon(viewIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(int index, StatusBarIcon icon) {
|
||||
if (icon == null) {
|
||||
removeIcon(index);
|
||||
return;
|
||||
}
|
||||
boolean isNew = getIcon(index) == null;
|
||||
super.setIcon(index, icon);
|
||||
if (isNew) {
|
||||
addSystemIcon(index, icon);
|
||||
} else {
|
||||
handleSet(index, icon);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSet(int index, StatusBarIcon icon) {
|
||||
int viewIndex = getViewIndex(index);
|
||||
mIconGroups.forEach(l -> l.onSetIcon(viewIndex, icon));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
// TODO: Dump info about all icon groups?
|
||||
ViewGroup statusIcons = mIconGroups.get(0).mGroup;
|
||||
int N = statusIcons.getChildCount();
|
||||
pw.println(" icon views: " + N);
|
||||
for (int i = 0; i < N; i++) {
|
||||
StatusBarIconView ic = (StatusBarIconView) statusIcons.getChildAt(i);
|
||||
pw.println(" [" + i + "] icon=" + ic);
|
||||
}
|
||||
super.dump(pw);
|
||||
}
|
||||
|
||||
public void dispatchDemoCommand(String command, Bundle args) {
|
||||
if (mDemoStatusIcons == null) {
|
||||
// TODO: Rework how we handle demo mode.
|
||||
int iconSize = mContext.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.status_bar_icon_size);
|
||||
mDemoStatusIcons = new DemoStatusIcons((LinearLayout) mIconGroups.get(0).mGroup,
|
||||
iconSize);
|
||||
}
|
||||
mDemoStatusIcons.dispatchDemoCommand(command, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
loadDimens();
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,8 @@ import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class StatusBarIconList {
|
||||
private ArrayList<String> mSlots = new ArrayList<>();
|
||||
private ArrayList<StatusBarIcon> mIcons = new ArrayList<>();
|
||||
protected ArrayList<String> mSlots = new ArrayList<>();
|
||||
protected ArrayList<StatusBarIcon> mIcons = new ArrayList<>();
|
||||
|
||||
public StatusBarIconList(String[] slots) {
|
||||
final int N = slots.length;
|
||||
|
||||
@@ -19,11 +19,14 @@ package com.android.systemui.statusbar.policy;
|
||||
import libcore.icu.LocaleData;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.StatusBarManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
@@ -35,12 +38,18 @@ import android.text.style.CharacterStyle;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Display;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.DemoMode;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.FontSizeUtils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
|
||||
@@ -52,10 +61,14 @@ import java.util.TimeZone;
|
||||
/**
|
||||
* Digital clock for the status bar.
|
||||
*/
|
||||
public class Clock extends TextView implements DemoMode, Tunable {
|
||||
public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.Callbacks,
|
||||
DarkReceiver, ConfigurationListener {
|
||||
|
||||
public static final String CLOCK_SECONDS = "clock_seconds";
|
||||
|
||||
private boolean mClockVisibleByPolicy = true;
|
||||
private boolean mClockVisibleByUser = true;
|
||||
|
||||
private boolean mAttached;
|
||||
private Calendar mCalendar;
|
||||
private String mClockFormatString;
|
||||
@@ -110,6 +123,8 @@ public class Clock extends TextView implements DemoMode, Tunable {
|
||||
null, Dependency.get(Dependency.TIME_TICK_HANDLER));
|
||||
Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
|
||||
StatusBarIconController.ICON_BLACKLIST);
|
||||
SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
|
||||
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);
|
||||
}
|
||||
|
||||
// NOTE: It's safe to do these after registering the receiver since the receiver always runs
|
||||
@@ -130,6 +145,9 @@ public class Clock extends TextView implements DemoMode, Tunable {
|
||||
getContext().unregisterReceiver(mIntentReceiver);
|
||||
mAttached = false;
|
||||
Dependency.get(TunerService.class).removeTunable(this);
|
||||
SysUiServiceProvider.getComponent(getContext(), CommandQueue.class)
|
||||
.removeCallbacks(this);
|
||||
Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +176,22 @@ public class Clock extends TextView implements DemoMode, Tunable {
|
||||
}
|
||||
};
|
||||
|
||||
public void setClockVisibleByUser(boolean visible) {
|
||||
mClockVisibleByUser = visible;
|
||||
updateClockVisibility();
|
||||
}
|
||||
|
||||
public void setClockVisibilityByPolicy(boolean visible) {
|
||||
mClockVisibleByPolicy = visible;
|
||||
updateClockVisibility();
|
||||
}
|
||||
|
||||
private void updateClockVisibility() {
|
||||
int visibility = (mClockVisibleByPolicy && mClockVisibleByUser)
|
||||
? View.VISIBLE : View.GONE;
|
||||
setVisibility(visibility);
|
||||
}
|
||||
|
||||
final void updateClock() {
|
||||
if (mDemoMode) return;
|
||||
mCalendar.setTimeInMillis(System.currentTimeMillis());
|
||||
@@ -170,9 +204,38 @@ public class Clock extends TextView implements DemoMode, Tunable {
|
||||
if (CLOCK_SECONDS.equals(key)) {
|
||||
mShowSeconds = newValue != null && Integer.parseInt(newValue) != 0;
|
||||
updateShowSeconds();
|
||||
} else {
|
||||
setClockVisibleByUser(!StatusBarIconController.getIconBlacklist(newValue)
|
||||
.contains("clock"));
|
||||
updateClockVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(int state1, int state2, boolean animate) {
|
||||
boolean clockVisibleByPolicy = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
|
||||
if (clockVisibleByPolicy != mClockVisibleByPolicy) {
|
||||
setClockVisibilityByPolicy(clockVisibleByPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDarkChanged(Rect area, float darkIntensity, int tint) {
|
||||
setTextColor(DarkIconDispatcher.getTint(area, this, tint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
FontSizeUtils.updateFontSize(this, R.dimen.status_bar_clock_size);
|
||||
setPaddingRelative(
|
||||
mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.status_bar_clock_starting_padding),
|
||||
0,
|
||||
mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.status_bar_clock_end_padding),
|
||||
0);
|
||||
}
|
||||
|
||||
private void updateShowSeconds() {
|
||||
if (mShowSeconds) {
|
||||
// Wait until we have a display to start trying to show seconds.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.res.Configuration;
|
||||
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
|
||||
/**
|
||||
* Common listener for configuration or subsets of configuration changes (like density or
|
||||
* font scaling), providing easy static dependence on these events.
|
||||
*/
|
||||
public interface ConfigurationController extends CallbackController<ConfigurationListener> {
|
||||
|
||||
interface ConfigurationListener {
|
||||
default void onConfigChanged(Configuration newConfig) {}
|
||||
default void onDensityOrFontScaleChanged() {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
|
||||
|
||||
public interface DarkIconDispatcher {
|
||||
|
||||
void setIconsDarkArea(Rect r);
|
||||
LightBarTransitionsController getTransitionsController();
|
||||
|
||||
void addDarkReceiver(DarkReceiver receiver);
|
||||
void addDarkReceiver(ImageView imageView);
|
||||
|
||||
// Must have been previously been added through one of the addDarkReceive methods above.
|
||||
void removeDarkReceiver(DarkReceiver object);
|
||||
void removeDarkReceiver(ImageView object);
|
||||
|
||||
// Used to reapply darkness on an object, must have previously been added through
|
||||
// addDarkReceiver.
|
||||
void applyDark(ImageView object);
|
||||
|
||||
int DEFAULT_ICON_TINT = Color.WHITE;
|
||||
Rect sTmpRect = new Rect();
|
||||
int[] sTmpInt2 = new int[2];
|
||||
|
||||
/**
|
||||
* @return the tint to apply to {@param view} depending on the desired tint {@param color} and
|
||||
* the screen {@param tintArea} in which to apply that tint
|
||||
*/
|
||||
static int getTint(Rect tintArea, View view, int color) {
|
||||
if (isInArea(tintArea, view)) {
|
||||
return color;
|
||||
} else {
|
||||
return DEFAULT_ICON_TINT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dark intensity to apply to {@param view} depending on the desired dark
|
||||
* {@param intensity} and the screen {@param tintArea} in which to apply that intensity
|
||||
*/
|
||||
static float getDarkIntensity(Rect tintArea, View view, float intensity) {
|
||||
if (isInArea(tintArea, view)) {
|
||||
return intensity;
|
||||
} else {
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if more than half of the {@param view} area are in {@param area}, false
|
||||
* otherwise
|
||||
*/
|
||||
static boolean isInArea(Rect area, View view) {
|
||||
if (area.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
sTmpRect.set(area);
|
||||
view.getLocationOnScreen(sTmpInt2);
|
||||
int left = sTmpInt2[0];
|
||||
|
||||
int intersectStart = Math.max(left, area.left);
|
||||
int intersectEnd = Math.min(left + view.getWidth(), area.right);
|
||||
int intersectAmount = Math.max(0, intersectEnd - intersectStart);
|
||||
|
||||
boolean coversFullStatusBar = area.top <= 0;
|
||||
boolean majorityOfWidth = 2 * intersectAmount > view.getWidth();
|
||||
return majorityOfWidth && coversFullStatusBar;
|
||||
}
|
||||
|
||||
interface DarkReceiver {
|
||||
void onDarkChanged(Rect area, float darkIntensity, int tint);
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,12 @@ public interface KeyguardMonitor extends CallbackController<Callback> {
|
||||
boolean isSecure();
|
||||
boolean canSkipBouncer();
|
||||
boolean isShowing();
|
||||
boolean isKeyguardFadingAway();
|
||||
boolean isKeyguardGoingAway();
|
||||
long getKeyguardFadingAwayDuration();
|
||||
long getKeyguardFadingAwayDelay();
|
||||
|
||||
public interface Callback {
|
||||
void onKeyguardChanged();
|
||||
void onKeyguardShowingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,10 @@ package com.android.systemui.statusbar.policy;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.view.WindowManagerGlobal;
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.systemui.settings.CurrentUserTracker;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitor.Callback;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -44,6 +41,10 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback
|
||||
private boolean mCanSkipBouncer;
|
||||
|
||||
private boolean mListening;
|
||||
private boolean mKeyguardFadingAway;
|
||||
private long mKeyguardFadingAwayDelay;
|
||||
private long mKeyguardFadingAwayDuration;
|
||||
private boolean mKeyguardGoingAway;
|
||||
|
||||
public KeyguardMonitorImpl(Context context) {
|
||||
mContext = context;
|
||||
@@ -115,8 +116,42 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback
|
||||
}
|
||||
|
||||
private void notifyKeyguardChanged() {
|
||||
for (Callback callback : mCallbacks) {
|
||||
callback.onKeyguardChanged();
|
||||
}
|
||||
mCallbacks.forEach(Callback::onKeyguardShowingChanged);
|
||||
}
|
||||
|
||||
public void notifyKeyguardFadingAway(long delay, long fadeoutDuration) {
|
||||
mKeyguardFadingAway = true;
|
||||
mKeyguardFadingAwayDelay = delay;
|
||||
mKeyguardFadingAwayDuration = fadeoutDuration;
|
||||
mCallbacks.forEach(Callback::onKeyguardShowingChanged);
|
||||
}
|
||||
|
||||
public void notifyKeyguardDoneFading() {
|
||||
mKeyguardFadingAway = false;
|
||||
mCallbacks.forEach(Callback::onKeyguardShowingChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyguardFadingAway() {
|
||||
return mKeyguardFadingAway;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyguardGoingAway() {
|
||||
return mKeyguardGoingAway;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getKeyguardFadingAwayDelay() {
|
||||
return mKeyguardFadingAwayDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getKeyguardFadingAwayDuration() {
|
||||
return mKeyguardFadingAwayDuration;
|
||||
}
|
||||
|
||||
public void notifyKeyguardGoingAway(boolean keyguardGoingAway) {
|
||||
mKeyguardGoingAway = keyguardGoingAway;
|
||||
}
|
||||
}
|
||||
@@ -850,7 +850,7 @@ public class UserSwitcherController {
|
||||
|
||||
private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() {
|
||||
@Override
|
||||
public void onKeyguardChanged() {
|
||||
public void onKeyguardShowingChanged() {
|
||||
notifyAdapters();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -36,14 +36,14 @@ public interface ZenModeController extends CallbackController<Callback> {
|
||||
int getCurrentUser();
|
||||
boolean isVolumeRestricted();
|
||||
|
||||
public static class Callback {
|
||||
public void onZenChanged(int zen) {}
|
||||
public void onConditionsChanged(Condition[] conditions) {}
|
||||
public void onNextAlarmChanged() {}
|
||||
public void onZenAvailableChanged(boolean available) {}
|
||||
public void onEffectsSupressorChanged() {}
|
||||
public void onManualRuleChanged(ZenRule rule) {}
|
||||
public void onConfigChanged(ZenModeConfig config) {}
|
||||
public static interface Callback {
|
||||
default void onZenChanged(int zen) {}
|
||||
default void onConditionsChanged(Condition[] conditions) {}
|
||||
default void onNextAlarmChanged() {}
|
||||
default void onZenAvailableChanged(boolean available) {}
|
||||
default void onEffectsSupressorChanged() {}
|
||||
default void onManualRuleChanged(ZenRule rule) {}
|
||||
default void onConfigChanged(ZenModeConfig config) {}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,6 +42,9 @@ import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
|
||||
import com.android.systemui.DemoMode;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.SystemUI;
|
||||
import com.android.systemui.SystemUIApplication;
|
||||
import com.android.systemui.settings.CurrentUserTracker;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
|
||||
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
|
||||
<uses-permission android:name="android.permission.REQUEST_NETWORK_SCORES" />
|
||||
<uses-permission android:name="android.permission.CONTROL_VPN" />
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
|
||||
@@ -18,11 +18,12 @@ package com.android.systemui;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.MessageQueue;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.systemui.utils.TestableContext;
|
||||
import com.android.systemui.utils.leaks.Tracker;
|
||||
@@ -30,17 +31,21 @@ import com.android.systemui.utils.leaks.Tracker;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
/**
|
||||
* Base class that does System UI specific setup.
|
||||
*/
|
||||
public abstract class SysuiTestCase {
|
||||
|
||||
private Throwable mException;
|
||||
private Handler mHandler;
|
||||
protected TestableContext mContext;
|
||||
protected TestDependency mDependency;
|
||||
|
||||
@Before
|
||||
public void SysuiSetup() throws Exception {
|
||||
mException = null;
|
||||
System.setProperty("dexmaker.share_classloader", "true");
|
||||
mContext = new TestableContext(InstrumentationRegistry.getTargetContext(), this);
|
||||
SystemUIFactory.createFromConfig(mContext);
|
||||
|
||||
@@ -24,14 +24,18 @@ import com.android.systemui.statusbar.phone.QuickStatusBarHeader;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.util.LayoutInflaterBuilder;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class QSFragmentTest extends FragmentTestCase {
|
||||
@@ -42,6 +46,13 @@ public class QSFragmentTest extends FragmentTestCase {
|
||||
|
||||
@Before
|
||||
public void addLeakCheckDependencies() {
|
||||
mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE,
|
||||
new LayoutInflaterBuilder(mContext)
|
||||
.replace("com.android.systemui.statusbar.policy.SplitClockView",
|
||||
FrameLayout.class)
|
||||
.replace("TextClock", View.class)
|
||||
.build());
|
||||
|
||||
injectTestDependency(Dependency.BG_LOOPER, Looper.getMainLooper());
|
||||
injectMockDependency(UserSwitcherController.class);
|
||||
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
|
||||
|
||||
@@ -41,6 +41,7 @@ public class CommandQueueTest extends SysuiTestCase {
|
||||
mCommandQueue = new CommandQueue();
|
||||
mCallbacks = mock(Callbacks.class);
|
||||
mCommandQueue.addCallbacks(mCallbacks);
|
||||
verify(mCallbacks).disable(eq(0), eq(0), eq(false));
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -181,7 +182,7 @@ public class CommandQueueTest extends SysuiTestCase {
|
||||
public void testAppTransitionPending() {
|
||||
mCommandQueue.appTransitionPending();
|
||||
waitForIdleSync();
|
||||
verify(mCallbacks).appTransitionPending();
|
||||
verify(mCallbacks).appTransitionPending(eq(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -195,7 +196,7 @@ public class CommandQueueTest extends SysuiTestCase {
|
||||
public void testAppTransitionStarting() {
|
||||
mCommandQueue.appTransitionStarting(1, 2);
|
||||
waitForIdleSync();
|
||||
verify(mCallbacks).appTransitionStarting(eq(1L), eq(2L));
|
||||
verify(mCallbacks).appTransitionStarting(eq(1L), eq(2L), eq(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.phone;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.StatusBarManager;
|
||||
import android.view.View;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
|
||||
import com.android.systemui.FragmentTestCase;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitor;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
import com.android.systemui.statusbar.policy.SecurityController;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class CollapsedStatusBarFragmentTest extends FragmentTestCase {
|
||||
|
||||
private NotificationIconAreaController mMockNotificiationAreaController;
|
||||
private View mNotificationAreaInner;
|
||||
|
||||
public CollapsedStatusBarFragmentTest() {
|
||||
super(CollapsedStatusBarFragment.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
|
||||
mContext.putComponent(StatusBar.class, mock(StatusBar.class));
|
||||
mContext.putComponent(TunerService.class, mock(TunerService.class));
|
||||
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
|
||||
mMockNotificiationAreaController = mock(NotificationIconAreaController.class);
|
||||
mNotificationAreaInner = mock(View.class);
|
||||
when(mNotificationAreaInner.animate()).thenReturn(mock(ViewPropertyAnimator.class));
|
||||
when(mMockNotificiationAreaController.getNotificationInnerAreaView()).thenReturn(
|
||||
mNotificationAreaInner);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableNone() throws Exception {
|
||||
postAndWait(() -> mFragments.dispatchResume());
|
||||
|
||||
CollapsedStatusBarFragment fragment = (CollapsedStatusBarFragment) mFragment;
|
||||
fragment.initNotificationIconArea(mMockNotificiationAreaController);
|
||||
fragment.disable(0, 0, false);
|
||||
|
||||
assertEquals(View.VISIBLE, mFragment.getView().findViewById(R.id.system_icon_area)
|
||||
.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableSystemInfo() throws Exception {
|
||||
postAndWait(() -> mFragments.dispatchResume());
|
||||
|
||||
CollapsedStatusBarFragment fragment = (CollapsedStatusBarFragment) mFragment;
|
||||
fragment.initNotificationIconArea(mMockNotificiationAreaController);
|
||||
fragment.disable(StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
|
||||
|
||||
assertEquals(View.INVISIBLE, mFragment.getView().findViewById(R.id.system_icon_area)
|
||||
.getVisibility());
|
||||
|
||||
fragment.disable(0, 0, false);
|
||||
|
||||
assertEquals(View.VISIBLE, mFragment.getView().findViewById(R.id.system_icon_area)
|
||||
.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableNotifications() throws Exception {
|
||||
postAndWait(() -> mFragments.dispatchResume());
|
||||
|
||||
CollapsedStatusBarFragment fragment = (CollapsedStatusBarFragment) mFragment;
|
||||
fragment.initNotificationIconArea(mMockNotificiationAreaController);
|
||||
fragment.disable(StatusBarManager.DISABLE_NOTIFICATION_ICONS, 0, false);
|
||||
|
||||
Mockito.verify(mNotificationAreaInner).setVisibility(eq(View.INVISIBLE));
|
||||
|
||||
fragment.disable(0, 0, false);
|
||||
|
||||
Mockito.verify(mNotificationAreaInner).setVisibility(eq(View.VISIBLE));
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,14 @@
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.view.Display;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.FragmentTestCase;
|
||||
import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.stackdivider.Divider;
|
||||
@@ -35,17 +39,21 @@ public class NavigationBarFragmentTest extends FragmentTestCase {
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
injectTestDependency(Dependency.BG_LOOPER, Looper.getMainLooper());
|
||||
mContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
|
||||
mContext.putComponent(StatusBar.class, mock(StatusBar.class));
|
||||
mContext.putComponent(Recents.class, mock(Recents.class));
|
||||
mContext.putComponent(Divider.class, mock(Divider.class));
|
||||
mContext.addMockSystemService(Context.WINDOW_SERVICE, mock(WindowManager.class));
|
||||
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
|
||||
WindowManager windowManager = mock(WindowManager.class);
|
||||
Display defaultDisplay = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
|
||||
when(windowManager.getDefaultDisplay()).thenReturn(
|
||||
defaultDisplay);
|
||||
mContext.addMockSystemService(Context.WINDOW_SERVICE, windowManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHomeLongPress() {
|
||||
mContext.addMockSystemService(Context.WINDOW_SERVICE, mock(WindowManager.class));
|
||||
NavigationBarFragment navigationBarFragment = (NavigationBarFragment) mFragment;
|
||||
|
||||
postAndWait(() -> mFragments.dispatchResume());
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.os.IBinder;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.LayoutInflater;
|
||||
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.utils.leaks.Tracker;
|
||||
@@ -99,6 +100,9 @@ public class TestableContext extends ContextWrapper implements SysUiServiceProvi
|
||||
if (mMockSystemServices != null && mMockSystemServices.containsKey(name)) {
|
||||
return mMockSystemServices.get(name);
|
||||
}
|
||||
if (name.equals(LAYOUT_INFLATER_SERVICE)) {
|
||||
return getBaseContext().getSystemService(LayoutInflater.class).cloneInContext(this);
|
||||
}
|
||||
return super.getSystemService(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,26 @@ public class FakeKeyguardMonitor implements KeyguardMonitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyguardFadingAway() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyguardGoingAway() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getKeyguardFadingAwayDuration() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getKeyguardFadingAwayDelay() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSkipBouncer() {
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.utils.leaks;
|
||||
|
||||
import com.android.internal.statusbar.StatusBarIcon;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
|
||||
|
||||
public class FakeStatusBarIconController extends BaseLeakChecker<IconManager>
|
||||
implements StatusBarIconController {
|
||||
|
||||
public FakeStatusBarIconController(LeakCheckedTest test) {
|
||||
super(test, "StatusBarGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIconGroup(IconManager iconManager) {
|
||||
addCallback(iconManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIconGroup(IconManager iconManager) {
|
||||
removeCallback(iconManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExternalIcon(String slot) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(String slot, int resourceId, CharSequence contentDescription) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(String slot, StatusBarIcon icon) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIconVisibility(String slotTty, boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIcon(String slot) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.util.ArrayMap;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.PluginManager;
|
||||
import com.android.systemui.statusbar.phone.ManagedProfileController;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
import com.android.systemui.statusbar.policy.CallbackController;
|
||||
@@ -75,6 +76,7 @@ public abstract class LeakCheckedTest extends SysuiTestCase {
|
||||
NetworkController.class,
|
||||
PluginManager.class,
|
||||
TunerService.class,
|
||||
StatusBarIconController.class,
|
||||
};
|
||||
|
||||
@Rule
|
||||
@@ -121,6 +123,8 @@ public abstract class LeakCheckedTest extends SysuiTestCase {
|
||||
obj = new FakePluginManager(mContext, this);
|
||||
} else if (cls == TunerService.class) {
|
||||
obj = new FakeTunerService(mContext, this);
|
||||
} else if (cls == StatusBarIconController.class) {
|
||||
obj = new FakeStatusBarIconController(this);
|
||||
} else {
|
||||
Assert.fail(cls.getName() + " is not supported by LeakCheckedTest yet");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user