package org.exalm.tabletkat.recent;
import android.animation.Animator;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import org.exalm.tabletkat.SystemR;
import org.exalm.tabletkat.TabletKatModule;
import org.exalm.tabletkat.TkR;
import org.exalm.tabletkat.statusbar.tablet.TabletStatusBarMod;
import java.util.ArrayList;
import de.robv.android.xposed.XposedHelpers;
public class RecentsPanel {
public static final boolean DEBUG = false;
public static final String TAG = "RecentsPanel";
protected static final int MSG_CLOSE_RECENTS_PANEL = 1021;
protected FrameLayout mRecentsPanel;
protected Choreographer mChoreo;
protected Object mRecentTasksLoader;
protected Context mContext;
protected WindowManager mWindowManager;
protected Object mBar;
protected TabletStatusBarMod mMod;
boolean useTabletLayout;
private boolean mVisible;
public RecentsPanel(Object bar, TabletStatusBarMod mod, boolean useTabletLayout) {
mBar = bar;
mMod = mod;
mContext = (Context) XposedHelpers.getObjectField(mBar, "mContext");
mWindowManager = (WindowManager) XposedHelpers.getObjectField(mBar, "mWindowManager");
mRecentTasksLoader = XposedHelpers.callStaticMethod(TabletKatModule.mRecentTasksLoaderClass, "getInstance", mContext);
this.useTabletLayout = useTabletLayout;
updateRecentsPanel();
}
public void destroy() {
mWindowManager.removeView(mRecentsPanel);
}
protected WindowManager.LayoutParams getRecentsLayoutParams(
ViewGroup.LayoutParams layoutParams) {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
useTabletLayout ? (int) mContext.getResources().getDimension(TkR.dimen.system_bar_recents_width) :
layoutParams.width,
useTabletLayout ? WindowManager.LayoutParams.MATCH_PARENT : layoutParams.height,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
if (useTabletLayout || ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
} else {
lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
lp.dimAmount = 0.75f;
}
lp.gravity = Gravity.BOTTOM | Gravity.START;
lp.setTitle("RecentsPanel");
lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
return lp;
}
protected void updateRecentsPanel(int recentsResId) {
// Recents Panel
boolean visible = false;
ArrayList recentTasksList = null;
boolean firstScreenful = false;
if (mRecentsPanel != null) {
visible = mRecentsPanel.getVisibility() == View.VISIBLE;
mWindowManager.removeView(mRecentsPanel);
recentTasksList = (ArrayList) XposedHelpers.getObjectField(mRecentsPanel, "mRecentTaskDescriptions");
firstScreenful = XposedHelpers.getBooleanField(mRecentTasksLoader, "mFirstScreenful");
}
// Provide RecentsPanelView with a temporary parent to allow layout params to work.
LinearLayout tmpRoot = new LinearLayout(mContext);
mRecentsPanel = (FrameLayout) LayoutInflater.from(mContext).inflate(
recentsResId, tmpRoot, false);
createChoreo();
XposedHelpers.setObjectField(mRecentsPanel, "mRecentTasksLoader", mRecentTasksLoader);
XposedHelpers.callMethod(mRecentTasksLoader, "cancelLoadingThumbnailsAndIcons");
XposedHelpers.callMethod(mRecentTasksLoader, "setRecentsPanel", mRecentsPanel, mRecentsPanel);
mRecentsPanel.setOnTouchListener(
new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL, mRecentsPanel));
if (!visible) {
mRecentsPanel.setVisibility(View.GONE);
}
WindowManager.LayoutParams lp = getRecentsLayoutParams(mRecentsPanel.getLayoutParams());
mWindowManager.addView(mRecentsPanel, lp);
if (visible) {
XposedHelpers.callMethod(mRecentsPanel, "show", true, recentTasksList, firstScreenful, false);
} else {
XposedHelpers.callMethod(mRecentsPanel, "refreshRecentTasksList", recentTasksList, firstScreenful);
}
}
public void updateRecentsPanel() {
if (useTabletLayout) {
updateRecentsPanel(TkR.layout.system_bar_recent_panel);
return;
}
updateRecentsPanel(SystemR.layout.status_bar_recent_panel);
// Make .03 alpha the minimum so you always see the item a bit-- slightly below
// .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
// a bit jarring
XposedHelpers.callMethod(mRecentsPanel, "setMinSwipeAlpha", 0.03f);
}
public void toggleRecentsActivity() {
if (mRecentsPanel != null) {
boolean b = mRecentsPanel.getVisibility() == View.VISIBLE;
//TODO: Somehow handle the situation when the task list is null
XposedHelpers.callMethod(mRecentsPanel, "show", !b, null, true, true);
}
}
public void preloadRecentTasksList() {
XposedHelpers.callMethod(mRecentTasksLoader, "preloadRecentTasksList");
}
public void cancelPreloadingRecentTasksList() {
XposedHelpers.callMethod(mRecentTasksLoader, "cancelPreloadingRecentTasksList");
}
public void closeRecents() {
if (mRecentsPanel != null) {
XposedHelpers.callMethod(mRecentsPanel, "show", false);
}
}
public void setVisibility(boolean show, boolean animate) {
if (animate) {
if (mVisible != show) {
mVisible = show;
if (show) {
mRecentsPanel.setVisibility(View.VISIBLE);
}
mChoreo.startAnimation(show);
}
} else {
mVisible = show;
mRecentsPanel.setVisibility(show ? View.VISIBLE : View.GONE);
mChoreo.jumpTo(show);
XposedHelpers.callMethod(mRecentsPanel, "onAnimationEnd",
new Class[]{Animator.class}, new Object[]{null});
}
if (mMod != null) {
mMod.setOverlayRecentsVisible(mVisible);
}
if (TabletKatModule.mPhoneStatusBarClass.isInstance(mBar)) {
XposedHelpers.callMethod(mBar, "checkBarModes");
}
}
public boolean isVisible() {
return mVisible;
}
public void onLayout() {
View v = (View) XposedHelpers.getObjectField(mRecentsPanel, "mRecentsContainer");
mChoreo.setPanelHeight(v.getHeight());
}
public void createChoreo() {
View mRecentsScrim = (View) XposedHelpers.getObjectField(mRecentsPanel, "mRecentsScrim");
View mRecentsContainer = (View) XposedHelpers.getObjectField(mRecentsPanel, "mRecentsContainer");
View mRecentsNoApps = (View) XposedHelpers.getObjectField(mRecentsPanel, "mRecentsNoApps");
mChoreo = new Choreographer(mRecentsPanel, mRecentsScrim, mRecentsContainer, mRecentsNoApps,
(Animator.AnimatorListener) mRecentsPanel, useTabletLayout);
}
public class TouchOutsideListener implements View.OnTouchListener {
private int mMsg;
private View mPanel;
public TouchOutsideListener(int msg, View panel) {
mMsg = msg;
mPanel = panel;
}
public boolean onTouch(View v, MotionEvent ev) {
final int action = ev.getAction();
if (action == MotionEvent.ACTION_OUTSIDE
|| (action == MotionEvent.ACTION_DOWN
&& !(Boolean) XposedHelpers.callMethod(mPanel, "isInContentArea", (int)ev.getX(), (int)ev.getY()))) {
Handler mHandler = (Handler) XposedHelpers.getObjectField(mBar, "mHandler");
mHandler.removeMessages(mMsg);
mHandler.sendEmptyMessage(mMsg);
return true;
}
return false;
}
}
}