Merge "Fix leaks in sysui"

This commit is contained in:
TreeHugger Robot
2017-02-02 18:08:23 +00:00
committed by Android (Google) Code Review
42 changed files with 373 additions and 114 deletions

View File

@@ -70,7 +70,7 @@ public class PluginManager extends BroadcastReceiver {
private boolean mListening;
private boolean mHasOneShot;
private PluginManager(Context context) {
public PluginManager(Context context) {
this(context, new PluginInstanceManagerFactory(),
Build.IS_DEBUGGABLE, Thread.getDefaultUncaughtExceptionHandler());
}
@@ -252,13 +252,6 @@ public class PluginManager extends BroadcastReceiver {
return new PluginContextWrapper(mContext.createApplicationContext(info, 0), classLoader);
}
public static PluginManager getInstance(Context context) {
if (sInstance == null) {
sInstance = new PluginManager(context.getApplicationContext());
}
return sInstance;
}
private class AllPluginClassLoader extends ClassLoader {
public AllPluginClassLoader(ClassLoader classLoader) {
super(classLoader);

View File

@@ -32,6 +32,8 @@ public interface NavGesture extends Plugin {
public boolean onInterceptTouchEvent(MotionEvent event);
public void setBarState(boolean vertical, boolean isRtl);
public default void destroy() { }
}
}

View File

@@ -76,7 +76,7 @@ public class BatteryMeterView extends ImageView implements
mDrawable.setBatteryController(mBatteryController);
mBatteryController.addCallback(this);
mDrawable.startListening();
TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
}
@Override
@@ -84,7 +84,7 @@ public class BatteryMeterView extends ImageView implements
super.onDetachedFromWindow();
mBatteryController.removeCallback(this);
mDrawable.stopListening();
TunerService.get(getContext()).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
}
@Override

View File

@@ -14,6 +14,7 @@
package com.android.systemui;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Handler;
import android.os.HandlerThread;
@@ -23,6 +24,7 @@ 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.ManagedProfileController;
import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
import com.android.systemui.statusbar.policy.AccessibilityController;
@@ -56,9 +58,11 @@ import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
import com.android.systemui.tuner.TunerService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;
/**
* Class to handle ugly dependencies throughout sysui until we determine the
@@ -167,12 +171,18 @@ public class Dependency extends SystemUI {
mProviders.put(DeviceProvisionedController.class.getName(), () ->
new DeviceProvisionedControllerImpl(mContext));
mProviders.put(PluginManager.class.getName(), () ->
new PluginManager(mContext));
mProviders.put(AssistManager.class.getName(), () ->
new AssistManager(getDependency(DeviceProvisionedController.class), mContext));
mProviders.put(SecurityController.class.getName(), () ->
new SecurityControllerImpl(mContext));
mProviders.put(TunerService.class.getName(), () ->
new TunerService(mContext));
// Put all dependencies above here so the factory can override them if it wants.
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
}
@@ -220,6 +230,17 @@ public class Dependency extends SystemUI {
T createDependency();
}
/**
* Used in separate processes (like tuner settings) to init the dependencies.
*/
public static void initDependencies(Context context) {
if (sDependency != null) return;
Dependency d = new Dependency();
d.mContext = context.getApplicationContext();
d.mComponents = new HashMap<>();
d.start();
}
public static <T> T get(Class<T> cls) {
return sDependency.getDependency(cls.getName());
}

View File

@@ -76,7 +76,7 @@ public class PluginInflateContainer extends AutoReinflateContainer
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (mAction != null) {
PluginManager.getInstance(getContext()).addPluginListener(mAction, this, mVersion);
Dependency.get(PluginManager.class).addPluginListener(mAction, this, mVersion);
}
}
@@ -84,7 +84,7 @@ public class PluginInflateContainer extends AutoReinflateContainer
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mAction != null) {
PluginManager.getInstance(getContext()).removePluginListener(this);
Dependency.get(PluginManager.class).removePluginListener(this);
}
}

View File

@@ -65,7 +65,6 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
private final Class<?>[] SERVICES = new Class[] {
Dependency.class,
FragmentService.class,
TunerService.class,
NotificationChannels.class,
CommandQueue.CommandQueueStart.class,
KeyguardViewMediator.class,
@@ -205,7 +204,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
mServices[i].onBootCompleted();
}
}
PluginManager.getInstance(this).addPluginListener(OverlayPlugin.ACTION,
Dependency.get(PluginManager.class).addPluginListener(OverlayPlugin.ACTION,
new PluginListener<OverlayPlugin>() {
@Override
public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {

View File

@@ -19,6 +19,7 @@ package com.android.systemui.doze;
import android.service.dreams.DreamService;
import android.util.Log;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.doze.DozeProvider;
@@ -47,7 +48,7 @@ public class DozeService extends DreamService implements DozeMachine.Service {
return;
}
DozeProvider provider = PluginManager.getInstance(this)
DozeProvider provider = Dependency.get(PluginManager.class)
.getOneShotPlugin(DozeProvider.ACTION, DozeProvider.VERSION);
mDozeMachine = new DozeFactory(provider).assembleMachine(this);
}

View File

@@ -19,6 +19,7 @@ import android.content.Context;
import android.util.Log;
import android.view.View;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.FragmentBase;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
@@ -38,7 +39,7 @@ public class PluginFragmentListener implements PluginListener<Plugin> {
Class<? extends FragmentBase> expectedInterface) {
mTag = tag;
mFragmentHostManager = FragmentHostManager.get(view);
mPluginManager = PluginManager.getInstance(view.getContext());
mPluginManager = Dependency.get(PluginManager.class);
mExpectedInterface = expectedInterface;
mDefaultClass = defaultFragment;
}

View File

@@ -49,6 +49,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.BackgroundThread;
import com.android.internal.policy.PipMotionHelper;
import com.android.internal.policy.PipSnapAlgorithm;
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.tuner.TunerService;
@@ -200,7 +201,7 @@ public class PipTouchHandler implements TunerService.Tunable {
setSnapToEdge(true);
// Register any tuner settings changes
TunerService.get(context).addTunable(this, TUNER_KEY_DRAG_TO_DISMISS,
Dependency.get(TunerService.class).addTunable(this, TUNER_KEY_DRAG_TO_DISMISS,
TUNER_KEY_ALLOW_MINIMIZE);
}

View File

@@ -20,6 +20,7 @@ import android.view.View.OnAttachStateChangeListener;
import android.view.View.OnLayoutChangeListener;
import android.widget.TextView;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.PagedTileLayout.PageListener;
import com.android.systemui.qs.QSPanel.QSTileLayout;
@@ -105,7 +106,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
@Override
public void onViewAttachedToWindow(View v) {
TunerService.get(mQs.getContext()).addTunable(this, ALLOW_FANCY_ANIMATION,
Dependency.get(TunerService.class).addTunable(this, ALLOW_FANCY_ANIMATION,
MOVE_FULL_ROWS, QuickQSPanel.NUM_QUICK_TILES);
}
@@ -114,7 +115,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
if (mHost != null) {
mHost.removeCallback(this);
}
TunerService.get(mQs.getContext()).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
}
@Override

View File

@@ -29,6 +29,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.qs.QS.DetailAdapter;
@@ -126,7 +127,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
TunerService.get(mContext).addTunable(this, QS_SHOW_BRIGHTNESS);
Dependency.get(TunerService.class).addTunable(this, QS_SHOW_BRIGHTNESS);
if (mHost != null) {
setTiles(mHost.getTiles());
}
@@ -134,8 +135,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
@Override
protected void onDetachedFromWindow() {
TunerService.get(mContext).removeTunable(this);
mHost.removeCallback(this);
Dependency.get(TunerService.class).removeTunable(this);
if (mHost != null) {
mHost.removeCallback(this);
}
for (TileRecord record : mRecords) {
record.tile.removeCallbacks();
}

View File

@@ -24,6 +24,7 @@ import android.view.View;
import android.widget.LinearLayout;
import android.widget.Space;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile.SignalState;
import com.android.systemui.qs.QSTile.State;
@@ -62,13 +63,13 @@ public class QuickQSPanel extends QSPanel {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
TunerService.get(mContext).addTunable(mNumTiles, NUM_QUICK_TILES);
Dependency.get(TunerService.class).addTunable(mNumTiles, NUM_QUICK_TILES);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
TunerService.get(mContext).removeTunable(mNumTiles);
Dependency.get(TunerService.class).removeTunable(mNumTiles);
}
public void setQSPanelAndHeader(QSPanel fullPanel, View header) {
@@ -141,7 +142,7 @@ public class QuickQSPanel extends QSPanel {
};
public int getNumQuickTiles(Context context) {
return TunerService.get(context).getValue(NUM_QUICK_TILES, 6);
return Dependency.get(TunerService.class).getValue(NUM_QUICK_TILES, 6);
}
private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {

View File

@@ -30,6 +30,7 @@ import android.widget.FrameLayout;
import java.util.ArrayList;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.PluginListener;
@@ -82,10 +83,21 @@ public class NotificationMenuRow extends FrameLayout
public NotificationMenuRow(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs);
PluginManager.getInstance(getContext()).addPluginListener(
mMenuItems.addAll(getDefaultNotificationMenuItems());
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Dependency.get(PluginManager.class).addPluginListener(
NotificationMenuRowProvider.ACTION, this,
NotificationMenuRowProvider.VERSION, false /* Allow multiple */);
mMenuItems.addAll(getDefaultNotificationMenuItems());
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Dependency.get(PluginManager.class).removePluginListener(this);
}
@Override

View File

@@ -220,7 +220,7 @@ public class SignalClusterView
int endPadding = mMobileSignalGroup.getChildCount() > 0 ? mMobileSignalGroupEndPadding : 0;
mMobileSignalGroup.setPaddingRelative(0, 0, endPadding, 0);
TunerService.get(mContext).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
apply();
applyIconTint();
@@ -231,7 +231,7 @@ public class SignalClusterView
@Override
protected void onDetachedFromWindow() {
mMobileSignalGroup.removeAllViews();
TunerService.get(mContext).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
mSecurityController.removeCallback(this);
mNetworkController.removeCallback(this);

View File

@@ -260,11 +260,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mAccessibilityController.addStateChangedCallback(this);
PluginManager.getInstance(getContext()).addPluginListener(RIGHT_BUTTON_PLUGIN,
Dependency.get(PluginManager.class).addPluginListener(RIGHT_BUTTON_PLUGIN,
mRightListener, IntentButtonProvider.VERSION, false /* Only allow one */);
PluginManager.getInstance(getContext()).addPluginListener(LEFT_BUTTON_PLUGIN,
Dependency.get(PluginManager.class).addPluginListener(LEFT_BUTTON_PLUGIN,
mLeftListener, IntentButtonProvider.VERSION, false /* Only allow one */);
TunerService.get(getContext()).addTunable(this, LockscreenFragment.LOCKSCREEN_LEFT_BUTTON,
Dependency.get(TunerService.class).addTunable(this, LockscreenFragment.LOCKSCREEN_LEFT_BUTTON,
LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON);
}
@@ -272,9 +272,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAccessibilityController.removeStateChangedCallback(this);
PluginManager.getInstance(getContext()).removePluginListener(mRightListener);
PluginManager.getInstance(getContext()).removePluginListener(mLeftListener);
TunerService.get(getContext()).removeTunable(this);
Dependency.get(PluginManager.class).removePluginListener(mRightListener);
Dependency.get(PluginManager.class).removePluginListener(mLeftListener);
Dependency.get(TunerService.class).removeTunable(this);
}
private void initAccessibility() {
@@ -575,7 +575,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
AsyncTask.execute(runnable);
} else {
boolean dismissShade = !TextUtils.isEmpty(mRightButtonStr)
&& TunerService.get(getContext()).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
&& Dependency.get(TunerService.class).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
mStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
dismissShade, false /* afterKeyguardGone */, true /* deferred */);
}
@@ -596,7 +596,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
});
} else {
boolean dismissShade = !TextUtils.isEmpty(mLeftButtonStr)
&& TunerService.get(getContext()).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0;
&& Dependency.get(TunerService.class).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0;
mActivityStarter.startActivity(mLeftButton.getIntent(), dismissShade);
}
}

View File

@@ -29,6 +29,7 @@ import android.view.ViewConfiguration;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
@@ -87,7 +88,11 @@ public class NavigationBarGestureHelper extends GestureDetector.SimpleOnGestureL
mScrollTouchSlop = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance);
mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
mTaskSwitcherDetector = new GestureDetector(context, this);
TunerService.get(context).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
Dependency.get(TunerService.class).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
}
public void destroy() {
Dependency.get(TunerService.class).removeTunable(this);
}
public void setComponents(RecentsComponent recentsComponent, Divider divider,

View File

@@ -30,6 +30,7 @@ import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Space;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
@@ -135,15 +136,16 @@ public class NavigationBarInflaterView extends FrameLayout
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
TunerService.get(getContext()).addTunable(this, NAV_BAR_VIEWS, NAV_BAR_LEFT,
Dependency.get(TunerService.class).addTunable(this, NAV_BAR_VIEWS, NAV_BAR_LEFT,
NAV_BAR_RIGHT);
PluginManager.getInstance(getContext()).addPluginListener(NavBarButtonProvider.ACTION, this,
Dependency.get(PluginManager.class).addPluginListener(NavBarButtonProvider.ACTION, this,
NavBarButtonProvider.VERSION, true /* Allow multiple */);
}
@Override
protected void onDetachedFromWindow() {
TunerService.get(getContext()).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
Dependency.get(PluginManager.class).removePluginListener(this);
super.onDetachedFromWindow();
}
@@ -278,10 +280,10 @@ public class NavigationBarInflaterView extends FrameLayout
View v = null;
String button = extractButton(buttonSpec);
if (LEFT.equals(button)) {
buttonSpec = TunerService.get(mContext).getValue(NAV_BAR_LEFT, NAVSPACE);
buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
button = extractButton(buttonSpec);
} else if (RIGHT.equals(button)) {
buttonSpec = TunerService.get(mContext).getValue(NAV_BAR_RIGHT, MENU_IME);
buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
button = extractButton(buttonSpec);
}
// Let plugins go first so they can override a standard view if they want.

View File

@@ -46,6 +46,7 @@ import android.view.WindowManagerGlobal;
import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.plugins.PluginListener;
@@ -200,7 +201,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
mVertical = false;
mShowMenu = false;
mGestureHelper = new NavigationBarGestureHelper(context);
mConfiguration = new Configuration();
mConfiguration.updateFrom(context.getResources().getConfiguration());
@@ -633,6 +633,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
}
private void updateTaskSwitchHelper() {
if (mGestureHelper == null) return;
boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
mGestureHelper.setBarState(mVertical, isRtl);
}
@@ -752,14 +753,18 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
PluginManager.getInstance(getContext()).addPluginListener(NavGesture.ACTION, this,
onPluginDisconnected(null); // Create default gesture helper
Dependency.get(PluginManager.class).addPluginListener(NavGesture.ACTION, this,
NavGesture.VERSION, false /* Only one */);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
PluginManager.getInstance(getContext()).removePluginListener(this);
Dependency.get(PluginManager.class).removePluginListener(this);
if (mGestureHelper != null) {
mGestureHelper.destroy();
}
}
@Override
@@ -772,6 +777,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
public void onPluginDisconnected(NavGesture plugin) {
NavigationBarGestureHelper defaultHelper = new NavigationBarGestureHelper(getContext());
defaultHelper.setComponents(mRecentsComponent, mDivider, this);
if (mGestureHelper != null) {
mGestureHelper.destroy();
}
mGestureHelper = defaultHelper;
updateTaskSwitchHelper();
}

View File

@@ -89,7 +89,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
mServices = new TileServices(this, Dependency.get(Dependency.BG_LOOPER));
TunerService.get(mContext).addTunable(this, TILES_SETTING);
Dependency.get(TunerService.class).addTunable(this, TILES_SETTING);
// AutoTileManager can modify mTiles so make sure mTiles has already been initialized.
mAutoTiles = new AutoTileManager(context, this);
}
@@ -101,7 +101,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
public void destroy() {
mTiles.values().forEach(tile -> tile.destroy());
mAutoTiles.destroy();
TunerService.get(mContext).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
mServices.destroy();
}

View File

@@ -36,6 +36,7 @@ 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;
@@ -127,7 +128,7 @@ public class StatusBarIconController extends StatusBarIconList implements Tunabl
mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone);
loadDimens();
TunerService.get(mContext).addTunable(this, ICON_BLACKLIST);
Dependency.get(TunerService.class).addTunable(this, ICON_BLACKLIST);
mTransitionsController = new LightBarTransitionsController(this::setIconTintInternal);
}

