Ejemplo n.º 1
0
  /**
   * Cancel execution if possible. This is called on the Worker thread
   *
   * <p>Do not override this unless you also call super.cancel(boolean).
   *
   * <p>Override onCanceled() is the normal notification location, and is called from the UI thread
   * with Task state updates handled for you.
   *
   * @param mayInterruptIfRunning (not yet supported)
   * @return
   */
  public synchronized boolean cancel(final boolean mayInterruptIfRunning) {
    boolean canceled = false;

    // #debug
    L.i("Begin explicit cancel task", "status=" + this.getStatusString() + " " + this);
    switch (status) {
      case EXEC_STARTED:
        if (mayInterruptIfRunning && Worker.interruptWorkable(this)) {
          setStatus(CANCELED);
          canceled = true;
        }
        break;

      case EXEC_FINISHED:
      case UI_RUN_FINISHED:
        // #debug
        L.i(
            "Attempt to cancel Task after run completes, suspicious but may be normal",
            this.toString());
        break;

      default:
        setStatus(CANCELED);
        canceled = true;
    }

    return canceled;
  }
Ejemplo n.º 2
0
    protected Object exec(Object in) {

      if (in != null) {
        // #debug
        L.i("Load feed success, type=" + getType, search);

        scrollY = 0;
        imageObjectModel.removeAllElements();
        images.clear();

        L.i("Vector in", in.toString());

        final Vector newModel = (Vector) in;

        for (int i = 0; i < newModel.size(); i++) {
          imageObjectModel.addElement(newModel.elementAt(i));
          String thumbUrl = ((PicasaImageObject) imageObjectModel.elementAt(i)).thumbUrl;
          try {
            PicasaStorage.imageCache.prefetch(thumbUrl);
          } catch (FlashDatabaseException e) {
            L.e("Could not fetch image", thumbUrl, e);
          }
        }

        top = -((imageObjectModel.size() * imageSide) / 2 - getHeight() / 2) + imageSide - 20;

        stopSpinner();
      } else {
        L.i("Variable in is null", "");
      }

      return in;
    }
Ejemplo n.º 3
0
  /**
   * Wait for a maximum of timeout milliseconds for the UITask to complete if needed and then also
   * complete the followup action on the user interface thread.
   *
   * <p>You will receive a debug time warning if you are currently on the UI thread and the timeout
   * value is greater than 100ms.
   *
   * @param timeout in milliseconds
   * @return final evaluation result of the Task
   * @throws InterruptedException - task was running when it was explicitly canceled by another
   *     thread
   * @throws CancellationException - task was explicitly canceled by another thread
   * @throws ExecutionException - an uncaught exception was thrown
   * @throws TimeoutException - UITask failed to complete within timeout milliseconds
   */
  public final Object joinUI(long timeout)
      throws InterruptedException, CancellationException, ExecutionException, TimeoutException {
    if (!(this instanceof UITask)) {
      throw new ClassCastException("Can not joinUI() unless Task is a UITask");
    }

    long t = System.currentTimeMillis();
    join(timeout);

    synchronized (this) {
      if (status < UI_RUN_FINISHED) {
        // #debug
        L.i("Start joinUI wait", "status=" + getStatusString());
        timeout -= System.currentTimeMillis() - t;
        while (timeout > 0) {
          final long t2 = System.currentTimeMillis();
          wait(timeout);
          if (status == UI_RUN_FINISHED) {
            break;
          }
          timeout -= System.currentTimeMillis() - t2;
        }
        // #debug
        L.i("End joinUI wait", "status=" + getStatusString());
        if (status < UI_RUN_FINISHED) {
          throw new TimeoutException("JoinUI(" + timeout + ") failed to complete quickly enough");
        }
      }

      return value;
    }
  }
