Home | History | Annotate | Download | only in alertwindowservice
      1 /*
      2  * Copyright (C) 2017 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 android.server.wm.alertwindowservice;
     18 
     19 import static android.graphics.Color.BLUE;
     20 import static android.view.Gravity.LEFT;
     21 import static android.view.Gravity.TOP;
     22 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
     23 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
     24 import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
     25 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
     26 
     27 import android.app.Service;
     28 import android.content.Intent;
     29 import android.graphics.Point;
     30 import android.os.Handler;
     31 import android.os.IBinder;
     32 import android.os.Message;
     33 import android.os.Messenger;
     34 import android.os.RemoteException;
     35 import android.util.Log;
     36 import android.view.View;
     37 import android.view.WindowManager;
     38 import android.widget.TextView;
     39 
     40 import java.util.LinkedList;
     41 
     42 /** Service for creating and managing alert windows. */
     43 public final class AlertWindowService extends Service {
     44 
     45     private static final String TAG = "AlertWindowService";
     46     private static final boolean DEBUG = false;
     47 
     48     public static final String EXTRA_MESSENGER = "messenger";
     49 
     50     public static final int MSG_ADD_ALERT_WINDOW = 1;
     51     public static final int MSG_REMOVE_ALERT_WINDOW = 2;
     52     public static final int MSG_REMOVE_ALL_ALERT_WINDOWS = 3;
     53 
     54     public static final int MSG_ON_ALERT_WINDOW_ADDED = 4;
     55     public static final int MSG_ON_ALERT_WINDOW_REMOVED = 5;
     56 
     57     private LinkedList<View> mAlertWindows = new LinkedList<>();
     58 
     59     private Messenger mOutgoingMessenger = null;
     60     private final Messenger mIncomingMessenger = new Messenger(new IncomingHandler());
     61 
     62     private class IncomingHandler extends Handler {
     63         @Override
     64         public void handleMessage(Message msg) {
     65             switch (msg.what) {
     66                 case MSG_ADD_ALERT_WINDOW:
     67                     addAlertWindow();
     68                     break;
     69                 case MSG_REMOVE_ALERT_WINDOW:
     70                     removeAlertWindow();
     71                     break;
     72                 case MSG_REMOVE_ALL_ALERT_WINDOWS:
     73                     removeAllAlertWindows();
     74                     break;
     75                 default:
     76                     super.handleMessage(msg);
     77             }
     78         }
     79     }
     80 
     81     private void addAlertWindow() {
     82         final Point size = new Point();
     83         final WindowManager wm = getSystemService(WindowManager.class);
     84         wm.getDefaultDisplay().getSize(size);
     85 
     86         final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
     87                 TYPE_APPLICATION_OVERLAY,
     88                 FLAG_NOT_FOCUSABLE | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_NOT_TOUCHABLE);
     89         params.width = size.x / 3;
     90         params.height = size.y / 3;
     91         params.gravity = TOP | LEFT;
     92 
     93         final TextView view = new TextView(this);
     94         view.setText("AlertWindowService" + mAlertWindows.size());
     95         view.setBackgroundColor(BLUE);
     96         wm.addView(view, params);
     97         mAlertWindows.add(view);
     98 
     99         if (DEBUG) Log.e(TAG, "addAlertWindow " + mAlertWindows.size());
    100         if (mOutgoingMessenger != null) {
    101             try {
    102                 mOutgoingMessenger.send(Message.obtain(null, MSG_ON_ALERT_WINDOW_ADDED));
    103             } catch (RemoteException e) {
    104 
    105             }
    106         }
    107     }
    108 
    109     private void removeAlertWindow() {
    110         if (mAlertWindows.size() == 0) {
    111             return;
    112         }
    113         final WindowManager wm = getSystemService(WindowManager.class);
    114         wm.removeView(mAlertWindows.pop());
    115 
    116         if (DEBUG) Log.e(TAG, "removeAlertWindow " + mAlertWindows.size());
    117         if (mOutgoingMessenger != null) {
    118             try {
    119                 mOutgoingMessenger.send(Message.obtain(null, MSG_ON_ALERT_WINDOW_REMOVED));
    120             } catch (RemoteException e) {
    121 
    122             }
    123         }
    124     }
    125 
    126     private void removeAllAlertWindows() {
    127         while (mAlertWindows.size() > 0) {
    128             removeAlertWindow();
    129         }
    130     }
    131 
    132     @Override
    133     public IBinder onBind(Intent intent) {
    134         if (DEBUG) Log.e(TAG, "onBind");
    135         mOutgoingMessenger = intent.getParcelableExtra(EXTRA_MESSENGER);
    136         return mIncomingMessenger.getBinder();
    137     }
    138 
    139     @Override
    140     public boolean onUnbind(Intent intent) {
    141         if (DEBUG) Log.e(TAG, "onUnbind");
    142         removeAllAlertWindows();
    143         return super.onUnbind(intent);
    144     }
    145 }
    146