package understanding.wms.samplewindow;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.Looper;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.InputChannel;
import android.view.IWindowSession;
import android.view.IWindow;
import android.view.Choreographer;
import android.view.InputEventReceiver;
import android.view.IWindowManager;
import android.view.InputEvent;
import android.view.DisplayInfo;
import android.os.ServiceManager;
import android.view.WindowManagerGlobal;
import android.hardware.display.IDisplayManager;
import android.view.Display;
import android.util.Log;
import android.os.ParcelFileDescriptor;
import android.os.Bundle;
import android.view.DragEvent;
public class SampleWindow {
private static final String TAG = "SampleWindow";
public static void main(String[] args)
{
try {
new SampleWindow().Run();
} catch (Exception e) {
e.printStackTrace();
}
}
IWindowSession mSession = null;
InputChannel mInputChannel = new InputChannel();
Rect mInsets = new Rect();
Rect mFrame = new Rect();
Rect mVisibleInsets = new Rect();
Configuration mConfig = new Configuration();
Surface mSurface = new Surface();
Paint mPaint = new Paint();
IBinder mToken = new Binder();
MyWindow mWindow = new MyWindow();
LayoutParams mLp = new LayoutParams();
Choreographer mChoreographer = null;
InputHandler mInputHandler = null;
boolean mContinueAnime = true;
public void Run() throws Exception
{
Looper.prepare();
IWindowManager wms = IWindowManager.Stub.asInterface (
ServiceManager.getService(Context.WINDOW_SERVICE));
mSession = WindowManagerGlobal.getWindowSession(Looper.myLooper());
IDisplayManager dm = IDisplayManager.Stub.asInterface(
ServiceManager.getService(Context.DISPLAY_SERVICE));
DisplayInfo di = dm.getDisplayInfo(Display.DEFAULT_DISPLAY);
Point scrnSize = new Point(di.appWidth, di.appHeight);
initLayoutParams(scrnSize);
installWindow(wms);
mChoreographer = Choreographer.getInstance();
scheduleNextFrame();
Looper.loop();
mContinueAnime = false;
uninstallWindow(wms);
}
public void initLayoutParams(Point screenSize) {
mLp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
mLp.setTitle("Sample * Window");
mLp.gravity = Gravity.LEFT | Gravity.TOP;
mLp.x = screenSize.x / 4;
mLp.y = screenSize.y / 4;
mLp.width = screenSize.x / 2;
mLp.height = screenSize.y / 2;
mLp.flags = mLp.flags | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
}
public void installWindow(IWindowManager wms) throws Exception {
wms.addWindowToken(mToken, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
mLp.token = mToken;
mSession.add(mWindow, 0, mLp, View.VISIBLE, mInsets, mInputChannel);
mSession.relayout(mWindow, 0, mLp, mLp.width, mLp.height, View.VISIBLE, 0,
mFrame, mInsets, mVisibleInsets, mConfig, mSurface);
if(!mSurface.isValid())
{
throw new RuntimeException("Failed creating Surface");
}
mInputHandler = new InputHandler(mInputChannel, Looper.myLooper());
}
public void uninstallWindow(IWindowManager wms) throws Exception {
mSession.remove(mWindow);
wms.removeWindowToken(mToken);
}
public void scheduleNextFrame() {
mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mFrameRender, null);
}
public Runnable mFrameRender = new Runnable(){
public void run() {
try {
long time = mChoreographer.getFrameTime() % 1000;
if(mSurface.isValid()){
Canvas canvas = mSurface.lockCanvas(null);
canvas.drawColor(Color.DKGRAY);
canvas.drawRect(2 * mLp.width * time / 1000 - mLp.width, 0, 2 * mLp.width * time /1000,
mLp.height, mPaint);
mSurface.unlockCanvasAndPost(canvas);
mSession.finishDrawing(mWindow);
}
if(mContinueAnime){
scheduleNextFrame();
}
} catch (Exception e){
e.printStackTrace();
}
};
};
class InputHandler extends InputEventReceiver {
Looper mLooper = null;
public InputHandler (InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
mLooper = looper;
}
@Override
public void onInputEvent(InputEvent event) {
if(event instanceof MotionEvent){
MotionEvent me = (MotionEvent)event;
if(me.getAction() == MotionEvent.ACTION_UP){
mLooper.quit();
}
}
super.onInputEvent(event);
}
}
class MyWindow extends IWindow.Stub {
private static final String TAG = "MyWindow";
public void resized(Rect frame, Rect contentInsets,
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
Log.i(TAG, "resized");
}
@Override
public void moved(int newX, int newY) {
Log.i(TAG, "moved");
}
public void dispatchAppVisibility(boolean visible) {
Log.i(TAG, "dispatchAppVisibility");
}
public void dispatchScreenState(boolean on) {
Log.i(TAG, "dispatchScreenState");
}
public void dispatchGetNewSurface() {
Log.i(TAG, "dispatchGetNewSurface");
}
public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
Log.i(TAG, "windowFocusChanged: hasFocus = " + hasFocus);
}
public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
Log.i(TAG, "executeCommand");
}
public void closeSystemDialogs(String reason) {
Log.i(TAG, "closeSystemDialogs:" + reason);
}
public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
boolean sync) {
Log.i(TAG, "dispatchWallpaperOffsets");
}
public void dispatchWallpaperCommand(String action, int x, int y,
int z, Bundle extras, boolean sync) {
Log.i(TAG, "dispatchWallpaperCommand");
}
/* Drag/drop */
public void dispatchDragEvent(DragEvent event) {
Log.i(TAG, "dispatchDragEvent");
}
public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
int localValue, int localChanges) {
Log.i(TAG, "dispatchSystemUiVisibilityChanged");
}
public void doneAnimating() {
Log.i(TAG, "doneAnimating");
}
}
}