Ejemplo n.º 4
0
  /**
   * Get the cache singleton associated with these parameters.
   *
   * @param priority
   * @param cacheType
   * @param startupTask
   * @return
   * @throws FlashDatabaseException
   */
  public FlashCache getFlashCache(
      final char priority, final int cacheType, final FlashCache.StartupTask startupTask)
      throws FlashDatabaseException {
    switch (cacheType) {
      case PlatformUtils.PHONE_DATABASE_CACHE:
        try {
          return new RMSFastCache(priority, startupTask);
        } catch (Exception e) {
          // #debug
          L.e(
              "Can not create flash cache, will attempt delete and re-init one time",
              "" + priority,
              e);
          RMSFastCache.deleteDataFiles(priority);
          try {
            final RMSFastCache cache = new RMSFastCache(priority, startupTask);
            // #debug
            L.i(
                "After deleting the files giving and error, we successfully created flash cache",
                "" + priority);
            return cache;
          } catch (Exception e2) {
            throw new FlashDatabaseException("Can not create flash cache: " + e2);
          }
        }

      default:
        throw new IllegalArgumentException(
            "Unsupported cache type "
                + cacheType
                + ": only PlatformAdapter.PHONE_DATABASE_CACHE is supported at this time");
    }
  }
Ejemplo n.º 5
0
  /**
   * Initializes the storage.
   *
   * @param width The width of the screen. This is used to determine how large images should be.
   */
  public static synchronized void init(final int width) {
    if (feedCache == null) {
      final ImageCacheView imageCacheView = PlatformUtils.getInstance().getImageCacheView();

      screenWidth = width;

      if (screenWidth < 256) {
        imageSide = 128; // Must be supported picasa thumb size
        imageSize = 288; // Image max size to get suitable sized images from picasa
      } else {
        imageSide = 256; // Must be supported thumb size in picasa
        imageSize = 720; // Picasa size for "fullsize" images
      }

      imageCacheView.setMaxSize(width, width);

      try {
        imageCache =
            StaticWebCache.getWebCache(
                '4',
                PlatformUtils.PHONE_DATABASE_CACHE,
                imageCacheView,
                new StaticWebCache.HttpTaskFactory(),
                null);
      } catch (FlashDatabaseException e) {
        L.e("Could not initialize imageCache.", "", e);
      }

      try {
        feedCache = StaticWebCache.getWebCache('5', (CacheView) new ImageObjectTypeHandler());
      } catch (FlashDatabaseException e) {
        L.e("Could not initialize feedCache.", "", e);
      }

      thumbSize = imageSide + "c"; // c is for cropped, ensures image proportions

      urlOptions =
          "?alt=json&kind=photo&max-results="
              + NR_OF_FEATURED
              + "&thumbsize="
              + thumbSize
              + "&fields=entry(title,author(name),updated,media:group)"
              + "&imgmax="
              + imageSize;

      featURL = "http://picasaweb.google.com/data/feed/base/featured" + urlOptions;

      searchURL = "http://picasaweb.google.com/data/feed/base/all" + urlOptions + "&q=";
    }
  }
Ejemplo n.º 6
0
  /**
   * You can call this as the return statement of your overriding method once you have set the
   * result
   *
   * @return
   */
  public final Object exec(Object in) {
    Object out = in;

    try {
      synchronized (this) {
        if (in == null) {
          in = value;
        } else {
          value = in;
        }
        if (status == Task.CANCELED || status == Task.EXCEPTION) {
          throw new IllegalStateException(
              this.getStatusString() + " state can not be executed: " + this);
        } else if (status != Task.EXEC_STARTED) {
          setStatus(Task.EXEC_STARTED);
        }
      }
      out = doInBackground(in);

      final boolean doRun;
      final Task t;
      synchronized (this) {
        value = out;
        doRun = status == EXEC_STARTED;
        if (doRun) {
          setStatus(EXEC_FINISHED);
        }
        t = chainedTask;
      }
      if (this instanceof UITask && doRun) {
        PlatformUtils.runOnUiThread((UITask) this);
      }
      if (t != null) {
        // #debug
        L.i("Begin exec chained task", chainedTask.toString() + " INPUT: " + out);
        t.exec(out);
        // #debug
        L.i("End exec chained task", chainedTask.toString());
      }
    } catch (final Throwable t) {
      // #debug
      L.e("Unhandled task exception", this.toString(), t);
      setStatus(EXCEPTION);
    }

    return out;
  }
