content: /*
   * 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.
   */
  
  package android.view;
  
  import android.annotation.NonNull;
  import android.annotation.UnsupportedAppUsage;
  import android.content.Context;
  import android.graphics.Region;
  import android.os.Bundle;
  import android.os.IBinder;
  import android.os.RemoteException;
  
  import com.android.internal.os.IResultReceiver;
  
  import java.util.List;
  
  /**
   * Provides low-level communication with the system window manager for
   * operations that are bound to a particular context, display or parent window.
   * Instances of this object are sensitive to the compatibility info associated
   * with the running application.
   *
   * This object implements the {@link ViewManager} interface,
   * allowing you to add any View subclass as a top-level window on the screen.
   * Additional window manager specific layout parameters are defined for
   * control over how windows are displayed.  It also implements the {@link WindowManager}
   * interface, allowing you to control the displays attached to the device.
   *
   * <p>Applications will not normally use WindowManager directly, instead relying
   * on the higher-level facilities in {@link android.app.Activity} and
   * {@link android.app.Dialog}.
   *
   * <p>Even for low-level window manager access, it is almost never correct to use
   * this class.  For example, {@link android.app.Activity#getWindowManager}
   * provides a window manager for adding windows that are associated with that
   * activity -- the window manager will not normally allow you to add arbitrary
   * windows that are not associated with an activity.
   *
   * @see WindowManager
   * @see WindowManagerGlobal
   * @hide
   */
  public final class WindowManagerImpl implements WindowManager {
      @UnsupportedAppUsage
      private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
      private final Context mContext;
      private final Window mParentWindow;
  
      private IBinder mDefaultToken;
  
      public WindowManagerImpl(Context context) {
          this(context, null);
      }
  
      private WindowManagerImpl(Context context, Window parentWindow) {
          mContext = context;
          mParentWindow = parentWindow;
      }
  
      public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
          return new WindowManagerImpl(mContext, parentWindow);
      }
  
      public WindowManagerImpl createPresentationWindowManager(Context displayContext) {
          return new WindowManagerImpl(displayContext, mParentWindow);
      }
  
      /**
       * Sets the window token to assign when none is specified by the client or
       * available from the parent window.
       *
       * @param token The default token to assign.
       */
      public void setDefaultToken(IBinder token) {
          mDefaultToken = token;
      }
  
      @Override
      public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
          applyDefaultToken(params);
          mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
      }
  
      @Override
      public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
          applyDefaultToken(params);
          mGlobal.updateViewLayout(view, params);
      }
  
      private void applyDefaultToken(@NonNull ViewGroup.LayoutParams params) {
          // Only use the default token if we don't have a parent window.
          if (mDefaultToken != null && mParentWindow == null) {
              if (!(params instanceof WindowManager.LayoutParams)) {
                  throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
              }
  
              // Only use the default token if we don't already have a token.
              final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
              if (wparams.token == null) {
                  wparams.token = mDefaultToken;
              }
          }
      }
  
      @Override
      public void removeView(View view) {
          mGlobal.removeView(view, false);
      }
  
      @Override
      public void removeViewImmediate(View view) {
          mGlobal.removeView(view, true);
      }
  
      @Override
      public void requestAppKeyboardShortcuts(
              final KeyboardShortcutsReceiver receiver, int deviceId) {
          IResultReceiver resultReceiver = new IResultReceiver.Stub() {
              @Override
              public void send(int resultCode, Bundle resultData) throws RemoteException {
                  List<KeyboardShortcutGroup> result =
                          resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY);
                  receiver.onKeyboardShortcutsReceived(result);
              }
          };
          try {
              WindowManagerGlobal.getWindowManagerService()
                  .requestAppKeyboardShortcuts(resultReceiver, deviceId);
          } catch (RemoteException e) {
          }
      }
  
      @Override
      public Display getDefaultDisplay() {
          return mContext.getDisplay();
      }
  
      @Override
      public Region getCurrentImeTouchRegion() {
          try {
              return WindowManagerGlobal.getWindowManagerService().getCurrentImeTouchRegion();
          } catch (RemoteException e) {
          }
          return null;
      }
  
      @Override
      public void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow) {
          try {
              WindowManagerGlobal.getWindowManagerService()
                      .setShouldShowWithInsecureKeyguard(displayId, shouldShow);
          } catch (RemoteException e) {
          }
      }
  
      @Override
      public void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
          try {
              WindowManagerGlobal.getWindowManagerService()
                      .setShouldShowSystemDecors(displayId, shouldShow);
          } catch (RemoteException e) {
          }
      }
  
      @Override
      public boolean shouldShowSystemDecors(int displayId) {
          try {
              return WindowManagerGlobal.getWindowManagerService().shouldShowSystemDecors(displayId);
          } catch (RemoteException e) {
          }
          return false;
      }
  
      @Override
      public void setShouldShowIme(int displayId, boolean shouldShow) {
          try {
              WindowManagerGlobal.getWindowManagerService().setShouldShowIme(displayId, shouldShow);
          } catch (RemoteException e) {
          }
      }
  
      @Override
      public boolean shouldShowIme(int displayId) {
          try {
              return WindowManagerGlobal.getWindowManagerService().shouldShowIme(displayId);
          } catch (RemoteException e) {
          }
          return false;
      }
  }
  