1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15package com.android.server.policy; 16 17import com.android.server.LocalServices; 18import com.android.server.statusbar.StatusBarManagerInternal; 19import com.android.server.statusbar.StatusBarManagerInternal.GlobalActionsListener; 20 21import android.content.Context; 22import android.os.Handler; 23import android.util.Slog; 24import android.view.WindowManagerPolicy.WindowManagerFuncs; 25 26class GlobalActions implements GlobalActionsListener { 27 28 private static final String TAG = "GlobalActions"; 29 private static final boolean DEBUG = false; 30 31 private final Context mContext; 32 private final StatusBarManagerInternal mStatusBarInternal; 33 private final Handler mHandler; 34 private final WindowManagerFuncs mWindowManagerFuncs; 35 private LegacyGlobalActions mLegacyGlobalActions; 36 private boolean mKeyguardShowing; 37 private boolean mDeviceProvisioned; 38 private boolean mStatusBarConnected; 39 private boolean mShowing; 40 41 public GlobalActions(Context context, WindowManagerFuncs windowManagerFuncs) { 42 mContext = context; 43 mHandler = new Handler(); 44 mWindowManagerFuncs = windowManagerFuncs; 45 mStatusBarInternal = LocalServices.getService(StatusBarManagerInternal.class); 46 47 // Some form factors do not have a status bar. 48 if (mStatusBarInternal != null) { 49 mStatusBarInternal.setGlobalActionsListener(this); 50 } 51 } 52 53 private void ensureLegacyCreated() { 54 if (mLegacyGlobalActions != null) return; 55 mLegacyGlobalActions = new LegacyGlobalActions(mContext, mWindowManagerFuncs, 56 this::onGlobalActionsDismissed); 57 } 58 59 public void showDialog(boolean keyguardShowing, boolean deviceProvisioned) { 60 if (DEBUG) Slog.d(TAG, "showDialog " + keyguardShowing + " " + deviceProvisioned); 61 mKeyguardShowing = keyguardShowing; 62 mDeviceProvisioned = deviceProvisioned; 63 mShowing = true; 64 if (mStatusBarConnected) { 65 mStatusBarInternal.showGlobalActions(); 66 mHandler.postDelayed(mShowTimeout, 5000); 67 } else { 68 // SysUI isn't alive, show legacy menu. 69 ensureLegacyCreated(); 70 mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned); 71 } 72 } 73 74 @Override 75 public void onGlobalActionsShown() { 76 if (DEBUG) Slog.d(TAG, "onGlobalActionsShown"); 77 // SysUI is showing, remove timeout callbacks. 78 mHandler.removeCallbacks(mShowTimeout); 79 } 80 81 @Override 82 public void onGlobalActionsDismissed() { 83 if (DEBUG) Slog.d(TAG, "onGlobalActionsDismissed"); 84 mShowing = false; 85 } 86 87 @Override 88 public void onStatusBarConnectedChanged(boolean connected) { 89 if (DEBUG) Slog.d(TAG, "onStatusBarConnectedChanged " + connected); 90 mStatusBarConnected = connected; 91 if (mShowing && !mStatusBarConnected) { 92 // Status bar died but we need to be showing global actions still, show the legacy. 93 ensureLegacyCreated(); 94 mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned); 95 } 96 } 97 98 private final Runnable mShowTimeout = new Runnable() { 99 @Override 100 public void run() { 101 if (DEBUG) Slog.d(TAG, "Global actions timeout"); 102 // We haven't heard from sysui, show the legacy dialog. 103 ensureLegacyCreated(); 104 mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned); 105 } 106 }; 107} 108