DreamController.java revision f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21f
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 199bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wrenimport com.android.internal.logging.MetricsLogger; 20f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wrenimport com.android.internal.logging.MetricsProto.MetricsEvent; 219bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren 22f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.ComponentName; 23f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.Context; 24f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.Intent; 25f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.content.ServiceConnection; 26f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.Binder; 27f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.Handler; 28f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.IBinder; 29f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.RemoteException; 30f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.IBinder.DeathRecipient; 319bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wrenimport android.os.SystemClock; 323edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brownimport android.os.Trace; 33cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasaniimport android.os.UserHandle; 34be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackbornimport android.service.dreams.DreamService; 35f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.service.dreams.IDreamService; 36f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.util.Slog; 37f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.view.IWindowManager; 38f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.view.WindowManager; 39f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.view.WindowManagerGlobal; 40f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 41f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.io.PrintWriter; 42f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.util.NoSuchElementException; 43f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 44f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock/** 45f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Internal controller for starting and stopping the current dream and managing related state. 46f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * 4762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown * Assumes all operations are called from the dream handler thread. 48f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock */ 49f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockfinal class DreamController { 5062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private static final String TAG = "DreamController"; 51f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 52006f567c214d67752cc7c2b6446c328744f40af7John Spurlock // How long we wait for a newly bound dream to create the service connection 53006f567c214d67752cc7c2b6446c328744f40af7John Spurlock private static final int DREAM_CONNECTION_TIMEOUT = 5 * 1000; 54006f567c214d67752cc7c2b6446c328744f40af7John Spurlock 55f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown // Time to allow the dream to perform an exit transition when waking up. 56f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown private static final int DREAM_FINISH_TIMEOUT = 5 * 1000; 57f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 58f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock private final Context mContext; 5962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private final Handler mHandler; 60f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock private final Listener mListener; 6162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private final IWindowManager mIWindowManager; 629bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren private long mDreamStartTime; 63f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 64be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackborn private final Intent mDreamingStartedIntent = new Intent(Intent.ACTION_DREAMING_STARTED) 6562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 66be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackborn private final Intent mDreamingStoppedIntent = new Intent(Intent.ACTION_DREAMING_STOPPED) 6762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 68f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 6957dd737443a174379eb638450e4888500d8e4a23Dianne Hackborn private final Intent mCloseNotificationShadeIntent; 70591a9e8d6ef2cab3ab3a701bd6279b6c12e6e4c6John Spurlock 7162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private DreamRecord mCurrentDream; 72f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 73006f567c214d67752cc7c2b6446c328744f40af7John Spurlock private final Runnable mStopUnconnectedDreamRunnable = new Runnable() { 74006f567c214d67752cc7c2b6446c328744f40af7John Spurlock @Override 75006f567c214d67752cc7c2b6446c328744f40af7John Spurlock public void run() { 76006f567c214d67752cc7c2b6446c328744f40af7John Spurlock if (mCurrentDream != null && mCurrentDream.mBound && !mCurrentDream.mConnected) { 77006f567c214d67752cc7c2b6446c328744f40af7John Spurlock Slog.w(TAG, "Bound dream did not connect in the time allotted"); 78f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 79006f567c214d67752cc7c2b6446c328744f40af7John Spurlock } 80006f567c214d67752cc7c2b6446c328744f40af7John Spurlock } 81006f567c214d67752cc7c2b6446c328744f40af7John Spurlock }; 82006f567c214d67752cc7c2b6446c328744f40af7John Spurlock 83f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown private final Runnable mStopStubbornDreamRunnable = new Runnable() { 84f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown @Override 85f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown public void run() { 86f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown Slog.w(TAG, "Stubborn dream did not finish itself in the time allotted"); 87f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 88f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 89f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown }; 90f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 9162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public DreamController(Context context, Handler handler, Listener listener) { 92f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock mContext = context; 9362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler = handler; 94f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock mListener = listener; 95f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock mIWindowManager = WindowManagerGlobal.getWindowManagerService(); 9657dd737443a174379eb638450e4888500d8e4a23Dianne Hackborn mCloseNotificationShadeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 9757dd737443a174379eb638450e4888500d8e4a23Dianne Hackborn mCloseNotificationShadeIntent.putExtra("reason", "dream"); 98f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 99f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 100f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock public void dump(PrintWriter pw) { 10162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println("Dreamland:"); 10262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream != null) { 10362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mCurrentDream:"); 10462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mToken=" + mCurrentDream.mToken); 10562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mName=" + mCurrentDream.mName); 10662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mIsTest=" + mCurrentDream.mIsTest); 1072687550272ba061448f5d5b914700dc335299ee7Jeff Brown pw.println(" mCanDoze=" + mCurrentDream.mCanDoze); 10862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mUserId=" + mCurrentDream.mUserId); 10962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mBound=" + mCurrentDream.mBound); 11062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mService=" + mCurrentDream.mService); 11162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mSentStartBroadcast=" + mCurrentDream.mSentStartBroadcast); 112f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown pw.println(" mWakingGently=" + mCurrentDream.mWakingGently); 11362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } else { 11462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mCurrentDream: null"); 115f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 116f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 117f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1182687550272ba061448f5d5b914700dc335299ee7Jeff Brown public void startDream(Binder token, ComponentName name, 1192687550272ba061448f5d5b914700dc335299ee7Jeff Brown boolean isTest, boolean canDoze, int userId) { 120f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 121f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1223edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Trace.traceBegin(Trace.TRACE_TAG_POWER, "startDream"); 1233edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 1243edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // Close the notification shade. Don't need to send to all, but better to be explicit. 1253edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL); 126591a9e8d6ef2cab3ab3a701bd6279b6c12e6e4c6John Spurlock 1273edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.i(TAG, "Starting dream: name=" + name 1283edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown + ", isTest=" + isTest + ", canDoze=" + canDoze 1293edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown + ", userId=" + userId); 130f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1313edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId); 132f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1339bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren mDreamStartTime = SystemClock.elapsedRealtime(); 1349bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren MetricsLogger.visible(mContext, 135f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren mCurrentDream.mCanDoze ? MetricsEvent.DOZING : MetricsEvent.DREAMING); 1369bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren 1373edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 1383edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM); 1393edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (RemoteException ex) { 1403edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.e(TAG, "Unable to add window token for dream.", ex); 1413edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown stopDream(true /*immediate*/); 1423edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown return; 1433edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 144f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1453edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Intent intent = new Intent(DreamService.SERVICE_INTERFACE); 1463edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown intent.setComponent(name); 1473edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 1483edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 1493edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (!mContext.bindServiceAsUser(intent, mCurrentDream, 150d69e4c1460017062e7c36be55801cb434ad19d97Dianne Hackborn Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, 151d69e4c1460017062e7c36be55801cb434ad19d97Dianne Hackborn new UserHandle(userId))) { 1523edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.e(TAG, "Unable to bind dream service: " + intent); 1533edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown stopDream(true /*immediate*/); 1543edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown return; 1553edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 1563edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (SecurityException ex) { 1573edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.e(TAG, "Unable to bind dream service: " + intent, ex); 158f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 15962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown return; 16062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 161f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1623edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mCurrentDream.mBound = true; 1633edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.postDelayed(mStopUnconnectedDreamRunnable, DREAM_CONNECTION_TIMEOUT); 1643edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } finally { 1653edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Trace.traceEnd(Trace.TRACE_TAG_POWER); 1663edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 16762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 168f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 169f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown public void stopDream(boolean immediate) { 17062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == null) { 171f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock return; 172f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 173f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1743edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Trace.traceBegin(Trace.TRACE_TAG_POWER, "stopDream"); 1753edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 1763edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (!immediate) { 1773edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (mCurrentDream.mWakingGently) { 1783edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown return; // already waking gently 1793edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 180f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 1813edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (mCurrentDream.mService != null) { 1823edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // Give the dream a moment to wake up and finish itself gently. 1833edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mCurrentDream.mWakingGently = true; 1843edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 1853edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mCurrentDream.mService.wakeUp(); 1863edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.postDelayed(mStopStubbornDreamRunnable, DREAM_FINISH_TIMEOUT); 1873edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown return; 1883edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (RemoteException ex) { 1893edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // oh well, we tried, finish immediately instead 1903edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 191f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 192f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 193f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 1943edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown final DreamRecord oldDream = mCurrentDream; 1953edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mCurrentDream = null; 1963edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.i(TAG, "Stopping dream: name=" + oldDream.mName 1973edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown + ", isTest=" + oldDream.mIsTest + ", canDoze=" + oldDream.mCanDoze 1983edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown + ", userId=" + oldDream.mUserId); 1999bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren MetricsLogger.hidden(mContext, 200f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren oldDream.mCanDoze ? MetricsEvent.DOZING : MetricsEvent.DREAMING); 2019bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren MetricsLogger.histogram(mContext, 2029bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren oldDream.mCanDoze ? "dozing_minutes" : "dreaming_minutes" , 2039bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren (int) ((SystemClock.elapsedRealtime() - mDreamStartTime) / (1000L * 60L))); 20462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 2053edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.removeCallbacks(mStopUnconnectedDreamRunnable); 2063edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.removeCallbacks(mStopStubbornDreamRunnable); 207006f567c214d67752cc7c2b6446c328744f40af7John Spurlock 2083edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (oldDream.mSentStartBroadcast) { 2093edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mContext.sendBroadcastAsUser(mDreamingStoppedIntent, UserHandle.ALL); 2103edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 211f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 2123edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (oldDream.mService != null) { 2133edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // Tell the dream that it's being stopped so that 2143edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // it can shut down nicely before we yank its window token out from 2153edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // under it. 2163edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 2173edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown oldDream.mService.detach(); 2183edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (RemoteException ex) { 2193edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // we don't care; this thing is on the way out 2203edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 2213edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown 2223edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 2233edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown oldDream.mService.asBinder().unlinkToDeath(oldDream, 0); 2243edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (NoSuchElementException ex) { 2253edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // don't care 2263edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 2273edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown oldDream.mService = null; 2282d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler } 2292d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler 2303edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (oldDream.mBound) { 2313edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mContext.unbindService(oldDream); 23262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 233f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 2343edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 2353edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mIWindowManager.removeWindowToken(oldDream.mToken); 2363edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (RemoteException ex) { 2373edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.w(TAG, "Error removing window token for dream.", ex); 2383edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 239f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 2403edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.post(new Runnable() { 2413edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown @Override 2423edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown public void run() { 2433edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mListener.onDreamStopped(oldDream.mToken); 2443edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 2453edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown }); 2463edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } finally { 2473edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Trace.traceEnd(Trace.TRACE_TAG_POWER); 248f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 24962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 25062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 25162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private void attach(IDreamService service) { 25262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown try { 25362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown service.asBinder().linkToDeath(mCurrentDream, 0); 2542687550272ba061448f5d5b914700dc335299ee7Jeff Brown service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze); 25562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } catch (RemoteException ex) { 25662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown Slog.e(TAG, "The dream service died unexpectedly.", ex); 257f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 25862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown return; 259f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 260f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 26162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mCurrentDream.mService = service; 262f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 26362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (!mCurrentDream.mIsTest) { 264cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasani mContext.sendBroadcastAsUser(mDreamingStartedIntent, UserHandle.ALL); 26562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mCurrentDream.mSentStartBroadcast = true; 266f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 267f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 268f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 26962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown /** 27062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown * Callback interface to be implemented by the {@link DreamManagerService}. 27162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown */ 27262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public interface Listener { 27362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown void onDreamStopped(Binder token); 274f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 275f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 27662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private final class DreamRecord implements DeathRecipient, ServiceConnection { 27762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final Binder mToken; 27862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final ComponentName mName; 27962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final boolean mIsTest; 2802687550272ba061448f5d5b914700dc335299ee7Jeff Brown public final boolean mCanDoze; 28162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final int mUserId; 28262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 28362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public boolean mBound; 284006f567c214d67752cc7c2b6446c328744f40af7John Spurlock public boolean mConnected; 28562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public IDreamService mService; 28662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public boolean mSentStartBroadcast; 28762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 288f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown public boolean mWakingGently; 289f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 29062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public DreamRecord(Binder token, ComponentName name, 2912687550272ba061448f5d5b914700dc335299ee7Jeff Brown boolean isTest, boolean canDoze, int userId) { 29262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mToken = token; 29362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mName = name; 29462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mIsTest = isTest; 2952687550272ba061448f5d5b914700dc335299ee7Jeff Brown mCanDoze = canDoze; 29662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mUserId = userId; 297f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 298f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 29962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown // May be called on any thread. 30062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 30162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void binderDied() { 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 }); 311f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 312f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 31362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown // May be called on any thread. 31462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 31562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void onServiceConnected(ComponentName name, final IBinder service) { 31662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler.post(new Runnable() { 31762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 31862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void run() { 319006f567c214d67752cc7c2b6446c328744f40af7John Spurlock mConnected = true; 32062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == DreamRecord.this && mService == null) { 32162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown attach(IDreamService.Stub.asInterface(service)); 32262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 32362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 32462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown }); 325f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 326f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 32762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown // May be called on any thread. 32862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 32962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void onServiceDisconnected(ComponentName name) { 33062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler.post(new Runnable() { 33162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 33262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void run() { 33362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mService = null; 33462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == DreamRecord.this) { 335f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 33662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 33762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 33862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown }); 33962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 34062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 341f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock}