Example #1
0
    public void run() {
      while (stillAlive.get()) {
        synchronized (this) {
          try {
            ScheduledJob job = schedule.peek();

            if (job == null) {
              // If null, wake up every minute or so to see if there's something to do.
              // Most likely there will not be.
              try {
                this.wait(TIMEOUT_MS);
              } catch (InterruptedException e) {
                // interruption should occur when items are added or removed from the queue.
              }
            } else {
              // We've passed the job execution time, so we will run.
              if (!job.getScheduledExecution().isAfterNow()) {
                // Run job. The invocation of jobs should be quick.
                ScheduledJob runningJob = schedule.poll();
                logger.info("Scheduler attempting to run " + runningJob.getId());

                // Execute the job here
                try {
                  executionManager.execute(runningJob.getId(), runningJob.isDependencyIgnored());
                } catch (JobExecutionException e) {
                  logger.info("Could not run job. " + e.getMessage());
                }
                // Immediately reschedule if it's possible. Let the execution manager
                // handle any duplicate runs.
                if (runningJob.updateTime()) {
                  schedule.add(runningJob);
                  saveSchedule();
                } else {
                  // No need to keep it in the schedule.
                  removeScheduledJob(runningJob);
                }
              } else {
                // wait until job run
                long millisWait =
                    Math.max(
                        0, job.getScheduledExecution().getMillis() - (new DateTime()).getMillis());
                try {
                  this.wait(Math.min(millisWait, TIMEOUT_MS));
                } catch (InterruptedException e) {
                  // interruption should occur when items are added or removed from the queue.
                }
              }
            }
          } catch (Exception e) {
            logger.error("Unexpected exception has been thrown in scheduler", e);
          } catch (Throwable e) {
            logger.error("Unexpected throwable has been thrown in scheduler", e);
          }
        }
      }
    }
  private void handleMeasurement() {
    if (!userConsented()) {
      Logger.i("Skipping measurement - User has not consented");
      return;
    }

    try {
      MeasurementTask task = taskQueue.peek();
      // Process the head of the queue.
      if (task != null && task.timeFromExecution() <= 0) {
        taskQueue.poll();
        Future<MeasurementResult> future;
        Logger.i("Processing task " + task.toString());
        // Run the head task using the executor
        if (task.getDescription().priority == MeasurementTask.USER_PRIORITY) {
          sendStringMsg("Scheduling user task:\n" + task);
          // User task can override the power policy. So a different task wrapper is used.
          future = measurementExecutor.submit(new UserMeasurementTask(task));
        } else {
          sendStringMsg("Scheduling task:\n" + task);
          future = measurementExecutor.submit(new PowerAwareTask(task, powerManager, this));
        }
        synchronized (pendingTasks) {
          pendingTasks.put(task, future);
        }

        MeasurementDesc desc = task.getDescription();
        long newStartTime = desc.startTime.getTime() + (long) desc.intervalSec * 1000;

        // Add a clone of the task if it's still valid.
        if (newStartTime < desc.endTime.getTime()
            && (desc.count == MeasurementTask.INFINITE_COUNT || desc.count > 1)) {
          MeasurementTask newTask = task.clone();
          if (desc.count != MeasurementTask.INFINITE_COUNT) {
            newTask.getDescription().count--;
          }
          newTask.getDescription().startTime.setTime(newStartTime);
          submitTask(newTask);
        }
      }
      // Schedule the next measurement in the taskQueue
      task = taskQueue.peek();
      if (task != null) {
        long timeFromExecution =
            Math.max(task.timeFromExecution(), Config.MIN_TIME_BETWEEN_MEASUREMENT_ALARM_MSEC);
        measurementIntentSender =
            PendingIntent.getBroadcast(
                this,
                0,
                new UpdateIntent("", UpdateIntent.MEASUREMENT_ACTION),
                PendingIntent.FLAG_CANCEL_CURRENT);
        alarmManager.set(
            AlarmManager.RTC_WAKEUP,
            System.currentTimeMillis() + timeFromExecution,
            measurementIntentSender);
      }
    } catch (IllegalArgumentException e) {
      // Task creation in clone can create this exception
      Logger.e("Exception when cloning task");
      sendStringMsg("Exception when cloning task: " + e);
    } catch (Exception e) {
      // We don't want any unexpected exception to crash the process
      Logger.e("Exception when handling measurements", e);
      sendStringMsg("Exception running task: " + e);
    }
    persistState();
  }