package com.smartisanos.sidebar; import java.util.HashSet; import java.util.Set; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.PixelFormat; import android.graphics.Point; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.onestep.IOneStep; import android.view.onestep.IOneStepStateObserver; import android.view.onestep.OneStepManager; import android.widget.FrameLayout; import com.smartisanos.sidebar.util.AppItem; import com.smartisanos.sidebar.util.AppManager; import com.smartisanos.sidebar.util.Constants; import com.smartisanos.sidebar.util.ContactManager; import com.smartisanos.sidebar.util.LOG; import com.smartisanos.sidebar.util.OngoingManager; import com.smartisanos.sidebar.util.RecentFileManager; import com.smartisanos.sidebar.util.RecentPhotoManager; import com.smartisanos.sidebar.util.ResolveInfoGroup; import com.smartisanos.sidebar.util.ResolveInfoManager; import com.smartisanos.sidebar.util.Tracker; import com.smartisanos.sidebar.util.Utils; import com.smartisanos.sidebar.util.anim.AnimStatusManager; import com.smartisanos.sidebar.view.ContentView; import com.smartisanos.sidebar.view.ContentView.ContentType; import com.smartisanos.sidebar.view.SideView; import com.smartisanos.sidebar.view.SidebarRootView; import com.smartisanos.sidebar.view.TopView; public class SidebarController { private static final LOG log = LOG.getInstance(SidebarController.class); private volatile static SidebarController sInstance; private Context mContext; private Handler mHandler; private WindowManager mWindowManager; private OneStepManager mOneStepManager; private SidebarRootView mSidebarRoot; private SideView mSideView; private TopView mTopView; private ContentView mContentView; private int mSidbarMode = SidebarMode.MODE_LEFT; private SidebarStatus mStatus = SidebarStatus.NORMAL; private float mRate = 1.0f; private int mScreenWidth, mScreenHeight; private int mSideViewWidth; private int mTopViewWidth, mTopViewHeight; private int mContentViewWidth, mContentViewHeight; public static SidebarController getInstance(Context context){ if(sInstance == null){ synchronized(SidebarController.class){ if(sInstance == null){ sInstance = new SidebarController(context); } } } return sInstance; } private SidebarController(Context context) { context = context.getApplicationContext(); mContext = context; mHandler = new Handler(Looper.getMainLooper()); mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); mOneStepManager = (OneStepManager) mContext.getSystemService(Context.ONE_STEP_SERVICE); Point pt = new Point(); mWindowManager.getDefaultDisplay().getSize(pt); mScreenWidth = pt.x; mScreenHeight = pt.y; mSideViewWidth = mContext.getResources().getDimensionPixelSize(R.dimen.sidebar_width); mRate = 1.0f - mSideViewWidth * 1.0f / mScreenWidth; mTopViewWidth = mScreenWidth - mSideViewWidth; mTopViewHeight = (int) (mScreenHeight * (1.0f - mRate)); mContentViewWidth = mScreenWidth - mSideViewWidth; mContentViewHeight = mScreenHeight - mTopViewHeight; boolean hasNavigationBar = mContext.getResources().getBoolean(com.android.internal.R.bool.config_showNavigationBar); // Allow a system property to override this. Used by the emulator. // See also hasNavigationBar(). String navBarOverride = SystemProperties.get("qemu.hw.mainkeys"); if ("1".equals(navBarOverride)) { hasNavigationBar = false; } else if ("0".equals(navBarOverride)) { hasNavigationBar = true; } if (hasNavigationBar) { mContentViewHeight += mContext.getResources().getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height); } } public void init() { AddWindows(); mOneStepManager.bindOneStepUI(mUIBinder); mOneStepManager.registerStateObserver(new OneStepManager.OneStepStateObserver() { @Override public void onExitOneStepMode() { stop(); } @Override public void onEnterOneStepMode(int state) { setSidebarMode(state); start(); } } , mHandler); AnimStatusManager.getInstance().addAnimFlagStatusChangedListener( AnimStatusManager.ENTER_ANIM_FLAG, new AnimStatusManager.AnimFlagStatusChangedListener() { @Override public void onChanged() { if (!AnimStatusManager.getInstance().isEnterAnimOngoing()) { onEnterAnimComplete(); } } }); IntentFilter closeSystemDialogFilter = new IntentFilter(); closeSystemDialogFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); mContext.registerReceiver(mBroadcastReceiver, closeSystemDialogFilter); // register receiver IntentFilter iconChangeFilter = new IntentFilter(); iconChangeFilter.addAction(ACTION_UPDATE_ICON); mContext.registerReceiver(mIconChangeReceiver, iconChangeFilter); } private void onSidebarModeChanged(){ if(mSideView != null){ mSideView.onSidebarModeChanged(); } } public void setSidebarMode(int mode){ if(mSidbarMode != mode){ mSidbarMode = mode; onSidebarModeChanged(); } } public int getSidebarMode(){ return mSidbarMode; } public void requestStatus(SidebarStatus status) { if (mStatus == status) { return; } mStatus = status; mTopView.requestStatus(mStatus); mSidebarRoot.requestStatus(mStatus); } public SidebarStatus getSidebarStatus() { return mStatus; } private void start(){ updateTopViewWindowBySidebarMode(); updateContentViewWindowBySidebarMode(); updateSideViewWindowBySidebarMode(); mTopView.show(true); mSidebarRoot.show(true); } public void onEnterAnimComplete() { RecentPhotoManager.getInstance(mContext).startObserver(); RecentFileManager.getInstance(mContext).startFileObserver(); } private void stop(){ AnimStatusManager.getInstance().reset(); mTopView.show(false); mSidebarRoot.show(false); dismissContent(false); RecentPhotoManager.getInstance(mContext).stopObserver(); RecentFileManager.getInstance(mContext).stopFileObserver(); mSideView.reportToTracker(); Tracker.flush(); } public void setEnabled(boolean enabled) { mSidebarRoot.setEnabled(enabled); mTopView.setEnabled(enabled); } private void AddWindows() { addTopViewWindow(); addContentViewWindow(); addSideViewWindow(); } public TopView getSidebarTopView() { return mTopView; } public SidebarRootView getSidebarRootView() { return mSidebarRoot; } public SideView getSideView() { return mSideView; } private void addSideViewWindow() { mSidebarRoot = (SidebarRootView) View.inflate(mContext, R.layout.sidebar_view, null); mSideView = (SideView) mSidebarRoot.findViewById(R.id.sidebar); final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SIDEBAR_TOOLS, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, PixelFormat.TRANSLUCENT); lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; lp.setTitle("sidebar_sideview"); lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; lp.packageName = mContext.getPackageName(); mSidebarRoot.setVisibility(View.GONE); mWindowManager.addView(mSidebarRoot, lp); } private void updateSideViewWindowBySidebarMode(){ final WindowManager.LayoutParams lp = (WindowManager.LayoutParams)mSidebarRoot.getLayoutParams(); if (getSidebarMode() == SidebarMode.MODE_LEFT) { lp.gravity = Gravity.LEFT | Gravity.FILL_VERTICAL; FrameLayout.LayoutParams llp = (FrameLayout.LayoutParams) mSideView .getLayoutParams(); llp.gravity = Gravity.LEFT | Gravity.FILL_VERTICAL; } else { // lp.windowAnimations = R.style.Animation_SidebarWindowRightAnim; lp.gravity = Gravity.RIGHT | Gravity.FILL_VERTICAL; FrameLayout.LayoutParams llp = (FrameLayout.LayoutParams) mSideView .getLayoutParams(); llp.gravity = Gravity.RIGHT | Gravity.FILL_VERTICAL; } mWindowManager.updateViewLayout(mSidebarRoot, lp); } public void updateDragWindow(boolean toFullScreen) { if (mSidebarRoot == null) { return; } final WindowManager.LayoutParams lp = (WindowManager.LayoutParams)mSidebarRoot.getLayoutParams(); if (toFullScreen) { if (mSidebarRoot.getTrash() == null) { log.error("updateDragWindow trash is null"); } else { mSidebarRoot.getTrash().initTrashView(); } lp.flags &= ~WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; lp.flags &= ~WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; mSidebarRoot.setBackgroundResource(R.color.sidebar_root_background); } else { if (mSidebarRoot.getTrash() != null) { mSidebarRoot.getTrash().hideTrashView(); } lp.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; lp.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; mSidebarRoot.setBackgroundResource(android.R.color.transparent); } mWindowManager.updateViewLayout(mSidebarRoot, lp); } private void addTopViewWindow() { mTopView = (TopView) View.inflate(mContext, R.layout.topbar_view, null); final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( mTopViewWidth, mTopViewHeight, WindowManager.LayoutParams.TYPE_SIDEBAR_TOOLS, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, PixelFormat.TRANSLUCENT); lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; lp.setTitle("sidebar_topview"); lp.packageName = mContext.getPackageName(); mTopView.setVisibility(View.GONE); mWindowManager.addView(mTopView, lp); } private void updateTopViewWindowBySidebarMode(){ final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mTopView.getLayoutParams(); if (getSidebarMode() == SidebarMode.MODE_LEFT) { lp.gravity = Gravity.TOP | Gravity.RIGHT; } else { lp.gravity = Gravity.TOP | Gravity.LEFT; } mWindowManager.updateViewLayout(mTopView, lp); } public void addContentViewWindow() { mContentView = (ContentView) View.inflate(mContext, R.layout.content_view, null); final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( mContentViewWidth, mContentViewHeight, WindowManager.LayoutParams.TYPE_SIDEBAR_TOOLS, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, PixelFormat.TRANSLUCENT); lp.setTitle("sidebar_contentview"); lp.packageName = mContext.getPackageName(); lp.isEatHomeKey = true; mContentView.setVisibility(View.GONE); mWindowManager.addView(mContentView, lp); } private void updateContentViewWindowBySidebarMode() { final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mContentView.getLayoutParams(); if (getSidebarMode() == SidebarMode.MODE_LEFT) { lp.gravity = Gravity.BOTTOM | Gravity.RIGHT; } else { lp.gravity = Gravity.BOTTOM | Gravity.LEFT; } mWindowManager.updateViewLayout(mContentView, lp); } public ContentType getCurrentContentType(){ return mContentView.getCurrentContent(); } public void showContent(ContentType ct) { mContentView.show(ct, true); } public void dismissContent(boolean anim) { mContentView.dismiss(mContentView.getCurrentContent(), anim); } public void resumeTopView(){ if (mTopView != null) { mTopView.resumeToNormal(); } } public void refreshCalendarView() { for (AppItem item : AppManager.getInstance(mContext).getAddedAppItem()) { if (Constants.CALENDAR_PACKAGE.equals(item.getPackageName())) { item.clearAvatarCache(); } } for (ResolveInfoGroup info : ResolveInfoManager.getInstance(mContext).getAddedResolveInfoGroup()) { if (Constants.CALENDAR_PACKAGE.equals(info.getPackageName())) { info.clearAvatarCache(); } } getSideView().notifyDataSetChanged(); } private final IOneStep.Stub mUIBinder = new IOneStep.Stub() { @Override public void updateOngoing(ComponentName name, int token, int pendingNumbers, CharSequence title, int pid) throws RemoteException { OngoingManager.getInstance(mContext).updateOngoing(name, token, pendingNumbers, title, pid); } @Override public void setEnabled(final boolean enabled) throws RemoteException { mHandler.post(new Runnable(){ @Override public void run() { SidebarController.this.setEnabled(enabled); } }); } @Override public void resumeOneStep() throws RemoteException { mHandler.post(new Runnable(){ @Override public void run() { Utils.resumeSidebar(mContext); } }); } }; private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { Utils.resumeSidebar(context); } } }; private static final String ACTION_UPDATE_ICON = "com.smartisanos.launcher.update_icon"; private static final String EXTRA_PACKAGENAME = "extra_packagename"; private BroadcastReceiver mIconChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (ACTION_UPDATE_ICON.equals(action)) { String packageNames = intent.getStringExtra(EXTRA_PACKAGENAME); if (packageNames != null) { String[] packagearr = packageNames.split(","); if (packagearr != null) { Set<String> packages = new HashSet<String>(); for (String pkg : packagearr) { packages.add(pkg); } ResolveInfoManager.getInstance(mContext).onIconChanged(packages); AppManager.getInstance(mContext).onIconChanged(packages); } } } } }; }