SampleWindow.java
package understanding.wms.samplewindow;
import android.content.res.Configuration;
import android.view.Surface;
import android.view.View;
import android.view.InputChannel;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.Choreographer;
import android.view.MotionEvent;
import android.view.InputEvent;
import android.view.InputEventReceiver;
import android.view.Display;
import android.view.IWindow;
import android.view.IWindowManager;
import android.view.IWindowSession;
import android.view.WindowManagerGlobal;
import android.hardware.display.IDisplayManager;
import android.graphics.Rect;
import android.graphics.Point;
import android.graphics.Paint;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Looper;
import android.os.Binder;
import android.os.IBinder;
import android.os.ServiceManager;
import android.content.Context;
public class 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();
IDisplayManager dm = IDisplayManager.Stub.asInterface(
ServiceManager.getService(Context.DISPLAY_SERVICE)
);
DisplayInfo di = dm.getDisplayInfo(Display.DEFAULT_DISPLAY);
Point screenSize = new Point(di.appWidth, di.appHeight);
initLayoutParams(screenSize);
installWindow(wms);
mChoreographer = Choreographer.getInstance();
scheduleNextFrame();
Looper.loop();
mContinueAnime = false;
uninstallWindow(wms);
}
public void initLayoutParams(Point screenSize) {
mLp.type = LayoutParams.TYPE_SYSTEM_ALERT;
mLp.setTitle("SampleWindow");
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, 0, null);
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, 0);
}
public void scheduleNextFrame() {
mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mFrameRender, null);
}
public Runnable mFrameRender = new Runnable() {
@Override
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, null);
}
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 {
// Keeping default implements
}
}
Android.mk
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := samplewindow
include $(BUILD_JAVA_LIBRARY)
sw.sh
base=/system
export CLASSPATH=$base/framework/samplewindow.jar
exec app_process $base/bin understanding.wms.samplewindow.SampleWindow "$@"