1922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem/*
2922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * Copyright (C) 2017 The Android Open Source Project
3922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem *
4922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * Licensed under the Apache License, Version 2.0 (the "License");
5922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * you may not use this file except in compliance with the License.
6922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * You may obtain a copy of the License at
7922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem *
8922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem *      http://www.apache.org/licenses/LICENSE-2.0
9922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem *
10922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * Unless required by applicable law or agreed to in writing, software
11922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * distributed under the License is distributed on an "AS IS" BASIS,
12922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * See the License for the specific language governing permissions and
14922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * limitations under the License
15922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem */
16922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriempackage com.android.dialer.common.concurrent;
17922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem
18922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriemimport com.google.common.util.concurrent.AbstractListeningExecutorService;
19922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriemimport com.google.common.util.concurrent.ListenableFuture;
20922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriemimport com.google.common.util.concurrent.SettableFuture;
21922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriemimport java.util.List;
22922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriemimport java.util.concurrent.Callable;
23922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriemimport java.util.concurrent.TimeUnit;
241632cfe1e3f3f94295289a62c69ec5a0489d8f13roldenburgimport javax.inject.Inject;
25922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem
26922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem/**
27922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * An ExecutorService that delegates to the UI thread. Rejects attempts to shut down, and all
28922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem * shutdown related APIs are unimplemented.
29922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem *
30922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem */
31922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriempublic class UiThreadExecutor extends AbstractListeningExecutorService {
32922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem
331632cfe1e3f3f94295289a62c69ec5a0489d8f13roldenburg  @Inject
3439009b4ad73d5017295b30fb18a77224195f06afzachh  public UiThreadExecutor() {}
351632cfe1e3f3f94295289a62c69ec5a0489d8f13roldenburg
36922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  @Override
37922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  public void shutdown() {
38922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem    throw new UnsupportedOperationException();
39922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  }
40922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem
41922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  @Override
42922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  public List<Runnable> shutdownNow() {
43922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem    throw new UnsupportedOperationException();
44922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  }
45922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem
46922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  @Override
47922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  public boolean isShutdown() {
48922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem    return false;
49922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  }
50922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem
51922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  @Override
52922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  public boolean isTerminated() {
53922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem    return false;
54922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  }
55922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem
56922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  @Override
57922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  public boolean awaitTermination(long l, TimeUnit timeUnit) throws InterruptedException {
58922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem    throw new UnsupportedOperationException();
59922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  }
60922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem
61922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  @Override
62922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  public <V> ListenableFuture<V> submit(final Callable<V> task) {
63922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem    final SettableFuture<V> resultFuture = SettableFuture.create();
64922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem    ThreadUtil.postOnUiThread(
65922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem        () -> {
66922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem          try {
67922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem            resultFuture.set(task.call());
68922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem          } catch (Exception e) {
69922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem            // uncaught exceptions on the UI thread should crash the app
70922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem            resultFuture.setException(e);
71922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem            throw new RuntimeException(e);
72922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem          }
73922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem        });
74922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem    return resultFuture;
75922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  }
76922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem
77922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  @Override
78922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  public void execute(final Runnable runnable) {
79922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem    ThreadUtil.postOnUiThread(runnable);
80922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem  }
81922cbed7a9ea329c3d1f89f64de14e35a26b96eaZachary Heidepriem}
82