Ejemplo n.º 7
0
  /**
   * Add a Task (or UITAsk, etc) which will run immediately after the present Task and on the same
   * Worker thread.
   *
   * <p>The output result of the present task is fed as the input to doInBackground() on the
   * nextTask, so any processing changes can propagated forward if the nextTask is so designed. This
   * Task behavior may thus be slightly different from the first Task in the chain, which by default
   * receives "null" as the input argument unless setValue() is called before fork()ing the first
   * task in the chain.
   *
   * @param nextTask
   * @return nextTask
   */
  public final synchronized Task chain(final Task nextTask) {
    // #mdebug
    if (nextTask == null) {
      L.i("WARNING", "chain(null) is probably a mistake- no effect");
    }
    // #enddebug
    this.chainedTask = nextTask;

    return nextTask;
  }
Ejemplo n.º 8
0
    public void onCanceled() {
      // #debug
      L.i("Load feed canceled, type=" + getType, search);

      if (getType == StaticWebCache.GET_LOCAL) {
        imageObjectModel.removeAllElements();
        images.clear();
        top = -getHeight();
      }

      stopSpinner();
    }
Ejemplo n.º 9
0
  private static void doJoinAll(final Task[] tasks, final long timeout, final boolean joinUI)
      throws InterruptedException, CancellationException, ExecutionException, TimeoutException {
    if (tasks == null) {
      throw new IllegalArgumentException("Can not joinAll(), list of tasks to join is null");
    }
    if (timeout < 0) {
      throw new IllegalArgumentException("Can not joinAll() with timeout < 0: timeout=" + timeout);
    }
    // #mdebug
    if (PlatformUtils.isUIThread() && timeout > 100) {
      L.i("WARNING- slow Task.joinAll() on UI Thread", "timeout=" + timeout);
    }
    // #enddebug

    // #debug
    L.i("Start joinAll(" + timeout + ")", "numberOfTasks=" + tasks.length);
    long timeLeft = Long.MAX_VALUE;
    try {
      final long startTime = System.currentTimeMillis();
      for (int i = 0; i < tasks.length; i++) {
        final Task task = tasks[i];
        timeLeft = startTime + timeout - System.currentTimeMillis();

        if (timeLeft <= 0) {
          throw new TimeoutException("joinAll(" + timeout + ") timout exceeded (" + timeLeft + ")");
        }
        if (joinUI && task instanceof UITask) {
          task.joinUI(timeout);
        } else {
          task.join(timeout);
        }
      }
    } finally {
      // #debug
      L.i(
          "End joinAll(" + timeout + ")",
          "numberOfTasks=" + tasks.length + " timeElapsed=" + (timeout - timeLeft));
    }
  }
Ejemplo n.º 10
0
  /**
   * @param search
   * @param getType
   * @return
   */
  public Task loadFeed(final String search, final int getType) {
    // #debug
    L.i("loadFeed", search);

    final Task task = new LoadFeedTask(search, getType);

    PicasaStorage.getImageObjects(search, Task.HIGH_PRIORITY, getType, task);

    if (getType != StaticWebCache.GET_LOCAL) {
      startSpinner();
    }

    return task;
  }
Ejemplo n.º 11
0
  /** @see com.nokia.example.picasaviewer.ui.GestureCanvas#gestureTap(int, int) */
  public boolean gestureTap(int startX, int startY) {
    boolean handled = false;

    if (!super.gestureTap(startX, startY)) {
      final int index = getItemIndex(startX, startY);

      if (index >= 0 && index < imageObjectModel.size()) {
        PicasaImageObject picasaImageObject = (PicasaImageObject) imageObjectModel.elementAt(index);
        PicasaStorage.setSelectedImage(picasaImageObject);

        // #debug
        L.i("select image", PicasaStorage.getSelectedImage().toString());

        viewManager.showView(ViewManager.DETAILS_VIEW_INDEX);
        handled = true;
      }
    }

    return handled;
  }
