/**
* Copyright (c) 2015-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.react.devsupport;
import javax.annotation.Nullable;
import java.lang.reflect.Constructor;
import android.content.Context;
/**
* A simple factory that creates instances of {@link DevSupportManager} implementations. Uses
* reflection to create DevSupportManagerImpl if it exists. This allows ProGuard to strip that class
* and its dependencies in release builds. If the class isn't found,
* {@link DisabledDevSupportManager} is returned instead.
*/
public class DevSupportManagerFactory {
private static final String DEVSUPPORT_IMPL_PACKAGE = "com.facebook.react.devsupport";
private static final String DEVSUPPORT_IMPL_CLASS = "DevSupportManagerImpl";
public static DevSupportManager create(
Context applicationContext,
ReactInstanceDevCommandsHandler reactInstanceCommandsHandler,
@Nullable String packagerPathForJSBundleName,
boolean enableOnCreate) {
return create(
applicationContext,
reactInstanceCommandsHandler,
packagerPathForJSBundleName,
enableOnCreate,
null);
}
public static DevSupportManager create(
Context applicationContext,
ReactInstanceDevCommandsHandler reactInstanceCommandsHandler,
@Nullable String packagerPathForJSBundleName,
boolean enableOnCreate,
@Nullable RedBoxHandler redBoxHandler) {
if (!enableOnCreate) {
return new DisabledDevSupportManager();
}
try {
// ProGuard is surprisingly smart in this case and will keep a class if it detects a call to
// Class.forName() with a static string. So instead we generate a quasi-dynamic string to
// confuse it.
String className =
new StringBuilder(DEVSUPPORT_IMPL_PACKAGE)
.append(".")
.append(DEVSUPPORT_IMPL_CLASS)
.toString();
Class<?> devSupportManagerClass =
Class.forName(className);
Constructor constructor =
devSupportManagerClass.getConstructor(
Context.class,
ReactInstanceDevCommandsHandler.class,
String.class,
boolean.class,
RedBoxHandler.class);
return (DevSupportManager) constructor.newInstance(
applicationContext,
reactInstanceCommandsHandler,
packagerPathForJSBundleName,
true,
redBoxHandler);
} catch (Exception e) {
throw new RuntimeException(
"Requested enabled DevSupportManager, but DevSupportManagerImpl class was not found" +
" or could not be created",
e);
}
}
}