title: Android: connecting to USB device, wait for permission
body: <p>I'm trying to do this: connect to USB device and get the opened (or failed) connection. I did the logic according to examples and explanations that I have found, but I have problem with waiting for permission grant. First I tried a "good" way of using wait()+notifyAll(), than I tried straightforward loop with checks, but both times the waiting method (waitConnection()) was blocking for the timeout I gave it, and only after that the message was received. So I tried these 2 versions.</p>
  
  <ol>
  <li><p>wait/notifyAll:</p>
  
  <pre><code>public UsbConnector startConnection(Context context) {
  
  BroadcastReceiver receiver = new BroadcastReceiver() {
      public void onReceive(Context context, Intent intent) {
          String action = intent.getAction();
          if (ACTION_USB_PERMISSION.equals(action)) {
              synchronized (syncObj) {
                  if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                      UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                      if (device != null) {
                          if (device.getVendorId() == vendorId &amp;&amp; device.getProductId() == productId) {
                              connection = usbManager.openDevice(device);
                              connectedDevice = device;
                          }
                      }
                  }
                  syncObj.notyfyAll();
              }
          }
      }
  };
  
  try {
      usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
      for (final UsbDevice device : usbManager.getDeviceList().values()) {
          if (device.getVendorId() == this.vendorId &amp;&amp; device.getProductId() == this.productId) {
  
              context.registerReceiver(receiver, new IntentFilter(ACTION_USB_PERMISSION));
              usbManager.requestPermission(device,
                      PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0));
              break;
          }
      }
  } catch (Exception e) {
  }
  return this;
  }
  
  public UsbDeviceConnection waitConnection(int timeout) {
  try {
      Thread.sleep(10, 0);
      syncObj.wait(timeout);
  } catch (InterruptedException e) {
  }
  return getConnection();
  }
  </code></pre></li>
  <li><p>straightforward loop</p>
  
  <pre><code>public UsbConnector startConnection(Context context) {
  
  BroadcastReceiver receiver = new BroadcastReceiver() {
      public void onReceive(Context context, Intent intent) {
          String action = intent.getAction();
          if (ACTION_USB_PERMISSION.equals(action)) {
              synchronized (this) {
                  if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                      UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                      if (device != null) {
                          if (device.getVendorId() == vendorId &amp;&amp; device.getProductId() == productId) {
                              connection = usbManager.openDevice(device);
                              connectedDevice = device;
                          }
                      }
                  }
                  permissionRequested = false;
              }
          }
      }
  };
  
  try {
      permissionRequested = false;
      usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
      for (final UsbDevice device : usbManager.getDeviceList().values()) {
          if (device.getVendorId() == this.vendorId &amp;&amp; device.getProductId() == this.productId) {
  
              permissionRequested = true;
              context.registerReceiver(receiver, new IntentFilter(ACTION_USB_PERMISSION));
              usbManager.requestPermission(device,
                      PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0));
              break;
          }
      }
  } catch (Exception e) {
  }
  return this;
  }
  
  public UsbDeviceConnection waitConnection(int timeout) {
  int waited = timeout;
  while (permissionRequested &amp;&amp; waited &gt; 0) {
      try {
          Thread.sleep(10, 0);
      } catch (InterruptedException e) {
      }
      waited -= 10;
  }
  
  return getConnection();
  }
  </code></pre></li>
  </ol>
  
  <p>So in both cases, according to logs, the waitConnection() method (that is called by the consumer immediately after startConnection()) seems to block the execution (I gave it timeout 10 seconds, and it was blocked for 10 seconds), and only right after it's completed, the BroadcastReceiver gets the message. It appears that requestPermission() is not async (as I thought it is), but in this case, how is it possible that startConnection() exits immediately and before the message is received? And how can I wait for BroadcastReceiver to get the message? Say if I don't use the waitConnection() method, how my consumer should know the moment when it can start checking for connection availability?</p>