Home | History | Annotate | Download | only in util
      1 /*
      2  *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 package org.appspot.apprtc.util;
     12 
     13 import android.os.Handler;
     14 import android.os.Looper;
     15 import android.util.Log;
     16 
     17 import java.util.concurrent.Executor;
     18 
     19 /**
     20  * Looper based executor class.
     21  */
     22 public class LooperExecutor extends Thread implements Executor {
     23   private static final String TAG = "LooperExecutor";
     24   // Object used to signal that looper thread has started and Handler instance
     25   // associated with looper thread has been allocated.
     26   private final Object looperStartedEvent = new Object();
     27   private Handler handler = null;
     28   private boolean running = false;
     29   private long threadId;
     30 
     31   @Override
     32   public void run() {
     33     Looper.prepare();
     34     synchronized (looperStartedEvent) {
     35       Log.d(TAG, "Looper thread started.");
     36       handler = new Handler();
     37       threadId = Thread.currentThread().getId();
     38       looperStartedEvent.notify();
     39     }
     40     Looper.loop();
     41   }
     42 
     43   public synchronized void requestStart() {
     44     if (running) {
     45       return;
     46     }
     47     running = true;
     48     handler = null;
     49     start();
     50     // Wait for Hander allocation.
     51     synchronized (looperStartedEvent) {
     52       while (handler == null) {
     53         try {
     54           looperStartedEvent.wait();
     55         } catch (InterruptedException e) {
     56           Log.e(TAG, "Can not start looper thread");
     57           running = false;
     58         }
     59       }
     60     }
     61   }
     62 
     63   public synchronized void requestStop() {
     64     if (!running) {
     65       return;
     66     }
     67     running = false;
     68     handler.post(new Runnable() {
     69       @Override
     70       public void run() {
     71         Looper.myLooper().quit();
     72         Log.d(TAG, "Looper thread finished.");
     73       }
     74     });
     75   }
     76 
     77   // Checks if current thread is a looper thread.
     78   public boolean checkOnLooperThread() {
     79     return (Thread.currentThread().getId() == threadId);
     80   }
     81 
     82   @Override
     83   public synchronized void execute(final Runnable runnable) {
     84     if (!running) {
     85       Log.w(TAG, "Running looper executor without calling requestStart()");
     86       return;
     87     }
     88     if (Thread.currentThread().getId() == threadId) {
     89       runnable.run();
     90     } else {
     91       handler.post(runnable);
     92     }
     93   }
     94 
     95 }
     96