/* * Copyright (C) 2015 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 com.android.systemui.stackdivider; import android.content.res.Configuration; import android.os.RemoteException; import android.view.IDockedStackListener; import android.view.LayoutInflater; import android.view.View; import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.recents.Recents; import com.android.systemui.recents.misc.SystemServicesProxy; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import java.io.FileDescriptor; import java.io.PrintWriter; /** * Controls the docked stack divider. */ public class Divider extends SystemUI { private DividerWindowManager mWindowManager; private DividerView mView; private final DividerState mDividerState = new DividerState(); private DockDividerVisibilityListener mDockDividerVisibilityListener; private boolean mVisible = false; private boolean mMinimized = false; private boolean mAdjustedForIme = false; private ForcedResizableInfoActivityController mForcedResizableController; @Override public void start() { mWindowManager = new DividerWindowManager(mContext); update(mContext.getResources().getConfiguration()); putComponent(Divider.class, this); mDockDividerVisibilityListener = new DockDividerVisibilityListener(); SystemServicesProxy ssp = Recents.getSystemServices(); ssp.registerDockedStackListener(mDockDividerVisibilityListener); mForcedResizableController = new ForcedResizableInfoActivityController(mContext); } @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); update(newConfig); } public DividerView getView() { return mView; } private void addDivider(Configuration configuration) { mView = (DividerView) LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null); mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE); final int size = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.docked_stack_divider_thickness); final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE; final int width = landscape ? size : MATCH_PARENT; final int height = landscape ? MATCH_PARENT : size; mWindowManager.add(mView, width, height); mView.injectDependencies(mWindowManager, mDividerState); } private void removeDivider() { mWindowManager.remove(); } private void update(Configuration configuration) { removeDivider(); addDivider(configuration); if (mMinimized) { mView.setMinimizedDockStack(true); updateTouchable(); } } private void updateVisibility(final boolean visible) { mView.post(new Runnable() { @Override public void run() { if (mVisible != visible) { mVisible = visible; mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); // Update state because animations won't finish. mView.setMinimizedDockStack(mMinimized); } } }); } private void updateMinimizedDockedStack(final boolean minimized, final long animDuration) { mView.post(new Runnable() { @Override public void run() { if (mMinimized != minimized) { mMinimized = minimized; updateTouchable(); if (animDuration > 0) { mView.setMinimizedDockStack(minimized, animDuration); } else { mView.setMinimizedDockStack(minimized); } } } }); } private void notifyDockedStackExistsChanged(final boolean exists) { mView.post(new Runnable() { @Override public void run() { mForcedResizableController.notifyDockedStackExistsChanged(exists); } }); } private void updateTouchable() { mWindowManager.setTouchable(!mMinimized && !mAdjustedForIme); } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.print(" mVisible="); pw.println(mVisible); pw.print(" mMinimized="); pw.println(mMinimized); pw.print(" mAdjustedForIme="); pw.println(mAdjustedForIme); } class DockDividerVisibilityListener extends IDockedStackListener.Stub { @Override public void onDividerVisibilityChanged(boolean visible) throws RemoteException { updateVisibility(visible); } @Override public void onDockedStackExistsChanged(boolean exists) throws RemoteException { notifyDockedStackExistsChanged(exists); } @Override public void onDockedStackMinimizedChanged(boolean minimized, long animDuration) throws RemoteException { updateMinimizedDockedStack(minimized, animDuration); } @Override public void onAdjustedForImeChanged(boolean adjustedForIme, long animDuration) throws RemoteException { mView.post(() -> { if (mAdjustedForIme != adjustedForIme) { mAdjustedForIme = adjustedForIme; updateTouchable(); if (!mMinimized) { if (animDuration > 0) { mView.setAdjustedForIme(adjustedForIme, animDuration); } else { mView.setAdjustedForIme(adjustedForIme); } } } }); } @Override public void onDockSideChanged(final int newDockSide) throws RemoteException { mView.post(() -> mView.notifyDockSideChanged(newDockSide)); } } }