/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.stetho.inspector.elements.android;
import android.app.Dialog;
import android.graphics.Rect;
import android.view.View;
import com.facebook.stetho.common.Accumulator;
import com.facebook.stetho.common.LogUtil;
import com.facebook.stetho.common.Util;
import com.facebook.stetho.common.android.DialogFragmentAccessor;
import com.facebook.stetho.common.android.FragmentCompat;
import com.facebook.stetho.inspector.elements.AbstractChainedDescriptor;
import com.facebook.stetho.inspector.elements.AttributeAccumulator;
import com.facebook.stetho.inspector.elements.ChainedDescriptor;
import com.facebook.stetho.inspector.elements.ComputedStyleAccumulator;
import com.facebook.stetho.inspector.elements.Descriptor;
import com.facebook.stetho.inspector.elements.DescriptorMap;
import com.facebook.stetho.inspector.elements.NodeType;
import com.facebook.stetho.inspector.elements.StyleAccumulator;
import com.facebook.stetho.inspector.elements.StyleRuleNameAccumulator;
import javax.annotation.Nullable;
final class DialogFragmentDescriptor
extends Descriptor<Object>
implements ChainedDescriptor<Object>, HighlightableDescriptor<Object> {
private final DialogFragmentAccessor mAccessor;
private Descriptor<? super Object> mSuper;
public static DescriptorMap register(DescriptorMap map) {
maybeRegister(map, FragmentCompat.getSupportLibInstance());
maybeRegister(map, FragmentCompat.getFrameworkInstance());
return map;
}
private static void maybeRegister(DescriptorMap map, @Nullable FragmentCompat compat) {
if (compat != null) {
Class<?> dialogFragmentClass = compat.getDialogFragmentClass();
LogUtil.d("Adding support for %s", dialogFragmentClass);
map.registerDescriptor(dialogFragmentClass, new DialogFragmentDescriptor(compat));
}
}
private DialogFragmentDescriptor(FragmentCompat compat) {
mAccessor = compat.forDialogFragment();
}
@Override
public void setSuper(Descriptor<? super Object> superDescriptor) {
Util.throwIfNull(superDescriptor);
if (superDescriptor != mSuper) {
if (mSuper != null) {
throw new IllegalStateException();
}
mSuper = superDescriptor;
}
}
@Override
public void hook(Object element) {
mSuper.hook(element);
}
@Override
public void unhook(Object element) {
mSuper.unhook(element);
}
@Override
public NodeType getNodeType(Object element) {
return mSuper.getNodeType(element);
}
@Override
public String getNodeName(Object element) {
return mSuper.getNodeName(element);
}
@Override
public String getLocalName(Object element) {
return mSuper.getLocalName(element);
}
@Nullable
@Override
public String getNodeValue(Object element) {
return mSuper.getNodeValue(element);
}
@Override
public void getChildren(Object element, Accumulator<Object> children) {
/**
* We do NOT want the children from our super-{@link Descriptor}, which is probably
* {@link FragmentDescriptor}. We only want to emit the {@link Dialog}, not the {@link View}.
* Therefore, we don't call mSuper.getChildren(), and this is the reason why we don't derive
* from {@link AbstractChainedDescriptor} (it doesn't allow a non-chained implementation of
* {@link Descriptor#getChildren(Object, Accumulator)}).
*/
children.store(mAccessor.getDialog(element));
}
@Override
public void getAttributes(Object element, AttributeAccumulator attributes) {
mSuper.getAttributes(element, attributes);
}
@Override
public void setAttributesAsText(Object element, String text) {
mSuper.setAttributesAsText(element, text);
}
@Nullable
@Override
public View getViewAndBoundsForHighlighting(Object element, Rect bounds) {
final Descriptor.Host host = getHost();
Dialog dialog = null;
HighlightableDescriptor descriptor = null;
if (host instanceof AndroidDescriptorHost) {
dialog = mAccessor.getDialog(element);
descriptor = ((AndroidDescriptorHost) host).getHighlightableDescriptor(dialog);
}
return descriptor == null
? null
: descriptor.getViewAndBoundsForHighlighting(dialog, bounds);
}
@Nullable
@Override
public Object getElementToHighlightAtPosition(Object element, int x, int y, Rect bounds) {
final Descriptor.Host host = getHost();
Dialog dialog = null;
HighlightableDescriptor descriptor = null;
if (host instanceof AndroidDescriptorHost) {
dialog = mAccessor.getDialog(element);
descriptor = ((AndroidDescriptorHost) host).getHighlightableDescriptor(dialog);
}
return descriptor == null
? null
: descriptor.getElementToHighlightAtPosition(dialog, x, y, bounds);
}
@Override
public void getStyleRuleNames(Object element, StyleRuleNameAccumulator accumulator) {
}
@Override
public void getStyles(Object element, String ruleName, StyleAccumulator accumulator) {
}
@Override
public void setStyle(Object element, String ruleName, String name, String value) {
}
@Override
public void getComputedStyles(Object element, ComputedStyleAccumulator styles) {
}
}