1 package io.keybase.ossifrage;
2 
3 import android.app.Application;
4 import android.content.Context;
5 
6 import androidx.multidex.MultiDex;
7 
8 import com.evernote.android.job.JobManager;
9 import com.facebook.react.PackageList;
10 import com.facebook.react.ReactApplication;
11 import com.rnim.rn.audio.ReactNativeAudioPackage;
12 import com.facebook.react.ReactNativeHost;
13 import com.facebook.react.ReactPackage;
14 import com.facebook.react.bridge.NativeModule;
15 import com.facebook.react.bridge.ReactApplicationContext;
16 import com.facebook.soloader.SoLoader;
17 
18 import org.unimodules.adapters.react.ModuleRegistryAdapter;
19 import org.unimodules.adapters.react.ReactAdapterPackage;
20 import org.unimodules.adapters.react.ReactModuleRegistryProvider;
21 import org.unimodules.core.interfaces.Package;
22 
23 // import java.lang.reflect.InvocationTargetException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.List;
27 
28 import expo.modules.barcodescanner.BarCodeScannerPackage;
29 import expo.modules.constants.ConstantsPackage;
30 import expo.modules.contacts.ContactsPackage;
31 import expo.modules.imagepicker.ImagePickerPackage;
32 import expo.modules.permissions.PermissionsPackage;
33 import expo.modules.sms.SMSPackage;
34 import io.keybase.ossifrage.modules.BackgroundJobCreator;
35 import io.keybase.ossifrage.modules.BackgroundSyncJob;
36 import io.keybase.ossifrage.modules.NativeLogger;
37 import io.keybase.ossifrage.modules.StorybookConstants;
38 
39 import static keybase.Keybase.forceGC;
40 
41 public class MainApplication extends Application implements ReactApplication {
42     private final ReactModuleRegistryProvider mModuleRegistryProvider = new ReactModuleRegistryProvider(Arrays.<Package>asList(
43       new ReactAdapterPackage(),
44       new ConstantsPackage(),
45       // Same order as package.json
46       new BarCodeScannerPackage(),
47       new ContactsPackage(),
48       new ImagePickerPackage(),
49       new PermissionsPackage(),
50       new SMSPackage()
51     ), null);
52 
53 
54     @Override
attachBaseContext(Context base)55     protected void attachBaseContext(Context base) {
56         super.attachBaseContext(base);
57         MultiDex.install(this);
58     }
59 
60     @Override
onCreate()61     public void onCreate() {
62         NativeLogger.info("MainApplication created");
63         super.onCreate();
64         SoLoader.init(this, /* native exopackage */ false);
65         // initializeFlipper(this); // Remove this line if you don't want Flipper enabled
66         JobManager manager = JobManager.create(this);
67         manager.addJobCreator(new BackgroundJobCreator());
68 
69         // Make sure exactly one background job is scheduled.
70         int numBackgroundJobs = manager.getAllJobRequestsForTag(BackgroundSyncJob.TAG).size();
71         if (numBackgroundJobs == 0) {
72             BackgroundSyncJob.scheduleJob();
73         } else if (numBackgroundJobs > 1) {
74             manager.cancelAllForTag(BackgroundSyncJob.TAG);
75             BackgroundSyncJob.scheduleJob();
76         }
77     }
78 
79     @Override
onLowMemory()80     public void onLowMemory() {
81         forceGC();
82         super.onLowMemory();
83     }
84 
85     /**
86      * Loads Flipper in React Native templates.
87      *
88      * @param context
89      */
90     // private static void initializeFlipper(Context context) {
91         // if (BuildConfig.DEBUG) {
92             // try {
93           // [>
94            // We use reflection here to pick up the class that initializes Flipper,
95           // since Flipper library is not available in release mode
96           // */
97                 // Class<?> aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper");
98                 // aClass.getMethod("initializeFlipper", Context.class).invoke(null, context);
99             // } catch (ClassNotFoundException e) {
100                 // e.printStackTrace();
101             // } catch (NoSuchMethodException e) {
102                 // e.printStackTrace();
103             // } catch (IllegalAccessException e) {
104                 // e.printStackTrace();
105             // } catch (InvocationTargetException e) {
106                 // e.printStackTrace();
107             // }
108         // }
109     // }
110 
111     private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
112 
113         @Override
114         public boolean getUseDeveloperSupport() {
115             return BuildConfig.DEBUG;
116         }
117 
118         @Override
119         protected List<ReactPackage> getPackages() {
120             Context context = getApplicationContext();
121             // limit fresco memory
122 //            ImagePipelineConfig frescoConfig = ImagePipelineConfig
123 //                    .newBuilder(context)
124 //                    .setBitmapMemoryCacheParamsSupplier(new CustomBitmapMemoryCacheParamsSupplier(context))
125 //                    .build();
126 //
127 //            MainPackageConfig appConfig = new MainPackageConfig.Builder().setFrescoConfig(frescoConfig).build();
128 
129             @SuppressWarnings("UnnecessaryLocalVariable")
130             List<ReactPackage> packages = new PackageList(this).getPackages();
131             // new MainReactPackage(appConfig),// removed from rn-diff but maybe we need it for fresco config?
132             packages.add(new KBReactPackage() {
133                 @Override
134                 public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
135                     if (BuildConfig.BUILD_TYPE == "storyBook") {
136                         List<NativeModule> modules = new ArrayList<>();
137                         modules.add(new StorybookConstants(reactApplicationContext));
138                         return modules;
139                     } else {
140                         return super.createNativeModules(reactApplicationContext);
141                     }
142                 }
143             });
144 
145             packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider));
146 
147             return packages;
148         }
149         @Override
150         protected String getJSMainModuleName() {
151             // This is a mildly hacky solution to mock out some code when we're in storybook mode.
152             // The code that handles this is in `shared/metro.config.js`.
153             if (BuildConfig.BUILD_TYPE == "storyBook") {
154                 return "storybook-index";
155             } else {
156                 return "normal-index";
157             }
158         }
159     };
160 
161     @Override
getReactNativeHost()162     public ReactNativeHost getReactNativeHost() {
163         return mReactNativeHost;
164     }
165 }
166