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; 20383db5ebcc3a4a615faf249bf4f126f42e80b82eTamas Berghammerimport com.android.internal.logging.nano.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; 279ede1d260284bbf0b47ca6f0315e943058624520Adrian Roosimport android.os.Bundle; 28f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.Handler; 29f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.IBinder; 309ede1d260284bbf0b47ca6f0315e943058624520Adrian Roosimport android.os.IRemoteCallback; 317445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roosimport android.os.PowerManager; 32f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.RemoteException; 33f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.os.IBinder.DeathRecipient; 349bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wrenimport android.os.SystemClock; 353edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brownimport android.os.Trace; 36cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasaniimport android.os.UserHandle; 37be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackbornimport android.service.dreams.DreamService; 38f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.service.dreams.IDreamService; 39f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.util.Slog; 40f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.view.IWindowManager; 41f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.view.WindowManager; 42f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport android.view.WindowManagerGlobal; 43f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 44f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.io.PrintWriter; 45f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockimport java.util.NoSuchElementException; 46f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 47ac2561e8206ac42921bb6ddbb0a5972fb360e394Wale Ogunwaleimport static android.view.Display.DEFAULT_DISPLAY; 48ac2561e8206ac42921bb6ddbb0a5972fb360e394Wale Ogunwaleimport static android.view.WindowManager.LayoutParams.TYPE_DREAM; 49ac2561e8206ac42921bb6ddbb0a5972fb360e394Wale Ogunwale 50f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock/** 51f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * Internal controller for starting and stopping the current dream and managing related state. 52f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock * 5362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown * Assumes all operations are called from the dream handler thread. 54f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock */ 55f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlockfinal class DreamController { 5662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private static final String TAG = "DreamController"; 57f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 58006f567c214d67752cc7c2b6446c328744f40af7John Spurlock // How long we wait for a newly bound dream to create the service connection 59006f567c214d67752cc7c2b6446c328744f40af7John Spurlock private static final int DREAM_CONNECTION_TIMEOUT = 5 * 1000; 60006f567c214d67752cc7c2b6446c328744f40af7John Spurlock 61f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown // Time to allow the dream to perform an exit transition when waking up. 62f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown private static final int DREAM_FINISH_TIMEOUT = 5 * 1000; 63f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 64f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock private final Context mContext; 6562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private final Handler mHandler; 66f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock private final Listener mListener; 6762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private final IWindowManager mIWindowManager; 689bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren private long mDreamStartTime; 69f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 70be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackborn private final Intent mDreamingStartedIntent = new Intent(Intent.ACTION_DREAMING_STARTED) 7162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 72be87e2f5885b28145a788fd31d1fb5ae88a71100Dianne Hackborn private final Intent mDreamingStoppedIntent = new Intent(Intent.ACTION_DREAMING_STOPPED) 7362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 74f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 7557dd737443a174379eb638450e4888500d8e4a23Dianne Hackborn private final Intent mCloseNotificationShadeIntent; 76591a9e8d6ef2cab3ab3a701bd6279b6c12e6e4c6John Spurlock 7762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private DreamRecord mCurrentDream; 78f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 79006f567c214d67752cc7c2b6446c328744f40af7John Spurlock private final Runnable mStopUnconnectedDreamRunnable = new Runnable() { 80006f567c214d67752cc7c2b6446c328744f40af7John Spurlock @Override 81006f567c214d67752cc7c2b6446c328744f40af7John Spurlock public void run() { 82006f567c214d67752cc7c2b6446c328744f40af7John Spurlock if (mCurrentDream != null && mCurrentDream.mBound && !mCurrentDream.mConnected) { 83006f567c214d67752cc7c2b6446c328744f40af7John Spurlock Slog.w(TAG, "Bound dream did not connect in the time allotted"); 84f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 85006f567c214d67752cc7c2b6446c328744f40af7John Spurlock } 86006f567c214d67752cc7c2b6446c328744f40af7John Spurlock } 87006f567c214d67752cc7c2b6446c328744f40af7John Spurlock }; 88006f567c214d67752cc7c2b6446c328744f40af7John Spurlock 89f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown private final Runnable mStopStubbornDreamRunnable = new Runnable() { 90f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown @Override 91f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown public void run() { 92f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown Slog.w(TAG, "Stubborn dream did not finish itself in the time allotted"); 93f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 94f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 95f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown }; 96f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 9762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public DreamController(Context context, Handler handler, Listener listener) { 98f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock mContext = context; 9962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler = handler; 100f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock mListener = listener; 101f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock mIWindowManager = WindowManagerGlobal.getWindowManagerService(); 10257dd737443a174379eb638450e4888500d8e4a23Dianne Hackborn mCloseNotificationShadeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 10357dd737443a174379eb638450e4888500d8e4a23Dianne Hackborn mCloseNotificationShadeIntent.putExtra("reason", "dream"); 104f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 105f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 106f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock public void dump(PrintWriter pw) { 10762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println("Dreamland:"); 10862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream != null) { 10962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mCurrentDream:"); 11062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mToken=" + mCurrentDream.mToken); 11162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mName=" + mCurrentDream.mName); 11262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mIsTest=" + mCurrentDream.mIsTest); 1132687550272ba061448f5d5b914700dc335299ee7Jeff Brown pw.println(" mCanDoze=" + mCurrentDream.mCanDoze); 11462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mUserId=" + mCurrentDream.mUserId); 11562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mBound=" + mCurrentDream.mBound); 11662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mService=" + mCurrentDream.mService); 11762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mSentStartBroadcast=" + mCurrentDream.mSentStartBroadcast); 118f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown pw.println(" mWakingGently=" + mCurrentDream.mWakingGently); 11962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } else { 12062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown pw.println(" mCurrentDream: null"); 121f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 122f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 123f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1242687550272ba061448f5d5b914700dc335299ee7Jeff Brown public void startDream(Binder token, ComponentName name, 1257445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roos boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock) { 126f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 127f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1283edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Trace.traceBegin(Trace.TRACE_TAG_POWER, "startDream"); 1293edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 1307445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roos // Close the notification shade. No need to send to all, but better to be explicit. 1313edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL); 132591a9e8d6ef2cab3ab3a701bd6279b6c12e6e4c6John Spurlock 1333edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.i(TAG, "Starting dream: name=" + name 1343edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown + ", isTest=" + isTest + ", canDoze=" + canDoze 1353edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown + ", userId=" + userId); 136f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1377445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roos mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId, wakeLock); 138f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1399bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren mDreamStartTime = SystemClock.elapsedRealtime(); 1409bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren MetricsLogger.visible(mContext, 141f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren mCurrentDream.mCanDoze ? MetricsEvent.DOZING : MetricsEvent.DREAMING); 1429bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren 1433edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 144ac2561e8206ac42921bb6ddbb0a5972fb360e394Wale Ogunwale mIWindowManager.addWindowToken(token, TYPE_DREAM, DEFAULT_DISPLAY); 1453edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (RemoteException ex) { 1463edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.e(TAG, "Unable to add window token for dream.", ex); 1473edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown stopDream(true /*immediate*/); 1483edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown return; 1493edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 150f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1513edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Intent intent = new Intent(DreamService.SERVICE_INTERFACE); 1523edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown intent.setComponent(name); 1533edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 1543edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 1553edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (!mContext.bindServiceAsUser(intent, mCurrentDream, 156d69e4c1460017062e7c36be55801cb434ad19d97Dianne Hackborn Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, 157d69e4c1460017062e7c36be55801cb434ad19d97Dianne Hackborn new UserHandle(userId))) { 1583edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.e(TAG, "Unable to bind dream service: " + intent); 1593edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown stopDream(true /*immediate*/); 1603edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown return; 1613edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 1623edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (SecurityException ex) { 1633edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.e(TAG, "Unable to bind dream service: " + intent, ex); 164f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 16562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown return; 16662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 167f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1683edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mCurrentDream.mBound = true; 1693edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.postDelayed(mStopUnconnectedDreamRunnable, DREAM_CONNECTION_TIMEOUT); 1703edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } finally { 1713edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Trace.traceEnd(Trace.TRACE_TAG_POWER); 1723edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 17362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 174f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 175f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown public void stopDream(boolean immediate) { 17662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == null) { 177f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock return; 178f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 179f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 1803edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Trace.traceBegin(Trace.TRACE_TAG_POWER, "stopDream"); 1813edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 1823edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (!immediate) { 1833edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (mCurrentDream.mWakingGently) { 1843edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown return; // already waking gently 1853edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 186f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 1873edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (mCurrentDream.mService != null) { 1883edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // Give the dream a moment to wake up and finish itself gently. 1893edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mCurrentDream.mWakingGently = true; 1903edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 1913edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mCurrentDream.mService.wakeUp(); 1923edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.postDelayed(mStopStubbornDreamRunnable, DREAM_FINISH_TIMEOUT); 1933edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown return; 1943edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (RemoteException ex) { 1953edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // oh well, we tried, finish immediately instead 1963edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 197f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 198f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown } 199f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 2003edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown final DreamRecord oldDream = mCurrentDream; 2013edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mCurrentDream = null; 2023edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.i(TAG, "Stopping dream: name=" + oldDream.mName 2033edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown + ", isTest=" + oldDream.mIsTest + ", canDoze=" + oldDream.mCanDoze 2043edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown + ", userId=" + oldDream.mUserId); 2059bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren MetricsLogger.hidden(mContext, 206f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren oldDream.mCanDoze ? MetricsEvent.DOZING : MetricsEvent.DREAMING); 2079bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren MetricsLogger.histogram(mContext, 2089bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren oldDream.mCanDoze ? "dozing_minutes" : "dreaming_minutes" , 2099bb290bcc36fe11f96312feb40aaf3323a96ebaeChris Wren (int) ((SystemClock.elapsedRealtime() - mDreamStartTime) / (1000L * 60L))); 21062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 2113edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.removeCallbacks(mStopUnconnectedDreamRunnable); 2123edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.removeCallbacks(mStopStubbornDreamRunnable); 213006f567c214d67752cc7c2b6446c328744f40af7John Spurlock 2143edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (oldDream.mSentStartBroadcast) { 2153edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mContext.sendBroadcastAsUser(mDreamingStoppedIntent, UserHandle.ALL); 2163edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 217f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 2183edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (oldDream.mService != null) { 2193edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // Tell the dream that it's being stopped so that 2203edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // it can shut down nicely before we yank its window token out from 2213edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // under it. 2223edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 2233edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown oldDream.mService.detach(); 2243edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (RemoteException ex) { 2253edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // we don't care; this thing is on the way out 2263edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 2273edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown 2283edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 2293edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown oldDream.mService.asBinder().unlinkToDeath(oldDream, 0); 2303edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (NoSuchElementException ex) { 2313edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown // don't care 2323edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 2333edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown oldDream.mService = null; 2342d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler } 2352d78490292090eeab84694330978c9ad7fad2d37Daniel Sandler 2363edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown if (oldDream.mBound) { 2373edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mContext.unbindService(oldDream); 23862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 2397445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roos oldDream.releaseWakeLockIfNeeded(); 240f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 2413edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown try { 242ac2561e8206ac42921bb6ddbb0a5972fb360e394Wale Ogunwale mIWindowManager.removeWindowToken(oldDream.mToken, DEFAULT_DISPLAY); 2433edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } catch (RemoteException ex) { 2443edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Slog.w(TAG, "Error removing window token for dream.", ex); 2453edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 246f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 2473edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mHandler.post(new Runnable() { 2483edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown @Override 2493edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown public void run() { 2503edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown mListener.onDreamStopped(oldDream.mToken); 2513edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 2523edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown }); 2533edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } finally { 2543edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown Trace.traceEnd(Trace.TRACE_TAG_POWER); 255f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 25662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 25762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 25862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private void attach(IDreamService service) { 25962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown try { 26062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown service.asBinder().linkToDeath(mCurrentDream, 0); 2619ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze, 2629ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos mCurrentDream.mDreamingStartedCallback); 26362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } catch (RemoteException ex) { 26462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown Slog.e(TAG, "The dream service died unexpectedly.", ex); 265f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 26662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown return; 267f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 268f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 26962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mCurrentDream.mService = service; 270f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 27162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (!mCurrentDream.mIsTest) { 272cd75706117432e33d11639e675bcff50479a6bb9Amith Yamasani mContext.sendBroadcastAsUser(mDreamingStartedIntent, UserHandle.ALL); 27362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mCurrentDream.mSentStartBroadcast = true; 274f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 275f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 276f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 27762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown /** 27862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown * Callback interface to be implemented by the {@link DreamManagerService}. 27962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown */ 28062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public interface Listener { 28162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown void onDreamStopped(Binder token); 282f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 283f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 28462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown private final class DreamRecord implements DeathRecipient, ServiceConnection { 28562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final Binder mToken; 28662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final ComponentName mName; 28762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final boolean mIsTest; 2882687550272ba061448f5d5b914700dc335299ee7Jeff Brown public final boolean mCanDoze; 28962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public final int mUserId; 29062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 2917445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roos public PowerManager.WakeLock mWakeLock; 29262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public boolean mBound; 293006f567c214d67752cc7c2b6446c328744f40af7John Spurlock public boolean mConnected; 29462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public IDreamService mService; 29562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public boolean mSentStartBroadcast; 29662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown 297f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown public boolean mWakingGently; 298f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown 29962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public DreamRecord(Binder token, ComponentName name, 3007445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roos boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock) { 30162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mToken = token; 30262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mName = name; 30362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mIsTest = isTest; 3042687550272ba061448f5d5b914700dc335299ee7Jeff Brown mCanDoze = canDoze; 30562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mUserId = userId; 3067445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roos mWakeLock = wakeLock; 3079ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos // Hold the lock while we're waiting for the service to connect and start dreaming. 3089ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos // Released after the service has started dreaming, we stop dreaming, or it timed out. 3097445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roos mWakeLock.acquire(); 3109ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos mHandler.postDelayed(mReleaseWakeLockIfNeeded, 10000); 311f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 312f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 31362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown // May be called on any thread. 31462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 31562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void binderDied() { 31662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler.post(new Runnable() { 31762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 31862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void run() { 31962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mService = null; 32062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == DreamRecord.this) { 321f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 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 onServiceConnected(ComponentName name, final IBinder service) { 33062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler.post(new Runnable() { 33162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 33262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void run() { 3339ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos mConnected = true; 3349ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos if (mCurrentDream == DreamRecord.this && mService == null) { 3359ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos attach(IDreamService.Stub.asInterface(service)); 3369ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos // Wake lock will be released once dreaming starts. 3379ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos } else { 3387445c0bb86c57172eb88a4e37183634abce2e37bAdrian Roos releaseWakeLockIfNeeded(); 33962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 34062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 34162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown }); 342f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock } 343f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock 34462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown // May be called on any thread. 34562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 34662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void onServiceDisconnected(ComponentName name) { 34762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mHandler.post(new Runnable() { 34862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown @Override 34962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown public void run() { 35062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown mService = null; 35162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown if (mCurrentDream == DreamRecord.this) { 352f6d466895b74d620d646abbec1c8911f3a0ce0bbJeff Brown stopDream(true /*immediate*/); 35362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 35462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 35562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown }); 35662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 3579ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos 3589ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos void releaseWakeLockIfNeeded() { 3599ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos if (mWakeLock != null) { 3609ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos mWakeLock.release(); 3619ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos mWakeLock = null; 3629ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos mHandler.removeCallbacks(mReleaseWakeLockIfNeeded); 3639ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos } 3649ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos } 3659ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos 3669ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos final Runnable mReleaseWakeLockIfNeeded = this::releaseWakeLockIfNeeded; 3679ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos 3689ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos final IRemoteCallback mDreamingStartedCallback = new IRemoteCallback.Stub() { 3699ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos // May be called on any thread. 3709ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos @Override 3719ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos public void sendResult(Bundle data) throws RemoteException { 3729ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos mHandler.post(mReleaseWakeLockIfNeeded); 3739ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos } 3749ede1d260284bbf0b47ca6f0315e943058624520Adrian Roos }; 37562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown } 376f4f6b4c8b0fcf77d46567f13b409255948fe107bJohn Spurlock}