package net.osmand.plus;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AlertDialog;
import net.osmand.IProgress;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.aidl.OsmandAidlApi;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.map.OsmandRegions;
import net.osmand.map.OsmandRegions.RegionTranslation;
import net.osmand.map.WorldRegion;
import net.osmand.osm.AbstractPoiType;
import net.osmand.osm.MapPoiTypes;
import net.osmand.plus.activities.DayNightHelper;
import net.osmand.plus.activities.LocalIndexHelper;
import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.SavingTrackHelper;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.liveupdates.LiveUpdatesHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.render.MapRenderRepositories;
import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.render.RendererRegistry;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.search.QuickSearchHelper;
import net.osmand.plus.views.corenative.NativeCoreContext;
import net.osmand.plus.voice.CommandPlayer;
import net.osmand.plus.voice.CommandPlayerException;
import net.osmand.plus.voice.MediaCommandPlayerImpl;
import net.osmand.plus.voice.TTSCommandPlayerImpl;
import net.osmand.render.RenderingRulesStorage;
import net.osmand.router.RoutingConfiguration;
import net.osmand.search.SearchUICore;
import net.osmand.util.Algorithms;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import btools.routingapp.BRouterServiceConnection;
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent;
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck;
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLiveUpdatesOn;
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate;
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency;
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate;
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent;
/**
*/
public class AppInitializer implements IProgress {
// 22 - 2.2
public static final int VERSION_2_2 = 22;
// 23 - 2.3
public static final int VERSION_2_3 = 23;
public static final boolean TIPS_AND_TRICKS = false;
public static final String FIRST_TIME_APP_RUN = "FIRST_TIME_APP_RUN"; //$NON-NLS-1$
public static final String VERSION_INSTALLED_NUMBER = "VERSION_INSTALLED_NUMBER"; //$NON-NLS-1$
public static final String NUMBER_OF_STARTS = "NUMBER_OF_STARTS"; //$NON-NLS-1$
public static final String FIRST_INSTALLED = "FIRST_INSTALLED"; //$NON-NLS-1$
private static final String VECTOR_INDEXES_CHECK = "VECTOR_INDEXES_CHECK"; //$NON-NLS-1$
private static final String VERSION_INSTALLED = "VERSION_INSTALLED"; //$NON-NLS-1$
private static final String EXCEPTION_FILE_SIZE = "EXCEPTION_FS"; //$NON-NLS-1$
public static final String LATEST_CHANGES_URL = "http://osmand.net/blog?id=osmand-2-6-released";
// public static final String LATEST_CHANGES_URL = null; // not enough to read
public static final int APP_EXIT_CODE = 4;
public static final String APP_EXIT_KEY = "APP_EXIT_KEY";
private OsmandApplication app;
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(AppInitializer.class);
private boolean initSettings = false;
private boolean firstTime;
private boolean activityChangesShowed = false;
private boolean appVersionChanged;
private int prevAppVersion;
private long startTime;
private long startBgTime;
private boolean appInitializing = true;
private List<String> warnings = new ArrayList<>();
private String taskName;
private List<AppInitializeListener> listeners = new ArrayList<>();
private SharedPreferences startPrefs;
public enum InitEvents {
FAVORITES_INITIALIZED, NATIVE_INITIALIZED,
NATIVE_OPEN_GLINITIALIZED,
TASK_CHANGED, MAPS_INITIALIZED, POI_TYPES_INITIALIZED, ASSETS_COPIED, INIT_RENDERERS,
RESTORE_BACKUPS, INDEX_REGION_BOUNDARIES, SAVE_GPX_TRACKS, LOAD_GPX_TRACKS
}
public interface AppInitializeListener {
void onProgress(AppInitializer init, InitEvents event);
void onFinish(AppInitializer init);
}
public AppInitializer(OsmandApplication app) {
this.app = app;
}
public List<String> getWarnings() {
return warnings;
}
public boolean isAppInitializing() {
return appInitializing;
}
@SuppressLint("CommitPrefEdits")
public void initVariables() {
if(initSettings) {
return;
}
startPrefs = app.getSharedPreferences(
getLocalClassName(app.getAppCustomization().getMapActivity().getName()),
Context.MODE_WORLD_WRITEABLE);
if(!startPrefs.contains(NUMBER_OF_STARTS)) {
startPrefs.edit().putInt(NUMBER_OF_STARTS, 1).commit();
} else {
startPrefs.edit().putInt(NUMBER_OF_STARTS, startPrefs.getInt(NUMBER_OF_STARTS, 0) + 1).commit();
}
if (!startPrefs.contains(FIRST_INSTALLED)) {
startPrefs.edit().putLong(FIRST_INSTALLED, System.currentTimeMillis()).commit();
}
if (!startPrefs.contains(FIRST_TIME_APP_RUN)) {
firstTime = true;
startPrefs.edit().putBoolean(FIRST_TIME_APP_RUN, true).commit();
startPrefs.edit().putString(VERSION_INSTALLED, Version.getFullVersion(app)).commit();
startPrefs.edit().putInt(VERSION_INSTALLED_NUMBER, VERSION_2_3).commit();
} else if (!Version.getFullVersion(app).equals(startPrefs.getString(VERSION_INSTALLED, ""))) {
prevAppVersion = startPrefs.getInt(VERSION_INSTALLED_NUMBER, 0);
if(prevAppVersion < VERSION_2_2) {
app.getSettings().SHOW_DASHBOARD_ON_START.set(true);
app.getSettings().SHOW_DASHBOARD_ON_MAP_SCREEN.set(true);
app.getSettings().SHOW_CARD_TO_CHOOSE_DRAWER.set(true);
startPrefs.edit().putInt(VERSION_INSTALLED_NUMBER, VERSION_2_2).commit();
}
if(prevAppVersion < VERSION_2_3) {
startPrefs.edit().putInt(VERSION_INSTALLED_NUMBER, VERSION_2_3).commit();
}
startPrefs.edit().putString(VERSION_INSTALLED, Version.getFullVersion(app)).commit();
appVersionChanged = true;
}
initSettings = true;
}
public int getNumberOfStarts() {
if(startPrefs == null) {
return 0;
}
return startPrefs.getInt(NUMBER_OF_STARTS, 1);
}
public long getFirstInstalledDays() {
if(startPrefs == null) {
return 0;
}
long nd = startPrefs.getLong(FIRST_INSTALLED, 0);
return (System.currentTimeMillis() - nd) / (1000l * 24l * 60l * 60l);
}
public void resetFirstTimeRun() {
if(startPrefs != null) {
startPrefs.edit().remove(FIRST_TIME_APP_RUN).commit();
}
}
public boolean isFirstTime() {
initVariables();
return firstTime;
}
public boolean isAppVersionChanged() {
return appVersionChanged;
}
public int getPrevAppVersion() {
return prevAppVersion;
}
public boolean checkAppVersionChanged() {
initVariables();
boolean showRecentChangesDialog = !firstTime && appVersionChanged;
// showRecentChangesDialog = true;
if (showRecentChangesDialog && !activityChangesShowed) {
activityChangesShowed = true;
return true;
}
checkMapUpdates();
return false;
}
private void checkMapUpdates() {
long diff = System.currentTimeMillis() - app.getSettings().LAST_CHECKED_UPDATES.get();
if (diff >= 2 * 24 * 60 * 60l && new Random().nextInt(5) == 0 &&
app.getSettings().isInternetConnectionAvailable()) {
app.getDownloadThread().runReloadIndexFiles();
} else if (Version.isDeveloperVersion(app)) {
// app.getDownloadThread().runReloadIndexFiles();
}
}
public boolean checkPreviousRunsForExceptions(Activity activity, boolean writeFileSize) {
initVariables();
long size = activity.getPreferences(Context.MODE_WORLD_READABLE).getLong(EXCEPTION_FILE_SIZE, 0);
final File file = app.getAppPath(OsmandApplication.EXCEPTION_PATH);
if (file.exists() && file.length() > 0) {
if (size != file.length() && !firstTime) {
if (writeFileSize) {
activity.getPreferences(Context.MODE_WORLD_WRITEABLE).edit().putLong(EXCEPTION_FILE_SIZE, file.length()).commit();
}
return true;
}
} else {
if (size > 0) {
activity.getPreferences(Context.MODE_WORLD_WRITEABLE).edit().putLong(EXCEPTION_FILE_SIZE, 0).commit();
}
}
return false;
}
// TODO
public void checkVectorIndexesDownloaded(final Activity ctx) {
OsmandApplication app = (OsmandApplication)ctx.getApplication();
MapRenderRepositories maps = app.getResourceManager().getRenderer();
SharedPreferences pref = ctx.getPreferences(Context.MODE_WORLD_WRITEABLE);
boolean check = pref.getBoolean(VECTOR_INDEXES_CHECK, true);
// do not show each time
if (check && new Random().nextInt() % 5 == 1) {
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
if (maps.isEmpty()) {
builder.setMessage(R.string.vector_data_missing);
} else if (!maps.basemapExists()) {
builder.setMessage(R.string.basemap_missing);
} else {
return;
}
builder.setPositiveButton(R.string.shared_string_download, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ctx.startActivity(new Intent(ctx, DownloadActivity.class));
}
});
builder.setNeutralButton(R.string.shared_string_no_thanks, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ctx.getPreferences(Context.MODE_WORLD_WRITEABLE).edit().putBoolean(VECTOR_INDEXES_CHECK, false).commit();
}
});
builder.setNegativeButton(R.string.first_time_continue, null);
builder.show();
}
}
private void indexRegionsBoundaries(List<String> warnings) {
try {
File file = app.getAppPath("regions.ocbf");
if (file != null) {
if (!file.exists()) {
Algorithms.streamCopy(OsmandRegions.class.getResourceAsStream("regions.ocbf"),
new FileOutputStream(file));
}
app.regions.prepareFile(file.getAbsolutePath());
}
} catch (Exception e) {
warnings.add(e.getMessage());
LOG.error(e.getMessage(), e);
}
}
private void initPoiTypes() {
if(app.getAppPath("poi_types.xml").exists()) {
app.poiTypes.init(app.getAppPath("poi_types.xml").getAbsolutePath());
} else {
app.poiTypes.init();
}
app.poiTypes.setPoiTranslator(new MapPoiTypes.PoiTranslator() {
@Override
public String getTranslation(AbstractPoiType type) {
if(type.getBaseLangType() != null) {
return getTranslation(type.getBaseLangType()) + " (" + app.getLangTranslation(type.getLang()).toLowerCase() +")";
}
return getTranslation(type.getIconKeyName());
}
@Override
public String getTranslation(String keyName) {
try {
Field f = R.string.class.getField("poi_" + keyName);
if (f != null) {
Integer in = (Integer) f.get(null);
return app.getString(in);
}
} catch (Exception e) {
LOG.debug("No translation for "+ keyName + " " + e.getMessage());
}
return null;
}
});
}
public void onCreateApplication() {
// always update application mode to default
OsmandSettings osmandSettings = app.getSettings();
if (!osmandSettings.FOLLOW_THE_ROUTE.get()) {
osmandSettings.APPLICATION_MODE.set(osmandSettings.DEFAULT_APPLICATION_MODE.get());
}
startTime = System.currentTimeMillis();
try {
app.bRouterServiceConnection = startupInit(BRouterServiceConnection.connect(app), BRouterServiceConnection.class);
} catch (Exception e) {
e.printStackTrace();
}
app.applyTheme(app);
app.poiTypes = startupInit(MapPoiTypes.getDefaultNoInit(), MapPoiTypes.class);
app.routingHelper = startupInit(new RoutingHelper(app), RoutingHelper.class);
app.resourceManager = startupInit(new ResourceManager(app), ResourceManager.class);
app.daynightHelper = startupInit(new DayNightHelper(app), DayNightHelper.class);
app.locationProvider = startupInit(new OsmAndLocationProvider(app), OsmAndLocationProvider.class);
app.avoidSpecificRoads = startupInit(new AvoidSpecificRoads(app), AvoidSpecificRoads.class);
app.savingTrackHelper = startupInit(new SavingTrackHelper(app), SavingTrackHelper.class);
app.notificationHelper = startupInit(new NotificationHelper(app), NotificationHelper.class);
app.liveMonitoringHelper = startupInit(new LiveMonitoringHelper(app), LiveMonitoringHelper.class);
app.selectedGpxHelper = startupInit(new GpxSelectionHelper(app, app.savingTrackHelper), GpxSelectionHelper.class);
app.gpxDatabase = startupInit(new GPXDatabase(app), GPXDatabase.class);
app.favorites = startupInit(new FavouritesDbHelper(app), FavouritesDbHelper.class);
app.waypointHelper = startupInit(new WaypointHelper(app), WaypointHelper.class);
app.aidlApi = startupInit(new OsmandAidlApi(app), OsmandAidlApi.class);
app.regions = startupInit(new OsmandRegions(), OsmandRegions.class);
updateRegionVars();
app.poiFilters = startupInit(new PoiFiltersHelper(app), PoiFiltersHelper.class);
app.rendererRegistry = startupInit(new RendererRegistry(app), RendererRegistry.class);
app.geocodingLookupService = startupInit(new GeocodingLookupService(app), GeocodingLookupService.class);
app.targetPointsHelper = startupInit(new TargetPointsHelper(app), TargetPointsHelper.class);
app.mapMarkersHelper = startupInit(new MapMarkersHelper(app), MapMarkersHelper.class);
app.searchUICore = startupInit(new QuickSearchHelper(app), QuickSearchHelper.class);
}
private void updateRegionVars() {
app.regions.setTranslator(new RegionTranslation() {
@Override
public String getTranslation(String id) {
if(WorldRegion.AFRICA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_africa);
} else if(WorldRegion.AUSTRALIA_AND_OCEANIA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_oceania);
} else if(WorldRegion.ASIA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_asia);
} else if(WorldRegion.CENTRAL_AMERICA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_central_america);
} else if(WorldRegion.EUROPE_REGION_ID.equals(id)){
return app.getString(R.string.index_name_europe);
} else if(WorldRegion.RUSSIA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_russia);
} else if(WorldRegion.NORTH_AMERICA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_north_america);
} else if(WorldRegion.SOUTH_AMERICA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_south_america);
}
return null;
}
});
app.regions.setLocale(app.getLanguage());
}
private <T> T startupInit(T object, Class<T> class1) {
long t = System.currentTimeMillis();
if(t - startTime > 7) {
System.err.println("Startup service " + class1.getName() + " took too long " + (t - startTime) + " ms");
}
startTime = t;
return object;
}
public net.osmand.router.RoutingConfiguration.Builder getLazyDefaultRoutingConfig() {
long tm = System.currentTimeMillis();
try {
File routingXml = app.getAppPath(IndexConstants.ROUTING_XML_FILE);
if (routingXml.exists() && routingXml.canRead()) {
try {
return RoutingConfiguration.parseFromInputStream(new FileInputStream(routingXml));
} catch (XmlPullParserException | IOException e) {
throw new IllegalStateException(e);
}
} else {
return RoutingConfiguration.getDefault();
}
} finally {
long te = System.currentTimeMillis();
if(te - tm > 30) {
System.err.println("Defalt routing config init took " + (te - tm) + " ms");
}
}
}
public synchronized void initVoiceDataInDifferentThread(final Activity uiContext,
final ApplicationMode applicationMode,
final String voiceProvider,
final Runnable run,
boolean showDialog) {
final ProgressDialog dlg = showDialog ? ProgressDialog.show(uiContext, app.getString(R.string.loading_data),
app.getString(R.string.voice_data_initializing)) : null;
new Thread(new Runnable() {
public CommandPlayer createCommandPlayer(String voiceProvider, ApplicationMode applicationMode,
OsmandApplication osmandApplication, Activity ctx)
throws CommandPlayerException {
if (voiceProvider != null) {
File parent = osmandApplication.getAppPath(IndexConstants.VOICE_INDEX_DIR);
File voiceDir = new File(parent, voiceProvider);
if (!voiceDir.exists()) {
throw new CommandPlayerException(ctx.getString(R.string.voice_data_unavailable));
}
if (MediaCommandPlayerImpl.isMyData(voiceDir)) {
return new MediaCommandPlayerImpl(osmandApplication, applicationMode, osmandApplication.getRoutingHelper().getVoiceRouter(), voiceProvider);
} else if (TTSCommandPlayerImpl.isMyData(voiceDir)) {
return new TTSCommandPlayerImpl(ctx, applicationMode, osmandApplication.getRoutingHelper().getVoiceRouter(), voiceProvider);
}
throw new CommandPlayerException(ctx.getString(R.string.voice_data_not_supported));
}
return null;
}
@Override
public void run() {
try {
if (app.player != null) {
app.player.clear();
}
app.player = createCommandPlayer(voiceProvider, applicationMode, app, uiContext);
app.getRoutingHelper().getVoiceRouter().setPlayer(app.player);
if(dlg != null) {
dlg.dismiss();
}
if (run != null && uiContext != null) {
uiContext.runOnUiThread(run);
}
} catch (CommandPlayerException e) {
if(dlg != null) {
dlg.dismiss();
}
app.showToastMessage(e.getError());
}
}
}).start();
}
private void startApplicationBackground() {
try {
startBgTime = System.currentTimeMillis();
app.favorites.loadFavorites();
notifyEvent(InitEvents.FAVORITES_INITIALIZED);
// init poi types before indexes and before POI
initPoiTypes();
notifyEvent(InitEvents.POI_TYPES_INITIALIZED);
app.resourceManager.reloadIndexesOnStart(this, warnings);
app.getRendererRegistry().initRenderers(this);
notifyEvent(InitEvents.INIT_RENDERERS);
// native depends on renderers
initNativeCore();
notifyEvent(InitEvents.NATIVE_INITIALIZED);
app.poiFilters.reloadAllPoiFilters();
app.poiFilters.loadSelectedPoiFilters();
notifyEvent(InitEvents.POI_TYPES_INITIALIZED);
indexRegionsBoundaries(warnings);
notifyEvent(InitEvents.INDEX_REGION_BOUNDARIES);
app.selectedGpxHelper.loadGPXTracks(this);
notifyEvent(InitEvents.LOAD_GPX_TRACKS);
saveGPXTracks();
notifyEvent(InitEvents.SAVE_GPX_TRACKS);
// restore backuped favorites to normal file
restoreBackupForFavoritesFiles();
notifyEvent(InitEvents.RESTORE_BACKUPS);
app.searchUICore.initSearchUICore();
checkLiveUpdatesAlerts();
} catch (RuntimeException e) {
e.printStackTrace();
warnings.add(e.getMessage());
} finally {
appInitializing = false;
notifyFinish();
if (warnings != null && !warnings.isEmpty()) {
app.showToastMessage(formatWarnings(warnings).toString());
}
}
}
private void checkLiveUpdatesAlerts() {
OsmandSettings settings = app.getSettings();
if (!settings.IS_LIVE_UPDATES_ON.get()) {
return;
}
LocalIndexHelper helper = new LocalIndexHelper(app);
List<LocalIndexInfo> fullMaps = helper.getLocalFullMaps(new AbstractLoadLocalIndexTask() {
@Override
public void loadFile(LocalIndexInfo... loaded) {
}
});
AlarmManager alarmMgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE);
for (LocalIndexInfo fm : fullMaps) {
String fileName = fm.getFileName();
if (!preferenceLiveUpdatesOn(fileName, settings).get()) {
continue;
}
int updateFrequencyOrd = preferenceUpdateFrequency(fileName, settings).get();
LiveUpdatesHelper.UpdateFrequency updateFrequency =
LiveUpdatesHelper.UpdateFrequency.values()[updateFrequencyOrd];
long lastCheck = preferenceLastCheck(fileName, settings).get();
if (System.currentTimeMillis() - lastCheck > updateFrequency.getTime() * 2) {
runLiveUpdate(app, fileName, false);
PendingIntent alarmIntent = getPendingIntent(app, fileName);
int timeOfDayOrd = preferenceTimeOfDayToUpdate(fileName, settings).get();
LiveUpdatesHelper.TimeOfDay timeOfDayToUpdate =
LiveUpdatesHelper.TimeOfDay.values()[timeOfDayOrd];
setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate);
}
}
}
private void restoreBackupForFavoritesFiles() {
final File appDir = app.getAppPath(null);
File save = new File(appDir, FavouritesDbHelper.FILE_TO_SAVE);
File bak = new File(appDir, FavouritesDbHelper.FILE_TO_BACKUP);
if (bak.exists() && (!save.exists() || bak.lastModified() > save.lastModified())) {
if (save.exists()) {
save.delete();
}
bak.renameTo(save);
}
}
private void saveGPXTracks() {
if (app.savingTrackHelper.hasDataToSave()) {
long timeUpdated = app.savingTrackHelper.getLastTrackPointTime();
if (System.currentTimeMillis() - timeUpdated >= 1000 * 60 * 30) {
startTask(app.getString(R.string.saving_gpx_tracks), -1);
try {
warnings.addAll(app.savingTrackHelper.saveDataToGpx(app.getAppCustomization().getTracksDir()));
} catch (RuntimeException e) {
warnings.add(e.getMessage());
}
} else {
app.savingTrackHelper.loadGpxFromDatabase();
}
}
if(app.getSettings().SAVE_GLOBAL_TRACK_TO_GPX.get() && OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class) != null){
int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get() ;
app.startNavigationService(NavigationService.USED_BY_GPX, interval < 30000 ? 0 : interval);
}
}
private void initNativeCore() {
if (!"qnx".equals(System.getProperty("os.name"))) {
OsmandSettings osmandSettings = app.getSettings();
if (osmandSettings.USE_OPENGL_RENDER.get()) {
boolean success = false;
if (!osmandSettings.OPENGL_RENDER_FAILED.get()) {
osmandSettings.OPENGL_RENDER_FAILED.set(true);
success = NativeCoreContext.tryCatchInit(app);
if (success) {
osmandSettings.OPENGL_RENDER_FAILED.set(false);
}
}
if (!success) {
// try next time once again ?
osmandSettings.OPENGL_RENDER_FAILED.set(false);
warnings.add("Native OpenGL library is not supported. Please try again after exit");
}
}
if (osmandSettings.NATIVE_RENDERING_FAILED.get()) {
osmandSettings.SAFE_MODE.set(true);
osmandSettings.NATIVE_RENDERING_FAILED.set(false);
warnings.add(app.getString(R.string.native_library_not_supported));
} else {
osmandSettings.SAFE_MODE.set(false);
osmandSettings.NATIVE_RENDERING_FAILED.set(true);
startTask(app.getString(R.string.init_native_library), -1);
RenderingRulesStorage storage = app.getRendererRegistry().getCurrentSelectedRenderer();
NativeOsmandLibrary lib = NativeOsmandLibrary.getLibrary(storage, app);
boolean initialized = lib != null;
osmandSettings.NATIVE_RENDERING_FAILED.set(false);
if (!initialized) {
LOG.info("Native library could not be loaded!");
} else {
File ls = app.getAppPath("fonts");
lib.loadFontData(ls);
}
}
app.getResourceManager().initMapBoundariesCacheNative();
}
}
private StringBuilder formatWarnings(List<String> warnings) {
final StringBuilder b = new StringBuilder();
boolean f = true;
for (String w : warnings) {
if (f) {
f = false;
} else {
b.append('\n');
}
b.append(w);
}
return b;
}
public void notifyFinish() {
app.uiHandler.post(new Runnable() {
@Override
public void run() {
for(AppInitializeListener l : listeners) {
l.onFinish(AppInitializer.this);
}
}
});
}
public void notifyEvent(final InitEvents event) {
if (event != InitEvents.TASK_CHANGED) {
long time = System.currentTimeMillis();
System.out.println("Initialized " + event + " in " + (time - startBgTime) + " ms");
startBgTime = time;
}
app.uiHandler.post(new Runnable() {
@Override
public void run() {
for(AppInitializeListener l : listeners) {
l.onProgress(AppInitializer.this, event);
}
}
});
}
@Override
public void startTask(String taskName, int work) {
this.taskName = taskName;
notifyEvent(InitEvents.TASK_CHANGED);
}
@Override
public void startWork(int work) {
}
@Override
public void progress(int deltaWork) {
}
@Override
public void remaining(int remainingWork) {
}
@Override
public void finishTask() {
taskName = null;
notifyEvent(InitEvents.TASK_CHANGED);
}
public String getCurrentInitTaskName() {
return taskName;
}
@Override
public boolean isIndeterminate() {
return true;
}
@Override
public boolean isInterrupted() {
return false;
}
private boolean applicationBgInitializing = false;
public synchronized void startApplication() {
if (applicationBgInitializing) {
return;
}
applicationBgInitializing = true;
new Thread(new Runnable() { //$NON-NLS-1$
@Override
public void run() {
try {
startApplicationBackground();
} finally {
applicationBgInitializing = false;
}
}
}, "Initializing app").start();
}
public void addListener(AppInitializeListener listener) {
this.listeners.add(listener);
if(!appInitializing) {
listener.onFinish(this);
}
}
public void removeListener(AppInitializeListener listener) {
this.listeners.remove(listener);
}
private String getLocalClassName(String cls) {
final String pkg = app.getPackageName();
int packageLen = pkg.length();
if (!cls.startsWith(pkg) || cls.length() <= packageLen
|| cls.charAt(packageLen) != '.') {
return cls;
}
return cls.substring(packageLen+1);
}
}