예제 #1
0
 public UpdateAsyncTask(Context c, @NonNull Set<String> apps) {
   selectedApps = apps;
   progressDialog = new ProgressDialog(c);
   progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
   progressDialog.setTitle(R.string.updating);
   sharingUri = Utils.getSharingUri(FDroidApp.repo);
 }
예제 #2
0
  @TargetApi(14)
  private void setUIFromWifi() {
    if (TextUtils.isEmpty(FDroidApp.repo.address)) return;
    // the fingerprint is not useful on the button label
    String buttonLabel = FDroidApp.repo.address.replaceAll("\\?.*$", "");
    TextView sharingUriTextView = (TextView) findViewById(R.id.sharing_uri);
    sharingUriTextView.setText(buttonLabel);
    /*
     * Set URL to UPPER for compact QR Code, FDroid will translate it back.
     * Remove the SSID from the query string since SSIDs are case-sensitive.
     * Instead the receiver will have to rely on the BSSID to find the right
     * wifi AP to join. Lots of QR Scanners are buggy and do not respect
     * custom URI schemes, so we have to use http:// or https:// :-(
     */
    final String qrUriString =
        Utils.getSharingUri(this, FDroidApp.repo)
            .toString()
            .replaceFirst("fdroidrepo", "http")
            .replaceAll("ssid=[^?]*", "")
            .toUpperCase(Locale.ENGLISH);
    Log.i("QRURI", qrUriString);
    if (Build.VERSION.SDK_INT >= 8) // zxing requires >= 8
    new QrGenAsyncTask(this, R.id.repoQrCode).execute(qrUriString);

    TextView wifiNetworkNameTextView = (TextView) findViewById(R.id.wifi_network);
    wifiNetworkNameTextView.setText(FDroidApp.ssid);

    TextView fingerprintTextView = (TextView) findViewById(R.id.fingerprint);
    if (FDroidApp.repo.fingerprint != null) {
      fingerprintTextView.setVisibility(View.VISIBLE);
      fingerprintTextView.setText(FDroidApp.repo.fingerprint);
    } else {
      fingerprintTextView.setVisibility(View.GONE);
    }

    // the required NFC API was added in 4.0 aka Ice Cream Sandwich
    if (Build.VERSION.SDK_INT >= 14) {
      NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
      if (nfcAdapter == null) return;
      nfcAdapter.setNdefPushMessage(
          new NdefMessage(
              new NdefRecord[] {
                NdefRecord.createUri(Utils.getSharingUri(this, FDroidApp.repo)),
              }),
          this);
    }
  }
예제 #3
0
  protected void downloadFromStream() throws IOException, InterruptedException {
    Log.d(TAG, "Downloading from stream");
    InputStream input = null;
    try {
      input = getInputStream();

      // Getting the input stream is slow(ish) for HTTP downloads, so we'll check if
      // we were interrupted before proceeding to the download.
      throwExceptionIfInterrupted();

      copyInputToOutputStream(getInputStream());
    } finally {
      Utils.closeQuietly(outputStream);
      Utils.closeQuietly(input);
    }

    // Even if we have completely downloaded the file, we should probably respect
    // the wishes of the user who wanted to cancel us.
    throwExceptionIfInterrupted();
  }
예제 #4
0
  public void copyApksToRepo(List<String> appsToCopy) {
    for (final String packageName : appsToCopy) {
      final App app = apps.get(packageName);

      if (app.installedApk != null) {
        SanitizedFile outFile = new SanitizedFile(repoDir, app.installedApk.apkName);
        if (Utils.symlinkOrCopyFile(app.installedApk.installedFile, outFile)) continue;
      }
      // if we got here, something went wrong
      throw new IllegalStateException("Unable to copy APK");
    }
  }
예제 #5
0
 public void addApp(Context context, String packageName) {
   App app;
   try {
     app = new App(context.getApplicationContext(), pm, packageName);
     if (!app.isValid()) return;
     PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_META_DATA);
     app.icon = getIconFile(packageName, packageInfo.versionCode).getName();
   } catch (PackageManager.NameNotFoundException | CertificateEncodingException | IOException e) {
     Log.e(TAG, "Error adding app to local repo", e);
     return;
   }
   Utils.DebugLog(TAG, "apps.put: " + packageName);
   apps.put(packageName, app);
 }
예제 #6
0
  private boolean attemptToShowNfc() {
    // TODO: What if NFC is disabled? Hook up with NfcNotEnabledActivity? Or maybe only if they
    // click a relevant button?

    // Even if they opted to skip the message which says "Touch devices to swap",
    // we still want to actually enable the feature, so that they could touch
    // during the wifi qr code being shown too.
    boolean nfcMessageReady = NfcHelper.setPushMessage(this, Utils.getSharingUri(FDroidApp.repo));

    if (Preferences.get().showNfcDuringSwap() && nfcMessageReady) {
      showFragment(new NfcSwapFragment(), STATE_NFC);
      return true;
    }
    return false;
  }