Ejemplo n.º 12
0
  /**
   * Change the status
   *
   * <p>You can only change status CANCELED or EXCEPTION to the READY state to explicitly indicate
   * you are going to re-use this Task. Note that Task re-use is generally not advised, but can be
   * valid if you have a special need such as performance when re-creating the Task is particularly
   * expensive.
   *
   * @param status
   */
  public final void setStatus(final int status) {
    if (status < EXEC_PENDING || status > READY) {
      throw new IllegalArgumentException("setStatus(" + status + ") not allowed");
    }
    final Task t;
    synchronized (this) {
      if ((this.status == CANCELED || this.status == EXCEPTION) && status != READY) {
        // #debug
        L.i(
            "State change from "
                + getStatusString()
                + " to "
                + Task.STATUS_STRINGS[status]
                + " is ignored",
            this.toString());
        return;
      }

      this.status = status;
      this.notifyAll();
      t = chainedTask;
    }

    if (status == CANCELED || status == EXCEPTION) {
      PlatformUtils.runOnUiThread(
          new Runnable() {
            public void run() {
              // #debug
              L.i("Task onCanceled()", Task.this.toString());
              onCanceled();
            }
          });
      // Also cancel any chained Tasks expecting the output of this Task
      if (t != null) {
        t.cancel(false);
      }
    }
  }
Ejemplo n.º 13
0
 /**
  * When parsing this RSS XML document, this indicates the body of an XML tag
  *
  * @param qname
  * @param chars
  * @param attributes
  */
 protected synchronized void parseElement(
     final String qname, final String chars, final XMLAttributes attributes) {
   try {
     if (currentItem != null) {
       synchronized (currentItem) {
         if (qname.equals("title")) {
           currentItem.setTitle(chars);
         } else if (qname.equals("description")) {
           currentItem.setDescription(chars);
         } else if (qname.equals("link")) {
           currentItem.setLink(chars);
         } else if (qname.equals("pubDate")) {
           currentItem.setPubDate(chars);
         } else if (qname.equals("media:thumbnail")) {
           currentItem.setThumbnail((String) attributes.getValue("url"));
         }
       }
     }
   } catch (Exception e) {
     // #debug
     L.e("RSS parsing error", "qname=" + qname + " - chars=" + chars, e);
   }
 }
Ejemplo n.º 14
0
 /**
  * This is executed on the UI thread
  *
  * <p>Override if needed, the default implementation does nothing except provide debug output.
  *
  * <p>Use getStatus() to distinguish between CANCELED and EXCEPTION states if necessary.
  */
 protected void onCanceled() {
   // #debug
   L.i("Task canceled", this.toString());
 }
