Home | History | Annotate | Download | only in view
      1 /*
      2  * Copyright (C) 2006 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.view;
     18 
     19 import android.app.Application;
     20 import android.content.Context;
     21 import android.content.res.CompatibilityInfo;
     22 import android.content.res.Configuration;
     23 import android.content.res.TypedArray;
     24 import android.graphics.PixelFormat;
     25 import android.graphics.drawable.Drawable;
     26 import android.net.Uri;
     27 import android.os.Bundle;
     28 import android.os.IBinder;
     29 import android.os.SystemProperties;
     30 import android.util.Slog;
     31 import android.view.accessibility.AccessibilityEvent;
     32 
     33 /**
     34  * Abstract base class for a top-level window look and behavior policy.  An
     35  * instance of this class should be used as the top-level view added to the
     36  * window manager. It provides standard UI policies such as a background, title
     37  * area, default key processing, etc.
     38  *
     39  * <p>The only existing implementation of this abstract class is
     40  * android.policy.PhoneWindow, which you should instantiate when needing a
     41  * Window.  Eventually that class will be refactored and a factory method
     42  * added for creating Window instances without knowing about a particular
     43  * implementation.
     44  */
     45 public abstract class Window {
     46     /** Flag for the "options panel" feature.  This is enabled by default. */
     47     public static final int FEATURE_OPTIONS_PANEL = 0;
     48     /** Flag for the "no title" feature, turning off the title at the top
     49      *  of the screen. */
     50     public static final int FEATURE_NO_TITLE = 1;
     51     /** Flag for the progress indicator feature */
     52     public static final int FEATURE_PROGRESS = 2;
     53     /** Flag for having an icon on the left side of the title bar */
     54     public static final int FEATURE_LEFT_ICON = 3;
     55     /** Flag for having an icon on the right side of the title bar */
     56     public static final int FEATURE_RIGHT_ICON = 4;
     57     /** Flag for indeterminate progress */
     58     public static final int FEATURE_INDETERMINATE_PROGRESS = 5;
     59     /** Flag for the context menu.  This is enabled by default. */
     60     public static final int FEATURE_CONTEXT_MENU = 6;
     61     /** Flag for custom title. You cannot combine this feature with other title features. */
     62     public static final int FEATURE_CUSTOM_TITLE = 7;
     63     /**
     64      * Flag for enabling the Action Bar.
     65      * This is enabled by default for some devices. The Action Bar
     66      * replaces the title bar and provides an alternate location
     67      * for an on-screen menu button on some devices.
     68      */
     69     public static final int FEATURE_ACTION_BAR = 8;
     70     /**
     71      * Flag for requesting an Action Bar that overlays window content.
     72      * Normally an Action Bar will sit in the space above window content, but if this
     73      * feature is requested along with {@link #FEATURE_ACTION_BAR} it will be layered over
     74      * the window content itself. This is useful if you would like your app to have more control
     75      * over how the Action Bar is displayed, such as letting application content scroll beneath
     76      * an Action Bar with a transparent background or otherwise displaying a transparent/translucent
     77      * Action Bar over application content.
     78      */
     79     public static final int FEATURE_ACTION_BAR_OVERLAY = 9;
     80     /**
     81      * Flag for specifying the behavior of action modes when an Action Bar is not present.
     82      * If overlay is enabled, the action mode UI will be allowed to cover existing window content.
     83      */
     84     public static final int FEATURE_ACTION_MODE_OVERLAY = 10;
     85     /** Flag for setting the progress bar's visibility to VISIBLE */
     86     public static final int PROGRESS_VISIBILITY_ON = -1;
     87     /** Flag for setting the progress bar's visibility to GONE */
     88     public static final int PROGRESS_VISIBILITY_OFF = -2;
     89     /** Flag for setting the progress bar's indeterminate mode on */
     90     public static final int PROGRESS_INDETERMINATE_ON = -3;
     91     /** Flag for setting the progress bar's indeterminate mode off */
     92     public static final int PROGRESS_INDETERMINATE_OFF = -4;
     93     /** Starting value for the (primary) progress */
     94     public static final int PROGRESS_START = 0;
     95     /** Ending value for the (primary) progress */
     96     public static final int PROGRESS_END = 10000;
     97     /** Lowest possible value for the secondary progress */
     98     public static final int PROGRESS_SECONDARY_START = 20000;
     99     /** Highest possible value for the secondary progress */
    100     public static final int PROGRESS_SECONDARY_END = 30000;
    101 
    102     /** The default features enabled */
    103     @SuppressWarnings({"PointlessBitwiseExpression"})
    104     protected static final int DEFAULT_FEATURES = (1 << FEATURE_OPTIONS_PANEL) |
    105             (1 << FEATURE_CONTEXT_MENU);
    106 
    107     /**
    108      * The ID that the main layout in the XML layout file should have.
    109      */
    110     public static final int ID_ANDROID_CONTENT = com.android.internal.R.id.content;
    111 
    112     private final Context mContext;
    113 
    114     private TypedArray mWindowStyle;
    115     private Callback mCallback;
    116     private WindowManager mWindowManager;
    117     private IBinder mAppToken;
    118     private String mAppName;
    119     private Window mContainer;
    120     private Window mActiveChild;
    121     private boolean mIsActive = false;
    122     private boolean mHasChildren = false;
    123     private boolean mCloseOnTouchOutside = false;
    124     private boolean mSetCloseOnTouchOutside = false;
    125     private int mForcedWindowFlags = 0;
    126 
    127     private int mFeatures = DEFAULT_FEATURES;
    128     private int mLocalFeatures = DEFAULT_FEATURES;
    129 
    130     private boolean mHaveWindowFormat = false;
    131     private boolean mHaveDimAmount = false;
    132     private int mDefaultWindowFormat = PixelFormat.OPAQUE;
    133 
    134     private boolean mHasSoftInputMode = false;
    135 
    136     private boolean mDestroyed;
    137 
    138     // The current window attributes.
    139     private final WindowManager.LayoutParams mWindowAttributes =
    140         new WindowManager.LayoutParams();
    141 
    142     /**
    143      * API from a Window back to its caller.  This allows the client to
    144      * intercept key dispatching, panels and menus, etc.
    145      */
    146     public interface Callback {
    147         /**
    148          * Called to process key events.  At the very least your
    149          * implementation must call
    150          * {@link android.view.Window#superDispatchKeyEvent} to do the
    151          * standard key processing.
    152          *
    153          * @param event The key event.
    154          *
    155          * @return boolean Return true if this event was consumed.
    156          */
    157         public boolean dispatchKeyEvent(KeyEvent event);
    158 
    159         /**
    160          * Called to process a key shortcut event.
    161          * At the very least your implementation must call
    162          * {@link android.view.Window#superDispatchKeyShortcutEvent} to do the
    163          * standard key shortcut processing.
    164          *
    165          * @param event The key shortcut event.
    166          * @return True if this event was consumed.
    167          */
    168         public boolean dispatchKeyShortcutEvent(KeyEvent event);
    169 
    170         /**
    171          * Called to process touch screen events.  At the very least your
    172          * implementation must call
    173          * {@link android.view.Window#superDispatchTouchEvent} to do the
    174          * standard touch screen processing.
    175          *
    176          * @param event The touch screen event.
    177          *
    178          * @return boolean Return true if this event was consumed.
    179          */
    180         public boolean dispatchTouchEvent(MotionEvent event);
    181 
    182         /**
    183          * Called to process trackball events.  At the very least your
    184          * implementation must call
    185          * {@link android.view.Window#superDispatchTrackballEvent} to do the
    186          * standard trackball processing.
    187          *
    188          * @param event The trackball event.
    189          *
    190          * @return boolean Return true if this event was consumed.
    191          */
    192         public boolean dispatchTrackballEvent(MotionEvent event);
    193 
    194         /**
    195          * Called to process generic motion events.  At the very least your
    196          * implementation must call
    197          * {@link android.view.Window#superDispatchGenericMotionEvent} to do the
    198          * standard processing.
    199          *
    200          * @param event The generic motion event.
    201          *
    202          * @return boolean Return true if this event was consumed.
    203          */
    204         public boolean dispatchGenericMotionEvent(MotionEvent event);
    205 
    206         /**
    207          * Called to process population of {@link AccessibilityEvent}s.
    208          *
    209          * @param event The event.
    210          *
    211          * @return boolean Return true if event population was completed.
    212          */
    213         public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
    214 
    215         /**
    216          * Instantiate the view to display in the panel for 'featureId'.
    217          * You can return null, in which case the default content (typically
    218          * a menu) will be created for you.
    219          *
    220          * @param featureId Which panel is being created.
    221          *
    222          * @return view The top-level view to place in the panel.
    223          *
    224          * @see #onPreparePanel
    225          */
    226         public View onCreatePanelView(int featureId);
    227 
    228         /**
    229          * Initialize the contents of the menu for panel 'featureId'.  This is
    230          * called if onCreatePanelView() returns null, giving you a standard
    231          * menu in which you can place your items.  It is only called once for
    232          * the panel, the first time it is shown.
    233          *
    234          * <p>You can safely hold on to <var>menu</var> (and any items created
    235          * from it), making modifications to it as desired, until the next
    236          * time onCreatePanelMenu() is called for this feature.
    237          *
    238          * @param featureId The panel being created.
    239          * @param menu The menu inside the panel.
    240          *
    241          * @return boolean You must return true for the panel to be displayed;
    242          *         if you return false it will not be shown.
    243          */
    244         public boolean onCreatePanelMenu(int featureId, Menu menu);
    245 
    246         /**
    247          * Prepare a panel to be displayed.  This is called right before the
    248          * panel window is shown, every time it is shown.
    249          *
    250          * @param featureId The panel that is being displayed.
    251          * @param view The View that was returned by onCreatePanelView().
    252          * @param menu If onCreatePanelView() returned null, this is the Menu
    253          *             being displayed in the panel.
    254          *
    255          * @return boolean You must return true for the panel to be displayed;
    256          *         if you return false it will not be shown.
    257          *
    258          * @see #onCreatePanelView
    259          */
    260         public boolean onPreparePanel(int featureId, View view, Menu menu);
    261 
    262         /**
    263          * Called when a panel's menu is opened by the user. This may also be
    264          * called when the menu is changing from one type to another (for
    265          * example, from the icon menu to the expanded menu).
    266          *
    267          * @param featureId The panel that the menu is in.
    268          * @param menu The menu that is opened.
    269          * @return Return true to allow the menu to open, or false to prevent
    270          *         the menu from opening.
    271          */
    272         public boolean onMenuOpened(int featureId, Menu menu);
    273 
    274         /**
    275          * Called when a panel's menu item has been selected by the user.
    276          *
    277          * @param featureId The panel that the menu is in.
    278          * @param item The menu item that was selected.
    279          *
    280          * @return boolean Return true to finish processing of selection, or
    281          *         false to perform the normal menu handling (calling its
    282          *         Runnable or sending a Message to its target Handler).
    283          */
    284         public boolean onMenuItemSelected(int featureId, MenuItem item);
    285 
    286         /**
    287          * This is called whenever the current window attributes change.
    288          *
    289          */
    290         public void onWindowAttributesChanged(WindowManager.LayoutParams attrs);
    291 
    292         /**
    293          * This hook is called whenever the content view of the screen changes
    294          * (due to a call to
    295          * {@link Window#setContentView(View, android.view.ViewGroup.LayoutParams)
    296          * Window.setContentView} or
    297          * {@link Window#addContentView(View, android.view.ViewGroup.LayoutParams)
    298          * Window.addContentView}).
    299          */
    300         public void onContentChanged();
    301 
    302         /**
    303          * This hook is called whenever the window focus changes.  See
    304          * {@link View#onWindowFocusChanged(boolean)
    305          * View.onWindowFocusChanged(boolean)} for more information.
    306          *
    307          * @param hasFocus Whether the window now has focus.
    308          */
    309         public void onWindowFocusChanged(boolean hasFocus);
    310 
    311         /**
    312          * Called when the window has been attached to the window manager.
    313          * See {@link View#onAttachedToWindow() View.onAttachedToWindow()}
    314          * for more information.
    315          */
    316         public void onAttachedToWindow();
    317 
    318         /**
    319          * Called when the window has been attached to the window manager.
    320          * See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()}
    321          * for more information.
    322          */
    323         public void onDetachedFromWindow();
    324 
    325         /**
    326          * Called when a panel is being closed.  If another logical subsequent
    327          * panel is being opened (and this panel is being closed to make room for the subsequent
    328          * panel), this method will NOT be called.
    329          *
    330          * @param featureId The panel that is being displayed.
    331          * @param menu If onCreatePanelView() returned null, this is the Menu
    332          *            being displayed in the panel.
    333          */
    334         public void onPanelClosed(int featureId, Menu menu);
    335 
    336         /**
    337          * Called when the user signals the desire to start a search.
    338          *
    339          * @return true if search launched, false if activity refuses (blocks)
    340          *
    341          * @see android.app.Activity#onSearchRequested()
    342          */
    343         public boolean onSearchRequested();
    344 
    345         /**
    346          * Called when an action mode is being started for this window. Gives the
    347          * callback an opportunity to handle the action mode in its own unique and
    348          * beautiful way. If this method returns null the system can choose a way
    349          * to present the mode or choose not to start the mode at all.
    350          *
    351          * @param callback Callback to control the lifecycle of this action mode
    352          * @return The ActionMode that was started, or null if the system should present it
    353          */
    354         public ActionMode onWindowStartingActionMode(ActionMode.Callback callback);
    355 
    356         /**
    357          * Called when an action mode has been started. The appropriate mode callback
    358          * method will have already been invoked.
    359          *
    360          * @param mode The new mode that has just been started.
    361          */
    362         public void onActionModeStarted(ActionMode mode);
    363 
    364         /**
    365          * Called when an action mode has been finished. The appropriate mode callback
    366          * method will have already been invoked.
    367          *
    368          * @param mode The mode that was just finished.
    369          */
    370         public void onActionModeFinished(ActionMode mode);
    371     }
    372 
    373     public Window(Context context) {
    374         mContext = context;
    375     }
    376 
    377     /**
    378      * Return the Context this window policy is running in, for retrieving
    379      * resources and other information.
    380      *
    381      * @return Context The Context that was supplied to the constructor.
    382      */
    383     public final Context getContext() {
    384         return mContext;
    385     }
    386 
    387     /**
    388      * Return the {@link android.R.styleable#Window} attributes from this
    389      * window's theme.
    390      */
    391     public final TypedArray getWindowStyle() {
    392         synchronized (this) {
    393             if (mWindowStyle == null) {
    394                 mWindowStyle = mContext.obtainStyledAttributes(
    395                         com.android.internal.R.styleable.Window);
    396             }
    397             return mWindowStyle;
    398         }
    399     }
    400 
    401     /**
    402      * Set the container for this window.  If not set, the DecorWindow
    403      * operates as a top-level window; otherwise, it negotiates with the
    404      * container to display itself appropriately.
    405      *
    406      * @param container The desired containing Window.
    407      */
    408     public void setContainer(Window container) {
    409         mContainer = container;
    410         if (container != null) {
    411             // Embedded screens never have a title.
    412             mFeatures |= 1<<FEATURE_NO_TITLE;
    413             mLocalFeatures |= 1<<FEATURE_NO_TITLE;
    414             container.mHasChildren = true;
    415         }
    416     }
    417 
    418     /**
    419      * Return the container for this Window.
    420      *
    421      * @return Window The containing window, or null if this is a
    422      *         top-level window.
    423      */
    424     public final Window getContainer() {
    425         return mContainer;
    426     }
    427 
    428     public final boolean hasChildren() {
    429         return mHasChildren;
    430     }
    431 
    432     /** @hide */
    433     public final void destroy() {
    434         mDestroyed = true;
    435     }
    436 
    437     /** @hide */
    438     public final boolean isDestroyed() {
    439         return mDestroyed;
    440     }
    441 
    442     /**
    443      * Set the window manager for use by this Window to, for example,
    444      * display panels.  This is <em>not</em> used for displaying the
    445      * Window itself -- that must be done by the client.
    446      *
    447      * @param wm The ViewManager for adding new windows.
    448      */
    449     public void setWindowManager(WindowManager wm, IBinder appToken, String appName) {
    450         setWindowManager(wm, appToken, appName, false);
    451     }
    452 
    453     /**
    454      * Set the window manager for use by this Window to, for example,
    455      * display panels.  This is <em>not</em> used for displaying the
    456      * Window itself -- that must be done by the client.
    457      *
    458      * @param wm The ViewManager for adding new windows.
    459      */
    460     public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
    461             boolean hardwareAccelerated) {
    462         mAppToken = appToken;
    463         mAppName = appName;
    464         if (wm == null) {
    465             wm = WindowManagerImpl.getDefault();
    466         }
    467         mWindowManager = new LocalWindowManager(wm, hardwareAccelerated);
    468     }
    469 
    470     static CompatibilityInfoHolder getCompatInfo(Context context) {
    471         Application app = (Application)context.getApplicationContext();
    472         return app != null ? app.mLoadedApk.mCompatibilityInfo : new CompatibilityInfoHolder();
    473     }
    474 
    475     private class LocalWindowManager extends WindowManagerImpl.CompatModeWrapper {
    476         private static final String PROPERTY_HARDWARE_UI = "persist.sys.ui.hw";
    477 
    478         private final boolean mHardwareAccelerated;
    479 
    480         LocalWindowManager(WindowManager wm, boolean hardwareAccelerated) {
    481             super(wm, getCompatInfo(mContext));
    482             mHardwareAccelerated = hardwareAccelerated ||
    483                     SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
    484         }
    485 
    486         public boolean isHardwareAccelerated() {
    487             return mHardwareAccelerated;
    488         }
    489 
    490         public final void addView(View view, ViewGroup.LayoutParams params) {
    491             // Let this throw an exception on a bad params.
    492             WindowManager.LayoutParams wp = (WindowManager.LayoutParams)params;
    493             CharSequence curTitle = wp.getTitle();
    494             if (wp.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
    495                 wp.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
    496                 if (wp.token == null) {
    497                     View decor = peekDecorView();
    498                     if (decor != null) {
    499                         wp.token = decor.getWindowToken();
    500                     }
    501                 }
    502                 if (curTitle == null || curTitle.length() == 0) {
    503                     String title;
    504                     if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA) {
    505                         title="Media";
    506                     } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY) {
    507                         title="MediaOvr";
    508                     } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
    509                         title="Panel";
    510                     } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL) {
    511                         title="SubPanel";
    512                     } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG) {
    513                         title="AtchDlg";
    514                     } else {
    515                         title=Integer.toString(wp.type);
    516                     }
    517                     if (mAppName != null) {
    518                         title += ":" + mAppName;
    519                     }
    520                     wp.setTitle(title);
    521                 }
    522             } else {
    523                 if (wp.token == null) {
    524                     wp.token = mContainer == null ? mAppToken : mContainer.mAppToken;
    525                 }
    526                 if ((curTitle == null || curTitle.length() == 0)
    527                         && mAppName != null) {
    528                     wp.setTitle(mAppName);
    529                 }
    530            }
    531             if (wp.packageName == null) {
    532                 wp.packageName = mContext.getPackageName();
    533             }
    534             if (mHardwareAccelerated) {
    535                 wp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
    536             }
    537             super.addView(view, params);
    538         }
    539     }
    540 
    541     /**
    542      * Return the window manager allowing this Window to display its own
    543      * windows.
    544      *
    545      * @return WindowManager The ViewManager.
    546      */
    547     public WindowManager getWindowManager() {
    548         return mWindowManager;
    549     }
    550 
    551     /**
    552      * Set the Callback interface for this window, used to intercept key
    553      * events and other dynamic operations in the window.
    554      *
    555      * @param callback The desired Callback interface.
    556      */
    557     public void setCallback(Callback callback) {
    558         mCallback = callback;
    559     }
    560 
    561     /**
    562      * Return the current Callback interface for this window.
    563      */
    564     public final Callback getCallback() {
    565         return mCallback;
    566     }
    567 
    568     /**
    569      * Take ownership of this window's surface.  The window's view hierarchy
    570      * will no longer draw into the surface, though it will otherwise continue
    571      * to operate (such as for receiving input events).  The given SurfaceHolder
    572      * callback will be used to tell you about state changes to the surface.
    573      */
    574     public abstract void takeSurface(SurfaceHolder.Callback2 callback);
    575 
    576     /**
    577      * Take ownership of this window's InputQueue.  The window will no
    578      * longer read and dispatch input events from the queue; it is your
    579      * responsibility to do so.
    580      */
    581     public abstract void takeInputQueue(InputQueue.Callback callback);
    582 
    583     /**
    584      * Return whether this window is being displayed with a floating style
    585      * (based on the {@link android.R.attr#windowIsFloating} attribute in
    586      * the style/theme).
    587      *
    588      * @return Returns true if the window is configured to be displayed floating
    589      * on top of whatever is behind it.
    590      */
    591     public abstract boolean isFloating();
    592 
    593     /**
    594      * Set the width and height layout parameters of the window.  The default
    595      * for both of these is MATCH_PARENT; you can change them to WRAP_CONTENT
    596      * or an absolute value to make a window that is not full-screen.
    597      *
    598      * @param width The desired layout width of the window.
    599      * @param height The desired layout height of the window.
    600      *
    601      * @see ViewGroup.LayoutParams#height
    602      * @see ViewGroup.LayoutParams#width
    603      */
    604     public void setLayout(int width, int height) {
    605         final WindowManager.LayoutParams attrs = getAttributes();
    606         attrs.width = width;
    607         attrs.height = height;
    608         if (mCallback != null) {
    609             mCallback.onWindowAttributesChanged(attrs);
    610         }
    611     }
    612 
    613     /**
    614      * Set the gravity of the window, as per the Gravity constants.  This
    615      * controls how the window manager is positioned in the overall window; it
    616      * is only useful when using WRAP_CONTENT for the layout width or height.
    617      *
    618      * @param gravity The desired gravity constant.
    619      *
    620      * @see Gravity
    621      * @see #setLayout
    622      */
    623     public void setGravity(int gravity)
    624     {
    625         final WindowManager.LayoutParams attrs = getAttributes();
    626         attrs.gravity = gravity;
    627         if (mCallback != null) {
    628             mCallback.onWindowAttributesChanged(attrs);
    629         }
    630     }
    631 
    632     /**
    633      * Set the type of the window, as per the WindowManager.LayoutParams
    634      * types.
    635      *
    636      * @param type The new window type (see WindowManager.LayoutParams).
    637      */
    638     public void setType(int type) {
    639         final WindowManager.LayoutParams attrs = getAttributes();
    640         attrs.type = type;
    641         if (mCallback != null) {
    642             mCallback.onWindowAttributesChanged(attrs);
    643         }
    644     }
    645 
    646     /**
    647      * Set the format of window, as per the PixelFormat types.  This overrides
    648      * the default format that is selected by the Window based on its
    649      * window decorations.
    650      *
    651      * @param format The new window format (see PixelFormat).  Use
    652      *               PixelFormat.UNKNOWN to allow the Window to select
    653      *               the format.
    654      *
    655      * @see PixelFormat
    656      */
    657     public void setFormat(int format) {
    658         final WindowManager.LayoutParams attrs = getAttributes();
    659         if (format != PixelFormat.UNKNOWN) {
    660             attrs.format = format;
    661             mHaveWindowFormat = true;
    662         } else {
    663             attrs.format = mDefaultWindowFormat;
    664             mHaveWindowFormat = false;
    665         }
    666         if (mCallback != null) {
    667             mCallback.onWindowAttributesChanged(attrs);
    668         }
    669     }
    670 
    671     /**
    672      * Specify custom animations to use for the window, as per
    673      * {@link WindowManager.LayoutParams#windowAnimations
    674      * WindowManager.LayoutParams.windowAnimations}.  Providing anything besides
    675      * 0 here will override the animations the window would
    676      * normally retrieve from its theme.
    677      */
    678     public void setWindowAnimations(int resId) {
    679         final WindowManager.LayoutParams attrs = getAttributes();
    680         attrs.windowAnimations = resId;
    681         if (mCallback != null) {
    682             mCallback.onWindowAttributesChanged(attrs);
    683         }
    684     }
    685 
    686     /**
    687      * Specify an explicit soft input mode to use for the window, as per
    688      * {@link WindowManager.LayoutParams#softInputMode
    689      * WindowManager.LayoutParams.softInputMode}.  Providing anything besides
    690      * "unspecified" here will override the input mode the window would
    691      * normally retrieve from its theme.
    692      */
    693     public void setSoftInputMode(int mode) {
    694         final WindowManager.LayoutParams attrs = getAttributes();
    695         if (mode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
    696             attrs.softInputMode = mode;
    697             mHasSoftInputMode = true;
    698         } else {
    699             mHasSoftInputMode = false;
    700         }
    701         if (mCallback != null) {
    702             mCallback.onWindowAttributesChanged(attrs);
    703         }
    704     }
    705 
    706     /**
    707      * Convenience function to set the flag bits as specified in flags, as
    708      * per {@link #setFlags}.
    709      * @param flags The flag bits to be set.
    710      * @see #setFlags
    711      */
    712     public void addFlags(int flags) {
    713         setFlags(flags, flags);
    714     }
    715 
    716     /**
    717      * Convenience function to clear the flag bits as specified in flags, as
    718      * per {@link #setFlags}.
    719      * @param flags The flag bits to be cleared.
    720      * @see #setFlags
    721      */
    722     public void clearFlags(int flags) {
    723         setFlags(0, flags);
    724     }
    725 
    726     /**
    727      * Set the flags of the window, as per the
    728      * {@link WindowManager.LayoutParams WindowManager.LayoutParams}
    729      * flags.
    730      *
    731      * <p>Note that some flags must be set before the window decoration is
    732      * created (by the first call to
    733      * {@link #setContentView(View, android.view.ViewGroup.LayoutParams)} or
    734      * {@link #getDecorView()}:
    735      * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN} and
    736      * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}.  These
    737      * will be set for you based on the {@link android.R.attr#windowIsFloating}
    738      * attribute.
    739      *
    740      * @param flags The new window flags (see WindowManager.LayoutParams).
    741      * @param mask Which of the window flag bits to modify.
    742      */
    743     public void setFlags(int flags, int mask) {
    744         final WindowManager.LayoutParams attrs = getAttributes();
    745         attrs.flags = (attrs.flags&~mask) | (flags&mask);
    746         if ((mask&WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0) {
    747             attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
    748         }
    749         mForcedWindowFlags |= mask;
    750         if (mCallback != null) {
    751             mCallback.onWindowAttributesChanged(attrs);
    752         }
    753     }
    754 
    755     /**
    756      * Set the amount of dim behind the window when using
    757      * {@link WindowManager.LayoutParams#FLAG_DIM_BEHIND}.  This overrides
    758      * the default dim amount of that is selected by the Window based on
    759      * its theme.
    760      *
    761      * @param amount The new dim amount, from 0 for no dim to 1 for full dim.
    762      */
    763     public void setDimAmount(float amount) {
    764         final WindowManager.LayoutParams attrs = getAttributes();
    765         attrs.dimAmount = amount;
    766         mHaveDimAmount = true;
    767         if (mCallback != null) {
    768             mCallback.onWindowAttributesChanged(attrs);
    769         }
    770     }
    771 
    772     /**
    773      * Specify custom window attributes.  <strong>PLEASE NOTE:</strong> the
    774      * layout params you give here should generally be from values previously
    775      * retrieved with {@link #getAttributes()}; you probably do not want to
    776      * blindly create and apply your own, since this will blow away any values
    777      * set by the framework that you are not interested in.
    778      *
    779      * @param a The new window attributes, which will completely override any
    780      *          current values.
    781      */
    782     public void setAttributes(WindowManager.LayoutParams a) {
    783         mWindowAttributes.copyFrom(a);
    784         if (mCallback != null) {
    785             mCallback.onWindowAttributesChanged(mWindowAttributes);
    786         }
    787     }
    788 
    789     /**
    790      * Retrieve the current window attributes associated with this panel.
    791      *
    792      * @return WindowManager.LayoutParams Either the existing window
    793      *         attributes object, or a freshly created one if there is none.
    794      */
    795     public final WindowManager.LayoutParams getAttributes() {
    796         return mWindowAttributes;
    797     }
    798 
    799     /**
    800      * Return the window flags that have been explicitly set by the client,
    801      * so will not be modified by {@link #getDecorView}.
    802      */
    803     protected final int getForcedWindowFlags() {
    804         return mForcedWindowFlags;
    805     }
    806 
    807     /**
    808      * Has the app specified their own soft input mode?
    809      */
    810     protected final boolean hasSoftInputMode() {
    811         return mHasSoftInputMode;
    812     }
    813 
    814     /** @hide */
    815     public void setCloseOnTouchOutside(boolean close) {
    816         mCloseOnTouchOutside = close;
    817         mSetCloseOnTouchOutside = true;
    818     }
    819 
    820     /** @hide */
    821     public void setCloseOnTouchOutsideIfNotSet(boolean close) {
    822         if (!mSetCloseOnTouchOutside) {
    823             mCloseOnTouchOutside = close;
    824             mSetCloseOnTouchOutside = true;
    825         }
    826     }
    827 
    828     /** @hide */
    829     public abstract void alwaysReadCloseOnTouchAttr();
    830 
    831     /** @hide */
    832     public boolean shouldCloseOnTouch(Context context, MotionEvent event) {
    833         if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN
    834                 && isOutOfBounds(context, event) && peekDecorView() != null) {
    835             return true;
    836         }
    837         return false;
    838     }
    839 
    840     private boolean isOutOfBounds(Context context, MotionEvent event) {
    841         final int x = (int) event.getX();
    842         final int y = (int) event.getY();
    843         final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
    844         final View decorView = getDecorView();
    845         return (x < -slop) || (y < -slop)
    846                 || (x > (decorView.getWidth()+slop))
    847                 || (y > (decorView.getHeight()+slop));
    848     }
    849 
    850     /**
    851      * Enable extended screen features.  This must be called before
    852      * setContentView().  May be called as many times as desired as long as it
    853      * is before setContentView().  If not called, no extended features
    854      * will be available.  You can not turn off a feature once it is requested.
    855      * You canot use other title features with {@link #FEATURE_CUSTOM_TITLE}.
    856      *
    857      * @param featureId The desired features, defined as constants by Window.
    858      * @return The features that are now set.
    859      */
    860     public boolean requestFeature(int featureId) {
    861         final int flag = 1<<featureId;
    862         mFeatures |= flag;
    863         mLocalFeatures |= mContainer != null ? (flag&~mContainer.mFeatures) : flag;
    864         return (mFeatures&flag) != 0;
    865     }
    866 
    867     /**
    868      * @hide Used internally to help resolve conflicting features.
    869      */
    870     protected void removeFeature(int featureId) {
    871         final int flag = 1<<featureId;
    872         mFeatures &= ~flag;
    873         mLocalFeatures &= ~(mContainer != null ? (flag&~mContainer.mFeatures) : flag);
    874     }
    875 
    876     public final void makeActive() {
    877         if (mContainer != null) {
    878             if (mContainer.mActiveChild != null) {
    879                 mContainer.mActiveChild.mIsActive = false;
    880             }
    881             mContainer.mActiveChild = this;
    882         }
    883         mIsActive = true;
    884         onActive();
    885     }
    886 
    887     public final boolean isActive()
    888     {
    889         return mIsActive;
    890     }
    891 
    892     /**
    893      * Finds a view that was identified by the id attribute from the XML that
    894      * was processed in {@link android.app.Activity#onCreate}.  This will
    895      * implicitly call {@link #getDecorView} for you, with all of the
    896      * associated side-effects.
    897      *
    898      * @return The view if found or null otherwise.
    899      */
    900     public View findViewById(int id) {
    901         return getDecorView().findViewById(id);
    902     }
    903 
    904     /**
    905      * Convenience for
    906      * {@link #setContentView(View, android.view.ViewGroup.LayoutParams)}
    907      * to set the screen content from a layout resource.  The resource will be
    908      * inflated, adding all top-level views to the screen.
    909      *
    910      * @param layoutResID Resource ID to be inflated.
    911      * @see #setContentView(View, android.view.ViewGroup.LayoutParams)
    912      */
    913     public abstract void setContentView(int layoutResID);
    914 
    915     /**
    916      * Convenience for
    917      * {@link #setContentView(View, android.view.ViewGroup.LayoutParams)}
    918      * set the screen content to an explicit view.  This view is placed
    919      * directly into the screen's view hierarchy.  It can itself be a complex
    920      * view hierarhcy.
    921      *
    922      * @param view The desired content to display.
    923      * @see #setContentView(View, android.view.ViewGroup.LayoutParams)
    924      */
    925     public abstract void setContentView(View view);
    926 
    927     /**
    928      * Set the screen content to an explicit view.  This view is placed
    929      * directly into the screen's view hierarchy.  It can itself be a complex
    930      * view hierarchy.
    931      *
    932      * <p>Note that calling this function "locks in" various characteristics
    933      * of the window that can not, from this point forward, be changed: the
    934      * features that have been requested with {@link #requestFeature(int)},
    935      * and certain window flags as described in {@link #setFlags(int, int)}.
    936      *
    937      * @param view The desired content to display.
    938      * @param params Layout parameters for the view.
    939      */
    940     public abstract void setContentView(View view, ViewGroup.LayoutParams params);
    941 
    942     /**
    943      * Variation on
    944      * {@link #setContentView(View, android.view.ViewGroup.LayoutParams)}
    945      * to add an additional content view to the screen.  Added after any existing
    946      * ones in the screen -- existing views are NOT removed.
    947      *
    948      * @param view The desired content to display.
    949      * @param params Layout parameters for the view.
    950      */
    951     public abstract void addContentView(View view, ViewGroup.LayoutParams params);
    952 
    953     /**
    954      * Return the view in this Window that currently has focus, or null if
    955      * there are none.  Note that this does not look in any containing
    956      * Window.
    957      *
    958      * @return View The current View with focus or null.
    959      */
    960     public abstract View getCurrentFocus();
    961 
    962     /**
    963      * Quick access to the {@link LayoutInflater} instance that this Window
    964      * retrieved from its Context.
    965      *
    966      * @return LayoutInflater The shared LayoutInflater.
    967      */
    968     public abstract LayoutInflater getLayoutInflater();
    969 
    970     public abstract void setTitle(CharSequence title);
    971 
    972     public abstract void setTitleColor(int textColor);
    973 
    974     public abstract void openPanel(int featureId, KeyEvent event);
    975 
    976     public abstract void closePanel(int featureId);
    977 
    978     public abstract void togglePanel(int featureId, KeyEvent event);
    979 
    980     public abstract void invalidatePanelMenu(int featureId);
    981 
    982     public abstract boolean performPanelShortcut(int featureId,
    983                                                  int keyCode,
    984                                                  KeyEvent event,
    985                                                  int flags);
    986     public abstract boolean performPanelIdentifierAction(int featureId,
    987                                                  int id,
    988                                                  int flags);
    989 
    990     public abstract void closeAllPanels();
    991 
    992     public abstract boolean performContextMenuIdentifierAction(int id, int flags);
    993 
    994     /**
    995      * Should be called when the configuration is changed.
    996      *
    997      * @param newConfig The new configuration.
    998      */
    999     public abstract void onConfigurationChanged(Configuration newConfig);
   1000 
   1001     /**
   1002      * Change the background of this window to a Drawable resource. Setting the
   1003      * background to null will make the window be opaque. To make the window
   1004      * transparent, you can use an empty drawable (for instance a ColorDrawable
   1005      * with the color 0 or the system drawable android:drawable/empty.)
   1006      *
   1007      * @param resid The resource identifier of a drawable resource which will be
   1008      *              installed as the new background.
   1009      */
   1010     public void setBackgroundDrawableResource(int resid)
   1011     {
   1012         setBackgroundDrawable(mContext.getResources().getDrawable(resid));
   1013     }
   1014 
   1015     /**
   1016      * Change the background of this window to a custom Drawable. Setting the
   1017      * background to null will make the window be opaque. To make the window
   1018      * transparent, you can use an empty drawable (for instance a ColorDrawable
   1019      * with the color 0 or the system drawable android:drawable/empty.)
   1020      *
   1021      * @param drawable The new Drawable to use for this window's background.
   1022      */
   1023     public abstract void setBackgroundDrawable(Drawable drawable);
   1024 
   1025     /**
   1026      * Set the value for a drawable feature of this window, from a resource
   1027      * identifier.  You must have called requestFeauture(featureId) before
   1028      * calling this function.
   1029      *
   1030      * @see android.content.res.Resources#getDrawable(int)
   1031      *
   1032      * @param featureId The desired drawable feature to change, defined as a
   1033      * constant by Window.
   1034      * @param resId Resource identifier of the desired image.
   1035      */
   1036     public abstract void setFeatureDrawableResource(int featureId, int resId);
   1037 
   1038     /**
   1039      * Set the value for a drawable feature of this window, from a URI. You
   1040      * must have called requestFeature(featureId) before calling this
   1041      * function.
   1042      *
   1043      * <p>The only URI currently supported is "content:", specifying an image
   1044      * in a content provider.
   1045      *
   1046      * @see android.widget.ImageView#setImageURI
   1047      *
   1048      * @param featureId The desired drawable feature to change. Features are
   1049      * constants defined by Window.
   1050      * @param uri The desired URI.
   1051      */
   1052     public abstract void setFeatureDrawableUri(int featureId, Uri uri);
   1053 
   1054     /**
   1055      * Set an explicit Drawable value for feature of this window. You must
   1056      * have called requestFeature(featureId) before calling this function.
   1057      *
   1058      * @param featureId The desired drawable feature to change.
   1059      * Features are constants defined by Window.
   1060      * @param drawable A Drawable object to display.
   1061      */
   1062     public abstract void setFeatureDrawable(int featureId, Drawable drawable);
   1063 
   1064     /**
   1065      * Set a custom alpha value for the given drawale feature, controlling how
   1066      * much the background is visible through it.
   1067      *
   1068      * @param featureId The desired drawable feature to change.
   1069      * Features are constants defined by Window.
   1070      * @param alpha The alpha amount, 0 is completely transparent and 255 is
   1071      *              completely opaque.
   1072      */
   1073     public abstract void setFeatureDrawableAlpha(int featureId, int alpha);
   1074 
   1075     /**
   1076      * Set the integer value for a feature.  The range of the value depends on
   1077      * the feature being set.  For FEATURE_PROGRESSS, it should go from 0 to
   1078      * 10000. At 10000 the progress is complete and the indicator hidden.
   1079      *
   1080      * @param featureId The desired feature to change.
   1081      * Features are constants defined by Window.
   1082      * @param value The value for the feature.  The interpretation of this
   1083      *              value is feature-specific.
   1084      */
   1085     public abstract void setFeatureInt(int featureId, int value);
   1086 
   1087     /**
   1088      * Request that key events come to this activity. Use this if your
   1089      * activity has no views with focus, but the activity still wants
   1090      * a chance to process key events.
   1091      */
   1092     public abstract void takeKeyEvents(boolean get);
   1093 
   1094     /**
   1095      * Used by custom windows, such as Dialog, to pass the key press event
   1096      * further down the view hierarchy. Application developers should
   1097      * not need to implement or call this.
   1098      *
   1099      */
   1100     public abstract boolean superDispatchKeyEvent(KeyEvent event);
   1101 
   1102     /**
   1103      * Used by custom windows, such as Dialog, to pass the key shortcut press event
   1104      * further down the view hierarchy. Application developers should
   1105      * not need to implement or call this.
   1106      *
   1107      */
   1108     public abstract boolean superDispatchKeyShortcutEvent(KeyEvent event);
   1109 
   1110     /**
   1111      * Used by custom windows, such as Dialog, to pass the touch screen event
   1112      * further down the view hierarchy. Application developers should
   1113      * not need to implement or call this.
   1114      *
   1115      */
   1116     public abstract boolean superDispatchTouchEvent(MotionEvent event);
   1117 
   1118     /**
   1119      * Used by custom windows, such as Dialog, to pass the trackball event
   1120      * further down the view hierarchy. Application developers should
   1121      * not need to implement or call this.
   1122      *
   1123      */
   1124     public abstract boolean superDispatchTrackballEvent(MotionEvent event);
   1125 
   1126     /**
   1127      * Used by custom windows, such as Dialog, to pass the generic motion event
   1128      * further down the view hierarchy. Application developers should
   1129      * not need to implement or call this.
   1130      *
   1131      */
   1132     public abstract boolean superDispatchGenericMotionEvent(MotionEvent event);
   1133 
   1134     /**
   1135      * Retrieve the top-level window decor view (containing the standard
   1136      * window frame/decorations and the client's content inside of that), which
   1137      * can be added as a window to the window manager.
   1138      *
   1139      * <p><em>Note that calling this function for the first time "locks in"
   1140      * various window characteristics as described in
   1141      * {@link #setContentView(View, android.view.ViewGroup.LayoutParams)}.</em></p>
   1142      *
   1143      * @return Returns the top-level window decor view.
   1144      */
   1145     public abstract View getDecorView();
   1146 
   1147     /**
   1148      * Retrieve the current decor view, but only if it has already been created;
   1149      * otherwise returns null.
   1150      *
   1151      * @return Returns the top-level window decor or null.
   1152      * @see #getDecorView
   1153      */
   1154     public abstract View peekDecorView();
   1155 
   1156     public abstract Bundle saveHierarchyState();
   1157 
   1158     public abstract void restoreHierarchyState(Bundle savedInstanceState);
   1159 
   1160     protected abstract void onActive();
   1161 
   1162     /**
   1163      * Return the feature bits that are enabled.  This is the set of features
   1164      * that were given to requestFeature(), and are being handled by this
   1165      * Window itself or its container.  That is, it is the set of
   1166      * requested features that you can actually use.
   1167      *
   1168      * <p>To do: add a public version of this API that allows you to check for
   1169      * features by their feature ID.
   1170      *
   1171      * @return int The feature bits.
   1172      */
   1173     protected final int getFeatures()
   1174     {
   1175         return mFeatures;
   1176     }
   1177 
   1178     /**
   1179      * Query for the availability of a certain feature.
   1180      *
   1181      * @param feature The feature ID to check
   1182      * @return true if the feature is enabled, false otherwise.
   1183      */
   1184     public boolean hasFeature(int feature) {
   1185         return (getFeatures() & (1 << feature)) != 0;
   1186     }
   1187 
   1188     /**
   1189      * Return the feature bits that are being implemented by this Window.
   1190      * This is the set of features that were given to requestFeature(), and are
   1191      * being handled by only this Window itself, not by its containers.
   1192      *
   1193      * @return int The feature bits.
   1194      */
   1195     protected final int getLocalFeatures()
   1196     {
   1197         return mLocalFeatures;
   1198     }
   1199 
   1200     /**
   1201      * Set the default format of window, as per the PixelFormat types.  This
   1202      * is the format that will be used unless the client specifies in explicit
   1203      * format with setFormat();
   1204      *
   1205      * @param format The new window format (see PixelFormat).
   1206      *
   1207      * @see #setFormat
   1208      * @see PixelFormat
   1209      */
   1210     protected void setDefaultWindowFormat(int format) {
   1211         mDefaultWindowFormat = format;
   1212         if (!mHaveWindowFormat) {
   1213             final WindowManager.LayoutParams attrs = getAttributes();
   1214             attrs.format = format;
   1215             if (mCallback != null) {
   1216                 mCallback.onWindowAttributesChanged(attrs);
   1217             }
   1218         }
   1219     }
   1220 
   1221     /** @hide */
   1222     protected boolean haveDimAmount() {
   1223         return mHaveDimAmount;
   1224     }
   1225 
   1226     public abstract void setChildDrawable(int featureId, Drawable drawable);
   1227 
   1228     public abstract void setChildInt(int featureId, int value);
   1229 
   1230     /**
   1231      * Is a keypress one of the defined shortcut keys for this window.
   1232      * @param keyCode the key code from {@link android.view.KeyEvent} to check.
   1233      * @param event the {@link android.view.KeyEvent} to use to help check.
   1234      */
   1235     public abstract boolean isShortcutKey(int keyCode, KeyEvent event);
   1236 
   1237     /**
   1238      * @see android.app.Activity#setVolumeControlStream(int)
   1239      */
   1240     public abstract void setVolumeControlStream(int streamType);
   1241 
   1242     /**
   1243      * @see android.app.Activity#getVolumeControlStream()
   1244      */
   1245     public abstract int getVolumeControlStream();
   1246 
   1247     /**
   1248      * Set extra options that will influence the UI for this window.
   1249      * @param uiOptions Flags specifying extra options for this window.
   1250      */
   1251     public void setUiOptions(int uiOptions) { }
   1252 
   1253     /**
   1254      * Set extra options that will influence the UI for this window.
   1255      * Only the bits filtered by mask will be modified.
   1256      * @param uiOptions Flags specifying extra options for this window.
   1257      * @param mask Flags specifying which options should be modified. Others will remain unchanged.
   1258      */
   1259     public void setUiOptions(int uiOptions, int mask) { }
   1260 }
   1261