com.appsimobile.appsii.HotspotHelperImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.appsimobile.appsii.HotspotHelperImpl.java

Source

/*
 * Copyright 2015. Appsi Mobile
 *
 * 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.appsimobile.appsii;

import android.Manifest;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.util.CircularArray;
import android.support.v4.util.LongSparseArray;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;

import com.appsimobile.appsii.SidebarHotspot.SidebarGestureCallback;
import com.appsimobile.appsii.permissions.PermissionUtils;
import com.crashlytics.android.Crashlytics;

import javax.inject.Inject;
import javax.inject.Singleton;

@Singleton
public class HotspotHelperImpl extends AbstractHotspotHelper
        implements OnClickListener, View.OnLongClickListener, SidebarGestureCallback, SidebarHotspot.SwipeListener {

    private static final String TAG = "HotspotHelperImpl";

    final int[] mOffsetInt = new int[2];
    final PopupLayer mPopupLayer;
    final LayoutInflater mLayoutInflater;
    final View mFullScreenWatcher;
    final WindowManager mWindowManager;
    final PermissionUtils mPermissionUtils;
    final SharedPreferences mSharedPreferences;
    private final Context mContext;
    private final LongSparseArray<HotspotContainerHelper> mSidebarHotspots = new LongSparseArray<>();
    HotspotHelperListener mCallback;
    boolean mDraggingHotspot;
    int mDragLocalX;
    int mRawStartDragY;
    int mDragLocalY;
    boolean mIsLeftHotspot;
    int mHotspotX;
    int mHotspotY;
    boolean mFullScreenWatcherAttached;
    private boolean mVibrateOnTouch;
    private boolean mHotspotsActive;
    private CircularArray<HotspotItem> mHotspotItems;

    @Inject
    public HotspotHelperImpl(Context context, SharedPreferences sharedPreferences, PermissionUtils permissionUtils,
            WindowManager windowManager, PopupLayer popupLayer) {
        super(context, windowManager);

        mWindowManager = windowManager;
        mSharedPreferences = sharedPreferences;
        mPermissionUtils = permissionUtils;
        mLayoutInflater = LayoutInflater.from(context);
        mPopupLayer = popupLayer;
        mContext = context;
        mVibrateOnTouch = mSharedPreferences.getBoolean("pref_sidebar_haptic_feedback", false);
        mFullScreenWatcher = new View(context) {
            {
                setFitsSystemWindows(true);
            }

        };
    }

    public static boolean isPageGesture(String stringUri) {
        if (stringUri == null)
            return false;
        Uri uri = Uri.parse(stringUri);
        return isPageGesture(uri);
    }

    public static boolean isPageGesture(Uri uri) {
        if (uri == null)
            return false;
        return true;
    }

    @Override
    public void setCallback(HotspotHelperListener callback) {
        mCallback = callback;
    }

    @Override
    public void onOrientationChanged() {
        if (mHotspotsActive) {
            updateHotspotLayoutParams();
        }
    }

    @Override
    public void onDestroy() {
        removeHotspots();
    }

    @Override
    public void setVibrate(boolean vibrate) {
        int count = mSidebarHotspots.size();
        mVibrateOnTouch = vibrate;
        for (int i = 0; i < count; i++) {
            HotspotContainerHelper sidebarHotspot = mSidebarHotspots.valueAt(i);
            sidebarHotspot.setVibrateOnTouch(vibrate);
        }
    }

    @Override
    public void addHotspots() throws PermissionDeniedException {
        Log.d(TAG, "addHotspots() called with: " + "");
        try {
            removeHotspots();
            mHotspotsActive = true;
            if (mHotspotItems != null) {
                int count = mHotspotItems.size();
                SharedPreferences prefs = mSharedPreferences;
                for (int i = 0; i < count; i++) {
                    HotspotItem conf = mHotspotItems.get(i);

                    HotspotContainerHelper hotspotContainerHelper = mSidebarHotspots.get(conf.mId);
                    boolean isAdded = hotspotContainerHelper != null;
                    if (!isAdded) {
                        hotspotContainerHelper = createSidebarHotspot();
                    }
                    hotspotContainerHelper.bind(conf);

                    mSidebarHotspots.put(conf.mId, hotspotContainerHelper);

                    if (!isAdded) {
                        WindowManager.LayoutParams lp = configureHotspot(hotspotContainerHelper, conf, prefs);
                        try {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                                    && !Settings.canDrawOverlays(mContext)) {

                                throw new PermissionDeniedException(Manifest.permission.SYSTEM_ALERT_WINDOW);
                            }

                            mWindowManager.addView(hotspotContainerHelper.mHotspotParent, lp);
                        } catch (PermissionDeniedException e) {
                            throw e;
                        } catch (Exception e) {
                            Log.w("HotspotHelperImpl", "error adding hotspot", e);
                            Crashlytics.logException(e);
                        }
                    }
                }
            }
            addScreenWatcher();
        } catch (PermissionDeniedException e) {
            mHotspotsActive = false;
        }
    }

    private HotspotContainerHelper createSidebarHotspot() {
        View result = mLayoutInflater.inflate(R.layout.hotspot, null);

        HotspotContainerHelper helper = new HotspotContainerHelper(result,
                (SidebarHotspot) result.findViewById(R.id.sidebar_hotspot));

        helper.setOnClickListener(this);
        helper.setOnLongClickListener(this);
        helper.setVibrateOnTouch(mVibrateOnTouch);
        helper.setCallback(this);
        return helper;
    }

    private void addScreenWatcher() throws PermissionDeniedException {
        if (!mPermissionUtils.canDrawOverlays(mContext)) {
            throw new PermissionDeniedException(Manifest.permission.SYSTEM_ALERT_WINDOW);
        }

        mWindowManager.addView(mFullScreenWatcher, createInsetParams());
        mFullScreenWatcherAttached = true;
    }

    @Override
    public void removeHotspots() {
        int count = mSidebarHotspots.size();
        for (int i = count - 1; i >= 0; i--) {
            HotspotContainerHelper hotspotContainerHelper = mSidebarHotspots.valueAt(i);
            SidebarHotspot sidebarHotspot = hotspotContainerHelper.mSidebarHotspot;
            View sidebarParent = hotspotContainerHelper.mHotspotParent;
            if (!sidebarHotspot.mIsDragOpening) {
                if (sidebarParent.getParent() != null) {
                    mWindowManager.removeView(sidebarParent);
                }
                hotspotContainerHelper.setOnClickListener(null);
                hotspotContainerHelper.setOnLongClickListener(null);
                hotspotContainerHelper.setCallback(null);
                long id = sidebarHotspot.getConfiguration().mId;
                mSidebarHotspots.remove(id);
            }
        }
        removeScreenWatcher();
        mHotspotsActive = false;
    }

    @Override
    public void onHotspotsLoaded(CircularArray<HotspotItem> configurations) {
        mHotspotItems = configurations;
    }

    @Override
    public int getTopOffset() {
        mOffsetInt[1] = -1;
        mFullScreenWatcher.getLocationOnScreen(mOffsetInt);
        return mOffsetInt[1];
    }

    private void removeScreenWatcher() {
        if (mFullScreenWatcherAttached) {
            mWindowManager.removeView(mFullScreenWatcher);
            mFullScreenWatcherAttached = false;
        }
    }

    public void updateHotspotLayoutParams() {
        if (!mHotspotsActive)
            return;

        if (mHotspotItems != null) {
            int count = mHotspotItems.size();
            SharedPreferences prefs = mSharedPreferences;
            for (int i = 0; i < count; i++) {
                HotspotItem conf = mHotspotItems.get(i);

                HotspotContainerHelper hotspotContainerHelper = mSidebarHotspots.get(conf.mId);
                boolean isAdded = hotspotContainerHelper != null;
                if (!isAdded) {
                    continue;
                }

                WindowManager.LayoutParams lp = configureHotspot(hotspotContainerHelper, conf, prefs);
                try {
                    mWindowManager.updateViewLayout(hotspotContainerHelper.mHotspotParent, lp);
                } catch (Exception e) {
                    Log.w("HotspotHelperImpl", "error adding hotspot", e);
                }
            }
        }
    }

    private WindowManager.LayoutParams configureHotspot(HotspotContainerHelper hotspot, HotspotItem hotspotItem,
            SharedPreferences prefs) {
        WindowManager.LayoutParams lp = createHotspotParams(hotspotItem, prefs);
        hotspot.mSidebarHotspot.setPosition(hotspotItem.mLeft, -lp.width, lp.y);
        return lp;
    }

    @Override
    public void onClick(View v) {
        // We can implement some feature here !
    }

    public boolean onLongClick(View v) {
        return true;
    }

    @Override
    public SidebarHotspot.SwipeListener open(SidebarHotspot hotspot, SidebarHotspot.Gesture action, int x, int y) {
        mIsLeftHotspot = hotspot.isLeft();
        mHotspotX = hotspot.getHPos();
        mHotspotY = hotspot.getVPos();
        HotspotItem conf = hotspot.getConfiguration();
        if (action == SidebarHotspot.Gesture.TAP) {
            //return mCallback.openSidebar(conf, null, 0);
            return null;
        } else {
            CircularArray<HotspotPageEntry> entries = hotspot.getHotspotPageEntries();
            return mCallback.openSidebar(conf, entries, Appsi.OPEN_FLAG_LIKE_NOTIFICATION_BAR);
        }
    }

    @Override
    public void cancelVisualHints(SidebarHotspot sidebarHotspot) {
        mCallback.cancelVisualHints();
    }

    @Override
    public SidebarHotspot.SwipeListener longPressGesturePerformed(SidebarHotspot hotspot, int startX, int startY,
            int rawStartY) {
        return null;
    }

    @Override
    public void removeIfNeeded(SidebarHotspot hotspot) {
        if (!mHotspotsActive) {
            HotspotItem configuration = hotspot.getConfiguration();
            HotspotContainerHelper added = mSidebarHotspots.get(configuration.mId);
            if (added.isHotspot(hotspot)) {
                removeHotspots();
            }
        }
    }

    @Override
    public void setSwipeLocation(SidebarHotspot hotspot, int localX, int localY, int rawX, int rawY) {
        WindowManager wm = mWindowManager;
        Display display = wm.getDefaultDisplay();
        int width = display.getWidth();
        if (mDraggingHotspot) {
            boolean left = rawX < width / 2;
            int deltaY = mRawStartDragY - rawY;
            setSwipeLocationForHotspotDrag(hotspot, localX, deltaY, left);
        }
    }

    @Override
    public void onSwipeEnd(SidebarHotspot hotspot, int screenX, int screenY, boolean cancelled,
            VelocityTracker velocityTracker) {

    }

    private void setSwipeLocationForHotspotDrag(SidebarHotspot hotspot, int localX, int deltaY, boolean left) {
        long id = hotspot.getHotspotId();
        HotspotContainerHelper helper = mSidebarHotspots.get(id);
        WindowManager wm = mWindowManager;
        WindowManager.LayoutParams params = (WindowManager.LayoutParams) helper.mHotspotParent.getLayoutParams();
        int y = mHotspotY - deltaY;
        params = updateLayoutParams(left, y, params);
        wm.updateViewLayout(helper.mHotspotParent, params);
    }

    static class HotspotContainerHelper {

        final View mHotspotParent;

        final SidebarHotspot mSidebarHotspot;

        HotspotContainerHelper(View hotspotParent, SidebarHotspot sidebarHotspot) {
            mHotspotParent = hotspotParent;
            mSidebarHotspot = sidebarHotspot;
        }

        public boolean isHotspot(SidebarHotspot hotspot) {
            return hotspot == mSidebarHotspot;
        }

        public void setVibrateOnTouch(boolean vibrate) {
            mSidebarHotspot.setVibrateOnTouch(vibrate);
        }

        public void setOnClickListener(HotspotHelperImpl appsiHotspotHelper) {
            mSidebarHotspot.setOnClickListener(appsiHotspotHelper);
        }

        public void setOnLongClickListener(HotspotHelperImpl appsiHotspotHelper) {
            mSidebarHotspot.setOnLongClickListener(appsiHotspotHelper);
        }

        public void setCallback(HotspotHelperImpl appsiHotspotHelper) {
            mSidebarHotspot.setCallback(appsiHotspotHelper);
        }

        public void bind(HotspotItem conf) {
            mSidebarHotspot.bind(conf);
        }
    }

}