Remove stetho (#762)
Summary: ## Summary Resolves https://github.com/facebook/flipper/issues/607 This removes stetho dependencies directly in favor of just copying in the used classes. This removes the last non-androidx dependency from the project, and is useful as stetho appears to be unmaintained. The fresco stetho dependency appeared to be completely unused. ## Changelog Remove stetho dependencies. It was unused other than a few utility methods, but came at the cost of preventing Flipper consumers from completely removing dependencies that hadn't updated to Androidx yet. Pull Request resolved: https://github.com/facebook/flipper/pull/762 Test Plan: Existing tests still pass with no regressions. Functionally this should be no difference. Reviewed By: jknoxville Differential Revision: D19577969 Pulled By: passy fbshipit-source-id: b277ddf97a9d2c846dd0b9227c02bb46c1ecd930
This commit is contained in:
committed by
Facebook Github Bot
parent
bdd4516dc4
commit
48d6ea4c30
@@ -14,9 +14,9 @@ import com.facebook.flipper.core.FlipperObject;
|
||||
import com.facebook.flipper.plugins.inspector.Named;
|
||||
import com.facebook.flipper.plugins.inspector.NodeDescriptor;
|
||||
import com.facebook.flipper.plugins.inspector.Touch;
|
||||
import com.facebook.stetho.common.android.FragmentActivityAccessor;
|
||||
import com.facebook.stetho.common.android.FragmentCompat;
|
||||
import com.facebook.stetho.common.android.FragmentManagerAccessor;
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies.FragmentActivityAccessor;
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies.FragmentCompat;
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies.FragmentManagerAccessor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -15,7 +15,7 @@ import com.facebook.flipper.core.FlipperObject;
|
||||
import com.facebook.flipper.plugins.inspector.Named;
|
||||
import com.facebook.flipper.plugins.inspector.NodeDescriptor;
|
||||
import com.facebook.flipper.plugins.inspector.Touch;
|
||||
import com.facebook.stetho.common.android.ResourcesUtil;
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies.ResourcesUtil;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -15,7 +15,7 @@ import com.facebook.flipper.core.FlipperObject;
|
||||
import com.facebook.flipper.plugins.inspector.Named;
|
||||
import com.facebook.flipper.plugins.inspector.NodeDescriptor;
|
||||
import com.facebook.flipper.plugins.inspector.Touch;
|
||||
import com.facebook.stetho.common.android.ResourcesUtil;
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies.ResourcesUtil;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -39,7 +39,7 @@ import com.facebook.flipper.plugins.inspector.descriptors.utils.AccessibilityEva
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.AccessibilityRoleUtil;
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.AccessibilityUtil;
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.EnumMapping;
|
||||
import com.facebook.stetho.common.android.ResourcesUtil;
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies.ResourcesUtil;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.facebook.flipper.plugins.inspector.InspectorValue;
|
||||
import com.facebook.flipper.plugins.inspector.Named;
|
||||
import com.facebook.flipper.plugins.inspector.NodeDescriptor;
|
||||
import com.facebook.flipper.plugins.inspector.Touch;
|
||||
import com.facebook.stetho.common.android.FragmentCompatUtil;
|
||||
import com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies.FragmentCompatUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.app.Dialog;
|
||||
|
||||
public interface DialogFragmentAccessor<DIALOG_FRAGMENT, FRAGMENT, FRAGMENT_MANAGER>
|
||||
extends FragmentAccessor<FRAGMENT, FRAGMENT_MANAGER> {
|
||||
Dialog getDialog(DIALOG_FRAGMENT dialogFragment);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface FragmentAccessor<FRAGMENT, FRAGMENT_MANAGER> {
|
||||
int NO_ID = 0;
|
||||
|
||||
@Nullable
|
||||
FRAGMENT_MANAGER getFragmentManager(FRAGMENT fragment);
|
||||
|
||||
Resources getResources(FRAGMENT fragment);
|
||||
|
||||
int getId(FRAGMENT fragment);
|
||||
|
||||
@Nullable
|
||||
String getTag(FRAGMENT fragment);
|
||||
|
||||
@Nullable
|
||||
View getView(FRAGMENT fragment);
|
||||
|
||||
@Nullable
|
||||
FRAGMENT_MANAGER getChildFragmentManager(FRAGMENT fragment);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.app.Activity;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface FragmentActivityAccessor<FRAGMENT_ACTIVITY extends Activity, FRAGMENT_MANAGER> {
|
||||
@Nullable
|
||||
FRAGMENT_MANAGER getFragmentManager(FRAGMENT_ACTIVITY activity);
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Build;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
/**
|
||||
* Compatibility abstraction which allows us to generalize access to both the support library's
|
||||
* fragments and the built-in framework version. Note: both versions can be live at the same time in
|
||||
* a single application and even on a single object instance.
|
||||
*
|
||||
* <p>Type safety is enforced via generics internal to the implementation but treated as opaque from
|
||||
* the outside.
|
||||
*
|
||||
* @param <FRAGMENT>
|
||||
* @param <DIALOG_FRAGMENT>
|
||||
* @param <FRAGMENT_MANAGER>
|
||||
* @param <FRAGMENT_ACTIVITY>
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public abstract class FragmentCompat<
|
||||
FRAGMENT, DIALOG_FRAGMENT, FRAGMENT_MANAGER, FRAGMENT_ACTIVITY extends Activity> {
|
||||
private static FragmentCompat sFrameworkInstance;
|
||||
private static FragmentCompat sSupportInstance;
|
||||
|
||||
private static final boolean sHasSupportFragment;
|
||||
|
||||
static {
|
||||
sHasSupportFragment =
|
||||
ReflectionUtil.tryGetClassForName("android.support.v4.app.Fragment") != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FragmentCompat getFrameworkInstance() {
|
||||
if (sFrameworkInstance == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
sFrameworkInstance = new FragmentCompatFramework();
|
||||
}
|
||||
return sFrameworkInstance;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FragmentCompat getSupportLibInstance() {
|
||||
if (sSupportInstance == null && sHasSupportFragment) {
|
||||
sSupportInstance = new FragmentCompatSupportLib();
|
||||
}
|
||||
return sSupportInstance;
|
||||
}
|
||||
|
||||
FragmentCompat() {}
|
||||
|
||||
public abstract Class<FRAGMENT> getFragmentClass();
|
||||
|
||||
public abstract Class<DIALOG_FRAGMENT> getDialogFragmentClass();
|
||||
|
||||
public abstract Class<FRAGMENT_ACTIVITY> getFragmentActivityClass();
|
||||
|
||||
public abstract FragmentAccessor<FRAGMENT, FRAGMENT_MANAGER> forFragment();
|
||||
|
||||
public abstract DialogFragmentAccessor<DIALOG_FRAGMENT, FRAGMENT, FRAGMENT_MANAGER>
|
||||
forDialogFragment();
|
||||
|
||||
public abstract FragmentManagerAccessor<FRAGMENT_MANAGER, FRAGMENT> forFragmentManager();
|
||||
|
||||
public abstract FragmentActivityAccessor<FRAGMENT_ACTIVITY, FRAGMENT_MANAGER>
|
||||
forFragmentActivity();
|
||||
|
||||
static class FragmentManagerAccessorViaReflection<FRAGMENT_MANAGER, FRAGMENT>
|
||||
implements FragmentManagerAccessor<FRAGMENT_MANAGER, FRAGMENT> {
|
||||
@Nullable private Field mFieldMAdded;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
@Override
|
||||
public List<FRAGMENT> getAddedFragments(FRAGMENT_MANAGER fragmentManager) {
|
||||
// This field is actually sitting on FragmentManagerImpl, which derives from FragmentManager.
|
||||
if (mFieldMAdded == null) {
|
||||
Field fieldMAdded =
|
||||
ReflectionUtil.tryGetDeclaredField(fragmentManager.getClass(), "mAdded");
|
||||
|
||||
if (fieldMAdded != null) {
|
||||
fieldMAdded.setAccessible(true);
|
||||
mFieldMAdded = fieldMAdded;
|
||||
}
|
||||
}
|
||||
|
||||
return (mFieldMAdded != null)
|
||||
? (List<FRAGMENT>) ReflectionUtil.getFieldValue(mFieldMAdded, fragmentManager)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
final class FragmentCompatFramework
|
||||
extends FragmentCompat<Fragment, DialogFragment, FragmentManager, Activity> {
|
||||
private static final FragmentAccessorFrameworkHoneycomb sFragmentAccessor;
|
||||
private static final DialogFragmentAccessorFramework sDialogFragmentAccessor;
|
||||
private static final FragmentManagerAccessorViaReflection<FragmentManager, Fragment>
|
||||
sFragmentManagerAccessor = new FragmentManagerAccessorViaReflection<>();
|
||||
private static final FragmentActivityAccessorFramework sFragmentActivityAccessor =
|
||||
new FragmentActivityAccessorFramework();
|
||||
|
||||
static {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
sFragmentAccessor = new FragmentAccessorFrameworkJellyBean();
|
||||
} else {
|
||||
sFragmentAccessor = new FragmentAccessorFrameworkHoneycomb();
|
||||
}
|
||||
|
||||
sDialogFragmentAccessor = new DialogFragmentAccessorFramework(sFragmentAccessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Fragment> getFragmentClass() {
|
||||
return Fragment.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<DialogFragment> getDialogFragmentClass() {
|
||||
return DialogFragment.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Activity> getFragmentActivityClass() {
|
||||
return Activity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FragmentAccessorFrameworkHoneycomb forFragment() {
|
||||
return sFragmentAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialogFragmentAccessorFramework forDialogFragment() {
|
||||
return sDialogFragmentAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FragmentManagerAccessorViaReflection<FragmentManager, Fragment> forFragmentManager() {
|
||||
return sFragmentManagerAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FragmentActivityAccessorFramework forFragmentActivity() {
|
||||
return sFragmentActivityAccessor;
|
||||
}
|
||||
|
||||
private static class FragmentAccessorFrameworkHoneycomb
|
||||
implements FragmentAccessor<Fragment, FragmentManager> {
|
||||
@Nullable
|
||||
@Override
|
||||
public FragmentManager getFragmentManager(Fragment fragment) {
|
||||
return fragment.getFragmentManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources(Fragment fragment) {
|
||||
return fragment.getResources();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(Fragment fragment) {
|
||||
return fragment.getId();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTag(Fragment fragment) {
|
||||
return fragment.getTag();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View getView(Fragment fragment) {
|
||||
return fragment.getView();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FragmentManager getChildFragmentManager(Fragment fragment) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
private static class FragmentAccessorFrameworkJellyBean
|
||||
extends FragmentAccessorFrameworkHoneycomb {
|
||||
@Nullable
|
||||
@Override
|
||||
public FragmentManager getChildFragmentManager(Fragment fragment) {
|
||||
return fragment.getChildFragmentManager();
|
||||
}
|
||||
}
|
||||
|
||||
private static class DialogFragmentAccessorFramework
|
||||
implements DialogFragmentAccessor<DialogFragment, Fragment, FragmentManager> {
|
||||
private final FragmentAccessor<Fragment, FragmentManager> mFragmentAccessor;
|
||||
|
||||
public DialogFragmentAccessorFramework(
|
||||
FragmentAccessor<Fragment, FragmentManager> fragmentAccessor) {
|
||||
mFragmentAccessor = fragmentAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog getDialog(DialogFragment dialogFragment) {
|
||||
return dialogFragment.getDialog();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FragmentManager getFragmentManager(Fragment fragment) {
|
||||
return mFragmentAccessor.getFragmentManager(fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources(Fragment fragment) {
|
||||
return mFragmentAccessor.getResources(fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(Fragment fragment) {
|
||||
return mFragmentAccessor.getId(fragment);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTag(Fragment fragment) {
|
||||
return mFragmentAccessor.getTag(fragment);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View getView(Fragment fragment) {
|
||||
return mFragmentAccessor.getView(fragment);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FragmentManager getChildFragmentManager(Fragment fragment) {
|
||||
return mFragmentAccessor.getChildFragmentManager(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FragmentActivityAccessorFramework
|
||||
implements FragmentActivityAccessor<Activity, FragmentManager> {
|
||||
@Nullable
|
||||
@Override
|
||||
public FragmentManager getFragmentManager(Activity activity) {
|
||||
return activity.getFragmentManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
final class FragmentCompatSupportLib
|
||||
extends FragmentCompat<Fragment, DialogFragment, FragmentManager, FragmentActivity> {
|
||||
private static final FragmentAccessorSupportLib sFragmentAccessor =
|
||||
new FragmentAccessorSupportLib();
|
||||
private static final DialogFragmentAccessorSupportLib sDialogFragmentAccessor =
|
||||
new DialogFragmentAccessorSupportLib();
|
||||
private static final FragmentManagerAccessorViaReflection<FragmentManager, Fragment>
|
||||
sFragmentManagerAccessor = new FragmentManagerAccessorViaReflection<>();
|
||||
private static final FragmentActivityAccessorSupportLib sFragmentActivityAccessor =
|
||||
new FragmentActivityAccessorSupportLib();
|
||||
|
||||
@Override
|
||||
public Class<Fragment> getFragmentClass() {
|
||||
return Fragment.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<DialogFragment> getDialogFragmentClass() {
|
||||
return DialogFragment.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<FragmentActivity> getFragmentActivityClass() {
|
||||
return FragmentActivity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FragmentAccessorSupportLib forFragment() {
|
||||
return sFragmentAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialogFragmentAccessorSupportLib forDialogFragment() {
|
||||
return sDialogFragmentAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FragmentManagerAccessor<FragmentManager, Fragment> forFragmentManager() {
|
||||
return sFragmentManagerAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FragmentActivityAccessorSupportLib forFragmentActivity() {
|
||||
return sFragmentActivityAccessor;
|
||||
}
|
||||
|
||||
private static class FragmentAccessorSupportLib
|
||||
implements FragmentAccessor<Fragment, FragmentManager> {
|
||||
@Nullable
|
||||
@Override
|
||||
public FragmentManager getFragmentManager(Fragment fragment) {
|
||||
return fragment.getFragmentManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources(Fragment fragment) {
|
||||
return fragment.getResources();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(Fragment fragment) {
|
||||
return fragment.getId();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTag(Fragment fragment) {
|
||||
return fragment.getTag();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View getView(Fragment fragment) {
|
||||
return fragment.getView();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FragmentManager getChildFragmentManager(Fragment fragment) {
|
||||
return fragment.getChildFragmentManager();
|
||||
}
|
||||
}
|
||||
|
||||
private static class DialogFragmentAccessorSupportLib extends FragmentAccessorSupportLib
|
||||
implements DialogFragmentAccessor<DialogFragment, Fragment, FragmentManager> {
|
||||
@Override
|
||||
public Dialog getDialog(DialogFragment dialogFragment) {
|
||||
return dialogFragment.getDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private static class FragmentActivityAccessorSupportLib
|
||||
implements FragmentActivityAccessor<FragmentActivity, FragmentManager> {
|
||||
@Nullable
|
||||
@Override
|
||||
public FragmentManager getFragmentManager(FragmentActivity activity) {
|
||||
return activity.getSupportFragmentManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class FragmentCompatUtil {
|
||||
private FragmentCompatUtil() {}
|
||||
|
||||
public static boolean isDialogFragment(Object fragment) {
|
||||
FragmentCompat supportLib = FragmentCompat.getSupportLibInstance();
|
||||
if (supportLib != null && supportLib.getDialogFragmentClass().isInstance(fragment)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
FragmentCompat framework = FragmentCompat.getFrameworkInstance();
|
||||
if (framework != null && framework.getDialogFragmentClass().isInstance(fragment)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Object findFragmentForView(View view) {
|
||||
Activity activity = ViewUtil.tryGetActivity(view);
|
||||
if (activity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findFragmentForViewInActivity(activity, view);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Object findFragmentForViewInActivity(Activity activity, View view) {
|
||||
FragmentCompat supportLib = FragmentCompat.getSupportLibInstance();
|
||||
|
||||
// Try the support library version if it is present and the activity is FragmentActivity.
|
||||
if (supportLib != null && supportLib.getFragmentActivityClass().isInstance(activity)) {
|
||||
Object fragment = findFragmentForViewInActivity(supportLib, activity, view);
|
||||
if (fragment != null) {
|
||||
return fragment;
|
||||
}
|
||||
}
|
||||
|
||||
// Try the actual Android runtime version if we are on a sufficiently high API level for it to
|
||||
// exist. Note that technically we can have both the support library and the framework
|
||||
// version in the same object instance due to FragmentActivity extending Activity (which has
|
||||
// fragment support in the system).
|
||||
FragmentCompat framework = FragmentCompat.getFrameworkInstance();
|
||||
if (framework != null) {
|
||||
Object fragment = findFragmentForViewInActivity(framework, activity, view);
|
||||
if (fragment != null) {
|
||||
return fragment;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Object findFragmentForViewInActivity(
|
||||
FragmentCompat compat, Activity activity, View view) {
|
||||
Object fragmentManager = compat.forFragmentActivity().getFragmentManager(activity);
|
||||
if (fragmentManager != null) {
|
||||
return findFragmentForViewInFragmentManager(compat, fragmentManager, view);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Object findFragmentForViewInFragmentManager(
|
||||
FragmentCompat compat, Object fragmentManager, View view) {
|
||||
List<?> fragments = compat.forFragmentManager().getAddedFragments(fragmentManager);
|
||||
|
||||
if (fragments != null) {
|
||||
for (int i = 0, N = fragments.size(); i < N; ++i) {
|
||||
Object fragment = fragments.get(i);
|
||||
Object result = findFragmentForViewInFragment(compat, fragment, view);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Object findFragmentForViewInFragment(
|
||||
FragmentCompat compat, Object fragment, View view) {
|
||||
FragmentAccessor accessor = compat.forFragment();
|
||||
|
||||
if (accessor.getView(fragment) == view) {
|
||||
return fragment;
|
||||
}
|
||||
|
||||
Object childFragmentManager = accessor.getChildFragmentManager(fragment);
|
||||
if (childFragmentManager != null) {
|
||||
return findFragmentForViewInFragmentManager(compat, childFragmentManager, view);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface FragmentManagerAccessor<FRAGMENT_MANAGER, FRAGMENT> {
|
||||
@Nullable
|
||||
List<FRAGMENT> getAddedFragments(FRAGMENT_MANAGER fragmentManager);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.util.Log;
|
||||
import java.lang.reflect.Field;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class ReflectionUtil {
|
||||
private ReflectionUtil() {}
|
||||
|
||||
@Nullable
|
||||
public static Class<?> tryGetClassForName(String className) {
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Field tryGetDeclaredField(Class<?> theClass, String fieldName) {
|
||||
try {
|
||||
return theClass.getDeclaredField(fieldName);
|
||||
} catch (NoSuchFieldException e) {
|
||||
Log.e(
|
||||
ReflectionUtil.class.getCanonicalName(),
|
||||
String.format("Could not retrieve %s field from %s", fieldName, theClass),
|
||||
e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Object getFieldValue(Field field, Object target) {
|
||||
try {
|
||||
return field.get(target);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Copied from Stetho. */
|
||||
public class ResourcesUtil {
|
||||
private ResourcesUtil() {}
|
||||
|
||||
@Nonnull
|
||||
public static String getIdStringQuietly(Object idContext, @Nullable Resources r, int resourceId) {
|
||||
try {
|
||||
return getIdString(r, resourceId);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
String idString = getFallbackIdString(resourceId);
|
||||
Log.w(
|
||||
ResourcesUtil.class.getCanonicalName(),
|
||||
"Unknown identifier encountered on " + idContext + ": " + idString);
|
||||
return idString;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getIdString(@Nullable Resources r, int resourceId)
|
||||
throws Resources.NotFoundException {
|
||||
if (r == null) {
|
||||
return getFallbackIdString(resourceId);
|
||||
}
|
||||
|
||||
String prefix;
|
||||
String prefixSeparator;
|
||||
switch (getResourcePackageId(resourceId)) {
|
||||
case 0x7f:
|
||||
prefix = "";
|
||||
prefixSeparator = "";
|
||||
break;
|
||||
default:
|
||||
prefix = r.getResourcePackageName(resourceId);
|
||||
prefixSeparator = ":";
|
||||
break;
|
||||
}
|
||||
|
||||
String typeName = r.getResourceTypeName(resourceId);
|
||||
String entryName = r.getResourceEntryName(resourceId);
|
||||
|
||||
StringBuilder sb =
|
||||
new StringBuilder(
|
||||
1
|
||||
+ prefix.length()
|
||||
+ prefixSeparator.length()
|
||||
+ typeName.length()
|
||||
+ 1
|
||||
+ entryName.length());
|
||||
sb.append("@");
|
||||
sb.append(prefix);
|
||||
sb.append(prefixSeparator);
|
||||
sb.append(typeName);
|
||||
sb.append("/");
|
||||
sb.append(entryName);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String getFallbackIdString(int resourceId) {
|
||||
return "#" + Integer.toHexString(resourceId);
|
||||
}
|
||||
|
||||
private static int getResourcePackageId(int id) {
|
||||
return (id >>> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.inspector.descriptors.utils.stethocopies;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.view.View;
|
||||
import android.view.ViewParent;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
final class ViewUtil {
|
||||
private ViewUtil() {}
|
||||
|
||||
@Nullable
|
||||
static Activity tryGetActivity(View view) {
|
||||
if (view == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Context context = view.getContext();
|
||||
|
||||
Activity activityFromContext = tryGetActivity(context);
|
||||
if (activityFromContext != null) {
|
||||
return activityFromContext;
|
||||
}
|
||||
|
||||
ViewParent parent = view.getParent();
|
||||
if (parent instanceof View) {
|
||||
View parentView = (View) parent;
|
||||
return tryGetActivity(parentView);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Activity tryGetActivity(Context context) {
|
||||
while (context != null) {
|
||||
if (context instanceof Activity) {
|
||||
return (Activity) context;
|
||||
} else if (context instanceof ContextWrapper) {
|
||||
context = ((ContextWrapper) context).getBaseContext();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user