<commit_before>/*
 * Copyright (C) 2006 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.
 */

///<reference path="../../android/view/Window.ts"/>
///<reference path="../../android/widget/FrameLayout.ts"/>
///<reference path="../../android/graphics/PixelFormat.ts"/>
///<reference path="../../android/text/TextUtils.ts"/>
///<reference path="../../android/util/Log.ts"/>
///<reference path="../../java/lang/Integer.ts"/>
///<reference path="../../java/lang/StringBuilder.ts"/>
///<reference path="../../android/view/Gravity.ts"/>
///<reference path="../../android/view/KeyEvent.ts"/>
///<reference path="../../android/view/View.ts"/>
///<reference path="../../android/view/ViewGroup.ts"/>
///<reference path="../../android/content/Context.ts"/>
///<reference path="../../android/view/MotionEvent.ts"/>
///<reference path="../../android/view/animation/Animation.ts"/>

module android.view {
import PixelFormat = android.graphics.PixelFormat;
import TextUtils = android.text.TextUtils;
import Log = android.util.Log;
import Integer = java.lang.Integer;
import StringBuilder = java.lang.StringBuilder;
import Gravity = android.view.Gravity;
import KeyEvent = android.view.KeyEvent;
import MotionEvent = android.view.MotionEvent;
import View = android.view.View;
import ViewGroup = android.view.ViewGroup;
import Window = android.view.Window;
import Context = android.content.Context;
import Animation = android.view.animation.Animation;

/**
 * The interface that apps use to talk to the window manager.
 * <p>
 * Use <code>Context.getSystemService(Context.WINDOW_SERVICE)</code> to get one of these.
 * </p><p>
 * Each window manager instance is bound to a particular {@link Display}.
 * To obtain a {@link WindowManager} for a different display, use
 * {@link Context#createDisplayContext} to obtain a {@link Context} for that
 * display, then use <code>Context.getSystemService(Context.WINDOW_SERVICE)</code>
 * to get the WindowManager.
 * </p><p>
 * The simplest way to show a window on another display is to create a
 * {@link Presentation}.  The presentation will automatically obtain a
 * {@link WindowManager} and {@link Context} for that display.
 * </p>
 *
 * @see android.content.Context#getSystemService
 * @see android.content.Context#WINDOW_SERVICE
 */
export class WindowManager {
    private mWindowsLayout:WindowManager.Layout;
    protected mActiveWindow:Window;

    private static FocusViewRemember = Symbol();

    constructor(context:Context) {
        this.mWindowsLayout = new WindowManager.Layout(context, this);
        let viewRootImpl = context.androidUI._viewRootImpl;
        let fakeAttachInfo = new View.AttachInfo(viewRootImpl, viewRootImpl.mHandler);
        fakeAttachInfo.mRootView = this.mWindowsLayout;
        this.mWindowsLayout.dispatchAttachedToWindow(fakeAttachInfo, 0);
        this.mWindowsLayout.mGroupFlags |= ViewGroup.FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW; // make attachInfo not handle when addWindow
        this.mWindowsLayout.mGroupFlags |= ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE; // activity animation should use cache
    }

    getWindowsLayout():ViewGroup {
        return this.mWindowsLayout;
    }