View File

@@ -108,7 +108,7 @@ public class Clock extends TextView implements DemoMode, Tunable {
getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter,
null, Dependency.get(Dependency.TIME_TICK_HANDLER));
TunerService.get(getContext()).addTunable(this, CLOCK_SECONDS,
Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
StatusBarIconController.ICON_BLACKLIST);
}
@@ -129,7 +129,7 @@ public class Clock extends TextView implements DemoMode, Tunable {
if (mAttached) {
getContext().unregisterReceiver(mIntentReceiver);
mAttached = false;
TunerService.get(getContext()).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
}
}

View File

@@ -22,6 +22,7 @@ import android.util.ArraySet;
import android.util.AttributeSet;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
@@ -49,12 +50,12 @@ public class BatteryPreference extends DropDownPreference implements TunerServic
super.onAttached();
mHasPercentage = Settings.System.getInt(getContext().getContentResolver(),
SHOW_PERCENT_SETTING, 0) != 0;
TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
}
@Override
public void onDetached() {
TunerService.get(getContext()).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
super.onDetached();
}
@@ -89,7 +90,7 @@ public class BatteryPreference extends DropDownPreference implements TunerServic
} else {
mBlacklist.remove(mBattery);
}
TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_BLACKLIST,
TextUtils.join(",", mBlacklist));
return true;
}

View File

@@ -18,6 +18,8 @@ import android.support.v7.preference.DropDownPreference;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.AttributeSet;
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.Clock;
@@ -44,13 +46,13 @@ public class ClockPreference extends DropDownPreference implements TunerService.
@Override
public void onAttached() {
super.onAttached();
TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
Clock.CLOCK_SECONDS);
}
@Override
public void onDetached() {
TunerService.get(getContext()).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
super.onDetached();
}
@@ -81,13 +83,14 @@ public class ClockPreference extends DropDownPreference implements TunerService.
@Override
protected boolean persistString(String value) {
TunerService.get(getContext()).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1 : 0);
Dependency.get(TunerService.class).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1
: 0);
if (DISABLED.equals(value)) {
mBlacklist.add(mClock);
} else {
mBlacklist.remove(mClock);
}
TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_BLACKLIST,
TextUtils.join(",", mBlacklist));
return true;
}

View File

@@ -43,6 +43,7 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
import com.android.systemui.statusbar.phone.ExpandableIndicator;
@@ -71,7 +72,7 @@ public class LockscreenFragment extends PreferenceFragment {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
mTunerService = TunerService.get(getContext());
mTunerService = Dependency.get(TunerService.class);
mHandler = new Handler();
addPreferencesFromResource(R.xml.lockscreen_settings);
setupGroup((PreferenceGroup) findPreference(KEY_LEFT), LOCKSCREEN_LEFT_BUTTON,

View File

@@ -51,6 +51,7 @@ import android.util.TypedValue;
import android.view.KeyEvent;
import android.widget.EditText;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.NavigationBarInflaterView;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -104,12 +105,12 @@ public class NavBarTuner extends PreferenceFragment {
@Override
public void onDestroy() {
super.onDestroy();
mTunables.forEach(t -> TunerService.get(getContext()).removeTunable(t));
mTunables.forEach(t -> Dependency.get(TunerService.class).removeTunable(t));
}
private void addTunable(Tunable tunable, String... keys) {
mTunables.add(tunable);
TunerService.get(getContext()).addTunable(tunable, keys);
Dependency.get(TunerService.class).addTunable(tunable, keys);
}
private void bindLayout(ListPreference preference) {
@@ -123,7 +124,7 @@ public class NavBarTuner extends PreferenceFragment {
preference.setOnPreferenceChangeListener((preference1, newValue) -> {
String val = (String) newValue;
if ("default".equals(val)) val = null;
TunerService.get(getContext()).setValue(NAV_BAR_VIEWS, val);
Dependency.get(TunerService.class).setValue(NAV_BAR_VIEWS, val);
return true;
});
}
@@ -215,7 +216,7 @@ public class NavBarTuner extends PreferenceFragment {
}
button = button + KEY_CODE_START + code + KEY_IMAGE_DELIM + uri + KEY_CODE_END;
}
TunerService.get(getContext()).setValue(setting, button);
Dependency.get(TunerService.class).setValue(setting, button);
}
private void setupIcons(ListPreference icon) {

View File

@@ -18,6 +18,7 @@ import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.phone.NavigationBarInflaterView;
public class PreviewNavInflater extends NavigationBarInflaterView {
@@ -31,7 +32,7 @@ public class PreviewNavInflater extends NavigationBarInflaterView {
super.onAttachedToWindow();
// Immediately remove tuner listening, since this is a preview, all values will be injected
// manually.
TunerService.get(getContext()).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
}
@Override

View File

@@ -25,6 +25,7 @@ import android.util.AttributeSet;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -41,12 +42,12 @@ public class StatusBarSwitch extends SwitchPreference implements Tunable {
@Override
public void onAttached() {
super.onAttached();
TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
}
@Override
public void onDetached() {
TunerService.get(getContext()).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
super.onDetached();
}

View File

@@ -24,6 +24,7 @@ import android.support.v7.preference.PreferenceScreen;
import android.util.Log;
import com.android.settingslib.drawer.SettingsDrawerActivity;
import com.android.systemui.Dependency;
import com.android.systemui.R;
public class TunerActivity extends SettingsDrawerActivity implements
@@ -36,6 +37,7 @@ public class TunerActivity extends SettingsDrawerActivity implements
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Dependency.initDependencies(this);
if (getFragmentManager().findFragmentByTag(TAG_TUNER) == null) {
final String action = getIntent().getAction();

View File

@@ -40,6 +40,7 @@ import android.util.ArraySet;
import com.android.systemui.BatteryMeterDrawable;
import com.android.systemui.DemoMode;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIApplication;
@@ -51,7 +52,7 @@ import java.util.HashMap;
import java.util.Set;
public class TunerService extends SystemUI {
public class TunerService {
public static final String ACTION_CLEAR = "com.android.systemui.action.CLEAR_TUNER";
@@ -64,13 +65,14 @@ public class TunerService extends SystemUI {
private final ArrayMap<Uri, String> mListeningUris = new ArrayMap<>();
// Map of settings keys to the listener.
private final HashMap<String, Set<Tunable>> mTunableLookup = new HashMap<>();
private final Context mContext;
private ContentResolver mContentResolver;
private int mCurrentUser;
private CurrentUserTracker mUserTracker;
@Override
public void start() {
public TunerService(Context context) {
mContext = context;
mContentResolver = mContext.getContentResolver();
for (UserInfo user : UserManager.get(mContext).getUsers()) {
@@ -79,7 +81,6 @@ public class TunerService extends SystemUI {
upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION);
}
}
putComponent(TunerService.class, this);
mCurrentUser = ActivityManager.getCurrentUser();
mUserTracker = new CurrentUserTracker(mContext) {
@@ -209,32 +210,6 @@ public class TunerService extends SystemUI {
}
}
// Only used in other processes, such as the tuner.
private static TunerService sInstance;
public static TunerService get(Context context) {
TunerService service = null;
if (context.getApplicationContext() instanceof SystemUIApplication) {
SystemUIApplication sysUi = (SystemUIApplication) context.getApplicationContext();
service = sysUi.getComponent(TunerService.class);
}
if (service == null) {
// Can't get it as a component, must in the tuner, lets just create one for now.
return getStaticService(context);
}
return service;
}
private static TunerService getStaticService(Context context) {
if (sInstance == null) {
sInstance = new TunerService();
sInstance.mContext = context.getApplicationContext();
sInstance.mComponents = new HashMap<>();
sInstance.start();
}
return sInstance;
}
public static final void showResetRequest(final Context context, final Runnable onDisabled) {
SystemUIDialog dialog = new SystemUIDialog(context);
dialog.setShowForAllUsers(true);
@@ -310,7 +285,7 @@ public class TunerService extends SystemUI {
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_CLEAR.equals(intent.getAction())) {
get(context).clearAll();
Dependency.get(TunerService.class).clearAll();
}
}
}

View File

@@ -7,6 +7,7 @@ import android.support.v14.preference.SwitchPreference;
import android.util.AttributeSet;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -26,12 +27,12 @@ public class TunerSwitch extends SwitchPreference implements Tunable {
@Override
public void onAttached() {
super.onAttached();
TunerService.get(getContext()).addTunable(this, getKey().split(","));
Dependency.get(TunerService.class).addTunable(this, getKey().split(","));
}
@Override
public void onDetached() {
TunerService.get(getContext()).removeTunable(this);
Dependency.get(TunerService.class).removeTunable(this);
super.onDetached();
}

View File

@@ -69,6 +69,7 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -165,7 +166,7 @@ public class VolumeDialog implements TunerService.Tunable {
controller.addCallback(mControllerCallbackH, mHandler);
controller.getState();
TunerService.get(mContext).addTunable(this, SHOW_FULL_ZEN);
Dependency.get(TunerService.class).addTunable(this, SHOW_FULL_ZEN);
final Configuration currentConfig = mContext.getResources().getConfiguration();
mDensity = currentConfig.densityDpi;

View File

@@ -72,7 +72,7 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna
mDialog = new VolumeDialog(context, WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY,
mController, mZenModeController, mVolumeDialogCallback);
applyConfiguration();
TunerService.get(mContext).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
Dependency.get(TunerService.class).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
VOLUME_SILENT_DO_NOT_DISTURB);
}

View File

@@ -17,6 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.systemui.tests">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" />
<uses-permission android:name="android.permission.INJECT_EVENTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

View File

@@ -19,13 +19,17 @@ import android.app.Fragment;
import android.app.FragmentController;
import android.app.FragmentHostCallback;
import android.app.FragmentManagerNonConfig;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout;
import com.android.systemui.utils.ViewUtils;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import org.junit.After;
@@ -45,7 +49,6 @@ public abstract class FragmentTestCase extends LeakCheckedTest {
private static final int VIEW_ID = 42;
private final Class<? extends Fragment> mCls;
private HandlerThread mHandlerThread;
private Handler mHandler;
private FrameLayout mView;
protected FragmentController mFragments;
@@ -59,9 +62,7 @@ public abstract class FragmentTestCase extends LeakCheckedTest {
public void setupFragment() throws IllegalAccessException, InstantiationException {
mView = new FrameLayout(mContext);
mView.setId(VIEW_ID);
mHandlerThread = new HandlerThread("FragmentTestThread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mHandler = new Handler(Looper.getMainLooper());
mFragment = mCls.newInstance();
postAndWait(() -> {
mFragments = FragmentController.createController(new HostCallbacks());
@@ -78,7 +79,6 @@ public abstract class FragmentTestCase extends LeakCheckedTest {
// Set mFragments to null to let it know not to destroy.
postAndWait(() -> mFragments.dispatchDestroy());
}
mHandlerThread.quit();
}
@Test
@@ -99,6 +99,26 @@ public abstract class FragmentTestCase extends LeakCheckedTest {
postAndWait(() -> mFragments.dispatchPause());
}
@Test
public void testAttachDetach() {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
LayoutParams.TYPE_SYSTEM_ALERT,
0, PixelFormat.TRANSLUCENT);
postAndWait(() -> mFragments.dispatchResume());
attachFragmentToWindow();
detachFragmentToWindow();
postAndWait(() -> mFragments.dispatchPause());
}
protected void attachFragmentToWindow() {
ViewUtils.attachView(mView);
}
protected void detachFragmentToWindow() {
ViewUtils.detachView(mView);
}
@Test
public void testRecreate() {
postAndWait(() -> mFragments.dispatchResume());

View File

@@ -65,7 +65,7 @@ public abstract class SysuiTestCase {
waitForIdleSync(mHandler);
}
protected void waitForIdleSync(Handler h) {
public static void waitForIdleSync(Handler h) {
validateThread(h.getLooper());
Idler idler = new Idler(null);
h.getLooper().getQueue().addIdleHandler(idler);

View File

@@ -42,6 +42,7 @@ import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import org.junit.Before;
import org.junit.Test;
@@ -60,11 +61,7 @@ public class QSFragmentTest extends FragmentTestCase {
public void addLeakCheckDependencies() {
injectTestDependency(Dependency.BG_LOOPER, Looper.getMainLooper());
injectMockDependency(UserSwitcherController.class);
injectLeakCheckedDependencies(BluetoothController.class, LocationController.class,
RotationLockController.class, NetworkController.class, ZenModeController.class,
HotspotController.class, CastController.class, FlashlightController.class,
UserInfoController.class, KeyguardMonitor.class, SecurityController.class,
BatteryController.class, NextAlarmController.class);
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
}
@Test
@@ -88,6 +85,6 @@ public class QSFragmentTest extends FragmentTestCase {
host.destroy();
// Ensure the tuner cleans up its persistent listeners.
TunerService.get(mContext).destroy();
Dependency.get(TunerService.class).destroy();
}
}

View File

@@ -0,0 +1,36 @@
/*
* 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;
import com.android.systemui.utils.ViewUtils;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import org.junit.Before;
import org.junit.Test;
public class NotificationMenuRowTest extends LeakCheckedTest {
@Before
public void setup() {
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
}
@Test
public void testAttachDetach() {
NotificationMenuRow row = new NotificationMenuRow(mContext);
ViewUtils.attachView(row);
ViewUtils.detachView(row);
}
}

View File

@@ -40,6 +40,7 @@ public class NavigationBarFragmentTest extends FragmentTestCase {
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);
}
@Test

View File

@@ -0,0 +1,46 @@
/*
* 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;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.support.test.InstrumentationRegistry;
import com.android.systemui.SysuiTestCase;
public class ViewUtils {
public static void attachView(View view) {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
LayoutParams.TYPE_SYSTEM_ALERT,
0, PixelFormat.TRANSLUCENT);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> InstrumentationRegistry.getContext()
.getSystemService(WindowManager.class).addView(view, lp));
SysuiTestCase.waitForIdleSync(handler);
}
public static void detachView(View view) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> InstrumentationRegistry.getContext()
.getSystemService(WindowManager.class).removeView(view));
SysuiTestCase.waitForIdleSync(handler);
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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 android.content.Context;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
public class FakePluginManager extends PluginManager {
private final BaseLeakChecker<PluginListener> mLeakChecker;
public FakePluginManager(Context context, LeakCheckedTest test) {
super(context);
mLeakChecker = new BaseLeakChecker<>(test, "Plugin");
}
@Override
public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
int version) {
mLeakChecker.addCallback(listener);
}
@Override
public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
int version, boolean allowMultiple) {
mLeakChecker.addCallback(listener);
}
@Override
public void removePluginListener(PluginListener<?> listener) {
mLeakChecker.removeCallback(listener);
}
@Override
public <T extends Plugin> T getOneShotPlugin(String action, int version) {
return null;
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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 android.content.Context;
import com.android.systemui.tuner.TunerService;
public class FakeTunerService extends TunerService {
private final BaseLeakChecker<Tunable> mBaseLeakChecker;
public FakeTunerService(Context context, LeakCheckedTest test) {
super(context);
mBaseLeakChecker = new BaseLeakChecker<>(test, "tunable");
}
@Override
public void addTunable(Tunable tunable, String... keys) {
for (String key : keys) {
tunable.onTuningChanged(key, null);
}
mBaseLeakChecker.addCallback(tunable);
}
@Override
public void removeTunable(Tunable tunable) {
mBaseLeakChecker.removeCallback(tunable);
}
}

View File

@@ -20,6 +20,7 @@ import static org.mockito.Mockito.doAnswer;
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.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
@@ -35,6 +36,7 @@ import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.SecurityController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
import org.junit.Assert;
import org.junit.Rule;
@@ -56,6 +58,25 @@ public abstract class LeakCheckedTest extends SysuiTestCase {
private final Map<String, Tracker> mTrackers = new HashMap<>();
private final Map<Class, Object> mLeakCheckers = new ArrayMap<>();
public static final Class<?>[] ALL_SUPPORTED_CLASSES = new Class[] {
BluetoothController.class,
LocationController.class,
RotationLockController.class,
ZenModeController.class,
CastController.class,
HotspotController.class,
FlashlightController.class,
UserInfoController.class,
KeyguardMonitor.class,
BatteryController.class,
SecurityController.class,
ManagedProfileController.class,
NextAlarmController.class,
NetworkController.class,
PluginManager.class,
TunerService.class,
};
@Rule
public TestWatcher successWatcher = new TestWatcher() {
@Override
@@ -96,6 +117,10 @@ public abstract class LeakCheckedTest extends SysuiTestCase {
obj = new FakeNextAlarmController(this);
} else if (cls == NetworkController.class) {
obj = new FakeNetworkController(this);
} else if (cls == PluginManager.class) {
obj = new FakePluginManager(mContext, this);
} else if (cls == TunerService.class) {
obj = new FakeTunerService(mContext, this);
} else {
Assert.fail(cls.getName() + " is not supported by LeakCheckedTest yet");
}