예제 #7
0
  private String writeFdroidApkToWebroot() {
    ApplicationInfo appInfo;
    String fdroidClientURL = "https://f-droid.org/FDroid.apk";

    try {
      appInfo = pm.getApplicationInfo(fdroidPackageName, PackageManager.GET_META_DATA);
      SanitizedFile apkFile = SanitizedFile.knownSanitized(appInfo.publicSourceDir);
      SanitizedFile fdroidApkLink = new SanitizedFile(webRoot, "fdroid.client.apk");
      attemptToDelete(fdroidApkLink);
      if (Utils.symlinkOrCopyFile(apkFile, fdroidApkLink))
        fdroidClientURL = "/" + fdroidApkLink.getName();
    } catch (PackageManager.NameNotFoundException e) {
      Log.e(TAG, "Could not set up F-Droid apk in the webroot", e);
    }
    return fdroidClientURL;
  }
예제 #8
0
  public void writeIndexPage(String repoAddress) {
    final String fdroidClientURL = writeFdroidApkToWebroot();
    try {
      File indexHtml = new File(webRoot, "index.html");
      BufferedReader in =
          new BufferedReader(
              new InputStreamReader(assetManager.open("index.template.html"), "UTF-8"));
      BufferedWriter out =
          new BufferedWriter(new OutputStreamWriter(new FileOutputStream(indexHtml)));

      String line;
      while ((line = in.readLine()) != null) {
        line = line.replaceAll("\\{\\{REPO_URL\\}\\}", repoAddress);
        line = line.replaceAll("\\{\\{CLIENT_URL\\}\\}", fdroidClientURL);
        out.write(line);
      }
      in.close();
      out.close();

      for (final String file : WEB_ROOT_ASSET_FILES) {
        Utils.copy(assetManager.open(file), new FileOutputStream(new File(webRoot, file)));
      }

      // make symlinks/copies in each subdir of the repo to make sure that
      // the user will always find the bootstrap page.
      symlinkEntireWebRootElsewhere("../", fdroidDir);
      symlinkEntireWebRootElsewhere("../../", repoDir);

      // add in /FDROID/REPO to support bad QR Scanner apps
      attemptToMkdir(fdroidDirCaps);
      attemptToMkdir(repoDirCaps);

      symlinkEntireWebRootElsewhere("../", fdroidDirCaps);
      symlinkEntireWebRootElsewhere("../../", repoDirCaps);

    } catch (IOException e) {
      Log.e(TAG, "Error writing local repo index", e);
    }
  }
예제 #9
0
 private void symlinkFileElsewhere(String fileName, String symlinkPrefix, File directory) {
   SanitizedFile index = new SanitizedFile(directory, fileName);
   attemptToDelete(index);
   Utils.symlinkOrCopyFile(new SanitizedFile(new File(directory, symlinkPrefix), fileName), index);
 }
예제 #10
0
  @Override
  public synchronized void start() {

    if (isConnected()) return;

    receiver =
        new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
            switch (intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, -1)) {
              case BluetoothAdapter.SCAN_MODE_NONE:
                setConnected(false);
                break;

              case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
                isDiscoverable = true;
                if (server != null && server.isRunning()) {
                  setConnected(true);
                }
                break;

                // Only other is BluetoothAdapter.SCAN_MODE_CONNECTABLE. For now don't handle that.
            }
          }
        };
    context.registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED));

    /*
    if (server != null) {
        Utils.debugLog(TAG, "Attempting to start Bluetooth swap, but it appears to be running already. Will cancel it so it can be restarted.");
        server.close();
        server = null;
    }*/

    if (server == null) server = new BluetoothServer(this, context.getFilesDir());

    sendBroadcast(SwapService.EXTRA_STARTING);

    // store the original bluetoothname, and update this one to be unique
    deviceBluetoothName = adapter.getName();

    /*
    Utils.debugLog(TAG, "Prefixing Bluetooth adapter name with " + BLUETOOTH_NAME_TAG + " to make it identifiable as a swap device.");
    if (!deviceBluetoothName.startsWith(BLUETOOTH_NAME_TAG))
        adapter.setName(BLUETOOTH_NAME_TAG + deviceBluetoothName);

    if (!adapter.getName().startsWith(BLUETOOTH_NAME_TAG)) {
        Log.e(TAG, "Couldn't change the name of the Bluetooth adapter, it will not get recognized by other swap clients.");
        // TODO: Should we bail here?
    }*/

    if (!adapter.isEnabled()) {
      Utils.debugLog(TAG, "Bluetooth adapter is disabled, attempting to enable.");
      if (!adapter.enable()) {
        Utils.debugLog(
            TAG, "Could not enable Bluetooth adapter, so bailing out of Bluetooth swap.");
        setConnected(false);
        return;
      }
    }

    if (adapter.isEnabled()) {
      setConnected(true);
    } else {
      Log.i(
          TAG,
          "Didn't start Bluetooth swapping server, because Bluetooth is disabled and couldn't be enabled.");
      setConnected(false);
    }
  }
예제 #11
0
 protected void onStopped() {
   Utils.debugLog(
       TAG, "Resetting bluetooth device name to " + deviceBluetoothName + " after swapping.");
   adapter.setName(deviceBluetoothName);
 }