    addWindow(window:Window):void{
        let wparams = window.getAttributes();
        if(!wparams){
            wparams = new WindowManager.LayoutParams();
        }
        if(!(wparams instanceof WindowManager.LayoutParams)){
            throw Error('can\'t addWindow, params must be WindowManager.LayoutParams : '+wparams);
        }

        window.setContainer(this);
        let decorView = window.getDecorView();


        //TODO use type as z-index
        let type = wparams.type;
        let lastFocusWindowView = this.mWindowsLayout.getTopFocusableWindowView();
        this.mWindowsLayout.addView(decorView, wparams);

        decorView.dispatchAttachedToWindow(window.mAttachInfo, 0);
        //window.mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);

        if(wparams.isFocusable()){
            decorView.dispatchWindowFocusChanged(true);

            //clearLastWindowFocus
            if(lastFocusWindowView && lastFocusWindowView.hasFocus()){
                const focused = lastFocusWindowView.findFocus();
                lastFocusWindowView[WindowManager.FocusViewRemember] = focused;
                if (focused != null) {
                    focused.clearFocusInternal(true, false);
                }
                lastFocusWindowView.dispatchWindowFocusChanged(false);

                //new window should be focused
                decorView.addOnLayoutChangeListener({
                    onLayoutChange(v:View, left:number , top:number , right:number , bottom:number,
                                   oldLeft:number , oldTop:number , oldRight:number , oldBottom:number){
                        decorView.removeOnLayoutChangeListener(this);

                        const newWindowFocused = FocusFinder.getInstance().findNextFocus(<ViewGroup>decorView, null, View.FOCUS_DOWN);
                        if (newWindowFocused != null) {
                            newWindowFocused.requestFocus(View.FOCUS_DOWN);
                        }
                    }
                });
            }
        }
        if(decorView instanceof ViewGroup){
            decorView.setMotionEventSplittingEnabled(wparams.isSplitTouch());
        }

        let enterAnimation = window.getContext().androidUI.mActivityThread.getOverrideEnterAnimation();
        if(enterAnimation === undefined) enterAnimation = wparams.enterAnimation;
        if(enterAnimation){
            decorView.startAnimation(enterAnimation);
        }
    }

    updateWindowLayout(window:Window, params:ViewGroup.LayoutParams):void{
        if(!(params instanceof WindowManager.LayoutParams)){
            throw Error('can\'t updateWindowLayout, params must be WindowManager.LayoutParams');
        }
        window.getDecorView().setLayoutParams(params);
    }

