AnimationThread.java revision 2eea6fab1cbb0a5c8f913491c2d622c904759893
12eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet/*
22eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * Copyright (C) 2010 The Android Open Source Project
32eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet *
42eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License");
52eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * you may not use this file except in compliance with the License.
62eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * You may obtain a copy of the License at
72eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet *
82eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet *      http://www.apache.org/licenses/LICENSE-2.0
92eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet *
102eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * Unless required by applicable law or agreed to in writing, software
112eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS,
122eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * See the License for the specific language governing permissions and
142eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet * limitations under the License.
152eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet */
162eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
172eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetpackage com.android.layoutlib.bridge.impl;
182eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
192eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport com.android.layoutlib.api.SceneResult;
202eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport com.android.layoutlib.api.LayoutScene.IAnimationListener;
212eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
222eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport android.animation.Animator;
232eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport android.animation.ValueAnimator;
242eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport android.os.Handler;
252eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport android.os.Handler_Delegate;
262eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport android.os.Message;
272eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport android.os.Handler_Delegate.IHandlerCallback;
282eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
292eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport java.util.LinkedList;
302eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport java.util.Queue;
312eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
322eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetpublic class AnimationThread extends Thread {
332eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
342eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    private static class MessageBundle {
352eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        final Handler mTarget;
362eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        final Message mMessage;
372eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        final long mUptimeMillis;
382eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
392eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        MessageBundle(Handler target, Message message, long uptimeMillis) {
402eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            mTarget = target;
412eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            mMessage = message;
422eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            mUptimeMillis = uptimeMillis;
432eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        }
442eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    }
452eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
462eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    private final LayoutSceneImpl mScene;
472eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    private final Animator mAnimator;
482eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
492eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    Queue<MessageBundle> mQueue = new LinkedList<MessageBundle>();
502eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    private final IAnimationListener mListener;
512eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
522eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    public AnimationThread(LayoutSceneImpl scene, Animator animator, IAnimationListener listener) {
532eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        mScene = scene;
542eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        mAnimator = animator;
552eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        mListener = listener;
562eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    }
572eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
582eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    @Override
592eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    public void run() {
602eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        mScene.prepareThread();
612eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        try {
622eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            Handler_Delegate.setCallback(new IHandlerCallback() {
632eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                public void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
642eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    if (msg.what == ValueAnimator.ANIMATION_START ||
652eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                            msg.what == ValueAnimator.ANIMATION_FRAME) {
662eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                        mQueue.add(new MessageBundle(handler, msg, uptimeMillis));
672eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    } else {
682eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                        // just ignore.
692eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    }
702eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                }
712eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            });
722eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
732eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            // start the animation. This will send a message to the handler right away, so
742eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            // mQueue is filled when this method returns.
752eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            mAnimator.start();
762eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
772eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            // loop the animation
782eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            do {
792eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                // get the next message.
802eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                MessageBundle bundle = mQueue.poll();
812eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                if (bundle == null) {
822eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    break;
832eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                }
842eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
852eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                // sleep enough for this bundle to be on time
862eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                long currentTime = System.currentTimeMillis();
872eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                if (currentTime < bundle.mUptimeMillis) {
882eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    try {
892eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                        sleep(bundle.mUptimeMillis - currentTime);
902eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    } catch (InterruptedException e) {
912eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                        // TODO Auto-generated catch block
922eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                        e.printStackTrace();
932eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    }
942eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                }
952eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
962eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                // ready to do the work, acquire the scene.
972eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                SceneResult result = mScene.acquire(250);
982eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                if (result != SceneResult.SUCCESS) {
992eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    mListener.done(result);
1002eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    return;
1012eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                }
1022eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
1032eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                // process the bundle. If the animation is not finished, this will enqueue
1042eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                // the next message, so mQueue will have another one.
1052eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                try {
1062eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    bundle.mTarget.handleMessage(bundle.mMessage);
1072eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    if (mScene.render() == SceneResult.SUCCESS) {
1082eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                        mListener.onNewFrame(mScene.getImage());
1092eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    }
1102eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                } finally {
1112eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                    mScene.release();
1122eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                }
1132eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            } while (mQueue.size() > 0);
1142eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
1152eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            mListener.done(SceneResult.SUCCESS);
1162eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        } finally {
1172eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            Handler_Delegate.setCallback(null);
1182eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            mScene.cleanupThread();
1192eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        }
1202eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    }
1212eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet}
122