Sysui: Add support for view injection
Test: Existing tests pass Change-Id: Ic6931ebec38ca9514e9368239dd9502ae2dee33c
This commit is contained in:
@@ -147,6 +147,52 @@ then the FragmentHostManager can do this for you.
|
|||||||
FragmentHostManager.get(view).create(NavigationBarFragment.class);
|
FragmentHostManager.get(view).create(NavigationBarFragment.class);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Using injection with Views
|
||||||
|
|
||||||
|
Generally, you shouldn't need to inject for a view, as the view should
|
||||||
|
be relatively self contained and logic that requires injection should be
|
||||||
|
moved to a higher level construct such as a Fragment or a top-level SystemUI
|
||||||
|
component, see above for how to do injection for both of which.
|
||||||
|
|
||||||
|
Still here? Yeah, ok, sysui has a lot of pre-existing views that contain a
|
||||||
|
lot of code that could benefit from injection and will need to be migrated
|
||||||
|
off from Dependency#get uses. Similar to how fragments are injected, the view
|
||||||
|
needs to be added to the interface
|
||||||
|
com.android.systemui.util.InjectionInflationController$ViewInstanceCreator.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface ViewInstanceCreator {
|
||||||
|
+ QuickStatusBarHeader createQsHeader();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Presumably you need to inflate that view from XML (otherwise why do you
|
||||||
|
need anything special? see earlier sections about generic injection). To obtain
|
||||||
|
an inflater that supports injected objects, call InjectionInflationController#injectable,
|
||||||
|
which will wrap the inflater it is passed in one that can create injected
|
||||||
|
objects when needed.
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
return mInjectionInflater.injectable(inflater).inflate(R.layout.my_layout, container, false);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
There is one other important thing to note about injecting with views. SysUI
|
||||||
|
already has a Context in its global dagger component, so if you simply inject
|
||||||
|
a Context, you will not get the one that the view should have with proper
|
||||||
|
theming. Because of this, always ensure to tag views that have @Inject with
|
||||||
|
the @Named view context.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public CustomView(@Named(VIEW_CONTEXT) Context themedViewContext, AttributeSet attrs,
|
||||||
|
OtherCustomDependency something) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## TODO List
|
## TODO List
|
||||||
|
|
||||||
- Eliminate usages of Depndency#get
|
- Eliminate usages of Depndency#get
|
||||||
|
|||||||
@@ -31,4 +31,7 @@
|
|||||||
-keep class com.android.systemui.fragments.FragmentService$FragmentCreator {
|
-keep class com.android.systemui.fragments.FragmentService$FragmentCreator {
|
||||||
*;
|
*;
|
||||||
}
|
}
|
||||||
|
-keep class com.android.systemui.util.InjectionInflationController$ViewInstanceCreator {
|
||||||
|
*;
|
||||||
|
}
|
||||||
-keep class androidx.core.app.CoreComponentFactory
|
-keep class androidx.core.app.CoreComponentFactory
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import android.os.Process;
|
|||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
import android.view.WindowManagerGlobal;
|
import android.view.WindowManagerGlobal;
|
||||||
|
|
||||||
@@ -470,7 +469,6 @@ public class DependencyProvider {
|
|||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
public UiOffloadThread provideUiOffloadThread() {
|
public UiOffloadThread provideUiOffloadThread() {
|
||||||
Log.d("TestTest", "provideUiOffloadThread");
|
|
||||||
return new UiOffloadThread();
|
return new UiOffloadThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
|
|||||||
import com.android.systemui.statusbar.ScrimView;
|
import com.android.systemui.statusbar.ScrimView;
|
||||||
import com.android.systemui.statusbar.notification.NotificationData;
|
import com.android.systemui.statusbar.notification.NotificationData;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||||
import com.android.systemui.statusbar.notification.NotificationRowBinder;
|
|
||||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||||
import com.android.systemui.statusbar.phone.KeyguardBouncer;
|
import com.android.systemui.statusbar.phone.KeyguardBouncer;
|
||||||
import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
|
import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
|
||||||
@@ -55,6 +54,7 @@ import com.android.systemui.statusbar.phone.StatusBar;
|
|||||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||||
|
import com.android.systemui.util.InjectionInflationController;
|
||||||
import com.android.systemui.volume.VolumeDialogComponent;
|
import com.android.systemui.volume.VolumeDialogComponent;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -223,5 +223,10 @@ public class SystemUIFactory {
|
|||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
FragmentService.FragmentCreator createFragmentCreator();
|
FragmentService.FragmentCreator createFragmentCreator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ViewCreator generates all Views that need injection.
|
||||||
|
*/
|
||||||
|
InjectionInflationController.ViewCreator createViewCreator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import com.android.systemui.statusbar.CommandQueue;
|
|||||||
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
|
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
|
||||||
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
|
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
|
||||||
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
|
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
|
||||||
|
import com.android.systemui.util.InjectionInflationController;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -76,16 +77,20 @@ public class QSFragment extends Fragment implements QS, CommandQueue.Callbacks {
|
|||||||
private boolean mQsDisabled;
|
private boolean mQsDisabled;
|
||||||
|
|
||||||
private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
|
private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
|
||||||
|
private final InjectionInflationController mInjectionInflater;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler) {
|
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
|
||||||
|
InjectionInflationController injectionInflater) {
|
||||||
mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
|
mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
|
||||||
|
mInjectionInflater = injectionInflater;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
inflater = inflater.cloneInContext(new ContextThemeWrapper(getContext(), R.style.qs_theme));
|
inflater = mInjectionInflater.injectable(
|
||||||
|
inflater.cloneInContext(new ContextThemeWrapper(getContext(), R.style.qs_theme)));
|
||||||
return inflater.inflate(R.layout.qs_panel, container, false);
|
return inflater.inflate(R.layout.qs_panel, container, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ package com.android.systemui.qs;
|
|||||||
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
|
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
|
||||||
import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
|
import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
|
||||||
|
|
||||||
|
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.annotation.ColorInt;
|
import android.annotation.ColorInt;
|
||||||
@@ -58,7 +60,6 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
|
|
||||||
import com.android.settingslib.Utils;
|
import com.android.settingslib.Utils;
|
||||||
import com.android.systemui.BatteryMeterView;
|
import com.android.systemui.BatteryMeterView;
|
||||||
import com.android.systemui.Dependency;
|
|
||||||
import com.android.systemui.Prefs;
|
import com.android.systemui.Prefs;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
@@ -84,6 +85,9 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View that contains the top-most bits of the screen (primarily the status bar with date, time, and
|
* View that contains the top-most bits of the screen (primarily the status bar with date, time, and
|
||||||
* battery) and also contains the {@link QuickQSPanel} along with some of the panel's inner
|
* battery) and also contains the {@link QuickQSPanel} along with some of the panel's inner
|
||||||
@@ -102,6 +106,11 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
public static final int MAX_TOOLTIP_SHOWN_COUNT = 2;
|
public static final int MAX_TOOLTIP_SHOWN_COUNT = 2;
|
||||||
|
|
||||||
private final Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
|
private final BatteryController mBatteryController;
|
||||||
|
private final NextAlarmController mAlarmController;
|
||||||
|
private final ZenModeController mZenController;
|
||||||
|
private final StatusBarIconController mStatusBarIconController;
|
||||||
|
private final ActivityStarter mActivityStarter;
|
||||||
|
|
||||||
private QSPanel mQsPanel;
|
private QSPanel mQsPanel;
|
||||||
|
|
||||||
@@ -141,8 +150,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
private TextView mBatteryRemainingText;
|
private TextView mBatteryRemainingText;
|
||||||
private boolean mShowBatteryPercentAndEstimate;
|
private boolean mShowBatteryPercentAndEstimate;
|
||||||
|
|
||||||
private NextAlarmController mAlarmController;
|
|
||||||
private ZenModeController mZenController;
|
|
||||||
private PrivacyItemController mPrivacyItemController;
|
private PrivacyItemController mPrivacyItemController;
|
||||||
/** Counts how many times the long press tooltip has been shown to the user. */
|
/** Counts how many times the long press tooltip has been shown to the user. */
|
||||||
private int mShownCount;
|
private int mShownCount;
|
||||||
@@ -172,10 +179,17 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public QuickStatusBarHeader(Context context, AttributeSet attrs) {
|
@Inject
|
||||||
|
public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
|
||||||
|
NextAlarmController nextAlarmController, ZenModeController zenModeController,
|
||||||
|
BatteryController batteryController, StatusBarIconController statusBarIconController,
|
||||||
|
ActivityStarter activityStarter) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
mAlarmController = Dependency.get(NextAlarmController.class);
|
mAlarmController = nextAlarmController;
|
||||||
mZenController = Dependency.get(ZenModeController.class);
|
mZenController = zenModeController;
|
||||||
|
mBatteryController = batteryController;
|
||||||
|
mStatusBarIconController = statusBarIconController;
|
||||||
|
mActivityStarter = activityStarter;
|
||||||
mPrivacyItemController = new PrivacyItemController(context, mPICCallback);
|
mPrivacyItemController = new PrivacyItemController(context, mPICCallback);
|
||||||
mShownCount = getStoredShownCount();
|
mShownCount = getStoredShownCount();
|
||||||
}
|
}
|
||||||
@@ -405,8 +419,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
if (!mShowBatteryPercentAndEstimate) {
|
if (!mShowBatteryPercentAndEstimate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mBatteryRemainingText.setText(
|
mBatteryRemainingText.setText(mBatteryController.getEstimatedTimeRemainingString());
|
||||||
Dependency.get(BatteryController.class).getEstimatedTimeRemainingString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExpanded(boolean expanded) {
|
public void setExpanded(boolean expanded) {
|
||||||
@@ -472,7 +485,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
@Override
|
@Override
|
||||||
public void onAttachedToWindow() {
|
public void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
|
mStatusBarIconController.addIconGroup(mIconManager);
|
||||||
requestApplyInsets();
|
requestApplyInsets();
|
||||||
mContext.getContentResolver().registerContentObserver(
|
mContext.getContentResolver().registerContentObserver(
|
||||||
Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mPercentSettingObserver,
|
Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mPercentSettingObserver,
|
||||||
@@ -515,7 +528,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public void onDetachedFromWindow() {
|
public void onDetachedFromWindow() {
|
||||||
setListening(false);
|
setListening(false);
|
||||||
Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager);
|
mStatusBarIconController.removeIconGroup(mIconManager);
|
||||||
mContext.getContentResolver().unregisterContentObserver(mPercentSettingObserver);
|
mContext.getContentResolver().unregisterContentObserver(mPercentSettingObserver);
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
}
|
}
|
||||||
@@ -544,10 +557,10 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (v == mClockView) {
|
if (v == mClockView) {
|
||||||
Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(new Intent(
|
mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
|
||||||
AlarmClock.ACTION_SHOW_ALARMS),0);
|
AlarmClock.ACTION_SHOW_ALARMS),0);
|
||||||
} else if (v == mBatteryMeterView) {
|
} else if (v == mBatteryMeterView) {
|
||||||
Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(new Intent(
|
mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
|
||||||
Intent.ACTION_POWER_USAGE_SUMMARY),0);
|
Intent.ACTION_POWER_USAGE_SUMMARY),0);
|
||||||
} else if (v == mPrivacyChip) {
|
} else if (v == mPrivacyChip) {
|
||||||
Handler mUiHandler = new Handler(Looper.getMainLooper());
|
Handler mUiHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|||||||
@@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 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.util;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.InflateException;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.systemui.SystemUIFactory;
|
||||||
|
import com.android.systemui.qs.QuickStatusBarHeader;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
import dagger.Subcomponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages inflation that requires dagger injection.
|
||||||
|
* See docs/dagger.md for details.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class InjectionInflationController {
|
||||||
|
|
||||||
|
public static final String VIEW_CONTEXT = "view_context";
|
||||||
|
private final ViewCreator mViewCreator;
|
||||||
|
private final ArrayMap<String, Method> mInjectionMap = new ArrayMap<>();
|
||||||
|
private final LayoutInflater.Factory2 mFactory = new InjectionFactory();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public InjectionInflationController(SystemUIFactory.SystemUIRootComponent rootComponent) {
|
||||||
|
mViewCreator = rootComponent.createViewCreator();
|
||||||
|
initInjectionMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayMap<String, Method> getInjectionMap() {
|
||||||
|
return mInjectionMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewCreator getFragmentCreator() {
|
||||||
|
return mViewCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a {@link LayoutInflater} to support creating dagger injected views.
|
||||||
|
* See docs/dagger.md for details.
|
||||||
|
*/
|
||||||
|
public LayoutInflater injectable(LayoutInflater inflater) {
|
||||||
|
LayoutInflater ret = inflater.cloneInContext(inflater.getContext());
|
||||||
|
ret.setPrivateFactory(mFactory);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initInjectionMap() {
|
||||||
|
for (Method method : ViewInstanceCreator.class.getDeclaredMethods()) {
|
||||||
|
if (View.class.isAssignableFrom(method.getReturnType())
|
||||||
|
&& (method.getModifiers() & Modifier.PUBLIC) != 0) {
|
||||||
|
mInjectionMap.put(method.getReturnType().getName(), method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The subcomponent of dagger that holds all views that need injection.
|
||||||
|
*/
|
||||||
|
@Subcomponent
|
||||||
|
public interface ViewCreator {
|
||||||
|
/**
|
||||||
|
* Creates another subcomponent to actually generate the view.
|
||||||
|
*/
|
||||||
|
ViewInstanceCreator createInstanceCreator(ViewAttributeProvider attributeProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Secondary sub-component that actually creates the views.
|
||||||
|
*
|
||||||
|
* Having two subcomponents lets us hide the complexity of providing the named context
|
||||||
|
* and AttributeSet from the SystemUIRootComponent, instead we have one subcomponent that
|
||||||
|
* creates a new ViewInstanceCreator any time we need to inflate a view.
|
||||||
|
*/
|
||||||
|
@Subcomponent(modules = ViewAttributeProvider.class)
|
||||||
|
public interface ViewInstanceCreator {
|
||||||
|
/**
|
||||||
|
* Creates the QuickStatusBarHeader.
|
||||||
|
*/
|
||||||
|
QuickStatusBarHeader createQsHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module for providing view-specific constructor objects.
|
||||||
|
*/
|
||||||
|
@Module
|
||||||
|
public class ViewAttributeProvider {
|
||||||
|
private final Context mContext;
|
||||||
|
private final AttributeSet mAttrs;
|
||||||
|
|
||||||
|
private ViewAttributeProvider(Context context, AttributeSet attrs) {
|
||||||
|
mContext = context;
|
||||||
|
mAttrs = attrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the view-themed context (as opposed to the global sysui application context).
|
||||||
|
*/
|
||||||
|
@Provides
|
||||||
|
@Named(VIEW_CONTEXT)
|
||||||
|
public Context provideContext() {
|
||||||
|
return mContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the AttributeSet for the current view being inflated.
|
||||||
|
*/
|
||||||
|
@Provides
|
||||||
|
public AttributeSet provideAttributeSet() {
|
||||||
|
return mAttrs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class InjectionFactory implements LayoutInflater.Factory2 {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(String name, Context context, AttributeSet attrs) {
|
||||||
|
Method creationMethod = mInjectionMap.get(name);
|
||||||
|
if (creationMethod != null) {
|
||||||
|
ViewAttributeProvider provider = new ViewAttributeProvider(context, attrs);
|
||||||
|
try {
|
||||||
|
return (View) creationMethod.invoke(
|
||||||
|
mViewCreator.createInstanceCreator(provider));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new InflateException("Could not inflate " + name, e);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
throw new InflateException("Could not inflate " + name, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
|
||||||
|
return onCreateView(name, context, attrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,11 +34,13 @@ import com.android.internal.logging.MetricsLogger;
|
|||||||
import com.android.keyguard.CarrierText;
|
import com.android.keyguard.CarrierText;
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.SystemUIFactory;
|
||||||
import com.android.systemui.SysuiBaseFragmentTest;
|
import com.android.systemui.SysuiBaseFragmentTest;
|
||||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||||
import com.android.systemui.statusbar.policy.Clock;
|
import com.android.systemui.statusbar.policy.Clock;
|
||||||
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
|
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
|
||||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||||
|
import com.android.systemui.util.InjectionInflationController;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
@@ -122,6 +124,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Fragment instantiate(Context context, String className, Bundle arguments) {
|
protected Fragment instantiate(Context context, String className, Bundle arguments) {
|
||||||
return new QSFragment(new RemoteInputQuickSettingsDisabler(context));
|
return new QSFragment(new RemoteInputQuickSettingsDisabler(context),
|
||||||
|
new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user