    removeWindow(window:Window):void{
        let decor = window.getDecorView();
        if(decor.getParent()==null) return;//not add<commit_msg>perf(HTMLView): html not visible when activity in animation.<commit_after>/*
 * Copyright (C) 2006 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.
 */

///<reference path="../../android/view/Window.ts"/>
///<reference path="../../android/widget/FrameLayout.ts"/>
///<reference path="../../android/graphics/PixelFormat.ts"/>
///<reference path="../../android/text/TextUtils.ts"/>
///<reference path="../../android/util/Log.ts"/>
///<reference path="../../java/lang/Integer.ts"/>
///<reference path="../../java/lang/StringBuilder.ts"/>
///<reference path="../../android/view/Gravity.ts"/>
///<reference path="../../android/view/KeyEvent.ts"/>
///<reference path="../../android/view/View.ts"/>
///<reference path="../../android/view/ViewGroup.ts"/>
///<reference path="../../android/content/Context.ts"/>
///<reference path="../../android/view/MotionEvent.ts"/>
///<reference path="../../android/view/animation/Animation.ts"/>

module android.view {
import PixelFormat = android.graphics.PixelFormat;
import TextUtils = android.text.TextUtils;
import Log = android.util.Log;
import Integer = java.lang.Integer;
import StringBuilder = java.lang.StringBuilder;
import Gravity = android.view.Gravity;
import KeyEvent = android.view.KeyEvent;
import MotionEvent = android.view.MotionEvent;
import View = android.view.View;
import ViewGroup = android.view.ViewGroup;
import Window = android.view.Window;
import Context = android.content.Context;
import Animation = android.view.animation.Animation;

/**
 * The interface that apps use to talk to the window manager.
 * <p>
 * Use <code>Context.getSystemService(Context.WINDOW_SERVICE)</code> to get one of these.
 * </p><p>
 * Each window manager instance is bound to a particular {@link Display}.
 * To obtain a {@link WindowManager} for a different display, use
 * {@link Context#createDisplayContext} to obtain a {@link Context} for that
 * display, then use <code>Context.getSystemService(Context.WINDOW_SERVICE)</code>
 * to get the WindowManager.
 * </p><p>
 * The simplest way to show a window on another display is to create a
 * {@link Presentation}.  The presentation will automatically obtain a
 * {@link WindowManager} and {@link Context} for that display.
 * </p>
 *
 * @see android.content.Context#getSystemService
 * @see android.content.Context#WINDOW_SERVICE
 */
export class WindowManager {
    private mWindowsLayout:WindowManager.Layout;
    protected mActiveWindow:Window;

    private static FocusViewRemember = Symbol();

    constructor(context:Context) {
        this.mWindowsLayout = new WindowManager.Layout(context, this);
        let viewRootImpl = context.androidUI._viewRootImpl;
        let fakeAttachInfo = new View.AttachInfo(viewRootImpl, viewRootImpl.mHandler);
        fakeAttachInfo.mRootView = this.mWindowsLayout;
        this.mWindowsLayout.dispatchAttachedToWindow(fakeAttachInfo, 0);
        this.mWindowsLayout.mGroupFlags |= ViewGroup.FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW; // make attachInfo not handle when addWindow
        this.mWindowsLayout.mGroupFlags |= ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE; // activity animation should use cache
    }

    getWindowsLayout():ViewGroup {
        return this.mWindowsLayout;
    }

    addWindow(window:Window):void{
        let wparams = window.getAttributes();
        if(!wparams){
            wparams = new WindowManager.LayoutParams();
        }
        if(!(wparams instanceof WindowManager.LayoutParams)){
            throw Error('can\'t addWindow, params must be WindowManager.LayoutParams : '+wparams);
        }

        window.setContainer(this);
        let decorView = window.getDecorView();


        //TODO use type as z-index
        let type = wparams.type;
        let lastFocusWindowView = this.mWindowsLayout.getTopFocusableWindowView();
        this.mWindowsLayout.addView(decorView, wparams);

        decorView.dispatchAttachedToWindow(window.mAttachInfo, 0);
        //window.mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);

        if(wparams.isFocusable()){
            decorView.dispatchWindowFocusChanged(true);

            //clearLastWindowFocus
            if(lastFocusWindowView && lastFocusWindowView.hasFocus()){
                const focused = lastFocusWindowView.findFocus();
                lastFocusWindowView[WindowManager.FocusViewRemember] = focused;
                if (focused != null) {
                    focused.clearFocusInternal(true, false);
                }
                lastFocusWindowView.dispatchWindowFocusChanged(false);

                //new window should be focused
                decorView.addOnLayoutChangeListener({
                    onLayoutChange(v:View, left:number , top:number , right:number , bottom:number,
                                   oldLeft:number , oldTop:number , oldRight:number , oldBottom:number){
                        decorView.removeOnLayoutChangeListener(this);

                        const newWindowFocused = FocusFinder.getInstance().findNextFocus(<ViewGroup>decorView, null, View.FOCUS_DOWN);
                        if (newWindowFocused != null) {
                            newWindowFocused.requestFocus(View.FOCUS_DOWN);
                        }
                    }
                });
            }
        }
        if(decorView instanceof ViewGroup){
            decorView.setMotionEventSplittingEnabled(wparams.isSplitTouch());
        }

        let enterAnimation = window.getContext().androidUI.mActivityThread.getOverrideEnterAnimation();
        if(enterAnimation === undefined) enterAnimation = wparams.enterAnimation;
        if(enterAnimation) {
            decorView.bindElement.style.visibility = 'hidden';
            enterAnimation.setAnimationListener({
                onAnimationStart(animation: Animation): void {
                },
                onAnimationEnd(animation: Animation): void {
                    decorView.bindElement.style.visibility = '';
                },
                onAnimationRepeat(animation: Animation): void {
                }
            });
            decorView.startAnimation(enterAnimation);
        }
    }

    updateWindowLayout(window:Window, params:ViewGroup.LayoutParams):void{
        if(!(params instanceof WindowManager.LayoutParams)){
            throw Error('can\'t updateWindowLayout, params must be WindowManager.LayoutParams');
        }
        window.getDecorView().setLayoutParams(params);
    }

    removeWindow(window:Window):void{
        let decor = window.getDecorView();
        if(decor.getParent()==null) return;//not add
{'fraction_non_alphanumeric': 0.11802418767302929, 'fraction_numerical': 0.0014570887367040652, 'mean_word_length': 2.90193291642979, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2866873', 'n_tokens_mistral': 3579, 'n_tokens_neox': 3468, 'n_words': 837}