From dfd2e4da29f9aa8a7d5fcf0ff086cea8d4aa4976 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Thu, 7 Mar 2019 19:01:26 +0800 Subject: [PATCH] Replace Handler with Executor for async DNS API Bug: 124882626 Test: built, flashed, booted atest DnsResolverTest DnsPacketTest Change-Id: Ie1dc27643d4767f2a8a39da755edf388a00962d5 --- core/java/android/net/DnsResolver.java | 64 +++++++++++++------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java index f248958055..93b8cf801d 100644 --- a/core/java/android/net/DnsResolver.java +++ b/core/java/android/net/DnsResolver.java @@ -22,11 +22,11 @@ import static android.net.NetworkUtils.resNetworkSend; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; +import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.os.Handler; -import android.os.MessageQueue; +import android.os.Looper; import android.system.ErrnoException; import android.util.Log; @@ -37,6 +37,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executor; /** * Dns resolver class for asynchronous dns querying @@ -182,20 +183,19 @@ public final class DnsResolver { } /** - * Pass in a blob and corresponding flags, get an answer back asynchronously - * through {@link AnswerCallback}. + * Send a raw DNS query. + * The answer will be provided asynchronously through the provided {@link AnswerCallback}. * * @param network {@link Network} specifying which network for querying. * {@code null} for query on default network. * @param query blob message * @param flags flags as a combination of the FLAGS_* constants - * @param handler {@link Handler} to specify the thread - * upon which the {@link AnswerCallback} will be invoked. + * @param executor The {@link Executor} that the callback should be executed on. * @param callback an {@link AnswerCallback} which will be called to notify the caller * of the result of dns query. */ public void query(@Nullable Network network, @NonNull byte[] query, @QueryFlag int flags, - @NonNull Handler handler, @NonNull AnswerCallback callback) { + @NonNull @CallbackExecutor Executor executor, @NonNull AnswerCallback callback) { final FileDescriptor queryfd; try { queryfd = resNetworkSend((network != null @@ -205,12 +205,12 @@ public final class DnsResolver { return; } - registerFDListener(handler.getLooper().getQueue(), queryfd, callback); + registerFDListener(executor, queryfd, callback); } /** - * Pass in a domain name and corresponding setting, get an answer back asynchronously - * through {@link AnswerCallback}. + * Send a DNS query with the specified name, class and query type. + * The answer will be provided asynchronously through the provided {@link AnswerCallback}. * * @param network {@link Network} specifying which network for querying. * {@code null} for query on default network. @@ -218,14 +218,13 @@ public final class DnsResolver { * @param nsClass dns class as one of the CLASS_* constants * @param nsType dns resource record (RR) type as one of the TYPE_* constants * @param flags flags as a combination of the FLAGS_* constants - * @param handler {@link Handler} to specify the thread - * upon which the {@link AnswerCallback} will be invoked. + * @param executor The {@link Executor} that the callback should be executed on. * @param callback an {@link AnswerCallback} which will be called to notify the caller * of the result of dns query. */ public void query(@Nullable Network network, @NonNull String domain, @QueryClass int nsClass, @QueryType int nsType, @QueryFlag int flags, - @NonNull Handler handler, @NonNull AnswerCallback callback) { + @NonNull @CallbackExecutor Executor executor, @NonNull AnswerCallback callback) { final FileDescriptor queryfd; try { queryfd = resNetworkQuery((network != null @@ -234,33 +233,32 @@ public final class DnsResolver { callback.onQueryException(e); return; } - registerFDListener(handler.getLooper().getQueue(), queryfd, callback); + registerFDListener(executor, queryfd, callback); } - private void registerFDListener(@NonNull MessageQueue queue, + private void registerFDListener(@NonNull Executor executor, @NonNull FileDescriptor queryfd, @NonNull AnswerCallback answerCallback) { - queue.addOnFileDescriptorEventListener( + Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener( queryfd, FD_EVENTS, (fd, events) -> { - byte[] answerbuf = null; - try { - // TODO: Implement result function in Java side instead of using JNI - // Because JNI method close fd prior than unregistering fd on - // event listener. - answerbuf = resNetworkResult(fd); - } catch (ErrnoException e) { - Log.e(TAG, "resNetworkResult:" + e.toString()); - answerCallback.onQueryException(e); - return 0; - } - - try { - answerCallback.onAnswer(answerCallback.parser.parse(answerbuf)); - } catch (ParseException e) { - answerCallback.onParseException(e); - } + executor.execute(() -> { + byte[] answerbuf = null; + try { + answerbuf = resNetworkResult(fd); + } catch (ErrnoException e) { + Log.e(TAG, "resNetworkResult:" + e.toString()); + answerCallback.onQueryException(e); + return; + } + try { + answerCallback.onAnswer( + answerCallback.parser.parse(answerbuf)); + } catch (ParseException e) { + answerCallback.onParseException(e); + } + }); // Unregister this fd listener return 0; });