@Override
 protected Throwable doInBackground(final String... params) {
   LCTX.d("BookLoadTask.doInBackground(): start");
   try {
     final File cached = scheme.loadToCache(intent.getData(), this);
     if (cached != null) {
       m_fileName = cached.getAbsolutePath();
       setProgressDialogMessage(startProgressStringId);
     }
     getView().waitForInitialization();
     documentModel.open(m_fileName, m_password);
     getDocumentController().init(this);
     return null;
   } catch (final MuPdfPasswordException pex) {
     LCTX.i(pex.getMessage());
     return pex;
   } catch (final Exception e) {
     LCTX.e(e.getMessage(), e);
     return e;
   } catch (final Throwable th) {
     LCTX.e("BookLoadTask.doInBackground(): Unexpected error", th);
     return th;
   } finally {
     LCTX.d("BookLoadTask.doInBackground(): finish");
   }
 }
 @Override
 public boolean onSingleTapUp(MotionEvent e) {
   if (LCTX.isDebugEnabled()) {
     LCTX.d("onSingleTapUp(): " + current);
   }
   endPoint = null;
   return true;
 }
 @Override
 public boolean onDown(final MotionEvent e) {
   startPoint = new PointF(e.getX(), e.getY());
   endPoint = startPoint;
   current = getRegion(startPoint, endPoint);
   if (LCTX.isDebugEnabled()) {
     LCTX.d("onDown(): " + current);
   }
   return true;
 }
 synchronized void closeDatabase(final SQLiteDatabase db) {
   if (db != upgragingInstance && db != m_db) {
     try {
       db.close();
     } catch (final Exception ex) {
       LCTX.e("Unexpected DB close error: ", ex);
     }
     LCTX.d("DB connection closed: " + m_db);
   }
 }
 @Override
 public boolean onSingleTapConfirmed(final MotionEvent e) {
   if (profile != null) {
     current = profile.getRegion(e.getX(), e.getY(), getWidth(), getHeight());
     if (LCTX.isDebugEnabled()) {
       LCTX.d("onSingleTapConfirmed(): " + current);
     }
     processRegion();
   }
   return true;
 }
 @Override
 public boolean onScroll(
     final MotionEvent e1, final MotionEvent e2, final float distanceX, final float distanceY) {
   final float x = e2.getX(), y = e2.getY();
   endPoint = new PointF(x, y);
   current = getRegion(startPoint, endPoint);
   if (LCTX.isDebugEnabled()) {
     LCTX.d("onScroll(): " + current);
   }
   invalidate();
   return true;
 }
 @Override
 public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
   upgragingInstance = db;
   LCTX.i("Upgrading from version " + oldVersion + " to version " + newVersion);
   try {
     final IDBAdapter oldAdapter = createAdapter(oldVersion);
     final IDBAdapter newAdapter = createAdapter(newVersion);
     switchAdapter(db, oldAdapter, newAdapter);
   } finally {
     upgragingInstance = null;
     LCTX.i("Upgrade finished");
   }
 }
 public void close() {
   if (m_db != null) {
     try {
       m_db.close();
     } catch (Exception ex) {
       LCTX.e("Unexpected DB close error: ", ex);
     }
     m_db = null;
   }
 }
 public DBSettingsManager(final Context context) {
   super(context, context.getPackageName() + ".settings", null, DB_VERSION);
   adapter = createAdapter(DB_VERSION);
   try {
     m_db = getWritableDatabase();
   } catch (final Exception ex) {
     LCTX.e("Unexpected DB error: ", ex);
   }
   BackupManager.addAgent(this);
 }
    @Override
    protected void onPostExecute(Throwable result) {
      LCTX.d("BookLoadTask.onPostExecute(): start");
      try {
        if (result == null) {
          try {
            getDocumentController().show();

            final DocumentModel dm = getDocumentModel();
            currentPageChanged(PageIndex.NULL, dm.getCurrentIndex());

          } catch (final Throwable th) {
            result = th;
          }
        }

        super.onPostExecute(result);

        if (result instanceof MuPdfPasswordException) {
          final MuPdfPasswordException pex = (MuPdfPasswordException) result;
          final int promptId =
              pex.isWrongPasswordEntered()
                  ? R.string.msg_wrong_password
                  : R.string.msg_password_required;

          askPassword(m_fileName, promptId);

        } else if (result != null) {
          final String msg = result.getMessage();
          LogManager.onUnexpectedError(result);
          showErrorDlg(R.string.msg_unexpected_error, msg);
        } else {
          if (codecType != null && codecType.useCustomFonts) {
            EBookDroidApp.checkInstalledFonts(getManagedComponent());
          }
        }
      } catch (final Throwable th) {
        LCTX.e("BookLoadTask.onPostExecute(): Unexpected error", th);
        LogManager.onUnexpectedError(result);
      } finally {
        LCTX.d("BookLoadTask.onPostExecute(): finish");
      }
    }
  /**
   * {@inheritDoc}
   *
   * @see android.database.sqlite.SQLiteOpenHelper#getWritableDatabase()
   */
  @Override
  public synchronized SQLiteDatabase getWritableDatabase() {
    if (upgragingInstance != null) {
      return upgragingInstance;
    }

    if (m_db != null && m_db.isOpen()) {
      return m_db;
    }
    LCTX.d("New DB connection created: " + m_db);
    m_db = super.getWritableDatabase();
    return m_db;
  }
    @Override
    protected RectF doInBackground(final String... params) {
      try {
        final int length = LengthUtils.length(params);

        pattern = length > 0 ? params[0] : null;
        final boolean forward = length >= 3 ? Boolean.parseBoolean(params[2]) : true;

        searchModel.setPattern(pattern);

        final RectF current = forward ? searchModel.moveToNext(this) : searchModel.moveToPrev(this);
        targetPage = searchModel.getCurrentPage();
        if (LCTX.isDebugEnabled()) {
          LCTX.d("SearchTask.doInBackground(): " + targetPage + " " + current);
        }
        return current;

      } catch (final Throwable th) {
        th.printStackTrace();
      }
      return null;
    }
 protected IViewController switchDocumentController(final BookSettings bs) {
   if (bs != null) {
     try {
       final IViewController newDc = bs.viewMode.create(this);
       if (newDc != null) {
         final IViewController oldDc = ctrl.getAndSet(newDc);
         getZoomModel().removeListener(oldDc);
         getZoomModel().addListener(newDc);
         return ctrl.get();
       }
     } catch (final Throwable e) {
       LCTX.e("Unexpected error: ", e);
     }
   }
   return null;
 }
    void scanDir(final File dir) {
      // Checks if scan should be continued
      if (!inScan.get()) {
        return;
      }

      if (dir == null || !dir.isDirectory()) {
        return;
      }

      if (dir.getAbsolutePath().startsWith("/sys")) {
        LCTX.d("Skip system dir: " + dir);
        return;
      }

      try {
        final File cd = CacheManager.getCacheDir();
        if (dir.getCanonicalPath().equals(cd.getCanonicalPath())) {
          LCTX.d("Skip file cache: " + dir);
          return;
        }
      } catch (final IOException ex) {
        ex.printStackTrace();
      }

      if (LCTX.isDebugEnabled()) {
        LCTX.d("Scan dir: " + dir);
      }

      // Retrieves file observer for scanning folder
      final FileObserver observer = getObserver(dir);
      // Stop watching
      observer.stopWatching();

      // Retrieves listener
      final Listener l = listeners.getListener();

      // Retrieves file list
      final File[] files = dir.listFiles((FilenameFilter) filter);
      // Sort file list
      if (LengthUtils.isNotEmpty(files)) {
        Arrays.sort(files, StringUtils.NFC);
      }
      // Call the file scan callback
      l.onFileScan(dir, files);

      // Retrieves files from current directory
      final File[] childDirs = dir.listFiles(DirectoryFilter.ALL);
      // Immediately starts folder watching
      getObserver(dir).startWatching();

      if (LengthUtils.isNotEmpty(childDirs)) {
        // Sort child dir list
        Arrays.sort(childDirs, StringUtils.NFC);
        // Add children for deep ordered scanning
        synchronized (this) {
          for (int i = childDirs.length - 1; i >= 0; i--) {
            this.paths.addFirst(childDirs[i]);
          }
        }
      }
    }
  /**
   * {@inheritDoc}
   *
   * @see org.emdev.ui.AbstractActivityController#afterCreate(android.app.Activity, boolean)
   */
  @Override
  public void afterCreate(final ViewerActivity activity, final boolean recreated) {

    final AppSettings appSettings = AppSettings.current();

    IUIManager.instance.setFullScreenMode(
        activity, getManagedComponent().view.getView(), appSettings.fullScreen);

    createAction(R.id.mainmenu_crop)
        .putValue("view", activity.getManualCropControls())
        .putValue("mode", DocumentViewMode.SINGLE_PAGE);
    createAction(R.id.mainmenu_zoom).putValue("view", activity.getZoomControls());
    createAction(R.id.mainmenu_search).putValue("view", activity.getSearchControls());
    createAction(R.id.actions_toggleTouchManagerView).putValue("view", activity.getTouchView());
    createAction(R.id.mainmenu_force_portrait).putValue("mode", BookRotationType.PORTRAIT);
    createAction(R.id.mainmenu_force_landscape).putValue("mode", BookRotationType.LANDSCAPE);

    if (recreated) {
      return;
    }

    documentModel = ActivityControllerStub.DM_STUB;
    searchModel = new SearchModel(this);

    if (intent == null) {
      showErrorDlg(R.string.msg_bad_intent, intent);
      return;
    }

    final Uri data = intent.getData();
    if (data == null) {
      showErrorDlg(R.string.msg_no_intent_data, intent);
      return;
    }

    scheme = ContentScheme.getScheme(intent);
    if (scheme == ContentScheme.UNKNOWN) {
      showErrorDlg(R.string.msg_bad_intent, intent);
      return;
    }

    bookTitle = scheme.getResourceName(activity.getContentResolver(), data);
    codecType = CodecType.getByUri(bookTitle);

    if (codecType == null) {
      bookTitle = ContentScheme.getDefaultResourceName(data, "");
      codecType = CodecType.getByUri(bookTitle);
    }

    if (codecType == null) {
      final String type = intent.getType();
      LCTX.i("Book mime type: " + type);
      if (LengthUtils.isNotEmpty(type)) {
        codecType = CodecType.getByMimeType(type);
      }
    }

    LCTX.i("Book codec type: " + codecType);
    LCTX.i("Book title: " + bookTitle);
    if (codecType == null) {
      showErrorDlg(R.string.msg_unknown_intent_data_type, data);
      return;
    }

    documentModel = new DocumentModel(codecType);
    documentModel.addListener(ViewerActivityController.this);
    progressModel = new DecodingProgressModel();
    progressModel.addListener(ViewerActivityController.this);

    final Uri uri = data;
    if (scheme.temporary) {
      m_fileName = scheme.key;
      CacheManager.clear(scheme.key);
    } else {
      m_fileName = PathFromUri.retrieve(activity.getContentResolver(), uri);
    }

    bookSettings = SettingsManager.create(id, m_fileName, scheme.temporary, intent);
    SettingsManager.applyBookSettingsChanges(null, bookSettings);
  }