1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.volume; 18 19 import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; 20 import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; 21 22 import android.content.BroadcastReceiver; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.IntentFilter; 26 import android.content.res.Resources; 27 import android.graphics.PixelFormat; 28 import android.os.Handler; 29 import android.os.Message; 30 import android.os.UserHandle; 31 import android.view.Gravity; 32 import android.view.LayoutInflater; 33 import android.view.View; 34 import android.view.View.OnAttachStateChangeListener; 35 import android.view.WindowManager; 36 import android.widget.ImageView; 37 import android.widget.TextView; 38 39 import com.android.systemui.R; 40 41 public class ZenToast { 42 private static final String ACTION_SHOW = ZenToast.class.getName() + ".SHOW"; 43 private static final String ACTION_HIDE = ZenToast.class.getName() + ".HIDE"; 44 private static final String EXTRA_ZEN = "zen"; 45 private static final String EXTRA_TEXT = "text"; 46 47 private static final int MSG_SHOW = 1; 48 private static final int MSG_HIDE = 2; 49 50 private final Context mContext; 51 private final WindowManager mWindowManager; 52 53 private View mZenToast; 54 55 public ZenToast(Context context) { 56 mContext = context; 57 mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 58 final IntentFilter filter = new IntentFilter(); 59 filter.addAction(ACTION_SHOW); 60 filter.addAction(ACTION_HIDE); 61 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); 62 } 63 64 public void show(int zen) { 65 mHandler.removeMessages(MSG_HIDE); 66 mHandler.removeMessages(MSG_SHOW); 67 mHandler.obtainMessage(MSG_SHOW, zen, 0).sendToTarget(); 68 } 69 70 public void hide() { 71 mHandler.removeMessages(MSG_HIDE); 72 mHandler.removeMessages(MSG_SHOW); 73 mHandler.obtainMessage(MSG_HIDE).sendToTarget(); 74 } 75 76 private void handleShow(int zen, String overrideText) { 77 handleHide(); 78 79 String text; 80 final int iconRes; 81 switch (zen) { 82 case ZEN_MODE_NO_INTERRUPTIONS: 83 text = mContext.getString(R.string.zen_no_interruptions); 84 iconRes = R.drawable.ic_zen_none; 85 break; 86 case ZEN_MODE_IMPORTANT_INTERRUPTIONS: 87 text = mContext.getString(R.string.zen_important_interruptions); 88 iconRes = R.drawable.ic_zen_important; 89 break; 90 default: 91 return; 92 } 93 if (overrideText != null) { 94 text = overrideText; 95 } 96 final Resources res = mContext.getResources(); 97 final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); 98 params.height = WindowManager.LayoutParams.WRAP_CONTENT; 99 params.width = res.getDimensionPixelSize(R.dimen.zen_toast_width); 100 params.format = PixelFormat.TRANSLUCENT; 101 params.windowAnimations = R.style.ZenToastAnimations; 102 params.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL; 103 params.setTitle(getClass().getSimpleName()); 104 params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 105 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 106 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 107 params.gravity = Gravity.CENTER; 108 params.packageName = mContext.getPackageName(); 109 mZenToast = LayoutInflater.from(mContext).inflate(R.layout.zen_toast, null); 110 final TextView message = (TextView) mZenToast.findViewById(android.R.id.message); 111 message.setText(text); 112 final ImageView icon = (ImageView) mZenToast.findViewById(android.R.id.icon); 113 icon.setImageResource(iconRes); 114 mZenToast.addOnAttachStateChangeListener(new OnAttachStateChangeListener() { 115 @Override 116 public void onViewDetachedFromWindow(View v) { 117 // noop 118 } 119 120 @Override 121 public void onViewAttachedToWindow(View v) { 122 mZenToast.announceForAccessibility(message.getText()); 123 } 124 }); 125 mWindowManager.addView(mZenToast, params); 126 final int animDuration = res.getInteger(R.integer.zen_toast_animation_duration); 127 final int visibleDuration = res.getInteger(R.integer.zen_toast_visible_duration); 128 mHandler.sendEmptyMessageDelayed(MSG_HIDE, animDuration + visibleDuration); 129 } 130 131 private void handleHide() { 132 if (mZenToast != null) { 133 mWindowManager.removeView(mZenToast); 134 mZenToast = null; 135 } 136 } 137 138 private final Handler mHandler = new Handler() { 139 public void handleMessage(Message msg) { 140 switch (msg.what) { 141 case MSG_SHOW: 142 handleShow(msg.arg1, null); 143 break; 144 case MSG_HIDE: 145 handleHide(); 146 break; 147 } 148 } 149 }; 150 151 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 152 @Override 153 public void onReceive(Context context, Intent intent) { 154 if (ACTION_SHOW.equals(intent.getAction())) { 155 final int zen = intent.getIntExtra(EXTRA_ZEN, ZEN_MODE_IMPORTANT_INTERRUPTIONS); 156 final String text = intent.getStringExtra(EXTRA_TEXT); 157 handleShow(zen, text); 158 } else if (ACTION_HIDE.equals(intent.getAction())) { 159 handleHide(); 160 } 161 } 162 }; 163 } 164