LockTaskNotify.java revision 62515beee67307d8859beec521b7baedfa54b2b5
1/* 2 * Copyright (C) 2013 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 17package com.android.server.am; 18 19import android.content.BroadcastReceiver; 20import android.content.Context; 21import android.content.Intent; 22import android.content.IntentFilter; 23import android.graphics.PixelFormat; 24import android.os.Handler; 25import android.os.Message; 26import android.util.DisplayMetrics; 27import android.util.Slog; 28import android.view.Gravity; 29import android.view.MotionEvent; 30import android.view.View; 31import android.view.ViewGroup; 32import android.view.WindowManager; 33import android.widget.FrameLayout; 34 35import com.android.internal.R; 36 37/** 38 * Helper to manage showing/hiding a image to notify them that they are entering 39 * or exiting lock-to-app mode. 40 */ 41public class LockTaskNotify { 42 private static final String TAG = "LockTaskNotify"; 43 44 private static final int SHOW_LENGTH_MS = 1500; 45 46 private final Context mContext; 47 private final H mHandler; 48 49 private ClingWindowView mClingWindow; 50 private WindowManager mWindowManager; 51 private boolean mIsStarting; 52 53 public LockTaskNotify(Context context) { 54 mContext = context; 55 mHandler = new H(); 56 mWindowManager = (WindowManager) 57 mContext.getSystemService(Context.WINDOW_SERVICE); 58 } 59 60 public void show(boolean starting) { 61 mIsStarting = starting; 62 mHandler.obtainMessage(H.SHOW).sendToTarget(); 63 } 64 65 public WindowManager.LayoutParams getClingWindowLayoutParams() { 66 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 67 ViewGroup.LayoutParams.MATCH_PARENT, 68 ViewGroup.LayoutParams.MATCH_PARENT, 69 WindowManager.LayoutParams.TYPE_TOAST, 70 0 71 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 72 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 73 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED 74 , 75 PixelFormat.TRANSLUCENT); 76 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 77 lp.setTitle("LockTaskNotify"); 78 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications; 79 lp.gravity = Gravity.FILL; 80 return lp; 81 } 82 83 public FrameLayout.LayoutParams getImageLayoutParams() { 84 return new FrameLayout.LayoutParams( 85 ViewGroup.LayoutParams.WRAP_CONTENT, 86 ViewGroup.LayoutParams.WRAP_CONTENT, 87 Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL); 88 } 89 90 private void handleShow() { 91 mClingWindow = new ClingWindowView(mContext); 92 93 // we will be hiding the nav bar, so layout as if it's already hidden 94 mClingWindow.setSystemUiVisibility( 95 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 96 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 97 98 // show the confirmation 99 WindowManager.LayoutParams lp = getClingWindowLayoutParams(); 100 mWindowManager.addView(mClingWindow, lp); 101 } 102 103 private void handleHide() { 104 if (mClingWindow != null) { 105 mWindowManager.removeView(mClingWindow); 106 mClingWindow = null; 107 } 108 } 109 110 111 private class ClingWindowView extends FrameLayout { 112 private View mView; 113 114 private Runnable mUpdateLayoutRunnable = new Runnable() { 115 @Override 116 public void run() { 117 if (mView != null && mView.getParent() != null) { 118 mView.setLayoutParams(getImageLayoutParams()); 119 } 120 } 121 }; 122 123 private BroadcastReceiver mReceiver = new BroadcastReceiver() { 124 @Override 125 public void onReceive(Context context, Intent intent) { 126 if (intent.getAction().equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 127 post(mUpdateLayoutRunnable); 128 } 129 } 130 }; 131 132 public ClingWindowView(Context context) { 133 super(context); 134 setClickable(true); 135 } 136 137 @Override 138 public void onAttachedToWindow() { 139 super.onAttachedToWindow(); 140 141 DisplayMetrics metrics = new DisplayMetrics(); 142 mWindowManager.getDefaultDisplay().getMetrics(metrics); 143 144 int id = R.layout.lock_to_app_exit; 145 if (mIsStarting) { 146 id = R.layout.lock_to_app_enter; 147 } 148 mView = View.inflate(getContext(), id, null); 149 150 addView(mView, getImageLayoutParams()); 151 152 mContext.registerReceiver(mReceiver, 153 new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED)); 154 mHandler.sendMessageDelayed(mHandler.obtainMessage(H.HIDE), SHOW_LENGTH_MS); 155 } 156 157 @Override 158 public void onDetachedFromWindow() { 159 mContext.unregisterReceiver(mReceiver); 160 } 161 162 @Override 163 public boolean onTouchEvent(MotionEvent motion) { 164 Slog.v(TAG, "ClingWindowView.onTouchEvent"); 165 return true; 166 } 167 } 168 169 private final class H extends Handler { 170 private static final int SHOW = 1; 171 private static final int HIDE = 2; 172 173 @Override 174 public void handleMessage(Message msg) { 175 switch(msg.what) { 176 case SHOW: 177 handleShow(); 178 break; 179 case HIDE: 180 handleHide(); 181 break; 182 } 183 } 184 } 185} 186