Ejemplo n.º 15
0
  /**
   * Wait for a maximum of timeout milliseconds for the Task to run and return it's evaluation
   * value, otherwise throw a TimeoutExeception.
   *
   * <p>Similar to get(), except the total wait() time if the AsyncTask has not completed is
   * explicitly limited to prevent long delays.
   *
   * <p>Never call join() from the UI thread with a timeout greater than 100ms. This is still bad
   * design and better handled with a chained Task or UITask. You will receive a debug warning, but
   * are not prevented from making longer join() calls from the user interface Thread.
   *
   * @param timeout in milliseconds
   * @return final evaluation result of the Task
   * @throws InterruptedException - task was running when it was explicitly canceled by another
   *     thread
   * @throws CancellationException - task was explicitly canceled by another thread
   * @throws ExecutionException - an uncaught exception was thrown
   * @throws TimeoutException - UITask failed to complete within timeout milliseconds
   */
  public final Object join(long timeout)
      throws InterruptedException, CancellationException, ExecutionException, TimeoutException {
    if (timeout < 0) {
      throw new IllegalArgumentException("Can not join() with timeout < 0: timeout=" + timeout);
    }
    // #mdebug
    if (PlatformUtils.isUIThread() && timeout > 100) {
      L.i("WARNING- slow Task.join() on UI Thread", "timeout=" + timeout + " " + this);
    }
    // #enddebug
    boolean doExec = false;
    Object r;

    synchronized (this) {
      // #debug
      L.i("Start join", "timeout=" + timeout + " " + this);
      switch (status) {
        case EXEC_PENDING:
          // #debug
          L.i("Start join of EXEC_PENDING task", "timeout=" + timeout + " " + this.toString());
          if (Worker.tryUnfork(this)) {
            doExec = true;
            break;
          }
          // Continue to next state
        case READY:
          if (status == READY) {
            Worker.fork(this, Worker.HIGH_PRIORITY);
          }
          // Continue to next state
        case EXEC_STARTED:
          // #debug
          L.i("Start join wait()", "status=" + getStatusString());
          do {
            final long t = System.currentTimeMillis();

            wait(timeout);
            if (status == EXEC_FINISHED) {
              break;
            }
            if (status == CANCELED) {
              throw new CancellationException(
                  "join() was to a Task which had already been canceled: " + this);
            }
            if (status == EXCEPTION) {
              throw new ExecutionException(
                  "join() was to a Task which had already expereienced an uncaught runtime exception: "
                      + this);
            }
            timeout -= System.currentTimeMillis() - t;
          } while (timeout > 0);
          // #debug
          L.i("End join wait()", "status=" + getStatusString());
          if (status == EXEC_STARTED) {
            throw new TimeoutException(
                "Task was already started when join() was call and did not complete during "
                    + timeout
                    + " milliseconds");
          }
          break;
        case CANCELED:
          throw new CancellationException(
              "join() was to a Task which was running but then canceled: " + this);
        case EXCEPTION:
          throw new ExecutionException(
              "join() was to a Task which had an uncaught exception: " + this);
        default:;
      }
      r = value;
    }
    if (doExec) {
      // #debug
      L.i(
          "Start exec() out-of-sequence exec() after join() and successful unfork()",
          this.toString());
      r = exec(r);
    }

    return r;
  }
Ejemplo n.º 16
0
    public Object convertToUseForm(Object key, byte[] bytes) {
      JSONObject responseJson;

      try {
        responseJson = new JSONObject(new String(bytes));
      } catch (JSONException ex) {
        // #debug
        L.e("bytes are not a JSON object", featURL, ex);
        return null;
      }

      JSONArray entries = new JSONArray();
      final Vector vector = new Vector();

      try {
        final JSONObject feed = ((JSONObject) responseJson).getJSONObject("feed");
        entries = feed.getJSONArray("entry");
      } catch (JSONException e) {
        vector.addElement(new PicasaImageObject("No Results", "", "", ""));

        // #debug
        L.e("JSON no result", featURL, e);
      }

      for (int i = 0; i < entries.length(); i++) {
        try {
          final JSONObject jsonObject = entries.getJSONObject(i);
          final String title = jsonObject.getJSONObject("title").getString("$t");
          final String author =
              jsonObject
                  .getJSONArray("author")
                  .getJSONObject(0)
                  .getJSONObject("name")
                  .getString("$t");
          final String thumbUrl =
              jsonObject
                  .getJSONObject("media$group")
                  .getJSONArray("media$thumbnail")
                  .getJSONObject(0)
                  .getString("url");
          final String imageUrl =
              jsonObject
                  .getJSONObject("media$group")
                  .getJSONArray("media$content")
                  .getJSONObject(0)
                  .getString("url");

          // #mdebug
          L.i("JSON parsed title: ", title);
          L.i("JSON parsed author: ", author);
          L.i("JSON parsed thumb url: ", thumbUrl);
          L.i("JSON parsed image url: ", imageUrl);
          // #enddebug

          vector.addElement(new PicasaImageObject(title, author, thumbUrl, imageUrl));
        } catch (JSONException e) {
          // #debug
          L.e("JSON item parse error", featURL, e);
        }
      }

      if (entries.length() == 0) {
        vector.addElement(new PicasaImageObject("No Results", "", "", ""));
      }

      return vector;
    }