blob: a514e8ad408f156b8d128900c6e5c5a104be538f [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.app2;
import android.app.Service;
import android.content.Intent;
import android.graphics.Point;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import java.util.LinkedList;
import static android.graphics.Color.BLUE;
import static android.view.Gravity.LEFT;
import static android.view.Gravity.TOP;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
/** Service for creating and managing alert windows. */
public class AlertWindowService extends Service {
private static final String TAG = "AlertWindowService";
private static final boolean DEBUG = false;
public static final int MSG_ADD_ALERT_WINDOW = 1;
public static final int MSG_REMOVE_ALERT_WINDOW = 2;
public static final int MSG_REMOVE_ALL_ALERT_WINDOWS = 3;
public static String NOTIFICATION_MESSENGER_EXTRA =
"com.android.app2.AlertWindowService.NOTIFICATION_MESSENGER_EXTRA";
public static final int MSG_ON_ALERT_WINDOW_ADDED = 4;
public static final int MSG_ON_ALERT_WINDOW_REMOVED = 5;
private LinkedList<View> mAlertWindows = new LinkedList<>();
private Messenger mOutgoingMessenger = null;
private final Messenger mIncomingMessenger = new Messenger(new IncomingHandler());
private class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ADD_ALERT_WINDOW:
addAlertWindow();
break;
case MSG_REMOVE_ALERT_WINDOW:
removeAlertWindow();
break;
case MSG_REMOVE_ALL_ALERT_WINDOWS:
removeAllAlertWindows();
break;
default:
super.handleMessage(msg);
}
}
}
private void addAlertWindow() {
final Point size = new Point();
final WindowManager wm = getSystemService(WindowManager.class);
wm.getDefaultDisplay().getSize(size);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
TYPE_APPLICATION_OVERLAY,
FLAG_NOT_FOCUSABLE | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_NOT_TOUCHABLE);
params.width = size.x / 3;
params.height = size.y / 3;
params.gravity = TOP | LEFT;
final TextView view = new TextView(this);
view.setText("AlertWindowService" + mAlertWindows.size());
view.setBackgroundColor(BLUE);
wm.addView(view, params);
mAlertWindows.add(view);
if (DEBUG) Log.e(TAG, "addAlertWindow " + mAlertWindows.size());
if (mOutgoingMessenger != null) {
try {
mOutgoingMessenger.send(Message.obtain(null, MSG_ON_ALERT_WINDOW_ADDED));
} catch (RemoteException e) {
}
}
}
private void removeAlertWindow() {
if (mAlertWindows.size() == 0) {
return;
}
final WindowManager wm = getSystemService(WindowManager.class);
wm.removeView(mAlertWindows.pop());
if (DEBUG) Log.e(TAG, "removeAlertWindow " + mAlertWindows.size());
if (mOutgoingMessenger != null) {
try {
mOutgoingMessenger.send(Message.obtain(null, MSG_ON_ALERT_WINDOW_REMOVED));
} catch (RemoteException e) {
}
}
}
private void removeAllAlertWindows() {
while (mAlertWindows.size() > 0) {
removeAlertWindow();
}
}
@Override
public IBinder onBind(Intent intent) {
if (DEBUG) Log.e(TAG, "onBind");
mOutgoingMessenger = intent.getParcelableExtra(NOTIFICATION_MESSENGER_EXTRA);
return mIncomingMessenger.getBinder();
}
@Override
public boolean onUnbind(Intent intent) {
if (DEBUG) Log.e(TAG, "onUnbind");
removeAllAlertWindows();
return super.onUnbind(intent);
}
}