@Override
  public void onStateChanged(DownloadEntry entry) {
    // TODO optimize
    adapter.notifyDataSetChanged();

    if (entry.state == DownloadService.State.finished) {
      String fontName = getFontNameFromDownloadKey(entry.key);
      if (fontName == null) { // this download doesn't belong to font manager.
        return;
      }

      try {
        String downloadedZip = getFontDownloadDestination(fontName);
        File fontDir = FontManager.getFontDir(fontName);
        fontDir.mkdirs();

        Log.d(TAG, "Going to unzip " + downloadedZip); // $NON-NLS-1$

        ZipInputStream zis =
            new ZipInputStream(new BufferedInputStream(new FileInputStream(downloadedZip)));
        try {
          ZipEntry ze;
          while ((ze = zis.getNextEntry()) != null) {
            String zname = ze.getName();
            Log.d(TAG, "Extracting from zip: " + zname); // $NON-NLS-1$
            File extractFile = new File(fontDir, zname);
            FileOutputStream fos = new FileOutputStream(extractFile);
            try {
              byte[] buf = new byte[4096];
              int count;
              while ((count = zis.read(buf)) != -1) {
                fos.write(buf, 0, count);
              }
            } finally {
              fos.close();
            }
          }
        } finally {
          zis.close();
        }

        new File(downloadedZip).delete();
      } catch (Exception e) {
        new AlertDialog.Builder(FontManagerActivity.this)
            .setMessage(
                getString(
                    R.string.fm_error_when_extracting_font,
                    fontName,
                    e.getClass().getSimpleName() + ' ' + e.getMessage()))
            .setPositiveButton(R.string.ok, null)
            .show();
      }
    }
  }
 @Override
 public void onProgress(DownloadEntry entry) {
   adapter.notifyDataSetChanged();
   // TODO optimize
 }