DreamController.java revision f6d466895b74d620d646abbec1c8911f3a0ce0bb
1f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock/* 2f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Copyright (C) 2012 The Android Open Source Project 3f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * 4f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 5f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * you may not use this file except in compliance with the License. 6f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * You may obtain a copy of the License at 7f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * 8f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * http://www.apache.org/licenses/LICENSE-2.0 9f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * 10f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Unless required by applicable law or agreed to in writing, software 11f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 12f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * See the License for the specific language governing permissions and 14f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * limitations under the License. 15f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock */ 16f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 17cef440f2a2bb8b6e8d082d12a67dc21f2ee65e3cJeff Brownpackage com.android.server.dreams; 18f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 19f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.ComponentName; 20f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.Context; 21f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.Intent; 22f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.ServiceConnection; 23f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.Binder; 24f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.Handler; 25f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.IBinder; 26f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.RemoteException; 27f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.IBinder.DeathRecipient; 28cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasaniimport android.os.UserHandle; 29be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackbornimport android.service.dreams.DreamService; 30f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.service.dreams.IDreamService; 31f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.util.Slog; 32f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.view.IWindowManager; 33f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.view.WindowManager; 34f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.view.WindowManagerGlobal; 35f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 36f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.io.PrintWriter; 37f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.util.NoSuchElementException; 38f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 39f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock/** 40f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Internal controller for starting and stopping the current dream and managing related state. 41f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * 4262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown * Assumes all operations are called from the dream handler thread. 43f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock */ 44f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockfinal class DreamController { 4562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private static final String TAG = "DreamController"; 46f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 47006f567c214d67752cc7c2b6446c328744f40af7John Spurlock // How long we wait for a newly bound dream to create the service connection 48006f567c214d67752cc7c2b6446c328744f40af7John Spurlock private static final int DREAM_CONNECTION_TIMEOUT = 5 * 1000; 49006f567c214d67752cc7c2b6446c328744f40af7John Spurlock 50f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown // Time to allow the dream to perform an exit transition when waking up. 51f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown private static final int DREAM_FINISH_TIMEOUT = 5 * 1000; 52f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 53f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock private final Context mContext; 5462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private final Handler mHandler; 55f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock private final Listener mListener; 5662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private final IWindowManager mIWindowManager; 57f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 58be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackborn private final Intent mDreamingStartedIntent = new Intent(Intent.ACTION_DREAMING_STARTED) 5962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 60be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackborn private final Intent mDreamingStoppedIntent = new Intent(Intent.ACTION_DREAMING_STOPPED) 6162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 62f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 63591a9e8d6ef2cab3ab3a701bd6279b6c12e6e4c6John Spurlock private final Intent mCloseNotificationShadeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 64591a9e8d6ef2cab3ab3a701bd6279b6c12e6e4c6John Spurlock 6562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private DreamRecord mCurrentDream; 66f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 67006f567c214d67752cc7c2b6446c328744f40af7John Spurlock private final Runnable mStopUnconnectedDreamRunnable = new Runnable() { 68006f567c214d67752cc7c2b6446c328744f40af7John Spurlock @Override 69006f567c214d67752cc7c2b6446c328744f40af7John Spurlock public void run() { 70006f567c214d67752cc7c2b6446c328744f40af7John Spurlock if (mCurrentDream != null && mCurrentDream.mBound && !mCurrentDream.mConnected) { 71006f567c214d67752cc7c2b6446c328744f40af7John Spurlock Slog.w(TAG, "Bound dream did not connect in the time allotted"); 72f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 73006f567c214d67752cc7c2b6446c328744f40af7John Spurlock } 74006f567c214d67752cc7c2b6446c328744f40af7John Spurlock } 75006f567c214d67752cc7c2b6446c328744f40af7John Spurlock }; 76006f567c214d67752cc7c2b6446c328744f40af7John Spurlock 77f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown private final Runnable mStopStubbornDreamRunnable = new Runnable() { 78f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown @Override 79f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown public void run() { 80f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown Slog.w(TAG, "Stubborn dream did not finish itself in the time allotted"); 81f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 82f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 83f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown }; 84f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 8562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public DreamController(Context context, Handler handler, Listener listener) { 86f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock mContext = context; 8762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler = handler; 88f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock mListener = listener; 89f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock mIWindowManager = WindowManagerGlobal.getWindowManagerService(); 90f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 91f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 92f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock public void dump(PrintWriter pw) { 9362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println("Dreamland:"); 9462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream != null) { 9562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mCurrentDream:"); 9662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mToken=" + mCurrentDream.mToken); 9762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mName=" + mCurrentDream.mName); 9862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mIsTest=" + mCurrentDream.mIsTest); 992687550272ba061448f5d5b914700dc335299ee7Jeff Brown pw.println(" mCanDoze=" + mCurrentDream.mCanDoze); 10062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mUserId=" + mCurrentDream.mUserId); 10162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mBound=" + mCurrentDream.mBound); 10262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mService=" + mCurrentDream.mService); 10362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mSentStartBroadcast=" + mCurrentDream.mSentStartBroadcast); 104f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown pw.println(" mWakingGently=" + mCurrentDream.mWakingGently); 10562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } else { 10662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mCurrentDream: null"); 107f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 108f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 109f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1102687550272ba061448f5d5b914700dc335299ee7Jeff Brown public void startDream(Binder token, ComponentName name, 1112687550272ba061448f5d5b914700dc335299ee7Jeff Brown boolean isTest, boolean canDoze, int userId) { 112f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 113f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 114cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasani // Close the notification shade. Don't need to send to all, but better to be explicit. 115cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasani mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL); 116591a9e8d6ef2cab3ab3a701bd6279b6c12e6e4c6John Spurlock 1172687550272ba061448f5d5b914700dc335299ee7Jeff Brown Slog.i(TAG, "Starting dream: name=" + name 1182687550272ba061448f5d5b914700dc335299ee7Jeff Brown + ", isTest=" + isTest + ", canDoze=" + canDoze 1192687550272ba061448f5d5b914700dc335299ee7Jeff Brown + ", userId=" + userId); 120f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1212687550272ba061448f5d5b914700dc335299ee7Jeff Brown mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId); 122f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 123f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock try { 12462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM); 12562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } catch (RemoteException ex) { 12662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown Slog.e(TAG, "Unable to add window token for dream.", ex); 127f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 128f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock return; 129f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 130f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 131be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackborn Intent intent = new Intent(DreamService.SERVICE_INTERFACE); 13262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown intent.setComponent(name); 13362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 13462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown try { 13527b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani if (!mContext.bindServiceAsUser(intent, mCurrentDream, 13627b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani Context.BIND_AUTO_CREATE, new UserHandle(userId))) { 13762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown Slog.e(TAG, "Unable to bind dream service: " + intent); 138f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 13962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown return; 14062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 14162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } catch (SecurityException ex) { 14262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown Slog.e(TAG, "Unable to bind dream service: " + intent, ex); 143f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 144f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock return; 145f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 146f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 14762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mCurrentDream.mBound = true; 148006f567c214d67752cc7c2b6446c328744f40af7John Spurlock mHandler.postDelayed(mStopUnconnectedDreamRunnable, DREAM_CONNECTION_TIMEOUT); 14962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 150f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 151f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown public void stopDream(boolean immediate) { 15262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == null) { 153f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock return; 154f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 155f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 156f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown if (!immediate) { 157f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown if (mCurrentDream.mWakingGently) { 158f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown return; // already waking gently 159f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 160f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 161f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown if (mCurrentDream.mService != null) { 162f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown // Give the dream a moment to wake up and finish itself gently. 163f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown mCurrentDream.mWakingGently = true; 164f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown try { 165f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown mCurrentDream.mService.wakeUp(); 166f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown mHandler.postDelayed(mStopStubbornDreamRunnable, DREAM_FINISH_TIMEOUT); 167f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown return; 168f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } catch (RemoteException ex) { 169f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown // oh well, we tried, finish immediately instead 170f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 171f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 172f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 173f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 17462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown final DreamRecord oldDream = mCurrentDream; 17562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mCurrentDream = null; 17662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown Slog.i(TAG, "Stopping dream: name=" + oldDream.mName 1772687550272ba061448f5d5b914700dc335299ee7Jeff Brown + ", isTest=" + oldDream.mIsTest + ", canDoze=" + oldDream.mCanDoze 1782687550272ba061448f5d5b914700dc335299ee7Jeff Brown + ", userId=" + oldDream.mUserId); 17962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 180006f567c214d67752cc7c2b6446c328744f40af7John Spurlock mHandler.removeCallbacks(mStopUnconnectedDreamRunnable); 181f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown mHandler.removeCallbacks(mStopStubbornDreamRunnable); 182006f567c214d67752cc7c2b6446c328744f40af7John Spurlock 18362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (oldDream.mSentStartBroadcast) { 184cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasani mContext.sendBroadcastAsUser(mDreamingStoppedIntent, UserHandle.ALL); 185f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 186f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 18762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (oldDream.mService != null) { 1882d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler // Tell the dream that it's being stopped so that 1892d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler // it can shut down nicely before we yank its window token out from 1902d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler // under it. 1912d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler try { 1922d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler oldDream.mService.detach(); 1932d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler } catch (RemoteException ex) { 1942d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler // we don't care; this thing is on the way out 1952d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler } 1962d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler 19762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown try { 19862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown oldDream.mService.asBinder().unlinkToDeath(oldDream, 0); 19962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } catch (NoSuchElementException ex) { 20062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown // don't care 20162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 20262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown oldDream.mService = null; 20362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 204f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 20562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (oldDream.mBound) { 20662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mContext.unbindService(oldDream); 20762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 208f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 20962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown try { 21062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mIWindowManager.removeWindowToken(oldDream.mToken); 21162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } catch (RemoteException ex) { 21262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown Slog.w(TAG, "Error removing window token for dream.", ex); 213f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 21462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 21562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler.post(new Runnable() { 21662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 21762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void run() { 21862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mListener.onDreamStopped(oldDream.mToken); 21962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 22062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown }); 22162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 22262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 22362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private void attach(IDreamService service) { 22462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown try { 22562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown service.asBinder().linkToDeath(mCurrentDream, 0); 2262687550272ba061448f5d5b914700dc335299ee7Jeff Brown service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze); 22762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } catch (RemoteException ex) { 22862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown Slog.e(TAG, "The dream service died unexpectedly.", ex); 229f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 23062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown return; 231f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 232f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 23362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mCurrentDream.mService = service; 234f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 23562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (!mCurrentDream.mIsTest) { 236cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasani mContext.sendBroadcastAsUser(mDreamingStartedIntent, UserHandle.ALL); 23762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mCurrentDream.mSentStartBroadcast = true; 238f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 239f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 240f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 24162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown /** 24262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown * Callback interface to be implemented by the {@link DreamManagerService}. 24362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown */ 24462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public interface Listener { 24562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown void onDreamStopped(Binder token); 246f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 247f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 24862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private final class DreamRecord implements DeathRecipient, ServiceConnection { 24962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final Binder mToken; 25062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final ComponentName mName; 25162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final boolean mIsTest; 2522687550272ba061448f5d5b914700dc335299ee7Jeff Brown public final boolean mCanDoze; 25362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final int mUserId; 25462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 25562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public boolean mBound; 256006f567c214d67752cc7c2b6446c328744f40af7John Spurlock public boolean mConnected; 25762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public IDreamService mService; 25862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public boolean mSentStartBroadcast; 25962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 260f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown public boolean mWakingGently; 261f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 26262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public DreamRecord(Binder token, ComponentName name, 2632687550272ba061448f5d5b914700dc335299ee7Jeff Brown boolean isTest, boolean canDoze, int userId) { 26462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mToken = token; 26562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mName = name; 26662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mIsTest = isTest; 2672687550272ba061448f5d5b914700dc335299ee7Jeff Brown mCanDoze = canDoze; 26862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mUserId = userId; 269f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 270f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 27162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown // May be called on any thread. 27262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 27362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void binderDied() { 27462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler.post(new Runnable() { 27562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 27662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void run() { 27762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mService = null; 27862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == DreamRecord.this) { 279f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 28062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 28162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 28262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown }); 283f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 284f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 28562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown // May be called on any thread. 28662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 28762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void onServiceConnected(ComponentName name, final IBinder service) { 28862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler.post(new Runnable() { 28962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 29062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void run() { 291006f567c214d67752cc7c2b6446c328744f40af7John Spurlock mConnected = true; 29262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == DreamRecord.this && mService == null) { 29362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown attach(IDreamService.Stub.asInterface(service)); 29462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 29562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 29662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown }); 297f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 298f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 29962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown // May be called on any thread. 30062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 30162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void onServiceDisconnected(ComponentName name) { 30262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler.post(new Runnable() { 30362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 30462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void run() { 30562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mService = null; 30662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == DreamRecord.this) { 307f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 30862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 30962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 31062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown }); 31162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 31262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 313f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock}