T $(int id) {
- return ViewTool.$(mView, id);
+ return ViewUtil.$(mView, id);
}
public View findViewById(int id) {
diff --git a/app/src/main/java/com/stardust/app/SimpleActivityLifecycleCallbacks.java b/app/src/main/java/com/stardust/app/SimpleActivityLifecycleCallbacks.java
new file mode 100644
index 000000000..ddf1e8fb2
--- /dev/null
+++ b/app/src/main/java/com/stardust/app/SimpleActivityLifecycleCallbacks.java
@@ -0,0 +1,47 @@
+package com.stardust.app;
+
+import android.app.Activity;
+import android.app.Application;
+import android.os.Bundle;
+
+/**
+ * Created by Stardust on 2017/4/2.
+ */
+
+public class SimpleActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
+
+ @Override
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+
+ }
+
+ @Override
+ public void onActivityStarted(Activity activity) {
+
+ }
+
+ @Override
+ public void onActivityResumed(Activity activity) {
+
+ }
+
+ @Override
+ public void onActivityPaused(Activity activity) {
+
+ }
+
+ @Override
+ public void onActivityStopped(Activity activity) {
+
+ }
+
+ @Override
+ public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
+
+ }
+
+ @Override
+ public void onActivityDestroyed(Activity activity) {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/stardust/hover/HoverMenuService.java b/app/src/main/java/com/stardust/hover/HoverMenuService.java
deleted file mode 100644
index e3106cf45..000000000
--- a/app/src/main/java/com/stardust/hover/HoverMenuService.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package com.stardust.hover;
-
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.IBinder;
-import android.support.annotation.Nullable;
-import android.util.Log;
-
-import io.mattcarroll.hover.HoverMenu;
-import io.mattcarroll.hover.HoverMenuAdapter;
-import io.mattcarroll.hover.Navigator;
-
-/**
- * Created by Stardust on 2017/3/11.
- */
-
-public abstract class HoverMenuService extends Service {
-
- private static final String TAG = "HoverMenuService";
-
- private static final String PREF_FILE = "hover_menu";
- private static final String PREF_HOVER_MENU_VISUAL_STATE = "hover_menu_visual_state";
-
-
- private HoverMenu mHoverMenu;
- private boolean mIsRunning;
- private SharedPreferences mPrefs;
- private HoverMenu.OnExitListener mWindowHoverMenuMenuExitListener = new HoverMenu.OnExitListener() {
- @Override
- public void onExitByUserRequest() {
- Log.d(TAG, "Menu exit requested.");
- savePreferredLocation();
- mHoverMenu.hide();
- onHoverMenuExitingByUserRequest();
- stopSelf();
- }
- };
-
- @Override
- public void onCreate() {
- Log.d(TAG, "onCreate()");
- mPrefs = getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
-
- mHoverMenu = new HoverMenuBuilder(getContextForHoverMenu())
- .displayWithinWindow()
- .useNavigator(createNavigator())
- .useAdapter(createHoverMenuAdapter())
- .restoreVisualState(loadPreferredLocation())
- .build();
- mHoverMenu.addOnExitListener(mWindowHoverMenuMenuExitListener);
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (!mIsRunning) {
- Log.d(TAG, "onStartCommand() - showing Hover menu.");
- mIsRunning = true;
- mHoverMenu.show();
- }
-
- return START_STICKY;
- }
-
- @Override
- public void onDestroy() {
- Log.d(TAG, "onDestroy()");
- mHoverMenu.hide();
- mIsRunning = false;
- }
-
-
- public HoverMenu getHoverMenu() {
- return mHoverMenu;
- }
-
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- /**
- * Hook for subclasses to return a custom Context to be used in the creation of the {@code HoverMenu}.
- * For example, subclasses might choose to provide a ContextThemeWrapper.
- *
- * @return context for HoverMenu initialization
- */
- protected Context getContextForHoverMenu() {
- return this;
- }
-
- /**
- * Subclasses can use this hook method to return a customized {@link Navigator} to be used
- * throughout the entire Hover menu. This {@link Navigator} will be used for every tab in the
- * Hover menu, so only supply a {@code Navigator} if you truly want every screen to display it.
- *
- * If you want only a portion of the screens in the Hover menu to look different, then consider
- * using composition of {@link NavigatorContent} to achieve the desired effect. For example,
- * if you want a {@code Toolbar} to appear on one or more screens, consider placing your content
- * within a {@link ToolbarNavigatorContent}, and then add the {@code ToolbarNavigatorContent}
- * as the content of the default {@code Navigator}.
- *
- * @return Custom Navigator to use on every screen in the Hover menu
- */
- protected Navigator createNavigator() {
- return null; // Subclasses can override this to provide a custom Navigator.
- }
-
- abstract protected HoverMenuAdapter createHoverMenuAdapter();
-
- /**
- * Hook method for subclasses to take action when the user exits the HoverMenu. This method runs
- * just before this {@code HoverMenuService} calls {@code stopSelf()}.
- */
- protected void onHoverMenuExitingByUserRequest() {
- // Hook for subclasses.
- }
-
- private void savePreferredLocation() {
- String memento = mHoverMenu.getVisualState();
- mPrefs.edit().putString(PREF_HOVER_MENU_VISUAL_STATE, memento).apply();
- }
-
- private String loadPreferredLocation() {
- return mPrefs.getString(PREF_HOVER_MENU_VISUAL_STATE, null);
- }
-}
diff --git a/app/src/main/java/com/stardust/hover/HoverMenuView.java b/app/src/main/java/com/stardust/hover/HoverMenuView.java
deleted file mode 100644
index c93c85e5e..000000000
--- a/app/src/main/java/com/stardust/hover/HoverMenuView.java
+++ /dev/null
@@ -1,1109 +0,0 @@
-package com.stardust.hover;
-
-/**
- * Created by Stardust on 2017/3/11.
- */
-
-
-import android.animation.Animator;
-import android.animation.LayoutTransition;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.animation.TimeInterpolator;
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.os.Build;
-import android.os.Vibrator;
-import android.support.annotation.ColorInt;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AnticipateInterpolator;
-import android.view.animation.BounceInterpolator;
-import android.view.animation.OvershootInterpolator;
-import android.widget.RelativeLayout;
-
-import io.mattcarroll.hover.Navigator;
-import io.mattcarroll.hover.R;
-import io.mattcarroll.hover.HoverMenuAdapter;
-import io.mattcarroll.hover.defaulthovermenu.CollapsedMenuAnchor;
-import io.mattcarroll.hover.defaulthovermenu.DefaultNavigator;
-import io.mattcarroll.hover.defaulthovermenu.Dragger;
-import io.mattcarroll.hover.defaulthovermenu.HoverMenuContentView;
-import io.mattcarroll.hover.defaulthovermenu.MagnetPositioner;
-import io.mattcarroll.hover.defaulthovermenu.Positionable;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Stack;
-
-/**
- * {@code HoverMenuView} is a floating menu implementation. This implementation displays tabs along
- * the top of its display, from right to left. Below the tabs, filling the remainder of the display
- * is a content region that displays the content for a selected tab. The content region includes
- * a visual indicator showing which tab is currently selected. Each tab's content includes a title
- * and a visual area. The visual area can display any {@code View}.
- *
- * {@code HoverMenuView} cannot be used in XML because it requires additional parameters in its
- * constructor.
- */
-@SuppressLint("ViewConstructor")
-public class HoverMenuView extends RelativeLayout {
-
- private static final String TAG = "HoverMenuView";
-
- private static final float EXIT_RADIUS_IN_DP = 75;
-
- private static final int EXPANDED = 1;
- private static final int COLLAPSED = 2;
- private static final int TRANSITIONING = 3;
-
- //------ Views From Layout XML -------
- private View mTabAnchorView;
- private HoverMenuContentView mContentView; // Content view to display a menu
- private Navigator mNavigator;
- private View mShadeView; // Dark backdrop that fills screen behind menu
- private View mExitGradientBackground; // Dark gradient that appears behind exit view on lower part of screen
- private View mExitView; // An "x" that appears near bottom of screen to signify "exit" from floating menu
-
- private View mLastTabInStrip;
- private TabSelectionListener mTabSelectionListener;
-
- private List mMotionAnimations = new ArrayList<>();
- private Point mDraggingPoint = new Point();
- private float mExitRadiusInPx; // Radius around mCenterOfExitView where the "primary" bubble can be dropped to signify an exit
- private boolean mIsExitRegionActivated = false;
-
- private HoverMenuAdapter mAdapter;
- private int mTabSizeInPx;
- private List mTabIds = new ArrayList<>();
- private String mActiveTabId;
- private View mActiveTab; // The tab whose menu is currently displayed, and the tab that will represent the collapsed menu.
-
- private int mVisualState;
- private CollapsedMenuAnchor mMenuAnchor;
- private Dragger mWindowDragWatcher;
- private HoverMenuTransitionListener mTransitionListener;
- private HoverMenuExitRequestListener mExitRequestListener;
-
- private HoverMenuContentView.HoverMenuContentResizer mHoverMenuContentResizer = new HoverMenuContentView.HoverMenuContentResizer() {
- @Override
- public void makeHoverMenuContentFullscreen() {
- RelativeLayout.LayoutParams contentContainerLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
- contentContainerLayoutParams.height = 0;
- contentContainerLayoutParams.addRule(RelativeLayout.BELOW, R.id.view_tab_strip_anchor);
- contentContainerLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
- contentContainerLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
- contentContainerLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
- mContentView.setLayoutParams(contentContainerLayoutParams);
- }
-
- @Override
- public void makeHoverMenuContentAsTallAsItsContent() {
- RelativeLayout.LayoutParams contentContainerLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- contentContainerLayoutParams.addRule(RelativeLayout.BELOW, R.id.view_tab_strip_anchor);
- contentContainerLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
- contentContainerLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
- mContentView.setLayoutParams(contentContainerLayoutParams);
- }
- };
-
- private OnTouchListener mTabOnTouchListener = new OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- if (MotionEvent.ACTION_DOWN == motionEvent.getAction()) {
- showTabAsPressed(view);
- } else if (MotionEvent.ACTION_UP == motionEvent.getAction()) {
- showTabAsNotPressed(view);
- }
-
- return false;
- }
- };
-
- private OnClickListener mTabOnClickListener = new OnClickListener() {
- @Override
- public void onClick(View tab) {
- String id = (String) tab.getTag(R.string.floatingmenuview_tabview_id);
-
- // If this is a selection of the tab that is already active, then collapse the menu.
- if (id.equals(mActiveTabId)) {
- collapse();
- }
-
- // Select the clicked tab.
- selectTab(id);
- }
- };
-
- private Positionable mSidePullerPositioner = new Positionable() {
- @Override
- public void setPosition(@NonNull Point position) {
- setCollapsedPosition(position.x, position.y);
- }
- };
-
- private CollapsedMenuViewController mCollapsedMenuViewController = new CollapsedMenuViewController() {
-
- @Override
- public void onPress() {
- onPressOfCollapsedMenu();
- startDragMode();
- }
-
- @Override
- public void onDragTo(@NonNull Point dragCenterPosition) {
- int left = dragCenterPosition.x - (getActiveTab().getWidth() / 2);
- int top = dragCenterPosition.y - (getActiveTab().getHeight() / 2);
-
- setCollapsedPosition(left, top);
-
- checkForExitRegionActivation();
- }
-
- @Override
- public void onRelease() {
- stopDragMode();
- onReleaseOfCollapsedMenu();
- }
-
- @Override
- public void pullToAnchor() {
- Log.d(TAG, "pullToAnchor()");
- MagnetPositioner magnetPositioner = new MagnetPositioner(getResources().getDisplayMetrics(), mSidePullerPositioner, new MagnetPositioner.OnCompletionListener() {
- @Override
- public void onPullToSideCompleted() {
- mVisualState = COLLAPSED;
- enableDragging();
- mTransitionListener.onCollapsed();
- }
- });
-
- View activeTab = getActiveTab();
- Log.d(TAG, "Active tab location - left: " + activeTab.getX() + ", top: " + activeTab.getY());
- Rect tabViewBounds = new Rect(
- (int) activeTab.getX(),
- (int) activeTab.getY(),
- (int) activeTab.getX() + activeTab.getWidth(),
- (int) activeTab.getY() + activeTab.getHeight());
-
- // Update the anchor location.
- mMenuAnchor.setAnchorByInterpolation(tabViewBounds);
- Log.d(TAG, "New anchor normalized Y: " + mMenuAnchor.getAnchorNormalizedY());
-
- // Pull the tab bounds to the anchor position.
- magnetPositioner.pullToAnchor(mMenuAnchor, tabViewBounds, new BounceInterpolator());
- }
- };
-
- private Dragger.DragListener mDragListener = new Dragger.DragListener() {
- @Override
- public void onPress(float x, float y) {
- getCollapsedMenuViewController().onPress();
- }
-
- @Override
- public void onDragStart(float x, float y) {
- }
-
- @Override
- public void onDragTo(float x, float y) {
- getCollapsedMenuViewController().onDragTo(new Point(
- (int) x + (getActiveTab().getWidth() / 2),
- (int) y + (getActiveTab().getHeight() / 2))
- );
- }
-
- @Override
- public void onReleasedAt(float x, float y) {
- Log.d(TAG, "Menu released at - x: " + x + ", y: " + y);
- // Update the visual pressed state of the hover menu.
- getCollapsedMenuViewController().onRelease();
-
- if (isActiveTabInExitRegion()) {
- // Notify our listener that an exit has been requested.
- Log.d(TAG, "Hover menu dropped in exit region. Requesting exit.");
- mExitRequestListener.onExitRequested();
- } else {
- // The user did not choose to exit the menu so pull the menu to the side of the screen.
- getCollapsedMenuViewController().pullToAnchor();
- }
- }
-
- @Override
- public void onTap() {
- // Update the visual pressed state of the hover menu.
- getCollapsedMenuViewController().onRelease();
-
- expand();
- }
- };
-
- private final HoverMenuAdapter.ContentChangeListener mAdapterListener = new HoverMenuAdapter.ContentChangeListener() {
- @Override
- public void onContentChange(@NonNull HoverMenuAdapter adapter) {
- // Update all the tab views.
- removeAllTabs();
- addAllTabs();
-
- Log.d(TAG, "Content change. Active id: " + mActiveTabId);
- Log.d(TAG, "Active tab view: " + findViewById(mActiveTabId.hashCode()));
- mActiveTab = findViewById(mActiveTabId.hashCode());
- mContentView.setActiveTab(mActiveTab);
- }
- };
-
- public HoverMenuView(Context context, @Nullable Navigator navigator, @NonNull Dragger windowDragWatcher,
- @NonNull PointF savedAnchor) {
- super(context);
- mWindowDragWatcher = windowDragWatcher;
- mMenuAnchor = new CollapsedMenuAnchor(getResources().getDisplayMetrics(), 10);
- mMenuAnchor.setAnchorAt((int) savedAnchor.x, savedAnchor.y);
- mNavigator = null == navigator ? new DefaultNavigator(context) : navigator;
- init();
- }
-
- private void init() {
- Log.d(TAG, "init()");
- LayoutInflater.from(getContext()).inflate(R.layout.view_hover_menu, this, true);
-
- mTabSizeInPx = getResources().getDimensionPixelSize(R.dimen.floating_icon_size);
-
- mTabAnchorView = findViewById(R.id.view_tab_strip_anchor);
- mContentView = (HoverMenuContentView) findViewById(R.id.view_content);
- mShadeView = findViewById(R.id.view_shade);
- mExitGradientBackground = findViewById(R.id.view_exit_gradient);
- mExitView = findViewById(R.id.view_exit);
- mExitRadiusInPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EXIT_RADIUS_IN_DP, getResources().getDisplayMetrics());
-
- mContentView.setContentResizer(mHoverMenuContentResizer);
- mContentView.setNavigator(mNavigator);
-
- initLayoutTransitionAnimations();
-
- // Initially we're not really in the EXPANDED or COLLAPSED states.
- mVisualState = TRANSITIONING;
-
- setTabSelectionListener(null);
- setHoverMenuTransitionListener(null);
- setHoverMenuExitRequestListener(null);
- }
-
- public void release() {
- mWindowDragWatcher.deactivate();
- }
-
- public void setContentBackgroundColor(@ColorInt int color) {
- mContentView.setBackgroundColor(color);
- }
-
- public CollapsedMenuViewController getCollapsedMenuViewController() {
- return mCollapsedMenuViewController;
- }
-
- public void collapse() {
- if (EXPANDED == mVisualState) {
- Log.d(TAG, "Collapsed Hover menu.");
- doCollapse(true);
- }
- }
-
- public void expand() {
- if (COLLAPSED == mVisualState) {
- Log.d(TAG, "Expanding Hover menu.");
- doExpansion(true);
- }
- }
-
- public void setHoverMenuTransitionListener(@Nullable HoverMenuTransitionListener transitionListener) {
- mTransitionListener = null == transitionListener ? new NoOpHoverMenuTransitionListener() : transitionListener;
- }
-
- public void setHoverMenuExitRequestListener(@Nullable HoverMenuExitRequestListener exitRequestListener) {
- mExitRequestListener = null == exitRequestListener ? new NoOpHoverMenuExitRequestListener() : exitRequestListener;
- }
-
- public PointF getAnchorState() {
- return new PointF(mMenuAnchor.getAnchorSide(), mMenuAnchor.getAnchorNormalizedY());
- }
-
- public void setAnchorState(@NonNull PointF anchorState) {
- mMenuAnchor.setAnchorAt((int) anchorState.x, anchorState.y);
-
- // If we're in the collapsed state, update the collapsed position to the new anchor position.
- if (COLLAPSED == mVisualState) {
- moveActiveTabToAnchor();
- }
- }
-
- private void doCollapse(boolean animate) {
- mVisualState = TRANSITIONING;
- mTransitionListener.onCollapsing();
-
- if (animate) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- LayoutTransition transition = getLayoutTransition();
- transition.enableTransitionType(LayoutTransition.DISAPPEARING);
- }
-
- Iterator tabIterator = getTailToHeadTabIterator();
- int timeUntilVisiblityChange = 0;
- while (tabIterator.hasNext()) {
- final View tabView = tabIterator.next();
-
- // We don't want to hide the active tab, so only hide the other tabs.
- if (getActiveTab() != tabView) {
- postDelayed(new Runnable() {
- @Override
- public void run() {
- tabView.setVisibility(View.GONE);
- }
- }, timeUntilVisiblityChange);
-
- timeUntilVisiblityChange += 50;
- }
- }
-
- // Disable transition animations after tabs are done animating in.
- postDelayed(new Runnable() {
- @Override
- public void run() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- LayoutTransition transition = getLayoutTransition();
- transition.disableTransitionType(LayoutTransition.DISAPPEARING);
- }
- }
- }, timeUntilVisiblityChange);
-
- postDelayed(new Runnable() {
- @Override
- public void run() {
- getShadeView().setVisibility(View.GONE);
-
- // Move the active tab to the anchor position.
- animateActiveTabToAnchorPosition();
- }
- }, timeUntilVisiblityChange);
- } else {
- // Change visibilities immediately.
- Iterator tailToHeadTabIterator = getTailToHeadTabIterator();
- while (tailToHeadTabIterator.hasNext()) {
- View tabView = tailToHeadTabIterator.next();
-
- // We don't want to hide the very first tab, so only hide tabs that have yet another tab leading them.
- if (getActiveTab() != tabView) {
- Log.d(TAG, "Hiding tab: " + tabView.getTag(R.string.floatingmenuview_tabview_id));
- tabView.setVisibility(View.GONE);
- }
- }
-
- getShadeView().setVisibility(View.GONE);
-
- moveActiveTabToAnchor();
- mTransitionListener.onCollapsed();
- }
-
- // Close the content area.
- getContentView().setVisibility(View.GONE);
- }
-
- private void doExpansion(boolean animate) {
- mVisualState = TRANSITIONING;
- mTransitionListener.onExpanding();
-
- disableDragging();
-
- getShadeView().setVisibility(View.VISIBLE);
-
- if (animate) {
- animateActiveTabToExpandedPosition(new OvershootInterpolator());
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- LayoutTransition transition = getLayoutTransition();
- transition.enableTransitionType(LayoutTransition.APPEARING);
- }
-
- Iterator headToTailTabIterator = getHeadToTailTabIterator();
- int timeUntilVisiblityChange = 0;
- while (headToTailTabIterator.hasNext()) {
- View tabView = headToTailTabIterator.next();
- Log.d(TAG, "Showing tab: " + tabView.getTag(R.string.floatingmenuview_tabview_id));
- final View tabRef = tabView;
- postDelayed(new Runnable() {
- @Override
- public void run() {
- tabRef.setVisibility(View.VISIBLE);
- }
- }, timeUntilVisiblityChange);
-
- timeUntilVisiblityChange += 50;
- }
-
- // Disable transition animations after tabs are done animating in.
- postDelayed(new Runnable() {
- @Override
- public void run() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- LayoutTransition transition = getLayoutTransition();
- transition.disableTransitionType(LayoutTransition.APPEARING);
- }
-
- // Set state to expanded.
- mVisualState = EXPANDED;
- mTransitionListener.onExpanded();
- mContentView.setActiveTab(mActiveTab);
- }
- }, timeUntilVisiblityChange);
- } else {
- // Change visibilities immediately.
- moveActiveTabTo(0, 0);
-
- Iterator headToTailTabIterator = getHeadToTailTabIterator();
- while (headToTailTabIterator.hasNext()) {
- View tabView = headToTailTabIterator.next();
- Log.d(TAG, "Showing tab: " + tabView.getTag(R.string.floatingmenuview_tabview_id));
- tabView.setVisibility(View.VISIBLE);
- }
-
- // Set state to expanded.
- mVisualState = EXPANDED;
- mTransitionListener.onExpanded();
- }
-
- // Open the content.
- getContentView().setVisibility(View.VISIBLE);
- }
-
- private void enableDragging() {
- Point anchorPosition = mDraggingPoint;
-
- Log.d(TAG, "Enabling dragging - x: " + anchorPosition.x + ", y: " + anchorPosition.y);
- Log.d(TAG, "Drag width: " + mTabSizeInPx + ", height: " + mTabSizeInPx);
-
- mWindowDragWatcher.deactivate();
- mWindowDragWatcher.activate(mDragListener, new Rect(
- anchorPosition.x,
- anchorPosition.y,
- anchorPosition.x + getActiveTab().getWidth(),
- anchorPosition.y + getActiveTab().getHeight()
- ));
- }
-
- private void disableDragging() {
- mWindowDragWatcher.deactivate();
- }
-
- private void moveActiveTabToAnchor() {
- Rect anchoredBounds = mMenuAnchor.anchor(new Rect(
- (int) mActiveTab.getX(),
- (int) mActiveTab.getY(),
- (int) mActiveTab.getX() + mActiveTab.getWidth(),
- (int) mActiveTab.getY() + mActiveTab.getHeight()
- ));
- moveActiveTabTo(anchoredBounds.left, anchoredBounds.top);
- }
-
- private void moveActiveTabTo(int x, int y) {
- View activeTab = getActiveTab();
- if (null != activeTab) {
- activeTab.setTranslationX(x);
- activeTab.setTranslationY(y);
- }
- }
-
- public void setAdapter(@Nullable HoverMenuAdapter adapter) {
- Log.d(TAG, "setAdapter()");
-
- // Remove all existing tabs from any previous adapter.
- mActiveTabId = null;
- removeAllTabs();
- if (null != mAdapter) {
- mAdapter.removeContentChangeListener(mAdapterListener);
- }
-
- // Update our adapter reference.
- mAdapter = adapter;
-
- if (null != adapter) {
- // Create all the tabs that the new adapter wants.
- addAllTabs();
-
- // Start listening for adapter changes.
- mAdapter.addContentChangeListener(mAdapterListener);
-
- // Select the first tab.
- setActiveTab(mTabIds.get(0));
-
- // We force a collapse because at this point we're in a weird initial state.
- doCollapse(true);
- }
- }
-
- @Nullable
- private View getActiveTab() {
- return mActiveTab;
- }
-
- @NonNull
- private View getShadeView() {
- return mShadeView;
- }
-
- @NonNull
- private HoverMenuContentView getContentView() {
- return mContentView;
- }
-
- @NonNull
- private Iterator getHeadToTailTabIterator() {
- return new HeadToTailTabIterator(mTabAnchorView);
- }
-
- @NonNull
- private Iterator getTailToHeadTabIterator() {
- return new TailToHeadTabIterator(mTabAnchorView);
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
-
- Log.d(TAG, "onLayoutChange()");
- Log.d(TAG, "New - left: " + left + ", top: " + top + ", right: " + right + ", bottom: " + bottom);
- Rect newBounds = new Rect(left, top, right, bottom);
-
- // Adjust anchor position.
- mMenuAnchor.setDisplayBounds(newBounds);
-
- if (null != mActiveTab) {
- Log.d(TAG, "Active tab - (" + mActiveTab.getX() + ", " + mActiveTab.getY() + "), width: " + mActiveTab.getWidth() + ", " + mActiveTab.getHeight());
- Log.d(TAG, "Active tab visibility: " + (mActiveTab.getVisibility() == VISIBLE ? "VISIBLE" : "NOT VISIBLE"));
- } else {
- Log.d(TAG, "Active tab is null.");
- return;
- }
-
- Rect anchoredBounds = mMenuAnchor.anchor(new Rect(0, 0, getActiveTab().getWidth(), getActiveTab().getHeight()));
- Log.d(TAG, "Adjusted anchor bounds at (" + anchoredBounds.left + ", " + anchoredBounds.top + ")");
-
- if (!changed) {
- return;
- }
-
- if (null != mActiveTab) {
- Log.d(TAG, "Adjusting tab position due to layout change.");
- getCollapsedMenuViewController().onDragTo(new Point(
- anchoredBounds.left + (mActiveTab.getWidth() / 2),
- anchoredBounds.top + (mActiveTab.getHeight() / 2)
- ));
- } else {
- Log.d(TAG, "There is no active tab, no need to adjust positioning during layout change.");
- }
-
- if (mVisualState == COLLAPSED) {
- Log.d(TAG, "Restarting dragging so that the drag area is adjusted due to layout change.");
- enableDragging();
- }
- }
-
- public boolean isExpanded() {
- return mVisualState == EXPANDED;
- }
-
- private void addTab(@NonNull String id, @NonNull View tabView) {
- mTabIds.add(id);
-
- Log.d(TAG, "Setting tab ID to: " + id.hashCode());
- tabView.setId(id.hashCode());
- tabView.setTag(R.string.floatingmenuview_tabview_id, id);
- tabView.setOnTouchListener(mTabOnTouchListener);
- tabView.setOnClickListener(mTabOnClickListener);
-
- if (null == mLastTabInStrip) {
- Log.d(TAG, "Adding first tab: " + tabView.getTag(R.string.floatingmenuview_tabview_id));
-
- // This is the first tab in the strip.
- addTabAfter(tabView, mTabAnchorView);
- } else {
- Log.d(TAG, "Adding additional tab: " + tabView.getTag(R.string.floatingmenuview_tabview_id) + " after " + mLastTabInStrip.getTag(R.string.floatingmenuview_tabview_id));
- // There are already tabs in the strip, append this one to the end.
- addTabAfter(tabView, mLastTabInStrip);
-
- if (!isExpanded()) {
- tabView.setVisibility(GONE);
- }
- }
-
- mLastTabInStrip = tabView;
- }
-
- private void addTabAfter(@NonNull View tabView, @NonNull View leadingView) {
- RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(mTabSizeInPx, mTabSizeInPx);
- layoutParams.addRule(LEFT_OF, leadingView.getId());
- layoutParams.addRule(RelativeLayout.ALIGN_TOP, leadingView.getId());
-
- // Tell the leading view who is anchored to it.
- leadingView.setTag(tabView);
-
- addView(tabView, layoutParams);
- }
-
- private void removeTab(@NonNull String id) {
- View tabView = findViewById(id.hashCode());
- if (null != tabView) {
- RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) tabView.getLayoutParams();
- int anchorViewId;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- anchorViewId = layoutParams.getRule(RelativeLayout.LEFT_OF);
- } else {
- anchorViewId = layoutParams.getRules()[RelativeLayout.LEFT_OF];
- }
- View leadingTabView = findViewById(anchorViewId);
-
- View trailingTabView = (View) tabView.getTag();
- if (null != trailingTabView) {
- addTabAfter(trailingTabView, leadingTabView);
- } else if (tabView == mLastTabInStrip) {
- mLastTabInStrip = leadingTabView;
- }
-
- removeView(tabView);
- }
- }
-
- private void addAllTabs() {
- for (int i = 0; i < mAdapter.getTabCount(); ++i) {
- addTab(i + "", mAdapter.getTabView(i));
- mTabIds.add(i + "");
- }
- }
-
- private void removeAllTabs() {
- for (String tabId : mTabIds) {
- removeView(findViewById(tabId.hashCode()));
- }
-
- mTabIds.clear();
- mLastTabInStrip = null;
- }
-
-// private void refreshTabs() {
-// int tabCount = mAdapter.getTabCount();
-// for (int i = 0; i < tabCount; ++i) {
-// replaceTabView()
-// }
-// }
-
- private void selectTab(@NonNull String id) {
- Log.d(TAG, "Selecting tab: " + id.hashCode());
- setActiveTab(id);
- mTabSelectionListener.onTabSelected(id);
- }
-
- private void setActiveTab(String id) {
- if (id.equals(mActiveTabId)) {
- // This tab is already selected.
- return;
- }
-
- mActiveTabId = id;
- mActiveTab = findViewById(id.hashCode());
- mContentView.setActiveTab(mActiveTab);
-
- // This is a top-level menu item so clear all content from the menu to start fresh.
-// mContentView.clearContent();
- mNavigator.clearContent();
-
- // Activate the chosen tab.
-// mAdapter.getNavigatorContent(Integer.parseInt(id)).execute(getContext(), mContentView);
-// mContentView.pushContent(mAdapter.getNavigatorContent(Integer.parseInt(id)));
- mNavigator.pushContent(mAdapter.getNavigatorContent(Integer.parseInt(id)));
- }
-
- public void setTabSelectionListener(@Nullable TabSelectionListener tabSelectionListener) {
- if (null != tabSelectionListener) {
- mTabSelectionListener = tabSelectionListener;
- } else {
- mTabSelectionListener = new NoOpTabSelectionListener();
- }
- }
-
- public boolean onBackPressed() {
- if (isExpanded() && !mContentView.onBackPressed()) {
- collapse();
- return true;
- } else {
- return false;
- }
- }
-
- private void onPressOfCollapsedMenu() {
- // Scale down the active tab to give "pressed" effect.
- if (null != mActiveTab) {
- showTabAsPressed(mActiveTab);
- }
- }
-
- private void onReleaseOfCollapsedMenu() {
- // Return scale of the active tab to normal state.
- if (null != mActiveTab) {
- showTabAsNotPressed(mActiveTab);
- }
- }
-
- private void onMenuCollapsed() {
- mVisualState = COLLAPSED;
- enableDragging();
- mTransitionListener.onCollapsed();
- }
-
- private void showTabAsPressed(@NonNull View tabView) {
- tabView.setScaleX(0.95f);
- tabView.setScaleY(0.95f);
- }
-
- private void showTabAsNotPressed(@NonNull View tabView) {
- tabView.setScaleX(1.0f);
- tabView.setScaleY(1.0f);
- }
-
- private void startDragMode() {
- Log.d(TAG, "startDragMode()");
- mExitGradientBackground.setAlpha(0.0f);
- ObjectAnimator.ofFloat(mExitGradientBackground, "alpha", 0.0f, 1.0f).setDuration(300).start();
- mExitGradientBackground.setVisibility(VISIBLE);
-
- LayoutTransition transition = getLayoutTransition();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- transition.enableTransitionType(LayoutTransition.APPEARING);
- }
-
- mExitView.setVisibility(VISIBLE);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- transition.disableTransitionType(LayoutTransition.APPEARING);
- }
- }
-
- private void stopDragMode() {
- Log.d(TAG, "stopDragMode()");
- ObjectAnimator animator = ObjectAnimator.ofFloat(mExitGradientBackground, "alpha", 1.0f, 0.0f).setDuration(300);
- animator.addListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animator) {
- }
-
- @Override
- public void onAnimationEnd(Animator animator) {
- mExitGradientBackground.setVisibility(INVISIBLE);
- }
-
- @Override
- public void onAnimationCancel(Animator animator) {
- }
-
- @Override
- public void onAnimationRepeat(Animator animator) {
- }
- });
- animator.start();
-
- LayoutTransition transition = getLayoutTransition();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- transition.enableTransitionType(LayoutTransition.DISAPPEARING);
- }
-
- mExitView.setVisibility(INVISIBLE);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- transition.disableTransitionType(LayoutTransition.DISAPPEARING);
- }
- }
-
- private void checkForExitRegionActivation() {
- if (!mIsExitRegionActivated && isActiveTabInExitRegion()) {
- activateExitRegion();
- } else if (mIsExitRegionActivated && !isActiveTabInExitRegion()) {
- deactivateExitRegion();
- }
- }
-
- private void activateExitRegion() {
- mIsExitRegionActivated = true;
-
- Vibrator vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
- vibrator.vibrate(50);
-
- mExitView.setScaleX(1.25f);
- mExitView.setScaleY(1.25f);
- }
-
- private void deactivateExitRegion() {
- mIsExitRegionActivated = false;
-
- mExitView.setScaleX(1.0f);
- mExitView.setScaleY(1.0f);
- }
-
- private void setCollapsedPosition(int x, int y) {
- Log.d(TAG, "Setting collapsed position - x: " + x + ", y: " + y);
- mDraggingPoint.set(x, y);
-
- if (!isExpanded() && null != mActiveTab) {
-// Log.d(TAG, "Setting collapsed menu position (dragging) - x: " + mDraggingPoint.x + ", y: " + mDraggingPoint.y);
- mActiveTab.setX(mDraggingPoint.x);
- mActiveTab.setY(mDraggingPoint.y);
- }
- }
-
- @Override
- public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
- if (KeyEvent.ACTION_UP == event.getAction() && KeyEvent.KEYCODE_BACK == event.getKeyCode()) {
- return onBackPressed();
- } else {
- return super.dispatchKeyEvent(event);
- }
- }
-
- private void initLayoutTransitionAnimations() {
- setLayoutTransition(new LayoutTransition());
- final LayoutTransition transition = getLayoutTransition();
-
- transition.setAnimator(LayoutTransition.APPEARING, createEnterObjectAnimator());
-
- transition.setAnimator(LayoutTransition.DISAPPEARING, createExitObjectAnimator());
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- transition.disableTransitionType(LayoutTransition.APPEARING);
- transition.disableTransitionType(LayoutTransition.DISAPPEARING);
- transition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
- transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
- transition.disableTransitionType(LayoutTransition.CHANGING);
- }
- }
-
- private ObjectAnimator createEnterObjectAnimator() {
- PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.0f, 1.0f);
- PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.0f, 1.0f);
-
- // Target object doesn't matter because it is overriden by layout system.
- ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(new Object(), scaleX, scaleY);
- animator.setDuration(500);
- animator.setInterpolator(new OvershootInterpolator());
- return animator;
- }
-
- private ObjectAnimator createExitObjectAnimator() {
- PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.1f);
- PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.1f);
-
- // Target object doesn't matter because it is overriden by layout system.
- ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(new Object(), scaleX, scaleY);
- animator.setDuration(500);
- animator.setInterpolator(new AnticipateInterpolator());
- return animator;
- }
-
- private void animateActiveTabToAnchorPosition() {
- Log.d(TAG, "animateActiveTabToAnchorPosition()");
- MagnetPositioner magnetPositioner = new MagnetPositioner(getResources().getDisplayMetrics(), mSidePullerPositioner, new MagnetPositioner.OnCompletionListener() {
- @Override
- public void onPullToSideCompleted() {
- onMenuCollapsed();
- }
- });
-
- View activeTab = getActiveTab();
- Log.d(TAG, "Active tab location - left: " + activeTab.getX() + ", top: " + activeTab.getY());
- Rect tabViewBounds = new Rect(
- (int) activeTab.getX(),
- (int) activeTab.getY(),
- (int) activeTab.getX() + activeTab.getWidth(),
- (int) activeTab.getY() + activeTab.getHeight());
-
- // Pull the tab bounds to the anchor position.
- magnetPositioner.pullToAnchor(mMenuAnchor, tabViewBounds, new OvershootInterpolator());
- }
-
- private void animateActiveTabToExpandedPosition(TimeInterpolator interpolator) {
- int x = 0;
- int y = 0;
-
- if (null == mActiveTab) {
- return;
- }
-
- for (Animator animator : mMotionAnimations) {
- if (animator.isRunning()) {
- animator.cancel();
- }
- }
- mMotionAnimations.clear();
-
- double distanceToAnimate = getDistanceBetweenTwoPoints(x, y, mActiveTab.getTranslationX(), mActiveTab.getTranslationY());
- int animationTimeInMillis = getTimeForAnimationDistance(distanceToAnimate);
-
- PropertyValuesHolder xChange = PropertyValuesHolder.ofFloat("translationX", mActiveTab.getTranslationX(), x);
- PropertyValuesHolder yChange = PropertyValuesHolder.ofFloat("translationY", mActiveTab.getTranslationY(), y);
-
- ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mActiveTab, xChange, yChange);
- animator.setDuration(animationTimeInMillis);
- animator.setInterpolator(interpolator);
- animator.start();
-
- mMotionAnimations.add(animator);
- }
-
- public boolean isActiveTabInExitRegion() {
- PointF centerOfExitView = new PointF(mExitView.getX() + (mExitView.getWidth() / 2), mExitView.getY() + (mExitView.getHeight() / 2));
- PointF iconPosition = new PointF(mActiveTab.getX() + (mActiveTab.getWidth() / 2), mActiveTab.getY() + (mActiveTab.getHeight() / 2));
- double distance = getDistanceBetweenTwoPoints(iconPosition.x, iconPosition.y, centerOfExitView.x, centerOfExitView.y);
- return distance <= mExitRadiusInPx;
- }
-
- private double getDistanceBetweenTwoPoints(float x1, float y1, float x2, float y2) {
- return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
- }
-
- private int getTimeForAnimationDistance(double distanceInPx) {
- double speedInDpPerSecond = 1000;
- double distanceInDp = distanceInPx / getResources().getDisplayMetrics().density;
- final int timingOffset = 200; // To give some time at front and back of animation regardless of how close we are to destination.
-
- return (int) ((distanceInDp / speedInDpPerSecond) * 1000) + timingOffset;
- }
-
- public interface TabSelectionListener {
-
- void onTabSelected(String id);
-
- }
-
- public static class NoOpTabSelectionListener implements TabSelectionListener {
- @Override
- public void onTabSelected(String id) {
- // no-op
- }
- }
-
- private static class HeadToTailTabIterator implements Iterator {
-
- private View mCurrTabView;
-
- public HeadToTailTabIterator(@NonNull View anchorView) {
- mCurrTabView = anchorView;
- }
-
- @Override
- public boolean hasNext() {
- return null != mCurrTabView.getTag();
- }
-
- @Override
- public View next() {
- return mCurrTabView = (View) mCurrTabView.getTag();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("You cannot remove tabs through this iterator.");
- }
-
- }
-
- private static class TailToHeadTabIterator implements Iterator {
-
- private Stack mTabStack = new Stack<>();
-
- public TailToHeadTabIterator(@NonNull View anchorView) {
- // Tabs are connected as a singly-linked list so to reverse order we put them on a stack.
- View tabView = (View) anchorView.getTag();
- while (null != tabView) {
- mTabStack.push(tabView);
- tabView = (View) tabView.getTag();
- }
- }
-
- @Override
- public boolean hasNext() {
- return !mTabStack.isEmpty();
- }
-
- @Override
- public View next() {
- return mTabStack.pop();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("You cannot remove tabs through this iterator.");
- }
- }
-
- public interface CollapsedMenuViewController {
- void onPress();
-
- void onDragTo(@NonNull Point dragCenterPosition);
-
- void onRelease();
-
- void pullToAnchor();
- }
-
- public interface HoverMenuTransitionListener {
- void onCollapsing();
-
- void onCollapsed();
-
- void onExpanding();
-
- void onExpanded();
- }
-
- public static class NoOpHoverMenuTransitionListener implements HoverMenuTransitionListener {
-
- @Override
- public void onCollapsing() {
- // No-Op
- }
-
- @Override
- public void onCollapsed() {
- // No-Op
- }
-
- @Override
- public void onExpanding() {
- // No-Op
- }
-
- @Override
- public void onExpanded() {
- // No-Op
- }
-
- }
-
- public interface HoverMenuExitRequestListener {
- void onExitRequested();
- }
-
- public static class NoOpHoverMenuExitRequestListener implements HoverMenuExitRequestListener {
-
- @Override
- public void onExitRequested() {
- // No-Op
- }
-
- }
-}
diff --git a/app/src/main/java/com/stardust/pio/PFile.java b/app/src/main/java/com/stardust/pio/PFile.java
deleted file mode 100644
index d6235ba4c..000000000
--- a/app/src/main/java/com/stardust/pio/PFile.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.stardust.pio;
-
-/**
- * Created by Stardust on 2017/4/1.
- */
-
-public class PFile {
-
- public static PFile open(String path, String mode) {
- switch (mode){
- case "r":
- return new PReadableFile(path);
- case "w":
- return new PWritableFile();
- }
- return null;
- }
-
- public static void create(String path){
-
- }
-
- public static void createIfNotExists(String path){
-
- }
-
- public static void delete(String path){
-
- }
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java
index 44f987509..6dac8c266 100644
--- a/app/src/main/java/com/stardust/scriptdroid/App.java
+++ b/app/src/main/java/com/stardust/scriptdroid/App.java
@@ -2,28 +2,17 @@
import android.app.Activity;
import android.app.Application;
+import android.content.Intent;
import android.os.Bundle;
-import android.preference.PreferenceManager;
-
-import com.stardust.automator.AccessibilityEventCommandHost;
-import com.stardust.scriptdroid.accessibility.AccessibilityInfoProvider;
-import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
-import com.stardust.scriptdroid.droid.script.JavaScriptEngine;
-import com.stardust.scriptdroid.droid.script.NodeJsJavaScriptEngine;
-import com.stardust.scriptdroid.droid.script.RhinoJavaScriptEngine;
-import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
-import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
-import com.stardust.scriptdroid.droid.script.file.StorageScriptFileList;
-import com.stardust.scriptdroid.layout_inspector.LayoutInspector;
-import com.stardust.scriptdroid.record.accessibility.AccessibilityActionRecorder;
-import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
+
import com.squareup.leakcanary.LeakCanary;
-import com.stardust.scriptdroid.droid.runtime.action.ActionPerformAccessibilityDelegate;
+import com.stardust.app.SimpleActivityLifecycleCallbacks;
+import com.stardust.scriptdroid.autojs.AutoJs;
+import com.stardust.scriptdroid.service.VolumeChangeObverseService;
+import com.stardust.scriptdroid.tool.CrashHandler;
import com.stardust.scriptdroid.ui.error.ErrorReportActivity;
import com.stardust.theme.ThemeColor;
import com.stardust.theme.ThemeColorManager;
-import com.stardust.util.CrashHandler;
-import com.stardust.util.StateObserver;
/**
* Created by Stardust on 2017/1/27.
@@ -34,25 +23,18 @@ public class App extends Application {
private static final String TAG = "App";
private static App instance;
- private static StateObserver stateObserver;
private static Activity currentActivity;
public static App getApp() {
return instance;
}
- public static StateObserver getStateObserver() {
- return stateObserver;
- }
-
-
public void onCreate() {
super.onCreate();
+ instance = this;
setUpDebugEnvironment();
init();
- configApp();
registerActivityLifecycleCallback();
- initAccessibilityServiceDelegates();
}
private void setUpDebugEnvironment() {
@@ -67,23 +49,16 @@ private void setUpDebugEnvironment() {
private void init() {
ThemeColorManager.setDefaultThemeColor(new ThemeColor(getResources().getColor(R.color.colorPrimary), getResources().getColor(R.color.colorPrimaryDark), getResources().getColor(R.color.colorAccent)));
ThemeColorManager.init(this);
- instance = this;
- stateObserver = new StateObserver(PreferenceManager.getDefaultSharedPreferences(this));
- }
-
- private void configApp() {
- ScriptFileList.setImpl(SharedPrefScriptFileList.getInstance());
- JavaScriptEngine.setDefault(new NodeJsJavaScriptEngine(DroidRuntime.getRuntime()));
- }
-
-
- private void initAccessibilityServiceDelegates() {
- AccessibilityWatchDogService.addDelegateIfNeeded(100, ActionPerformAccessibilityDelegate.class);
- AccessibilityWatchDogService.addDelegateIfNeeded(200, AccessibilityActionRecorder.getInstance());
- AccessibilityWatchDogService.addDelegateIfNeeded(300, AccessibilityEventCommandHost.getInstance());
- AccessibilityWatchDogService.addDelegateIfNeeded(400, AccessibilityInfoProvider.getInstance());
- AccessibilityWatchDogService.addDelegateIfNeeded(500, LayoutInspector.getInstance());
-
+ AutoJs.initInstance(this);
+ VolumeChangeObverseService.addOnVolumeChangeListener(new VolumeChangeObverseService.OnVolumeChangeListener() {
+ @Override
+ public void onVolumeChange() {
+ if (Pref.isRunningVolumeControlEnabled()) {
+ AutoJs.getInstance().getScriptEngineService().stopAllAndToast();
+ }
+ }
+ });
+ startService(new Intent(this, VolumeChangeObverseService.class));
}
private void registerActivityLifecycleCallback() {
@@ -93,7 +68,6 @@ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
currentActivity = activity;
}
-
@Override
public void onActivityPaused(Activity activity) {
currentActivity = null;
@@ -120,42 +94,4 @@ public static String getResString(int id) {
return getApp().getString(id);
}
-
- private static class SimpleActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {
-
- @Override
- public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
-
- }
-
- @Override
- public void onActivityStarted(Activity activity) {
-
- }
-
- @Override
- public void onActivityResumed(Activity activity) {
-
- }
-
- @Override
- public void onActivityPaused(Activity activity) {
-
- }
-
- @Override
- public void onActivityStopped(Activity activity) {
-
- }
-
- @Override
- public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
-
- }
-
- @Override
- public void onActivityDestroyed(Activity activity) {
-
- }
- }
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/Pref.java b/app/src/main/java/com/stardust/scriptdroid/Pref.java
index b7ef2003b..080161601 100644
--- a/app/src/main/java/com/stardust/scriptdroid/Pref.java
+++ b/app/src/main/java/com/stardust/scriptdroid/Pref.java
@@ -5,6 +5,7 @@
import android.preference.PreferenceManager;
import com.stardust.automator.AccessibilityEventCommandHost;
+import com.stardust.scriptdroid.autojs.AutoJs;
/**
* Created by Stardust on 2017/1/31.
@@ -18,7 +19,7 @@ public class Pref {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(App.getResString(R.string.key_run_mode))) {
- AccessibilityEventCommandHost.getInstance().setRunMode(getRunModeFromValue(sharedPreferences.getString(key, null)));
+ AutoJs.getInstance().getCommandHost().setRunMode(getRunModeFromValue(sharedPreferences.getString(key, null)));
}
}
};
diff --git a/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java
new file mode 100644
index 000000000..30b0aa9bd
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/autojs/AutoJs.java
@@ -0,0 +1,123 @@
+package com.stardust.scriptdroid.autojs;
+
+import android.content.Context;
+
+import com.stardust.autojs.ScriptEngineService;
+import com.stardust.autojs.ScriptEngineServiceBuilder;
+import com.stardust.autojs.engine.NodeJsJavaScriptEngine;
+import com.stardust.autojs.engine.NodeJsJavaScriptEngineManager;
+import com.stardust.autojs.runtime.*;
+import com.stardust.autojs.runtime.action.ActionPerformAccessibilityDelegate;
+import com.stardust.autojs.runtime.api.Console;
+import com.stardust.automator.AccessibilityEventCommandHost;
+import com.stardust.scriptdroid.App;
+import com.stardust.scriptdroid.Pref;
+import com.stardust.scriptdroid.R;
+import com.stardust.scriptdroid.scripts.StorageScriptProvider;
+import com.stardust.view.accessibility.AccessibilityInfoProvider;
+import com.stardust.scriptdroid.layout_inspector.LayoutInspector;
+import com.stardust.scriptdroid.record.accessibility.AccessibilityActionRecorder;
+import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
+import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
+import com.stardust.scriptdroid.ui.console.TimberConsole;
+import com.stardust.view.accessibility.AccessibilityServiceUtils;
+
+
+/**
+ * Created by Stardust on 2017/4/2.
+ */
+
+public class AutoJs implements AccessibilityBridge {
+
+ private static AutoJs instance;
+
+ public static AutoJs getInstance() {
+ return instance;
+ }
+
+ public static void initInstance(Context context) {
+ instance = new AutoJs(context);
+ }
+
+ private final AccessibilityEventCommandHost mAccessibilityEventCommandHost = new AccessibilityEventCommandHost();
+ private final ActionPerformAccessibilityDelegate mActionPerformAccessibilityDelegate = new ActionPerformAccessibilityDelegate();
+ private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
+ private final LayoutInspector mLayoutInspector = new LayoutInspector();
+ private final ScriptEngineService mScriptEngineService;
+ private final AccessibilityInfoProvider mAccessibilityInfoProvider;
+ private final ScriptRuntime mRuntime;
+
+
+ private AutoJs(Context context) {
+ mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
+ Console console = new TimberConsole();
+ mRuntime = new ScriptRuntime(context, console, this);
+ NodeJsJavaScriptEngineManager manager = new NodeJsJavaScriptEngineManager(context, mRuntime);
+ manager.setRequirePath(StorageScriptProvider.DEFAULT_DIRECTORY_PATH);
+ mScriptEngineService = new ScriptEngineServiceBuilder()
+ .context(context)
+ .engineManger(manager)
+ .console(console)
+ .runtime(mRuntime)
+ .build();
+ ScriptEngineService.setInstance(mScriptEngineService);
+ addAccessibilityServiceDelegates();
+ }
+
+ private void addAccessibilityServiceDelegates() {
+ AccessibilityWatchDogService.addDelegateIfNeeded(100, mActionPerformAccessibilityDelegate);
+ AccessibilityWatchDogService.addDelegateIfNeeded(200, mAccessibilityActionRecorder);
+ AccessibilityWatchDogService.addDelegateIfNeeded(300, mAccessibilityEventCommandHost);
+ AccessibilityWatchDogService.addDelegateIfNeeded(400, mAccessibilityInfoProvider);
+ AccessibilityWatchDogService.addDelegateIfNeeded(500, mLayoutInspector);
+ }
+
+ public AccessibilityActionRecorder getAccessibilityActionRecorder() {
+ return mAccessibilityActionRecorder;
+ }
+
+ public LayoutInspector getLayoutInspector() {
+ return mLayoutInspector;
+ }
+
+ @Override
+ public AccessibilityEventCommandHost getCommandHost() {
+ return mAccessibilityEventCommandHost;
+ }
+
+ @Override
+ public ActionPerformAccessibilityDelegate getActionPerformHost() {
+ return mActionPerformAccessibilityDelegate;
+ }
+
+ @Override
+ public void ensureServiceEnabled() {
+ if (AccessibilityWatchDogService.getInstance() == null) {
+ String errorMessage = null;
+ if (AccessibilityServiceUtils.isAccessibilityServiceEnabled(App.getApp(), AccessibilityWatchDogService.class)) {
+ errorMessage = App.getApp().getString(R.string.text_auto_operate_service_enabled_but_not_running);
+ } else {
+ if (Pref.def().getBoolean(App.getApp().getString(R.string.key_enable_accessibility_service_by_root), false)) {
+ if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(AccessibilityWatchDogService.class, 3000)) {
+ errorMessage = App.getApp().getString(R.string.text_enable_accessibility_service_by_root_timeout);
+ }
+ } else {
+ errorMessage = App.getApp().getString(R.string.text_no_accessibility_permission);
+ }
+ }
+ if (errorMessage != null) {
+ mRuntime.toast(errorMessage);
+ throw new ScriptStopException(errorMessage);
+ }
+ }
+ }
+
+ @Override
+ public AccessibilityInfoProvider getInfoProvider() {
+ return mAccessibilityInfoProvider;
+ }
+
+ public ScriptEngineService getScriptEngineService() {
+ return mScriptEngineService;
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/Droid.java b/app/src/main/java/com/stardust/scriptdroid/droid/Droid.java
deleted file mode 100644
index a66d08804..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/Droid.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package com.stardust.scriptdroid.droid;
-
-import android.content.Intent;
-import android.support.annotation.NonNull;
-import android.text.TextUtils;
-
-import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.Pref;
-import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
-import com.stardust.scriptdroid.droid.script.JavaScriptEngine;
-import com.stardust.scriptdroid.droid.script.ScriptExecuteActivity;
-import com.stardust.scriptdroid.service.VolumeChangeObverseService;
-import com.stardust.scriptdroid.tool.FileUtils;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.Serializable;
-import java.text.DateFormat;
-import java.util.Date;
-
-import timber.log.Timber;
-
-/**
- * Created by Stardust on 2017/1/23.
- */
-
-public class Droid {
-
- public static final java.lang.String STAY = "\"stay\";";
-
- public static final String UI = "\"ui\";";
-
- public static final String AUTO = "\"auto\";";
-
- public interface OnRunFinishedListener extends Serializable {
- void onRunFinished(Object result);
-
- void onException(@NonNull Exception e);
- }
-
- public static class SimpleOnRunFinishedListener implements OnRunFinishedListener {
-
- @Override
- public void onRunFinished(Object result) {
-
- }
-
- @Override
- public void onException(@NonNull Exception e) {
-
- }
- }
-
- private static final DroidRuntime RUNTIME = DroidRuntime.getRuntime();
- public static final JavaScriptEngine JAVA_SCRIPT_ENGINE = JavaScriptEngine.getDefault();
- private static final OnRunFinishedListener DEFAULT_LISTENER = new SimpleOnRunFinishedListener() {
- @Override
- public void onException(@NonNull Exception e) {
- if (!causedByInterruptedException(e)) {
- RUNTIME.toast(App.getApp().getString(R.string.text_error) + ": " + e.getMessage());
- Timber.e(e.getMessage());
- }
- }
- };
- private static Droid instance = new Droid();
- private VolumeChangeObverseService.OnVolumeChangeListener mOnVolumeChangeListener = new VolumeChangeObverseService.OnVolumeChangeListener() {
- @Override
- public void onVolumeChange() {
- if (Pref.isRunningVolumeControlEnabled()) {
- stopAllAndToast();
- }
- }
- };
-
-
- private Droid() {
- VolumeChangeObverseService.addOnVolumeChangeListener(mOnVolumeChangeListener);
- }
-
- public static Droid getInstance() {
- return instance;
- }
-
- public static boolean causedByInterruptedException(Throwable e) {
- while (e != null) {
- if (e instanceof InterruptedException) {
- return true;
- }
- e = e.getCause();
- }
- return false;
- }
-
- public void runScriptFile(File file) {
- runScriptFile(file, null, new RunningConfig());
- }
-
- public void runScriptFile(File file, OnRunFinishedListener listener, RunningConfig config) {
- Timber.v(DateFormat.getTimeInstance().format(new Date()) + " " + App.getResString(R.string.text_start_running) + " " + file);
- listener = listener == null ? DEFAULT_LISTENER : listener;
- int errorMsgId = PathChecker.check(file.getPath());
- if(errorMsgId != PathChecker.CHECK_RESULT_OK){
- listener.onException(new IOException(App.getResString(errorMsgId)));
- }
- runScript(FileUtils.readString(file), listener, config.path(file.getPath()));
- }
-
-
- public void runScriptFile(String path) {
- runScriptFile(new File(path));
- }
-
- public void runScript(String script) {
- runScript(script, null, RunningConfig.getDefault());
- }
-
- public void runScript(String script, OnRunFinishedListener listener, RunningConfig config) {
- App.getApp().startService(new Intent(App.getApp(), VolumeChangeObverseService.class));
- listener = listener == null ? DEFAULT_LISTENER : listener;
- if (!TextUtils.isEmpty(config.prepareScript))
- script = config.prepareScript + "\n" + script;
- if (config.runInNewThread) {
- if (script.startsWith(UI)) {
- ScriptExecuteActivity.runScript(script, listener, config);
- } else {
- new Thread(new RunScriptRunnable(script, listener, config)).start();
- }
- } else {
- new RunScriptRunnable(script, listener, config).run();
- }
-
- }
-
-
- public int stopAll() {
- return JAVA_SCRIPT_ENGINE.stopAll();
- }
-
-
- public void stopAllAndToast() {
- int n = stopAll();
- if (n > 0)
- RUNTIME.toast(String.format(App.getResString(R.string.text_already_stop_n_scripts), n));
- else
- RUNTIME.toast(App.getResString(R.string.text_no_running_script));
- }
-
- private static class RunScriptRunnable implements Runnable {
-
- private final String mScript;
- private OnRunFinishedListener mOnRunFinishedListener;
-
- RunScriptRunnable(String script, OnRunFinishedListener listener, RunningConfig config) {
- mOnRunFinishedListener = listener;
- mScript = script;
- }
-
- @Override
- public void run() {
- try {
- if (mScript.startsWith(AUTO))
- DroidRuntime.getRuntime().ensureAccessibilityServiceEnabled();
- mOnRunFinishedListener.onRunFinished(JAVA_SCRIPT_ENGINE.execute(mScript));
- } catch (Exception e) {
- mOnRunFinishedListener.onException(e);
- }
- }
-
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/PathChecker.java b/app/src/main/java/com/stardust/scriptdroid/droid/PathChecker.java
deleted file mode 100644
index 29ccbcc84..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/PathChecker.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.stardust.scriptdroid.droid;
-
-import android.app.Activity;
-import android.os.Build;
-import android.text.TextUtils;
-import android.widget.Toast;
-
-import com.stardust.scriptdroid.R;
-
-import java.io.File;
-import java.util.LinkedList;
-import java.util.List;
-
-import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
-/**
- * Created by Stardust on 2017/4/1.
- */
-
-public class PathChecker {
- public static final int CHECK_RESULT_OK = 0;
-
- private Activity mActivity;
-
- public PathChecker(Activity activity) {
- mActivity = activity;
- }
-
-
- public static int check(final String path) {
- if (TextUtils.isEmpty(path))
- return R.string.text_path_is_empty;
- if (!new File(path).exists())
- return R.string.text_file_not_exists;
- return CHECK_RESULT_OK;
- }
-
- public boolean checkAndToastError(String path) {
- int result = checkWithStoragePermission(path);
- if (result != CHECK_RESULT_OK) {
- Toast.makeText(mActivity, result, Toast.LENGTH_SHORT).show();
- return false;
- }
- return true;
- }
-
- private int checkWithStoragePermission(String path) {
- if (!hasStorageReadPermission(mActivity)) {
- return R.string.text_no_file_rw_permission;
- }
- return check(path);
- }
-
- private static boolean hasStorageReadPermission(Activity activity) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
- activity.checkSelfPermission(READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED;
- }
- return true;
- }
-
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/RunningConfig.java b/app/src/main/java/com/stardust/scriptdroid/droid/RunningConfig.java
deleted file mode 100644
index 8b61f3e08..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/RunningConfig.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.stardust.scriptdroid.droid;
-
-import android.app.Activity;
-import android.content.Context;
-
-/**
- * Created by Stardust on 2017/2/1.
- */
-public class RunningConfig {
-
- private static final RunningConfig RUNNING_CONFIG = new RunningConfig();
- public String path;
- public String prepareScript = "";
-
- public static RunningConfig getDefault() {
- return RUNNING_CONFIG;
- }
-
- public boolean runInNewThread = true;
-
- public RunningConfig runInNewThread(boolean runInNewThread) {
- this.runInNewThread = runInNewThread;
- return this;
- }
-
- public RunningConfig path(String path) {
- this.path = path;
- return this;
- }
-
- public RunningConfig prepareScript(String script) {
- this.prepareScript = script;
- return this;
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/DroidRuntime.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/DroidRuntime.java
deleted file mode 100644
index ae5908b63..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/DroidRuntime.java
+++ /dev/null
@@ -1,436 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime;
-
-import android.accessibilityservice.AccessibilityService;
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.os.Environment;
-import android.os.Handler;
-import android.support.annotation.Nullable;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.style.ForegroundColorSpan;
-import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.Toast;
-
-import com.afollestad.materialdialogs.MaterialDialog;
-import com.jraska.console.timber.ConsoleTree;
-import com.stardust.automator.AccessibilityEventCommandHost;
-import com.stardust.scriptdroid.Pref;
-import com.stardust.scriptdroid.accessibility.AccessibilityInfoProvider;
-import com.stardust.scriptdroid.droid.runtime.action.ActionTarget;
-import com.stardust.scriptdroid.droid.runtime.api.UiSelector;
-import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
-import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
-import com.stardust.scriptdroid.tool.IntentTool;
-import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
-import com.jraska.console.Console;
-import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.droid.runtime.action.Action;
-import com.stardust.scriptdroid.droid.runtime.action.ActionFactory;
-import com.stardust.scriptdroid.droid.runtime.action.ActionPerformAccessibilityDelegate;
-import com.stardust.scriptdroid.tool.FileUtils;
-import com.stardust.scriptdroid.tool.Shell;
-import com.stardust.scriptdroid.ui.console.ConsoleActivity;
-import com.stardust.view.accessibility.AccessibilityServiceUtils;
-
-import java.io.File;
-import java.util.List;
-
-import timber.log.Timber;
-
-;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public class DroidRuntime {
-
- static {
- Timber.plant(new ConsoleTree.Builder()
- .minPriority(Log.VERBOSE)
- .verboseColor(0xff909090)
- .debugColor(0xffc88b48)
- .infoColor(0xffc9c9c9)
- .warnColor(0xffa97db6)
- .errorColor(0xffff534e)
- .assertColor(0xffff5540)
- .build());
- }
-
- private static class PerformGlobalActionCommand implements AccessibilityEventCommandHost.Command {
-
- boolean result;
- private int mGlobalAction;
-
- PerformGlobalActionCommand(int globalAction) {
- mGlobalAction = globalAction;
- }
-
- @Override
- public void execute(AccessibilityService service, AccessibilityEvent event) {
- result = service.performGlobalAction(mGlobalAction);
- }
- }
-
- private static final String TAG = "DroidRuntime";
- private static DroidRuntime runtime = new DroidRuntime();
-
- private final Object mActionPerformLock = new Object();
- private Handler mUIHandler;
-
- public static DroidRuntime getRuntime() {
- return runtime;
- }
-
- protected DroidRuntime() {
- mUIHandler = new Handler(App.getApp().getMainLooper());
- }
-
- public boolean launchPackage(String packageName) {
- try {
- PackageManager packageManager = App.getApp().getPackageManager();
- App.getApp().startActivity(packageManager.getLaunchIntentForPackage(packageName));
- return true;
- } catch (Exception e) {
- return false;
- }
-
- }
-
- public boolean launchApp(String appName) {
- return launchPackage(getPackageName(appName));
- }
-
- public String getPackageName(String appName) {
- PackageManager packageManager = App.getApp().getPackageManager();
- List installedApplications = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
- for (ApplicationInfo applicationInfo : installedApplications) {
- if (packageManager.getApplicationLabel(applicationInfo).toString().equals(appName)) {
- return applicationInfo.processName;
- }
- }
- return "";
- }
-
- public boolean openAppSetting(String packageName) {
- return IntentTool.goToAppSetting(App.getApp(), packageName);
- }
-
- public ActionTarget text(String text, int i) {
- return new ActionTarget.TextActionTarget(text, i);
- }
-
- public ActionTarget bounds(int left, int top, int right, int bottom) {
- return new ActionTarget.BoundsActionTarget(new Rect(left, top, right, bottom));
- }
-
- public ActionTarget editable(int i) {
- return new ActionTarget.EditableActionTarget(i);
- }
-
- public ActionTarget id(String id) {
- return new ActionTarget.IdActionTarget(id);
- }
-
- public boolean click(ActionTarget target) {
- return performAction(target.createAction(AccessibilityNodeInfo.ACTION_CLICK));
- }
-
- public boolean longClick(ActionTarget target) {
- return performAction(target.createAction(AccessibilityNodeInfo.ACTION_LONG_CLICK));
- }
-
- public boolean scrollUp(ActionTarget target) {
- return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD));
- }
-
- public boolean scrollDown(ActionTarget target) {
- return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD));
- }
-
- public boolean scrollUp(int i) {
- return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, i));
- }
-
- public boolean scrollDown(int i) {
- return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, i));
- }
-
- public boolean scrollAllUp() {
- return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD));
- }
-
- public boolean scrollAllDown() {
- return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD));
- }
-
- public boolean focus(ActionTarget target) {
- return performAction(target.createAction(AccessibilityNodeInfo.ACTION_FOCUS));
- }
-
- public boolean select(ActionTarget target) {
- return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SELECT));
- }
-
- public boolean setText(ActionTarget target, String text) {
- return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SET_TEXT, text));
- }
-
- public void setClip(final String text) {
- mUIHandler.post(new Runnable() {
- @Override
- public void run() {
- ((ClipboardManager) App.getApp().getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText(TAG, text));
- }
- });
- }
-
- public boolean back() {
- return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
- }
-
- public boolean home() {
- return performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
- }
-
- public boolean powerDialog() {
- return performGlobalAction(AccessibilityService.GLOBAL_ACTION_POWER_DIALOG);
- }
-
- public boolean notifications() {
- return performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS);
- }
-
- public boolean quickSettings() {
- return performGlobalAction(AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS);
- }
-
- public boolean recents() {
- return performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS);
- }
-
- public boolean splitScreen() {
- return performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);
- }
-
- public boolean swipeDown() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_DOWN);
- }
-
- public boolean swipeDownLeft() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_DOWN_AND_LEFT);
- }
-
- public boolean swipeDownRight() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_DOWN_AND_RIGHT);
- }
-
- public boolean swipeDownUp() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_DOWN_AND_UP);
- }
-
- public boolean swipeUp() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_UP);
- }
-
- public boolean swipeUpLeft() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_UP_AND_LEFT);
- }
-
- public boolean swipeUpRight() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_UP_AND_RIGHT);
- }
-
- public boolean swipeUpDown() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_UP_AND_DOWN);
- }
-
- public boolean swipeLeft() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_LEFT);
- }
-
- public boolean swipeLeftRight() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_LEFT_AND_RIGHT);
- }
-
- public boolean swipeLeftUp() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_LEFT_AND_UP);
- }
-
- public boolean swipeLeftDown() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_LEFT_AND_DOWN);
- }
-
- public boolean swipeRight() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_RIGHT);
- }
-
- public boolean swipeRightLeft() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_RIGHT_AND_LEFT);
- }
-
- public boolean swipeRightUp() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_RIGHT_AND_UP);
- }
-
- public boolean swipeRightDown() {
- return performGlobalAction(AccessibilityService.GESTURE_SWIPE_RIGHT_AND_DOWN);
- }
-
- private boolean performGlobalAction(final int action) {
- ensureAccessibilityServiceEnabled();
- PerformGlobalActionCommand command = new PerformGlobalActionCommand(action);
- AccessibilityEventCommandHost.getInstance().executeAndWaitForEvent(command);
- return command.result;
- }
-
- public boolean paste(ActionTarget target) {
- return performAction(target.createAction(AccessibilityNodeInfo.ACTION_PASTE));
- }
-
- public void log(@Nullable Object o) {
- String str = o + "";
- SpannableString spannableString = new SpannableString(str);
- spannableString.setSpan(new ForegroundColorSpan(Color.BLACK), 0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- Console.writeLine(spannableString);
- }
-
- public void err(@Nullable Object o) {
- Timber.e("" + o);
- }
-
- public void console() {
- App.getApp().startActivity(new Intent(App.getApp(), ConsoleActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
- }
-
- public void clearConsole() {
- Console.clear();
- }
-
- private T performAction(Action action) {
- ensureAccessibilityServiceEnabled();
- ActionPerformAccessibilityDelegate.setAction(action);
- synchronized (mActionPerformLock) {
- try {
- mActionPerformLock.wait();
- } catch (InterruptedException e) {
- ActionPerformAccessibilityDelegate.setAction(ActionPerformAccessibilityDelegate.NO_ACTION);
- throw new ScriptStopException(App.getApp().getString(R.string.text_script_stopped), e);
- }
- }
- return (T) action.getResult();
- }
-
- public void ensureAccessibilityServiceEnabled() {
- if (AccessibilityWatchDogService.getInstance() == null) {
- String errorMessage = null;
- if (AccessibilityServiceUtils.isAccessibilityServiceEnabled(App.getApp(), AccessibilityWatchDogService.class)) {
- errorMessage = App.getApp().getString(R.string.text_auto_operate_service_enabled_but_not_running);
- } else {
- if (Pref.def().getBoolean(App.getApp().getString(R.string.key_enable_accessibility_service_by_root), false)) {
- if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(AccessibilityWatchDogService.class, 3000)) {
- errorMessage = App.getApp().getString(R.string.text_enable_accessibility_service_by_root_timeout);
- }
- } else {
- errorMessage = App.getApp().getString(R.string.text_no_accessibility_permission);
- }
- }
- if (errorMessage != null) {
- toast(errorMessage);
- throw new ScriptStopException(errorMessage);
- }
- }
- }
-
- public void toast(final String text) {
- mUIHandler.post(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(App.getApp(), text, Toast.LENGTH_SHORT).show();
- }
- });
- }
-
- public void sleep(long millis) {
- try {
- Thread.sleep(millis);
- } catch (InterruptedException e) {
- throw new ScriptStopException(e);
- }
- }
-
- public void addAccessibilityEventListener(final Object delegate) {
- if (delegate == null)
- return;
-
- }
-
- public Shell.CommandResult shell(String cmd, int root) {
- return Shell.execCommand(cmd, root != 0);
- }
-
- public String currentPackage() {
- ensureAccessibilityServiceEnabled();
- return AccessibilityInfoProvider.getInstance().getLatestPackage();
- }
-
- public String currentActivity() {
- ensureAccessibilityServiceEnabled();
- return AccessibilityInfoProvider.getInstance().getLatestActivity();
- }
-
- public UiSelector selector() {
- return new UiSelector();
- }
-
- public boolean isStopped() {
- return Thread.currentThread().isInterrupted();
- }
-
- public void stop() {
- Thread.interrupted();
- }
-
- public String readFile(String path) {
- return FileUtils.readString(new File(Environment.getExternalStorageDirectory() + "/" + path));
- }
-
- public ThemeColorMaterialDialogBuilder dialog() {
- if (App.currentActivity() == null) {
- throw new ScriptStopException(App.getApp().getString(R.string.text_cannot_create_dialog_when_app_invisible));
- }
- return new ThemeColorMaterialDialogBuilder(App.currentActivity()) {
-
- public MaterialDialog show() {
- mUIHandler.post(new Runnable() {
- @Override
- public void run() {
- superShow();
- }
- });
- return null;
- }
-
- private void superShow() {
- super.show();
- }
- };
- }
-
- public void notifyActionPerformed() {
- synchronized (mActionPerformLock) {
- mActionPerformLock.notify();
- }
- }
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/ScriptStopException.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/ScriptStopException.java
deleted file mode 100644
index b31da3a15..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/ScriptStopException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime;
-
-/**
- * Created by Stardust on 2017/1/29.
- */
-public class ScriptStopException extends RuntimeException {
-
-
- public ScriptStopException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public ScriptStopException(String message) {
- super(message);
- }
-
- public ScriptStopException() {
-
- }
-
- public ScriptStopException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/Able.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/Able.java
deleted file mode 100644
index 4042385ea..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/Able.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.util.SparseArray;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.stardust.util.SparseArrayEntries;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public interface Able {
-
- SparseArray ABLE_MAP = new SparseArrayEntries()
- .entry(AccessibilityNodeInfo.ACTION_CLICK, new Able() {
- @Override
- public boolean isAble(AccessibilityNodeInfo nodeInfo) {
- return nodeInfo.isClickable();
- }
- })
- .entry(AccessibilityNodeInfo.ACTION_LONG_CLICK, new Able() {
- @Override
- public boolean isAble(AccessibilityNodeInfo nodeInfo) {
- return nodeInfo.isLongClickable();
- }
- })
- .entry(AccessibilityNodeInfo.ACTION_FOCUS, new Able() {
- @Override
- public boolean isAble(AccessibilityNodeInfo nodeInfo) {
- return nodeInfo.isFocusable();
- }
- })
- .entry(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, new Able() {
- @Override
- public boolean isAble(AccessibilityNodeInfo nodeInfo) {
- return nodeInfo.isScrollable();
- }
- })
- .entry(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, new Able() {
- @Override
- public boolean isAble(AccessibilityNodeInfo nodeInfo) {
- return nodeInfo.isScrollable();
- }
- })
- .sparseArray();
-
- boolean isAble(AccessibilityNodeInfo node);
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/Action.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/Action.java
deleted file mode 100644
index 1513667e0..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/Action.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.view.accessibility.AccessibilityNodeInfo;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public abstract class Action {
-
- private boolean mPerformUtilSucceed = false;
- private volatile Object mResult = false;
-
- public Action(boolean performUtilSucceed) {
- mPerformUtilSucceed = performUtilSucceed;
- }
-
- public Action() {
- this(false);
- }
-
- public abstract boolean perform(AccessibilityNodeInfo root);
-
- public boolean performUtilSucceed() {
- return mPerformUtilSucceed;
- }
-
- public Action setPerformUtilSucceed(boolean performUtilSucceed) {
- mPerformUtilSucceed = performUtilSucceed;
- return this;
- }
-
- public Object getResult() {
- return mResult;
- }
-
- public void setResult(Object result) {
- mResult = result;
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionFactory.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionFactory.java
deleted file mode 100644
index efdb4d80f..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionFactory.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.stardust.util.MapEntries;
-
-import java.util.Map;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public class ActionFactory {
-
- private static Map searchUpAction = new MapEntries()
- .entry(AccessibilityNodeInfo.ACTION_CLICK, null)
- .entry(AccessibilityNodeInfo.ACTION_LONG_CLICK, null)
- .entry(AccessibilityNodeInfo.ACTION_SELECT, null)
- .entry(AccessibilityNodeInfo.ACTION_FOCUS, null)
- .entry(AccessibilityNodeInfo.ACTION_SELECT, null)
- .entry(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, null)
- .entry(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, null)
- .map();
-
- public static Action createActionWithTextFilter(int action, String text, int index) {
- if (searchUpAction.containsKey(action))
- return new SearchUpTargetAction(action, new FilterAction.TextFilter(text, index));
- else
- return new DepthFirstSearchTargetAction(action, new FilterAction.TextFilter(text, index));
- }
-
- public static Action createActionWithBoundsFilter(int action, Rect rect) {
- if (searchUpAction.containsKey(action))
- return new SearchUpTargetAction(action, new FilterAction.BoundsFilter(rect));
- else
- return new DepthFirstSearchTargetAction(action, new FilterAction.BoundsFilter(rect));
- }
-
- public static Action createActionWithEditableFilter(int action, int index, final String text) {
- return new SearchTargetAction(action, new FilterAction.EditableFilter(index)) {
-
- @Override
- protected void performAction(AccessibilityNodeInfo node) {
- Bundle args = new Bundle();
- args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
- node.performAction(getAction(), args);
- }
- };
- }
-
- public static Action createScrollMaxAction(int action) {
- return new ScrollMaxAction(action);
- }
-
- public static Action createScrollAction(int action, int i) {
- return new ScrollAction(action, i);
- }
-
- public static Action createActionWithIdFilter(int action, String id) {
- return new FilterAction.SimpleFilterAction(action, new FilterAction.IdFilter(id));
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformAccessibilityDelegate.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformAccessibilityDelegate.java
deleted file mode 100644
index 4779b7868..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformAccessibilityDelegate.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.accessibilityservice.AccessibilityService;
-import android.content.ComponentName;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
-import com.stardust.view.accessibility.AccessibilityDelegate;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-
-
-/**
- * Created by Stardust on 2017/1/21.
- */
-
-public class ActionPerformAccessibilityDelegate implements AccessibilityDelegate {
-
- private static final String TAG = "ActionPerformDelegate";
-
- public static final Action NO_ACTION = null;
-
- private static final Object ACTION_LOCK = new Object();
-
- private static Action action;
-
- //private Executor mExecutor = Executors.newFixedThreadPool(5);
-
- public static void setAction(Action action) {
- synchronized (ACTION_LOCK) {
- ActionPerformAccessibilityDelegate.action = action;
- }
- }
-
- @Override
- public boolean onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event) {
- synchronized (ACTION_LOCK) {
- if (action == NO_ACTION)
- return false;
- AccessibilityNodeInfo root = service.getRootInActiveWindow();
- if (root == null) {
- Log.v(TAG, "root = null");
- return false;
- }
- performAction(root, action);
- return false;
- }
- }
-
- private void performAction(final AccessibilityNodeInfo root, final Action action) {
- new Runnable() {
- @Override
- public void run() {
- Log.i(TAG, "perform action:" + action);
- if (action.perform(root)) {
- action.setResult(true);
- onActionPerformed();
- } else if (!action.performUtilSucceed()) {
- action.setResult(false);
- onActionPerformed();
- }
- }
- }.run();
- }
-
-
- private void onActionPerformed() {
- synchronized (ACTION_LOCK) {
- action = NO_ACTION;
- DroidRuntime.getRuntime().notifyActionPerformed();
- }
- }
-
-
-}
-
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionTarget.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionTarget.java
deleted file mode 100644
index 6a37b8e75..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionTarget.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.graphics.Rect;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public interface ActionTarget {
-
- Action createAction(int action, Object... params);
-
- class TextActionTarget implements ActionTarget {
-
- String mText;
- int mIndex;
-
- public TextActionTarget(String text, int i) {
- mText = text;
- mIndex = i;
- }
-
- @Override
- public Action createAction(int action, Object... params) {
- return ActionFactory.createActionWithTextFilter(action, mText, mIndex);
- }
- }
-
- class BoundsActionTarget implements ActionTarget {
-
- Rect mBoundsInRect;
-
- public BoundsActionTarget(Rect rect) {
- mBoundsInRect = rect;
- }
-
- @Override
- public Action createAction(int action, Object... params) {
- return ActionFactory.createActionWithBoundsFilter(action, mBoundsInRect);
- }
- }
-
- class EditableActionTarget implements ActionTarget {
- private int mIndex;
-
- public EditableActionTarget(int index) {
- mIndex = index;
- }
-
- @Override
- public Action createAction(int action, Object... params) {
- return ActionFactory.createActionWithEditableFilter(action, mIndex, params[0].toString());
- }
- }
-
- class IdActionTarget implements ActionTarget {
- private String mId;
-
- public IdActionTarget(String id) {
- mId = id;
- }
-
- @Override
- public Action createAction(int action, Object... params) {
- return ActionFactory.createActionWithIdFilter(action, mId);
- }
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/DepthFirstSearchTargetAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/DepthFirstSearchTargetAction.java
deleted file mode 100644
index 261f3f331..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/DepthFirstSearchTargetAction.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.view.accessibility.AccessibilityNodeInfo;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public class DepthFirstSearchTargetAction extends SearchTargetAction {
-
-
- private Able mAble;
-
- public DepthFirstSearchTargetAction(int action, Filter filter) {
- super(action, filter);
- mAble = Able.ABLE_MAP.get(action);
- }
-
-
- @Override
- public AccessibilityNodeInfo searchTarget(AccessibilityNodeInfo n) {
- if (n == null)
- return null;
- if (mAble.isAble(n))
- return n;
- for (int i = 0; i < n.getChildCount(); i++) {
- AccessibilityNodeInfo child = n.getChild(i);
- if (child == null)
- continue;
- AccessibilityNodeInfo node = searchTarget(child);
- if (node != null)
- return node;
- else
- child.recycle();
- }
- return null;
- }
-
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/FilterAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/FilterAction.java
deleted file mode 100644
index 40d2a05fc..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/FilterAction.java
+++ /dev/null
@@ -1,165 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.graphics.Rect;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public abstract class FilterAction extends Action {
-
-
- public interface Filter {
-
- List filter(AccessibilityNodeInfo root);
- }
-
- public static class TextFilter implements Filter {
-
- String mText;
- int mIndex;
-
- public TextFilter(String text, int index) {
- mText = text;
- mIndex = index;
- }
-
- @Override
- public List filter(AccessibilityNodeInfo root) {
-
- List list = root.findAccessibilityNodeInfosByText(mText);
- if (mIndex == -1)
- return list;
- if (mIndex >= list.size())
- return Collections.EMPTY_LIST;
- return Collections.singletonList(list.get(mIndex));
- }
- }
-
- public static class BoundsFilter implements Filter {
-
- Rect mBoundsInScreen;
-
- public BoundsFilter(Rect boundsInScreen) {
- mBoundsInScreen = boundsInScreen;
- }
-
- @Override
- public List filter(AccessibilityNodeInfo root) {
- return Collections.singletonList(findAccessibilityNodeInfosByBounds(root));
- }
-
- private AccessibilityNodeInfo findAccessibilityNodeInfosByBounds(AccessibilityNodeInfo root) {
- if (root == null)
- return null;
- Rect rect = new Rect();
- root.getBoundsInScreen(rect);
- if (rect.equals(mBoundsInScreen)) {
- return root;
- }
- for (int i = 0; i < root.getChildCount(); i++) {
- AccessibilityNodeInfo child = root.getChild(i);
- if (child == null)
- continue;
- AccessibilityNodeInfo nodeInfo = findAccessibilityNodeInfosByBounds(child);
- if (nodeInfo != null)
- return nodeInfo;
- else
- child.recycle();
- }
- return null;
- }
- }
-
- public static class EditableFilter implements Filter {
-
- private int mIndex;
-
- public EditableFilter(int index) {
- mIndex = index;
- }
-
- @Override
- public List filter(AccessibilityNodeInfo root) {
- List editableList = findEditable(root);
- if (mIndex == -1)
- return editableList;
- if (mIndex >= editableList.size())
- return Collections.EMPTY_LIST;
- return Collections.singletonList(editableList.get(mIndex));
- }
-
- @SuppressWarnings("unchecked")
- public static List findEditable(AccessibilityNodeInfo root) {
- if (root == null) {
- return Collections.EMPTY_LIST;
- }
- if (root.isEditable()) {
- return Collections.singletonList(root);
- }
- List list = new LinkedList<>();
- for (int i = 0; i < root.getChildCount(); i++) {
- list.addAll(findEditable(root.getChild(i)));
- }
- return list;
- }
- }
-
- public static class IdFilter implements Filter {
-
- private final String mId;
-
- public IdFilter(String id) {
- this.mId = id;
- }
-
- @Override
- public List filter(AccessibilityNodeInfo root) {
- return root.findAccessibilityNodeInfosByViewId(mId);
- }
- }
-
-
- private Filter mFilter;
-
- public FilterAction(Filter filter) {
- mFilter = filter;
- }
-
- public boolean perform(AccessibilityNodeInfo root) {
- if (root == null)
- return false;
- return perform(mFilter.filter(root));
- }
-
- public abstract boolean perform(List nodes);
-
- public static class SimpleFilterAction extends FilterAction {
-
- private int mAction;
-
- public SimpleFilterAction(int action, Filter filter) {
- super(filter);
- mAction = action;
- }
-
- @Override
- public boolean perform(List nodes) {
- if(nodes == null || nodes.isEmpty())
- return false;
- boolean succeed = true;
- for(AccessibilityNodeInfo nodeInfo : nodes){
- if(!nodeInfo.performAction(mAction)){
- succeed = false;
- }
- }
- return succeed;
- }
- }
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/GetTextAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/GetTextAction.java
deleted file mode 100644
index 6e9003743..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/GetTextAction.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by Stardust on 2017/2/14.
- */
-
-public class GetTextAction extends Action {
-
-
- @Override
- public boolean perform(AccessibilityNodeInfo root) {
- List texts = new ArrayList<>();
- getText(root, texts);
- super.setResult(texts);
- return true;
- }
-
- private void getText(AccessibilityNodeInfo nodeInfo, List texts) {
- CharSequence text = nodeInfo.getText();
- if (text != null && text.length() != 0) {
- texts.add(text.toString());
- }
- for (int i = 0; i < nodeInfo.getChildCount(); i++) {
- AccessibilityNodeInfo child = nodeInfo.getChild(i);
- if (child != null) {
- getText(child, texts);
- child.recycle();
- }
- }
- }
-
- @Override
- public void setResult(Object result) {
- if (result instanceof List)
- super.setResult(result);
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollAction.java
deleted file mode 100644
index e66915fb9..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollAction.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by Stardust on 2017/2/12.
- */
-public class ScrollAction extends Action {
-
- private int mIndex, mAction;
-
- public ScrollAction(int action, int i) {
- mAction = action;
- mIndex = i;
- }
-
- @Override
- public boolean perform(AccessibilityNodeInfo root) {
- List scrollableNodes = findScrollableNodes(root);
- boolean result = mIndex < scrollableNodes.size() && scrollableNodes.get(mIndex).performAction(mAction);
- recycle(scrollableNodes, root);
- return result;
- }
-
- private void recycle(List list, AccessibilityNodeInfo root) {
- for (AccessibilityNodeInfo nodeInfo : list) {
- if (nodeInfo != root)
- nodeInfo.recycle();
- }
- }
-
- private List findScrollableNodes(AccessibilityNodeInfo root) {
- List list = new ArrayList<>();
- findScrollableNodes(root, list);
- return list;
- }
-
- private static boolean findScrollableNodes(AccessibilityNodeInfo node, List list) {
- if (node == null) {
- return false;
- }
- if (node.isScrollable()) {
- list.add(node);
- }
- for (int i = 0; i < node.getChildCount(); i++) {
- AccessibilityNodeInfo child = node.getChild(i);
- if (child == null)
- continue;
- if (!findScrollableNodes(child, list))
- child.recycle();
- }
- return node.isScrollable();
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollMaxAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollMaxAction.java
deleted file mode 100644
index 4057c48ef..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollMaxAction.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.graphics.Rect;
-import android.util.Log;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public class ScrollMaxAction extends Action {
-
- private static final String TAG = ScrollMaxAction.class.getSimpleName();
- private int mScrollAction;
- private AccessibilityNodeInfo mMaxScrollableNode;
- private AccessibilityNodeInfo mRootNode;
-
- public ScrollMaxAction(int scrollAction) {
- mScrollAction = scrollAction;
- }
-
- @Override
- public boolean perform(AccessibilityNodeInfo rootNodeInfo) {
- reset();
- mRootNode = rootNodeInfo;
- findMaxScrollableNodeInfo(rootNodeInfo);
- boolean result = mMaxScrollableNode != null && mMaxScrollableNode.performAction(mScrollAction);
- reset();
- return result;
- }
-
- private void reset() {
- if (mMaxScrollableNode != null && mMaxScrollableNode != mRootNode) {
- mMaxScrollableNode.recycle();
- }
- mMaxScrollableNode = mRootNode = null;
- }
-
- private void findMaxScrollableNodeInfo(AccessibilityNodeInfo nodeInfo) {
- if (nodeInfo == null)
- return;
- if (nodeInfo.isScrollable()) {
- if (mMaxScrollableNode == null) {
- mMaxScrollableNode = nodeInfo;
- } else if (getAreaInScreen(mMaxScrollableNode) < getAreaInScreen(nodeInfo)) {
- if (mMaxScrollableNode != mRootNode)
- mMaxScrollableNode.recycle();
- mMaxScrollableNode = nodeInfo;
- }
- }
- for (int i = 0; i < nodeInfo.getChildCount(); i++) {
- AccessibilityNodeInfo child = nodeInfo.getChild(i);
- if (child != null) {
- findMaxScrollableNodeInfo(child);
- if (mMaxScrollableNode != child) {
- child.recycle();
- }
- }
- }
- }
-
- private long getAreaInScreen(AccessibilityNodeInfo nodeInfo) {
- Rect rect = new Rect();
- nodeInfo.getBoundsInScreen(rect);
- long area = ((long) rect.width()) * rect.height();
- Log.v(TAG, "area=" + area);
- return area;
- }
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/SearchTargetAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/SearchTargetAction.java
deleted file mode 100644
index 6e07ec830..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/SearchTargetAction.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import java.util.List;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public abstract class SearchTargetAction extends FilterAction {
-
- private int mAction;
-
- public SearchTargetAction(int action, Filter filter) {
- super(filter);
- mAction = action;
- }
-
-
- @Override
- public boolean perform(List nodes) {
- boolean performed = false;
- for (AccessibilityNodeInfo node : nodes) {
- node = searchTarget(node);
- if (node != null) {
- performAction(node);
- performed = true;
- }
- }
- return performed;
- }
-
- protected void performAction(AccessibilityNodeInfo node) {
- node.performAction(mAction);
- }
-
- public int getAction(){
- return mAction;
- }
-
- public AccessibilityNodeInfo searchTarget(AccessibilityNodeInfo node) {
- return node;
- }
-
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/SearchUpTargetAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/SearchUpTargetAction.java
deleted file mode 100644
index 117f628cc..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/SearchUpTargetAction.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.view.accessibility.AccessibilityNodeInfo;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public class SearchUpTargetAction extends SearchTargetAction {
-
- private Able mAble;
-
- public SearchUpTargetAction(int action, Filter filter) {
- super(action, filter);
- mAble = Able.ABLE_MAP.get(action);
- }
-
- @Override
- public AccessibilityNodeInfo searchTarget(AccessibilityNodeInfo n) {
- AccessibilityNodeInfo node = n;
- while (node != null && !mAble.isAble(node)) {
- AccessibilityNodeInfo parent = node.getParent();
- if (node != n) {
- node.recycle();
- }
- node = parent;
- }
- return node;
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/InjectableWebClient.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/InjectableWebClient.java
deleted file mode 100644
index 625794851..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/InjectableWebClient.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.api;
-
-import android.annotation.SuppressLint;
-import android.util.Log;
-import android.util.Pair;
-import android.webkit.JavascriptInterface;
-import android.webkit.ValueCallback;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import com.stardust.scriptdroid.droid.runtime.ScriptStopException;
-
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.Scriptable;
-
-import java.util.LinkedList;
-import java.util.Queue;
-
-/**
- * Created by Stardust on 2017/4/1.
- */
-
-public class InjectableWebClient extends WebViewClient {
-
- private static final String TAG = "InjectableWebClient";
-
- private Queue>> mToInjectJavaScripts = new LinkedList<>();
- private final ValueCallback defaultCallback = new ValueCallback() {
- @Override
- public void onReceiveValue(String value) {
- Log.i(TAG, "onReceiveValue: " + value);
- }
- };
- private WebView mWebView;
- private Context mContext;
- private Scriptable mScriptable;
- private ScriptBridge mScriptBridge = new ScriptBridge();
-
- public InjectableWebClient(Context context, Scriptable scriptable) {
- mContext = context;
- mScriptable = scriptable;
- }
-
- @Override
- public void onPageFinished(WebView view, String url) {
- mWebView = view;
- setUpWebView(view);
- while (!mToInjectJavaScripts.isEmpty()) {
- Pair> pair = mToInjectJavaScripts.poll();
- inject(view, pair.first, pair.second);
- }
- super.onPageFinished(view, url);
- }
-
- @SuppressLint("SetJavaScriptEnabled")
- private void setUpWebView(WebView view) {
- view.addJavascriptInterface(mScriptBridge, "rhino");
- WebSettings webSettings = view.getSettings();
- webSettings.setJavaScriptEnabled(true);
- webSettings.setAllowUniversalAccessFromFileURLs(true);
- }
-
- private void inject(WebView view, String script, ValueCallback callback) {
- view.evaluateJavascript(script, callback);
- }
-
- public void inject(String script, ValueCallback callback) {
- if (mWebView != null) {
- inject(mWebView, script, callback);
- return;
- }
- mToInjectJavaScripts.offer(new Pair<>(script, callback));
- }
-
- public void inject(String script) {
- inject(script, defaultCallback);
- }
-
- public String injectAndWait(String script) {
- InjectReturnCallback callback = new InjectReturnCallback();
- inject(script, callback);
- return callback.waitResult();
- }
-
-
- private class ScriptBridge {
-
- private Object result;
-
- @JavascriptInterface
- public String eval(final String script) {
- result = null;
- mWebView.post(new Runnable() {
- @Override
- public void run() {
- Log.v(TAG, "ScriptBridge.eval: " + script);
- result = mContext.evaluateString(mScriptable, script, "", 1, null);
- Log.v(TAG, "ScriptBridge.eval = " + result);
- synchronized (ScriptBridge.this) {
- ScriptBridge.this.notify();
- }
- }
- });
- synchronized (ScriptBridge.this) {
- try {
- ScriptBridge.this.wait();
- } catch (InterruptedException e) {
- throw new ScriptStopException(e);
- }
- }
- return result.toString();
- }
- }
-
- private static class InjectReturnCallback implements ValueCallback {
-
- private String result;
-
- @Override
- public void onReceiveValue(String value) {
- result = value;
- synchronized (this) {
- this.notify();
- }
- }
-
- String waitResult() {
- synchronized (this) {
- try {
- this.wait();
- } catch (InterruptedException e) {
- throw new ScriptStopException(e);
- }
- }
- return result;
- }
- }
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/InjectableWebView.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/InjectableWebView.java
deleted file mode 100644
index 9e115e372..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/InjectableWebView.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.api;
-
-import android.content.Context;
-import android.os.Build;
-import android.support.annotation.RequiresApi;
-import android.util.AttributeSet;
-import android.util.Pair;
-import android.webkit.ValueCallback;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import org.mozilla.javascript.Scriptable;
-
-/**
- * Created by Stardust on 2017/4/1.
- */
-
-public class InjectableWebView extends WebView {
-
- private InjectableWebClient mInjectableWebClient;
-
- public InjectableWebView(Context context, org.mozilla.javascript.Context jsCtx, Scriptable scriptable) {
- super(context);
- init(jsCtx, scriptable);
- }
-
- private void init(org.mozilla.javascript.Context jsCtx, Scriptable scriptable) {
- mInjectableWebClient = new InjectableWebClient(jsCtx, scriptable);
- setWebViewClient(mInjectableWebClient);
- }
-
- public void inject(String script, ValueCallback callback) {
- mInjectableWebClient.inject(script, callback);
- }
-
- public void inject(String script) {
- mInjectableWebClient.inject(script);
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/Shell.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/Shell.java
deleted file mode 100644
index 4d4b75565..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/Shell.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.api;
-
-/**
- * Created by Stardust on 2017/3/7.
- */
-
-public class Shell extends com.stardust.scriptdroid.tool.Shell {
-
- public Shell(boolean root) {
- super(root);
- }
-
- public void Tap(int x, int y) {
- execute("input tap " + x + " " + y);
- }
-
- public void Swipe(int x1, int y1, int x2, int y2) {
- execute("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2);
- }
-
- public void Swipe(int x1, int y1, int x2, int y2, long duration) {
- execute("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + duration);
- }
-
- public void KeyCode(int keyCode) {
- execute("input keyevent " + keyCode);
- }
-
- public void KeyCode(String keyCode) {
- execute("input keyevent " + keyCode);
- }
-
- public void Home() {
- KeyCode(3);
- }
-
- public void Back() {
- KeyCode(4);
- }
-
- public void Power() {
- KeyCode(26);
- }
-
- public void Up() {
- KeyCode(19);
- }
-
- public void Down() {
- KeyCode(20);
- }
-
- public void Left() {
- KeyCode(21);
- }
-
- public void Right() {
- KeyCode(22);
- }
-
- public void OK() {
- KeyCode(23);
- }
-
- public void VolumeUp() {
- KeyCode(24);
- }
-
- public void VolumeDown() {
- KeyCode(25);
- }
-
- public void Menu() {
- KeyCode(1);
- }
-
- public void Camera() {
- KeyCode(27);
- }
-
- public void Text(String text) {
- execute("input text " + text);
- }
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/script/JavaScriptEngine.java b/app/src/main/java/com/stardust/scriptdroid/droid/script/JavaScriptEngine.java
deleted file mode 100644
index 881a450aa..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/script/JavaScriptEngine.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.stardust.scriptdroid.droid.script;
-
-import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.BuildConfig;
-import com.stardust.scriptdroid.tool.FileUtils;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public abstract class JavaScriptEngine {
-
- private static JavaScriptEngine defaultEngine;
-
- public static JavaScriptEngine getDefault() {
- return defaultEngine;
- }
-
- public static void setDefault(JavaScriptEngine engine) {
- defaultEngine = engine;
- }
-
- Map mVariableMap = new HashMap<>();
-
- public abstract Object execute(String script);
-
- public void set(String varName, Object value) {
- mVariableMap.put(varName, value);
- }
-
- public abstract void removeAndDestroy();
-
- public abstract int stopAll();
-
- public abstract String[] getGlobalFunctions();
-
- static class Init {
- private static final String INIT_SCRIPT = readInitScript();
-
- private static String readInitScript() {
- try {
- return FileUtils.readString(App.getApp().getAssets().open("javasccript_engine_init.js"));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- static String getInitScript() {
- if (BuildConfig.DEBUG) {
- // 调试时不缓存INIT_SCRIPT否则修改javasccript_engine_init.js后不会更新
- return readInitScript();
- } else {
- return INIT_SCRIPT;
- }
- }
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/script/NodeJsJavaScriptEngine.java b/app/src/main/java/com/stardust/scriptdroid/droid/script/NodeJsJavaScriptEngine.java
deleted file mode 100644
index c90f79415..000000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/script/NodeJsJavaScriptEngine.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.stardust.scriptdroid.droid.script;
-
-import com.iwebpp.node.Dns;
-import com.iwebpp.node.NodeContext;
-import com.iwebpp.node.Url;
-import com.iwebpp.node.http.http;
-import com.iwebpp.node.js.rhino.Host;
-import com.iwebpp.node.stream.Duplex;
-import com.iwebpp.node.stream.PassThrough;
-import com.iwebpp.node.stream.Readable2;
-import com.iwebpp.node.stream.Transform;
-import com.iwebpp.node.stream.Writable2;
-import com.iwebpp.nodeandroid.MainActivity;
-import com.iwebpp.nodeandroid.Toaster;
-import com.iwebpp.wspp.WebSocketServer;
-import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.droid.Droid;
-import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
-import com.stardust.scriptdroid.tool.FileUtils;
-
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.Scriptable;
-import org.mozilla.javascript.ScriptableObject;
-
-import java.io.IOException;
-
-/**
- * Created by Stardust on 2017/3/25.
- */
-
-public class NodeJsJavaScriptEngine extends RhinoJavaScriptEngine {
-
- public NodeJsJavaScriptEngine(DroidRuntime runtime) {
- super(runtime);
- }
-
-
- @Override
- public Object execute(String script) {
- NodeContext nodectx = new NodeContext();
- Context context = createContext();
- Scriptable scope = createScope(context);
- ScriptableObject.putProperty(scope, "NodeCurrentContext", Context.javaToJS(nodectx, scope));
- init(context, scope);
- Object result = context.evaluateString(scope, script, "