1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/* 2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Copyright (C) 2010 The Android Open Source Project 3bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 4bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Licensed under the Apache License, Version 2.0 (the "License"); 5bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * you may not use this file except in compliance with the License. 6bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * You may obtain a copy of the License at 7bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 8bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * http://www.apache.org/licenses/LICENSE-2.0 9bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 10bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless required by applicable law or agreed to in writing, software 11bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS, 12bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * See the License for the specific language governing permissions and 14bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * limitations under the License. 15bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 16bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 17bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpackage com.android.email; 18bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.os.Handler; 20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.Controller.Result; 22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.mail.MessagingException; 23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.util.ArrayList; 25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/** 27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * A {@link Result} that wraps another {@link Result} and makes sure methods gets called back 28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * on the UI thread. 29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>Optionally it supports the "synchronous" mode, if you pass null for the {@code handler} 31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * parameter, which allows unit tests to run synchronously. 32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpublic class ControllerResultUiThreadWrapper<T extends Result> extends Result { 34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final Handler mHandler; 35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final T mWrappee; 36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public ControllerResultUiThreadWrapper(Handler handler, T wrappee) { 38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mHandler = handler; 39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mWrappee = wrappee; 40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public T getWrappee() { 43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mWrappee; 44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void setRegistered(boolean registered) { 48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super.setRegistered(registered); 49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mWrappee.setRegistered(registered); 50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private void run(Runnable runnable) { 53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mHandler == null) { 54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook runnable.run(); 55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mHandler.post(runnable); 57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void loadAttachmentCallback(final MessagingException result, final long accountId, 62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final long messageId, final long attachmentId, final int progress) { 63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook run(new Runnable() { 64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void run() { 65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /* It's possible this callback is unregistered after this Runnable was posted and 66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * sitting in the handler queue, so we always need to check if it's still registered 67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * on the UI thread. 68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isRegistered()) return; 70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mWrappee.loadAttachmentCallback(result, accountId, messageId, attachmentId, 71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook progress); 72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook }); 74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void loadMessageForViewCallback(final MessagingException result, final long accountId, 78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final long messageId, final int progress) { 79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook run(new Runnable() { 80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void run() { 81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isRegistered()) return; 82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mWrappee.loadMessageForViewCallback(result, accountId, messageId, progress); 83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook }); 85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void sendMailCallback(final MessagingException result, final long accountId, 89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final long messageId, final int progress) { 90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook run(new Runnable() { 91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void run() { 92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isRegistered()) return; 93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mWrappee.sendMailCallback(result, accountId, messageId, progress); 94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook }); 96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void serviceCheckMailCallback(final MessagingException result, final long accountId, 100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final long mailboxId, final int progress, final long tag) { 101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook run(new Runnable() { 102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void run() { 103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isRegistered()) return; 104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mWrappee.serviceCheckMailCallback(result, accountId, mailboxId, progress, tag); 105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook }); 107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void updateMailboxCallback(final MessagingException result, final long accountId, 111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final long mailboxId, final int progress, final int numNewMessages, 112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final ArrayList<Long> addedMessages) { 113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook run(new Runnable() { 114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void run() { 115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isRegistered()) return; 116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mWrappee.updateMailboxCallback(result, accountId, mailboxId, progress, 117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook numNewMessages, addedMessages); 118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook }); 120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void updateMailboxListCallback(final MessagingException result, final long accountId, 124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final int progress) { 125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook run(new Runnable() { 126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void run() { 127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isRegistered()) return; 128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mWrappee.updateMailboxListCallback(result, accountId, progress); 129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook }); 131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook} 133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook