├── .gitattributes ├── .gitignore ├── AndroidManifest.xml ├── README.md ├── assets └── xposed_init ├── build.gradle ├── gradlew ├── gradlew.bat ├── res ├── drawable-hdpi │ ├── ic_add_bookmark_white.png │ ├── ic_add_home_white.png │ ├── ic_add_white.png │ ├── ic_added_bookmark_white.png │ ├── ic_back_white.png │ ├── ic_bookmarks_white.png │ ├── ic_clear_white.png │ ├── ic_close_all_white.png │ ├── ic_close_tab_white.png │ ├── ic_data_saver_off_white.png │ ├── ic_data_saver_white.png │ ├── ic_desktop_site_white.png │ ├── ic_direct_share_white.png │ ├── ic_downloads_white.png │ ├── ic_edit_url_white.png │ ├── ic_exit_home_white.png │ ├── ic_exit_white.png │ ├── ic_expand_notifications_white.png │ ├── ic_find_white.png │ ├── ic_forward_white.png │ ├── ic_fullscreen_exit_white.png │ ├── ic_fullscreen_white.png │ ├── ic_help_white.png │ ├── ic_history_white.png │ ├── ic_launch_white.png │ ├── ic_launcher.png │ ├── ic_mobile_site_white.png │ ├── ic_most_visited_white.png │ ├── ic_new_incognito_white.png │ ├── ic_new_tab_white.png │ ├── ic_next_tab_white.png │ ├── ic_prev_tab_white.png │ ├── ic_print_white.png │ ├── ic_reader_mode_white.png │ ├── ic_recent_apps.png │ ├── ic_recent_tabs_white.png │ ├── ic_refresh_white.png │ ├── ic_reload_white.png │ ├── ic_restore_page_white.png │ ├── ic_scroll_bottom_white.png │ ├── ic_scroll_top_white.png │ ├── ic_settings_white.png │ ├── ic_share_white.png │ ├── ic_show_tabs_white.png │ ├── ic_stop_white.png │ └── ic_voice_search_white.png ├── drawable-mdpi │ ├── ic_add_bookmark_white.png │ ├── ic_add_home_white.png │ ├── ic_add_white.png │ ├── ic_added_bookmark_white.png │ ├── ic_back_white.png │ ├── ic_bookmarks_white.png │ ├── ic_clear_white.png │ ├── ic_close_all_white.png │ ├── ic_close_tab_white.png │ ├── ic_data_saver_off_white.png │ ├── ic_data_saver_white.png │ ├── ic_desktop_site_white.png │ ├── ic_direct_share_white.png │ ├── ic_downloads_white.png │ ├── ic_edit_url_white.png │ ├── ic_exit_home_white.png │ ├── ic_exit_white.png │ ├── ic_expand_notifications_white.png │ ├── ic_find_white.png │ ├── ic_forward_white.png │ ├── ic_fullscreen_exit_white.png │ ├── ic_fullscreen_white.png │ ├── ic_help_white.png │ ├── ic_history_white.png │ ├── ic_launch_white.png │ ├── ic_launcher.png │ ├── ic_mobile_site_white.png │ ├── ic_most_visited_white.png │ ├── ic_new_incognito_white.png │ ├── ic_new_tab_white.png │ ├── ic_next_tab_white.png │ ├── ic_prev_tab_white.png │ ├── ic_print_white.png │ ├── ic_reader_mode_white.png │ ├── ic_recent_apps.png │ ├── ic_recent_tabs_white.png │ ├── ic_refresh_white.png │ ├── ic_reload_white.png │ ├── ic_restore_page_white.png │ ├── ic_scroll_bottom_white.png │ ├── ic_scroll_top_white.png │ ├── ic_settings_white.png │ ├── ic_share_white.png │ ├── ic_show_tabs_white.png │ ├── ic_stop_white.png │ └── ic_voice_search_white.png ├── drawable-xhdpi │ ├── ic_add_bookmark_white.png │ ├── ic_add_home_white.png │ ├── ic_add_white.png │ ├── ic_added_bookmark_white.png │ ├── ic_back_white.png │ ├── ic_bookmarks_white.png │ ├── ic_clear_white.png │ ├── ic_close_all_white.png │ ├── ic_close_tab_white.png │ ├── ic_data_saver_off_white.png │ ├── ic_data_saver_white.png │ ├── ic_desktop_site_white.png │ ├── ic_direct_share_white.png │ ├── ic_downloads_white.png │ ├── ic_edit_url_white.png │ ├── ic_exit_home_white.png │ ├── ic_exit_white.png │ ├── ic_expand_notifications_white.png │ ├── ic_find_white.png │ ├── ic_forward_white.png │ ├── ic_fullscreen_exit_white.png │ ├── ic_fullscreen_white.png │ ├── ic_help_white.png │ ├── ic_history_white.png │ ├── ic_launch_white.png │ ├── ic_launcher.png │ ├── ic_mobile_site_white.png │ ├── ic_most_visited_white.png │ ├── ic_new_incognito_white.png │ ├── ic_new_tab_white.png │ ├── ic_next_tab_white.png │ ├── ic_prev_tab_white.png │ ├── ic_print_white.png │ ├── ic_reader_mode_white.png │ ├── ic_recent_apps.png │ ├── ic_recent_tabs_white.png │ ├── ic_refresh_white.png │ ├── ic_reload_white.png │ ├── ic_restore_page_white.png │ ├── ic_scroll_bottom_white.png │ ├── ic_scroll_top_white.png │ ├── ic_settings_white.png │ ├── ic_share_white.png │ ├── ic_show_tabs_white.png │ ├── ic_stop_white.png │ └── ic_voice_search_white.png ├── drawable-xxhdpi │ ├── ic_add_bookmark_white.png │ ├── ic_add_home_white.png │ ├── ic_add_white.png │ ├── ic_added_bookmark_white.png │ ├── ic_back_white.png │ ├── ic_bookmarks_white.png │ ├── ic_clear_white.png │ ├── ic_close_all_white.png │ ├── ic_close_tab_white.png │ ├── ic_data_saver_off_white.png │ ├── ic_data_saver_white.png │ ├── ic_desktop_site_white.png │ ├── ic_direct_share_white.png │ ├── ic_downloads_white.png │ ├── ic_edit_url_white.png │ ├── ic_exit_home_white.png │ ├── ic_exit_white.png │ ├── ic_expand_notifications_white.png │ ├── ic_find_white.png │ ├── ic_forward_white.png │ ├── ic_fullscreen_exit_white.png │ ├── ic_fullscreen_white.png │ ├── ic_help_white.png │ ├── ic_history_white.png │ ├── ic_launch_white.png │ ├── ic_launcher.png │ ├── ic_mobile_site_white.png │ ├── ic_most_visited_white.png │ ├── ic_new_incognito_white.png │ ├── ic_new_tab_white.png │ ├── ic_next_tab_white.png │ ├── ic_prev_tab_white.png │ ├── ic_print_white.png │ ├── ic_reader_mode_white.png │ ├── ic_recent_apps.png │ ├── ic_recent_tabs_white.png │ ├── ic_refresh_white.png │ ├── ic_reload_white.png │ ├── ic_restore_page_white.png │ ├── ic_scroll_bottom_white.png │ ├── ic_scroll_top_white.png │ ├── ic_settings_white.png │ ├── ic_share_white.png │ ├── ic_show_tabs_white.png │ ├── ic_stop_white.png │ └── ic_voice_search_white.png ├── drawable │ ├── null_icon.xml │ └── tab_nr.xml ├── layout │ ├── help_dialog.xml │ ├── mainpref_remove.xml │ ├── qc_tabs_view.xml │ └── seekbar_preference.xml ├── menu │ └── main_menu.xml ├── values-ja │ └── strings.xml ├── values-ko │ └── strings.xml ├── values-ru │ └── strings.xml ├── values-sk │ └── strings.xml ├── values-v21 │ └── styles.xml ├── values-zh-rCN │ └── strings.xml ├── values-zh-rTW │ └── strings.xml ├── values-zh │ └── strings.xml ├── values │ ├── arrays.xml │ ├── colors.xml │ ├── dimensions.xml │ ├── strings.xml │ └── styles.xml └── xml │ ├── aosp_preferences.xml │ ├── main_preferences.xml │ ├── menu_preferences.xml │ └── preference_screen.xml └── src └── com └── jt5 └── xposed └── chromepie ├── ChromeDocumentHelper.java ├── ChromeHelper.java ├── ChromePie.java ├── PieControl.java ├── PieItem.java ├── Utils.java ├── broadcastreceiver └── PieReceiver.java ├── settings ├── ItemsPreferenceFragment.java ├── MenuPreferenceFragment.java ├── PiePreferenceFragment.java ├── PieSettings.java └── preference │ ├── PieListPreference.java │ ├── PieMainPreference.java │ └── PieSeekBarPreference.java └── view ├── BaseItem.java └── PieMenu.java /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.txt 3 | 4 | .gradle 5 | .idea 6 | build/ 7 | gradle/ 8 | libs/ 9 | 10 | local.properties -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 51 | 54 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ChromePie 2 | ========= 3 | 4 | Add Pie Controls to Google Chrome with Xposed 5 | -------------------------------------------------------------------------------- /assets/xposed_init: -------------------------------------------------------------------------------- 1 | com.jt5.xposed.chromepie.ChromePie -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | google() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.1.3' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | jcenter() 15 | google() 16 | } 17 | } 18 | 19 | apply plugin: 'com.android.application' 20 | 21 | android { 22 | compileSdkVersion 26 23 | buildToolsVersion '27.0.3' 24 | 25 | defaultConfig { 26 | applicationId "com.jt5.xposed.chromepie" 27 | minSdkVersion 16 28 | targetSdkVersion 23 29 | } 30 | 31 | lintOptions { 32 | abortOnError false 33 | } 34 | 35 | sourceSets { 36 | main { 37 | manifest.srcFile 'AndroidManifest.xml' 38 | java.srcDirs = ['src'] 39 | res.srcDirs = ['res'] 40 | assets.srcDirs = ['assets'] 41 | } 42 | } 43 | } 44 | 45 | dependencies { 46 | compileOnly 'de.robv.android.xposed:api:82' 47 | implementation 'org.apache.commons:commons-lang3:3.4' 48 | } 49 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_add_bookmark_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_add_bookmark_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_add_home_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_add_home_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_add_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_add_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_added_bookmark_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_added_bookmark_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_back_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_back_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_bookmarks_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_bookmarks_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_clear_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_clear_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_close_all_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_close_all_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_close_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_close_tab_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_data_saver_off_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_data_saver_off_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_data_saver_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_data_saver_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_desktop_site_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_desktop_site_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_direct_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_direct_share_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_downloads_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_downloads_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_edit_url_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_edit_url_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_exit_home_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_exit_home_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_exit_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_expand_notifications_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_expand_notifications_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_find_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_find_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_forward_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_forward_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_fullscreen_exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_fullscreen_exit_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_fullscreen_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_fullscreen_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_help_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_help_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_history_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_history_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launch_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_launch_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_mobile_site_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_mobile_site_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_most_visited_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_most_visited_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_new_incognito_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_new_incognito_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_new_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_new_tab_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_next_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_next_tab_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_prev_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_prev_tab_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_print_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_print_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_reader_mode_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_reader_mode_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_recent_apps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_recent_apps.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_recent_tabs_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_recent_tabs_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_refresh_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_refresh_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_reload_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_reload_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_restore_page_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_restore_page_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_scroll_bottom_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_scroll_bottom_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_scroll_top_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_scroll_top_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_settings_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_share_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_show_tabs_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_show_tabs_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_stop_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_stop_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_voice_search_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-hdpi/ic_voice_search_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_add_bookmark_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_add_bookmark_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_add_home_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_add_home_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_add_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_add_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_added_bookmark_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_added_bookmark_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_back_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_back_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_bookmarks_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_bookmarks_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_clear_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_clear_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_close_all_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_close_all_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_close_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_close_tab_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_data_saver_off_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_data_saver_off_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_data_saver_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_data_saver_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_desktop_site_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_desktop_site_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_direct_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_direct_share_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_downloads_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_downloads_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_edit_url_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_edit_url_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_exit_home_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_exit_home_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_exit_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_expand_notifications_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_expand_notifications_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_find_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_find_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_forward_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_forward_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_fullscreen_exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_fullscreen_exit_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_fullscreen_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_fullscreen_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_help_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_help_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_history_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_history_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launch_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_launch_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_mobile_site_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_mobile_site_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_most_visited_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_most_visited_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_new_incognito_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_new_incognito_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_new_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_new_tab_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_next_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_next_tab_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_prev_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_prev_tab_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_print_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_print_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_reader_mode_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_reader_mode_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_recent_apps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_recent_apps.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_recent_tabs_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_recent_tabs_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_refresh_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_refresh_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_reload_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_reload_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_restore_page_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_restore_page_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_scroll_bottom_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_scroll_bottom_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_scroll_top_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_scroll_top_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_settings_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_share_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_show_tabs_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_show_tabs_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_stop_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_stop_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_voice_search_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-mdpi/ic_voice_search_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_add_bookmark_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_add_bookmark_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_add_home_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_add_home_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_add_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_add_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_added_bookmark_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_added_bookmark_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_back_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_back_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_bookmarks_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_bookmarks_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_clear_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_clear_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_close_all_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_close_all_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_close_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_close_tab_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_data_saver_off_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_data_saver_off_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_data_saver_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_data_saver_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_desktop_site_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_desktop_site_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_direct_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_direct_share_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_downloads_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_downloads_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_edit_url_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_edit_url_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_exit_home_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_exit_home_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_exit_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_expand_notifications_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_expand_notifications_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_find_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_find_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_forward_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_forward_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_fullscreen_exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_fullscreen_exit_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_fullscreen_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_fullscreen_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_help_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_help_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_history_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_history_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launch_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_launch_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_mobile_site_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_mobile_site_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_most_visited_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_most_visited_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_new_incognito_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_new_incognito_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_new_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_new_tab_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_next_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_next_tab_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_prev_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_prev_tab_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_print_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_print_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_reader_mode_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_reader_mode_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_recent_apps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_recent_apps.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_recent_tabs_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_recent_tabs_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_refresh_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_refresh_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_reload_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_reload_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_restore_page_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_restore_page_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_scroll_bottom_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_scroll_bottom_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_scroll_top_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_scroll_top_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_settings_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_share_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_show_tabs_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_show_tabs_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_stop_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_stop_white.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_voice_search_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xhdpi/ic_voice_search_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_add_bookmark_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_add_bookmark_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_add_home_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_add_home_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_add_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_add_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_added_bookmark_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_added_bookmark_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_back_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_back_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_bookmarks_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_bookmarks_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_clear_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_clear_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_close_all_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_close_all_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_close_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_close_tab_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_data_saver_off_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_data_saver_off_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_data_saver_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_data_saver_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_desktop_site_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_desktop_site_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_direct_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_direct_share_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_downloads_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_downloads_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_edit_url_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_edit_url_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_exit_home_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_exit_home_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_exit_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_expand_notifications_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_expand_notifications_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_find_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_find_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_forward_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_forward_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_fullscreen_exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_fullscreen_exit_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_fullscreen_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_fullscreen_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_help_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_help_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_history_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_history_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_launch_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_launch_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_mobile_site_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_mobile_site_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_most_visited_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_most_visited_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_new_incognito_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_new_incognito_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_new_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_new_tab_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_next_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_next_tab_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_prev_tab_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_prev_tab_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_print_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_print_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_reader_mode_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_reader_mode_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_recent_apps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_recent_apps.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_recent_tabs_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_recent_tabs_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_refresh_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_refresh_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_reload_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_reload_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_restore_page_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_restore_page_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_scroll_bottom_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_scroll_bottom_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_scroll_top_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_scroll_top_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_settings_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_share_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_show_tabs_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_show_tabs_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_stop_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_stop_white.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_voice_search_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JayT5/ChromePie/ffeafae4c9511374a3f277ed56fc6d8883eec502/res/drawable-xxhdpi/ic_voice_search_white.png -------------------------------------------------------------------------------- /res/drawable/null_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /res/drawable/tab_nr.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 20 | 21 | 23 | 24 | -------------------------------------------------------------------------------- /res/layout/help_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 19 | 20 | 27 | 28 | 33 | 34 | 39 | 40 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /res/layout/mainpref_remove.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 15 | 16 | -------------------------------------------------------------------------------- /res/layout/qc_tabs_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 21 | 26 | 36 | 37 | -------------------------------------------------------------------------------- /res/layout/seekbar_preference.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | 13 | 19 | 20 | -------------------------------------------------------------------------------- /res/menu/main_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 14 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /res/values-ja/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ChromePie 4 | Google Chromeにパイ操作機能を追加します 5 | サポートなどはXDA 6 | 公式ページ (英語)でしています。 7 | ChromePieはカスタマイズできるパイ操作機能を、Google ChromeとGoogle Chrome Betaに追加するXposedモジュールです。\n\n 8 | 内蔵している機能: 9 | \n• 戻る、進む、再読み込み、新しいタブ、新しいシークレットタブ、タブを閉じる 10 | \n• ブックマークに追加、履歴、PC版サイトを見る、ページ内検索 11 | \n• ホーム画面に追加、共有、一番上へスクロール、全画面表示など 12 | 「新しいスライスの追加」をタップすると、パイメニューを開いたとき最初に表示される 13 | メインアイテムを追加できます。メインアイテムに指をスライドしたときに 14 | 表示されるサブアイテムを追加することもできます。作成したメインアイテムの数だけ 15 | サブアイテムを表示できます。アクションを実行するには、 16 | アイテムを選んだ状態で指を離してください。スライスを変更した後はChromeを再起動しないといけません。 17 | バージョン: %s 18 | ヘルプ 19 | デフォルトの値を読み込む 20 | Chromeの再起動 21 | スライスを変更した後はこのオプションでChromeを再起動しないといけません。 22 | Chromeのキル 23 | Chromeをキルしました 24 | パイメニュー 25 | パイメニューアイテムの編集 26 | 新しいスライスの追加 27 | パイスライス 28 | ホームアプリのアイコンを隠す 29 | トリガー領域 30 | 31 | 32 | パイメニューのサイズ 33 | トリガー領域のサイズ 34 | スライス 35 | パイアイテム 36 | メインアイテム 37 | 38 | なし 39 | 戻る 40 | 進む 41 | 再読み込み 42 | URLの編集 43 | ページ内検索 44 | 共有 45 | ブックマーク 46 | ブックマークに追加 47 | 履歴 48 | 新しいタブ 49 | タブを閉じる 50 | 新しいシークレットタブ 51 | タブを全て閉じる 52 | タブの表示 53 | 全画面表示 54 | 設定 55 | PC版サイトを見る 56 | ホーム画面に追加 57 | 最近使ったタブ 58 | よくアクセスするページ 59 | 印刷 60 | ヘルプ 61 | 一番上へスクロール 62 | 終了 63 | 次のタブ 64 | 前のタブ 65 | -------------------------------------------------------------------------------- /res/values-ko/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ChromePie 4 | 탭 닫기 5 | 데이터 세이버 중지 6 | 데이터 세이버 실행 7 | 데스크탑 버전으로 보기 8 | 공유 9 | 파이 메뉴를 설정합니다. 10 | 파이 메뉴 11 | URL 수정 12 | 종료 13 | 알림창 열기 14 | 페이지에서 찾기 15 | 전체화면 16 | 홈페이지 열기 17 | 도움말 18 | 런처 아이콘 숨기기 19 | 방문 기록 20 | 크롬 재실행 21 | 변경된 설정을 적용하기 위해 크롬을 재실행 시켜야 합니다. 22 | 초기화 23 | 메인 아이템 24 | 크롬을 종료시킵니다. 25 | 새 시크립 탭 26 | 새로운 파이 조각 추가 27 | 새 탭 28 | 다음 탭 29 | 없음 30 | 파이 아이템 31 | 파이 메뉴 크기 32 | 파이 메뉴 조각 33 | 이전 탭 34 | 인쇄 35 | 읽기 모드 36 | 최근 앱 37 | 최근 탭 38 | 자주 방문한 페이지 39 | 새로 고침 40 | 화면 외각에 파이 메뉴가 생성될 때 잘려지지 않도록 위치를 옮깁니다. 41 | 파이 메뉴를 화면에 맞추기 42 | 맨 아래로 이동 43 | 맨 위로 이동 44 | 설정 45 | 공유 46 | 탭 보기 47 | 조각 48 | 데이터 세이버 토글 49 | 실행 영역 크기 50 | 실행 위치 51 | 왼쪽 52 | 오른쪽 53 | 음성 검색 54 | 크롬파이 테마를 지원하는 사이트에서만 적용 가능합니다. 55 | 사이트 테마 적용 56 | 앱 선택 57 | 크롬을 종료시켰습니다. 58 | 북마크 추가 59 | 홈 화면에 추가 60 | 크롬파이는 구글 크롬과 크롬 베타를 사용자 정의된 파이를 추가하여 61 | 컨트롤하는 Xposed 모듈입니다.\n\n 62 | 다음 동작들이 가능합니다. 63 | \n• 뒤로, 앞으로, 새로 고침, 새 탭, 새 시크릿 탭, 탭 종료 64 | \n• 북마크 추가, 방문 기록, 데스크탑 버전으로 보기, 페이지에서 찾기 65 | \n• 홈 화면에 추가, 공유, 맨 위로 이동, 전체 화면, 그 외... 66 | 구글 크롬을 컨트롤하는 파이를 추가합니다. 67 | 도움말 68 | 버전: %s 69 | 뒤로 70 | 북마크 71 | 크롬을 찾지 못 했습니다 72 | 모든 탭 닫기 73 | 이 앱에 대한 지원 및 피드백은 XDA Developers의 공식 스레드에서 하고 있습니다.파이 메뉴를 열 때 처음 표시되는 메인 메뉴를 추가하기 위해선 \'새로운 파이 조각 추가\'를 74 | 누르면 됩니다. 이 메인 메뉴에 서브 메뉴를 추가할 수 있으며 서브 메뉴는 메인 메뉴로 75 | 손가락으로 드래그해서 선택하게 되면 표시됩니다. 서브 메뉴 개수는 메인 메뉴의 개수와 76 | 같습니다. 메뉴를 선택한 다음 손을 떼면 설정된 작업을 수행합니다. 변경된 설정들은 77 | 크롬이 재실행 후 적용됩니다. 78 | 아래쪽 79 | 앞으로 80 | 81 | 82 | -------------------------------------------------------------------------------- /res/values-ru/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Добавить закладку 4 | Добавить на главный экран 5 | "ChromePie - это Xposed модуль, который добавляет настраиваемые элементы управления в Google Chrome и Google Chrome Beta. 6 | 7 | Действия: 8 | • Назад, вперед, обновить, новая вкладка, новая вкладка инкогнито, закрыть вкладку 9 | • Добавить закладку, история, переход на полную версию, поиск на странице 10 | • Добавить на главный экран, отправить, перейти к началу, на весь экран и т.д." 11 | Добавление элементов управления в Google Chrome 12 | "Нажмите \"Добавить новый элемент\", чтобы добавить основной элемент, который будет изначально отображаться при открытии меню. Основные элементы могут содержать пункты, которые появляются, когда Вы перемещаете палец на основной элемент. Количество отображаемых пунктов равно числу основных элементов. Для выполнения действий выберите элемент и поднимите палец. Для применения любых изменений требуются перезапуск Chrome." 13 | Справка 14 | ChromePie 15 | Для поддержки и отзывов посетите - официальную страницу на XDA Developers 16 | Версия: %s 17 | Назад 18 | Закладки 19 | Chrome закрыт 20 | Закрыть все 21 | Закрыть вкладку 22 | Полная версия 23 | Изменить элементы 24 | Меню элементов 25 | Изменить URL 26 | Выход 27 | Поиск на странице 28 | Вперед 29 | На весь экран 30 | Справка 31 | Скрыть иконку в лаунчере 32 | История 33 | Перезапуск Chrome 34 | Перезапуск Chrome для применения изменений 35 | Установить значения по умолчанию 36 | основной 37 | Закрыть Chrome 38 | Часто посещаемые 39 | Новая вкладка инкогнито 40 | Добавить новый элемент 41 | Новая вкладка 42 | Следующая вкладка 43 | Нет 44 | Пункт 45 | Размер элемента 46 | Элементы 47 | Предыдущая вкладка 48 | Печать 49 | Недавние вкладки 50 | Обновить 51 | Прокрутка вверх 52 | Настройки 53 | Отправить 54 | Показать вкладки 55 | Элемент 56 | Размер зоны запуска 57 | Сторона запуска 58 | Левая 59 | Правая 60 | Выберите приложение 61 | Chrome не найден 62 | Прямая передача 63 | На домашний экран 64 | Использовать цвета темы сайта для элементов (доступно на поддерживаемых сайтах) 65 | Цвета сайта для элементов 66 | Режим чтения 67 | Расположить элементы так, чтобы они не обрезались при открытии 68 | Разместить на экране 69 | Прокрутка вниз 70 | Внизу 71 | Голосовой поиск 72 | Недавние приложения 73 | Экономия трафика ВЫКЛ 74 | Экономия трафика ВКЛ 75 | Развернуть уведомления 76 | ВКЛ/ВЫКЛ экономию трафика 77 | 78 | -------------------------------------------------------------------------------- /res/values-sk/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ChromePie 5 | Pridá koláčové ovládanie Google Chrome 6 | Prejdite na oficálnu 7 | tému na XDA Developers pre podporu a spätnú väzbu 8 | ChromePie je Xposed module, ktorý pridá upraviteľné koláčové ovládanie 9 | do Google Chrome a Google Chrome Beta.\n\n 10 | Akcia zahŕňajú: 11 | \n• Dozadu, dopredu, obnoviť, nová karta, nová karta inkognito, zavrieť kartu 12 | \n• Pridať záložku, história, vyžiadať desktopovú stránku, nájsť na stránke 13 | \n• Pridať domov, zdieľať, prejsť nahor, celá obrazovka & ďalšie 14 | 15 | Kliknite na \'Pridať nový plátok\' pre pridanie hlavnej položky, 16 | ktorá sa zobrazí pri otvorení ponuky. Tieto hlavné položky môžu obsahovať podpoložky, 17 | ktoré sa objavia, keď pohnete prstom na hlavnú položku. Počet zobrazených podpoložiek 18 | sa rovná počtu vytvorených hlavných položiek. Ak chcete vykonať akciu, zdvihnite prst 19 | z danej položky. Akékoľvek zmeny vyžadujú reštartovanie aplikácie Chrome. 20 | 21 | Verzia: %s 22 | Pomocník 23 | Načítať predvolené hodnoty 24 | 25 | Reštartovať Chrome 26 | Zmeny vyžadujú reštartovanie aplikácie Chrome 27 | Ukončiť Chrome 28 | Chrome sa ukončil 29 | Chrome sa nenašiel 30 | Vyberte aplikáciu 31 | 32 | Koláčová ponuka 33 | Upraviť položky v koláčovej ponuke 34 | 35 | Pridať nový plátok 36 | Plátky koláča 37 | Skryť ikonu v spúšťači 38 | 39 | Pozície spustenia 40 | Vľavo 41 | Vpravo 42 | Dole 43 | 44 | Veľkosť koláčovej ponuky 45 | Veľkosť oblasti spustenia 46 | 47 | Prispôsobiť rozloženie koláčovej ponuky na obrazovke 48 | Upraviť pozíciu koláčovej ponuky, aby sa zábranilo jej orezaniu, keď je aktivovaná príliš vysoko alebo nízko na obrazovke 49 | 50 | Použiť farby témy stránky pre koláčovú ponuku 51 | K dispozícii iba na podporovaných stránkach 52 | 53 | Plátok 54 | Položka koláča 55 | Hlavná položka 56 | 57 | 58 | Žiadna 59 | Dozadu 60 | Dopredu 61 | Obnoviť 62 | Upraviť URL 63 | Nájsť na stránke 64 | Zdieľať 65 | Záložky 66 | Pridať záložku 67 | História 68 | Nová karta 69 | Zavrieť kartu 70 | Nová karta inkognito 71 | Zavrieť všetky 72 | Zobraziť karty 73 | Celá obrazovka 74 | Nastavenia 75 | Vyžiadať dekstopovú stránku 76 | Pridať domov 77 | Nedávne karty 78 | Najnavštevovanejšie 79 | Vytlačiť 80 | Pomocník 81 | Prejsť nahor 82 | Prejsť na domovskú obrazovku 83 | Ukončiť 84 | Ďalšia karta 85 | Predchádzajúca karta 86 | Režim čítačky 87 | Posunúť nadol 88 | Zdieľať priamo 89 | Hlasové vyhľadávanie 90 | 91 | -------------------------------------------------------------------------------- /res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ChromePie 5 | 向 Google Chrome 中添加 Pie 控制菜单 6 | 查看 XDA 7 | 论坛内的官方话题帖以获取帮助或反馈问题 8 | ChromePie 是一款能够在 Google Chrome 和 Google Chrome Beta 中添加 9 | 可定制化 Pie 控制菜单的 Xposed 模块。\n\n 10 | 所支持的操作包括: 11 | \n• 前进,后退,刷新,打开新的标签页,打开新的隐身标签页,关闭标签页 12 | \n• 添加到书签,历史记录,请求桌面版网站,在网页中查找 13 | \n• 添加到主屏幕,分享,去往页面顶端,全屏模式等 14 | 15 | 点击\'添加新区域\' 来新增一个用于在打开控制菜单时初始显示的主项目。 16 | 在当中还可以包含有指向主项目时用于额外显示的分项目。分项目的数量取决于所创建主项目的数量大小。 17 | 要执行一项操作,请在选中一个项目后抬起手指。任何设置项的变更都需要在重启 Chrome 后才能生效。 18 | 19 | 版本:%s 20 | 帮助 21 | 还原默认设置 22 | 23 | 重启 Chrome 24 | 需要重启 Chrome 以使变更生效 25 | 终止 Chrome 26 | Chrome 已终止 27 | 没有找到 Chrome 28 | 选择应用 29 | 30 | Pie 菜单 31 | 编辑 Pie 菜单上的项目 32 | 33 | 添加新区域 34 | 区域设置 35 | 隐藏程序图标 36 | 37 | 触发位置 38 | 右侧 39 | 左侧 40 | 底部 41 | 42 | Pie 菜单大小 43 | 触发区域大小 44 | 45 | 确保 Pie 菜单适配屏幕 46 | 自动调整 Pie 菜单的位置以防止于屏幕较顶端或底端启用时所造成的显示不全 47 | 48 | 将网站的主题配色应用至 Pie 菜单 49 | 仅对适配过的网站可用 50 | 51 | 数据流量节省已开启 52 | 数据流量节省已关闭 53 | 54 | 区域 55 | Pie 菜单项 56 | 主项目 57 | 58 | 59 | 60 | 后退 61 | 前进 62 | 刷新 63 | 编辑网址 64 | 在网页中查找 65 | 分享 66 | 书签 67 | 添加到书签 68 | 历史记录 69 | 打开新的标签页 70 | 关闭标签页 71 | 新的隐身标签页 72 | 关闭所有标签页 73 | 显示标签页 74 | 全屏模式 75 | 设置 76 | 请求桌面版网站 77 | 添加到主屏幕 78 | 最近打开的标签页 79 | 经常访问的页面 80 | 打印 81 | 帮助 82 | 去往页面顶端 83 | 回到主屏幕 84 | 退出 Chrome 85 | 后一个标签页 86 | 前一个标签页 87 | 阅读模式 88 | 去往页面底端 89 | 直接分享 90 | 语音搜索 91 | 显示最近任务 92 | 切换数据流量节省状态 93 | 展开通知栏 94 | 95 | 96 | -------------------------------------------------------------------------------- /res/values-zh-rTW/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ChromePie 5 | 在Chrome裡新增圓餅控制 6 | " 前往"XDA Developers 7 | 尋求幫助或回報問題 8 | "ChromePie是一個Xposed模組,可以自定新增圓餅控制 9 | 到Google Chrome及Google Chrome Beta。\n\n 10 | 包含: 11 | \n• 上一頁、下一頁、重新整理、新分頁、新無痕分頁、關閉分頁 12 | \n• 新增書籤、歷史記錄、要求電腦版顯示、在頁面中搜尋 13 | \n• 加到主畫面、分享、滑至底部、全螢幕 & 更多功能 14 | 15 | 按下 \'新增項目\' 加入一個主項目(打開圓餅時顯示)。 16 | 這些主項目可以包含子項目,當您的手指滑到該項目,子項目就會出現。 17 | 子項目的數量與主項目相同。 18 | 要執行操作,將您的手指滑動到該項目,然後放開即可。 19 | 任何項目設定修改後,必須將Chrome重新啟動才會生效。 20 | 21 | 版本: %s 22 | 幫助 23 | 載入預設值 24 | 25 | 重啟 Chrome 26 | 修改後,Chrome 必須重啟 27 | 關閉 Chrome 28 | Chrome 已停止 29 | 未發現 Chrome 30 | 選擇程式 31 | 32 | 圓餅選單 33 | 編輯圓餅選單項目 34 | 35 | 新增項目 36 | 圓餅項目 37 | 隱藏程式圖標 38 | 39 | 觸發位置 40 | 41 | 42 | 43 | 44 | 圓餅選單大小 45 | 觸發範圍大小 46 | 47 | 確保圓餅選單符合螢幕 48 | 重新定位圓餅選單,以防止在過大或過小的螢幕上超出畫面。 49 | 50 | 使用網站的顏色(圓餅選單) 51 | 僅可於支援的網站中使用 52 | 53 | Data saver 已開啟 54 | Data saver 已關閉 55 | 56 | 主項目 57 | 子項目 58 | 主項目 59 | 60 | 61 | 62 | 上一頁 63 | 下一頁 64 | 重新整理 65 | 編輯網址 66 | 在頁面中搜尋 67 | 分享 68 | 書籤 69 | 新增書籤 70 | 歷史記錄 71 | 新分頁 72 | 關閉分頁 73 | 新無痕分頁 74 | 關閉全部 75 | 顯示所有分頁 76 | 全螢幕 77 | 設定 78 | 要求電腦版顯示 79 | 加到主畫面 80 | 最近開啟分頁 81 | 最常瀏覽分頁 82 | 列印 83 | 幫助 84 | 滑至頂部 85 | 回到首頁 86 | 離開 87 | 下一分頁 88 | 上一分頁 89 | 閱讀模式 90 | 滑至底部 91 | 直接分享 92 | 語音搜尋 93 | 最近開啟程式 94 | 開關 Data Saver 95 | 展開通知 96 | 下載 97 | 開起最近關閉分頁 98 | 99 | 100 | -------------------------------------------------------------------------------- /res/values-zh/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ChromePie 5 | 在Chrome里新增pie控制 6 | " 前往"XDA Developers 寻求帮助或者提交bug 7 | "ChromePie是一个Xposed模組,可以自定新增pie控制到Google Chrome及Google Chrome Beta。\n\n 8 | 包含: 9 | \n• 上一页、下一页、重新整理、新标签页、新隐身标签页、关闭标签页 10 | \n• 新增书签、历史记录、切换到桌面版网站、在页面内搜索 11 | \n• 加到主页面、分享、滑至底部、全屏 & 更多功能 12 | 13 | 按下 \'新增項目\' 加入一个主项目(打开pie时显示)。 14 | 这些主项目可以包含子项目,当您的手指滑到该项目,子项目就会出現。 15 | 子项目的数量与主项目相同。 16 | 要执行操作,将您的手指滑动到该项目,然后放开即可。 17 | 任何项目设定修改后,必须将Chrome重新启动才会生效。 18 | 19 | 版本: %s 20 | 帮助 21 | 载入预设值 22 | 23 | 重启 Chrome 24 | 修改后,Chrome 必须重启 25 | 关闭 Chrome 26 | Chrome 已停止 27 | 未发现 Chrome 28 | 选择程序 29 | 30 | pie选项 31 | 编辑pie菜单项目 32 | 33 | 新增项目 34 | pie项目 35 | 隐藏程序图标 36 | 37 | 触发位置 38 | 39 | 40 | 41 | 42 | pie菜单大小 43 | 触发范围大小 44 | 45 | 确保pie菜单适应屏幕 46 | 重新定位pie菜单,以防止在过大或过小的屏幕上超出画面。 47 | 48 | 使用网站的颜色(pie菜单) 49 | 只能在支持的网站中使用 50 | 主项目 51 | 子项目 52 | 主项目 53 | 54 | 55 | 56 | 上一页 57 | 下一页 58 | 重新整理 59 | 编辑网址 60 | 在当前页面搜索 61 | 分享 62 | 书签 63 | 新增书签 64 | 历史记录 65 | 新标签页 66 | 关闭当前标签页 67 | 新隐私标签页 68 | 关闭全部 69 | 显示所有标签页 70 | 全屏幕 71 | 设置 72 | 切换为电脑版 73 | 加到主页 74 | 最近浏览 75 | 最常浏览 76 | 列印 77 | 帮助 78 | 滑至顶部 79 | 回到首页 80 | 离开 81 | 下一分页 82 | 上一分页 83 | 阅读模式 84 | 滑至底部 85 | 直接分享 86 | 语音搜索 87 | 最近打开的程序 88 | 关闭 Data Saver 89 | 展开通知 90 | 91 | -------------------------------------------------------------------------------- /res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | @string/none 6 | @string/back 7 | @string/forward 8 | @string/refresh 9 | @string/new_tab 10 | @string/new_incognito_tab 11 | @string/close_tab 12 | @string/close_all 13 | @string/bookmarks 14 | @string/add_bookmark 15 | @string/history 16 | @string/most_visited 17 | @string/recent_tabs 18 | @string/show_tabs 19 | @string/add_to_home 20 | @string/find_in_page 21 | @string/edit_url 22 | @string/desktop_site 23 | @string/fullscreen 24 | @string/scroll_to_top 25 | @string/scroll_to_bottom 26 | @string/share 27 | @string/direct_share 28 | @string/print 29 | @string/settings 30 | @string/help 31 | @string/go_to_home 32 | @string/exit 33 | @string/next_tab 34 | @string/previous_tab 35 | @string/reader_mode 36 | @string/voice_search 37 | @string/recent_apps 38 | @string/toggle_data_saver 39 | @string/expand_notifications 40 | @string/downloads 41 | @string/open_recently_closed 42 | 43 | 44 | 45 | none 46 | back 47 | forward 48 | refresh 49 | new_tab 50 | new_incognito_tab 51 | close_tab 52 | close_all 53 | bookmarks 54 | add_bookmark 55 | history 56 | most_visited 57 | recent_tabs 58 | show_tabs 59 | add_to_home 60 | find_in_page 61 | edit_url 62 | desktop_site 63 | fullscreen 64 | scroll_to_top 65 | scroll_to_bottom 66 | share 67 | direct_share 68 | print 69 | settings 70 | help 71 | go_to_home 72 | exit 73 | next_tab 74 | previous_tab 75 | reader_mode 76 | voice_search 77 | recent_apps 78 | toggle_data_saver 79 | expand_notifications 80 | downloads 81 | open_recently_closed 82 | 83 | 84 | 85 | @drawable/null_icon 86 | @drawable/ic_back_white 87 | @drawable/ic_forward_white 88 | @drawable/ic_refresh_white 89 | @drawable/ic_new_tab_white 90 | @drawable/ic_new_incognito_white 91 | @drawable/ic_close_tab_white 92 | @drawable/ic_close_all_white 93 | @drawable/ic_bookmarks_white 94 | @drawable/ic_add_bookmark_white 95 | @drawable/ic_history_white 96 | @drawable/ic_most_visited_white 97 | @drawable/ic_recent_tabs_white 98 | @drawable/ic_show_tabs_white 99 | @drawable/ic_add_home_white 100 | @drawable/ic_find_white 101 | @drawable/ic_edit_url_white 102 | @drawable/ic_desktop_site_white 103 | @drawable/ic_fullscreen_white 104 | @drawable/ic_scroll_top_white 105 | @drawable/ic_scroll_bottom_white 106 | @drawable/ic_share_white 107 | @drawable/ic_direct_share_white 108 | @drawable/ic_print_white 109 | @drawable/ic_settings_white 110 | @drawable/ic_help_white 111 | @drawable/ic_exit_home_white 112 | @drawable/ic_exit_white 113 | @drawable/ic_next_tab_white 114 | @drawable/ic_prev_tab_white 115 | @drawable/ic_reader_mode_white 116 | @drawable/ic_voice_search_white 117 | @drawable/ic_recent_apps 118 | @drawable/ic_data_saver_white 119 | @drawable/ic_expand_notifications_white 120 | @drawable/ic_downloads_white 121 | @drawable/ic_restore_page_white 122 | 123 | 124 | 125 | 126 | back_menu_id 127 | forward_menu_id 128 | reload_menu_id 129 | new_tab_menu_id 130 | new_incognito_tab_menu_id 131 | 132 | close_all_tabs_menu_id 133 | all_bookmarks_menu_id 134 | bookmark_this_page_id 135 | open_history_menu_id 136 | 137 | recent_tabs_menu_id 138 | 139 | add_to_homescreen_id 140 | find_in_page_id 141 | focus_url_bar 142 | request_desktop_site_id 143 | 144 | 145 | 146 | share_menu_id 147 | direct_share_menu_id 148 | print_id 149 | preferences_id 150 | help_id 151 | 152 | 153 | 154 | 155 | reader_mode_id 156 | 157 | 158 | 159 | 160 | downloads_menu_id 161 | open_recently_closed_tab 162 | 163 | 164 | 165 | @string/ts_left 166 | @string/ts_right 167 | @string/ts_bottom 168 | 169 | 170 | 171 | 0 172 | 1 173 | 2 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | #E02A96BC 23 | #E0FF8800 24 | #F01A5B73 25 | #F033B5E5 26 | 27 | -------------------------------------------------------------------------------- /res/values/dimensions.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 80 15 | 10 16 | 15dp 17 | 40dp 18 | 35dp 19 | 67dp 20 | 21 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ChromePie 5 | Add Pie Controls to Google Chrome 6 | Check out the official 7 | thread at XDA Developers for support and feedback 8 | ChromePie is an Xposed module which adds customisable Pie Controls 9 | to Google Chrome and Google Chrome Beta.\n\n 10 | Actions include: 11 | \n• Back, forward, refresh, new tab, new incognito tab, close tab 12 | \n• Add bookmark, history, request desktop site, find in page 13 | \n• Add to home, share, scroll to top, full screen & more 14 | 15 | Tap \'Add new slice\' to add a main item which will be initially 16 | displayed when the menu is opened. These main items can contain sub-items which 17 | appear when you move your finger onto a main item. The number of sub-items 18 | displayed is equal to the number of main items created. To perform an action, lift 19 | your finger when selecting an item. Any changes require Chrome to be restarted. 20 | 21 | Version: %s 22 | Help 23 | Load default values 24 | 25 | Restart Chrome 26 | Changes require Chrome to be restarted 27 | Kill Chrome 28 | Chrome killed 29 | Chrome not found 30 | Select app 31 | 32 | Pie menu 33 | Edit Pie menu items 34 | 35 | Add new slice 36 | Pie Slices 37 | Hide launcher icon 38 | 39 | Trigger positions 40 | Right 41 | Left 42 | Bottom 43 | 44 | Pie menu size 45 | Trigger area size 46 | 47 | Ensure pie menu fits on screen 48 | Reposition the pie menu to prevent it getting cut off when activated too high or low on screen 49 | 50 | Use site theme colours for pie menu 51 | Only available on supported sites 52 | 53 | Data saver enabled 54 | Data saver disabled 55 | 56 | Slice 57 | Pie Item 58 | Main item 59 | 60 | 61 | None 62 | Back 63 | Forward 64 | Refresh 65 | Edit URL 66 | Find in page 67 | Share 68 | Bookmarks 69 | Add bookmark 70 | History 71 | New tab 72 | Close tab 73 | New incognito tab 74 | Close all 75 | Show tabs 76 | Fullscreen 77 | Settings 78 | Request desktop site 79 | Add to home 80 | Recent tabs 81 | Most visited 82 | Print 83 | Help 84 | Scroll to top 85 | Go to home screen 86 | Exit 87 | Next tab 88 | Previous tab 89 | Reader mode 90 | Scroll to bottom 91 | Direct share 92 | Voice search 93 | Recent apps 94 | Toggle data saver 95 | Expand notifications 96 | Downloads 97 | Open recently closed tab 98 | 99 | 100 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 15 | 16 | 17 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /res/xml/aosp_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 11 | 14 | 17 | 20 | 23 | 26 | 27 | 30 | 33 | 36 | 39 | 42 | 45 | 48 | 49 | 52 | 55 | 58 | 61 | 64 | 67 | 70 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 93 | 96 | 99 | 102 | 105 | 108 | 111 | 114 | 115 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /res/xml/main_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 14 | 20 | 26 | 32 | 37 | 42 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /res/xml/menu_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /res/xml/preference_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/ChromeDocumentHelper.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie; 2 | 3 | import android.app.Activity; 4 | 5 | import de.robv.android.xposed.XposedBridge; 6 | 7 | class ChromeDocumentHelper extends ChromeHelper { 8 | 9 | ChromeDocumentHelper(Activity activity) { 10 | super(activity); 11 | } 12 | 13 | @Override 14 | boolean isDocumentMode() { 15 | return true; 16 | } 17 | 18 | @Override 19 | Object getTabModel() { 20 | try { 21 | return Utils.getObjectField(mActivity, "mTabModel"); 22 | } catch (NoSuchFieldError nsfe) { 23 | 24 | } 25 | try { 26 | return Utils.getObjectField(mActivity, "mTabList"); 27 | } catch (NoSuchFieldError nsfe) { 28 | 29 | } 30 | return super.getTabModel(); 31 | } 32 | 33 | @Override 34 | Object getLayoutManager() { 35 | try { 36 | return Utils.callMethod(Utils.callMethod(mActivity, "getCompositorViewHolder"), "getLayoutManager"); 37 | } catch (NoSuchMethodError nsme) { 38 | 39 | } 40 | return super.getLayoutManager(); 41 | } 42 | 43 | @Override 44 | Object getToolbarManager() { 45 | try { 46 | Object helper = Utils.getObjectField(mActivity, "mDocumentToolbarHelper"); 47 | return Utils.getObjectField(helper, "mToolbarManager"); 48 | } catch (NoSuchFieldError nsfe) { 49 | 50 | } 51 | return super.getToolbarManager(); 52 | } 53 | 54 | @Override 55 | Integer getThemeColor() { 56 | try { 57 | return (Integer) Utils.callMethod(mActivity, "getThemeColor"); 58 | } catch (NoSuchMethodError nsme) { 59 | 60 | } 61 | return super.getThemeColor(); 62 | } 63 | 64 | @Override 65 | void showOverview() { 66 | toggleRecentApps(); 67 | } 68 | 69 | @Override 70 | void closeCurrentTab() { 71 | Object nextTab = getNextTabIfClosed(); 72 | super.closeCurrentTab(); 73 | if (nextTab != null) { 74 | showNextTab(nextTab); 75 | } 76 | } 77 | 78 | private Object getNextTabIfClosed() { 79 | Object tabToClose = getCurrentTab(); 80 | try { 81 | int closingTabIndex = getTabIndex(getTabModel(), tabToClose); 82 | Object adjacentTab = getTabAt((closingTabIndex == 0) ? 1 : closingTabIndex - 1); 83 | Object parentTab = getTabById((Integer) Utils.callMethod(tabToClose, "getParentId")); 84 | 85 | // Determine which tab to select next according to these rules: 86 | // * Select the parent tab if it exists. 87 | // * Otherwise, select an adjacent tab if one exists. 88 | // * Otherwise, if closing the last incognito tab, select the current normal tab. 89 | // * Otherwise, select nothing. 90 | 91 | Object nextTab = null; 92 | if (parentTab != null) { 93 | nextTab = parentTab; 94 | } else if (adjacentTab != null) { 95 | nextTab = adjacentTab; 96 | } else if (isIncognito()) { 97 | nextTab = Utils.callStaticMethod(Utils.CLASS_TAB_MODEL_UTILS, "getCurrentTab", getDocumentModel(false)); 98 | } 99 | return nextTab; 100 | } catch (NoSuchMethodError nsme) { 101 | XposedBridge.log(TAG + nsme); 102 | } 103 | return null; 104 | } 105 | 106 | private void showNextTab(Object tab) { 107 | try { 108 | Object model = getDocumentModel((Boolean) Utils.callMethod(tab, "isIncognito")); 109 | int index = getTabIndex(model, tab); 110 | Utils.callStaticMethod(Utils.CLASS_TAB_MODEL_UTILS, "setIndex", model, index); 111 | } catch (NoSuchMethodError nsme) { 112 | XposedBridge.log(TAG + nsme); 113 | } 114 | } 115 | 116 | private Object getDocumentModel(boolean incognito) { 117 | try { 118 | return Utils.callMethod(Utils.callStaticMethod(Utils.CLASS_CHROME_APPLICATION, "getDocumentTabModelSelector"), "getModel", incognito); 119 | } catch (NoSuchMethodError nsme) { 120 | XposedBridge.log(TAG + nsme); 121 | } 122 | return new Object(); 123 | } 124 | 125 | private Object getTabById(int id) { 126 | try { 127 | return Utils.callStaticMethod(Utils.CLASS_TAB_MODEL_UTILS, "getTabById", getTabModel(), id); 128 | } catch (NoSuchMethodError nsme) { 129 | XposedBridge.log(TAG + nsme); 130 | } 131 | return null; 132 | } 133 | 134 | private Object getTabAt(int index) { 135 | try { 136 | return Utils.callMethod(getTabModel(), "getTabAt", index); 137 | } catch (NoSuchMethodError nsme) { 138 | 139 | } 140 | try { 141 | return Utils.callMethod(getTabModel(), "getTab", index); 142 | } catch (NoSuchMethodError nsme) { 143 | XposedBridge.log(TAG + nsme); 144 | } 145 | return null; 146 | } 147 | 148 | private Integer getTabIndex(Object model, Object tab) { 149 | try { 150 | return (Integer) Utils.callMethod(model, "indexOf", tab); 151 | } catch (NoSuchMethodError nsme) { 152 | XposedBridge.log(TAG + nsme); 153 | } 154 | return -1; 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/ChromePie.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie; 2 | 3 | import android.app.Activity; 4 | import android.content.pm.PackageManager; 5 | import android.content.res.Resources; 6 | import android.os.Handler; 7 | import android.view.ViewGroup; 8 | 9 | import com.jt5.xposed.chromepie.settings.PieSettings; 10 | 11 | import de.robv.android.xposed.IXposedHookZygoteInit; 12 | import de.robv.android.xposed.XC_MethodHook; 13 | import de.robv.android.xposed.XSharedPreferences; 14 | import de.robv.android.xposed.XposedBridge; 15 | import de.robv.android.xposed.XposedHelpers; 16 | 17 | public class ChromePie implements IXposedHookZygoteInit { 18 | 19 | private static final String TAG = "ChromePie: "; 20 | static final String PACKAGE_NAME = ChromePie.class.getPackage().getName(); 21 | 22 | @Override 23 | public void initZygote(StartupParam startupParam) throws Throwable { 24 | final XSharedPreferences preferences = new XSharedPreferences(PACKAGE_NAME); 25 | preferences.makeWorldReadable(); 26 | 27 | XposedHelpers.findAndHookMethod(Activity.class, "onStart", new XC_MethodHook() { 28 | @Override 29 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 30 | final Activity activity = (Activity) param.thisObject; 31 | if (!PieSettings.CHROME_ACTIVITY_CLASSES.contains(activity.getClass().getName())) { 32 | return; 33 | } 34 | if (XposedHelpers.getAdditionalInstanceField(activity, "pie_control") == null) { 35 | initPieControl(activity, preferences); 36 | } 37 | } 38 | }); 39 | 40 | XposedHelpers.findAndHookMethod(Activity.class, "onDestroy", new XC_MethodHook() { 41 | @Override 42 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 43 | final Activity activity = (Activity) param.thisObject; 44 | if (!PieSettings.CHROME_ACTIVITY_CLASSES.contains(activity.getClass().getName())) { 45 | return; 46 | } 47 | PieControl control = (PieControl) XposedHelpers.getAdditionalInstanceField(activity, "pie_control"); 48 | if (control != null) { 49 | control.destroy(); 50 | XposedHelpers.removeAdditionalInstanceField(activity, "pie_control"); 51 | } 52 | } 53 | }); 54 | } 55 | 56 | private void initPieControl(final Activity activity, final XSharedPreferences preferences) { 57 | final Resources resources = getResources(activity); 58 | if (resources == null) return; 59 | final ViewGroup container = activity.findViewById(android.R.id.content); 60 | final Handler handler = new Handler(); 61 | handler.postDelayed(new Runnable() { 62 | @Override 63 | public void run() { 64 | PieControl control = new PieControl(activity, resources, preferences); 65 | control.attachToContainer(container); 66 | XposedHelpers.setAdditionalInstanceField(activity, "pie_control", control); 67 | } 68 | }, 1000L); 69 | } 70 | 71 | private Resources getResources(final Activity activity) { 72 | try { 73 | Resources resources = activity.getPackageManager().getResourcesForApplication(PACKAGE_NAME); 74 | resources.getInteger(R.integer.qc_radius_increment); 75 | return resources; 76 | } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { 77 | XposedBridge.log(TAG + "Failed to initialise resources. Have you rebooted? " + e); 78 | return null; 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/PieControl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.jt5.xposed.chromepie; 18 | 19 | import android.app.Activity; 20 | import android.content.SharedPreferences; 21 | import android.content.res.Resources; 22 | import android.content.res.TypedArray; 23 | import android.preference.PreferenceManager; 24 | import android.view.View; 25 | import android.view.ViewGroup; 26 | import android.view.ViewGroup.LayoutParams; 27 | import android.widget.ImageView; 28 | import android.widget.ImageView.ScaleType; 29 | import android.widget.TextView; 30 | 31 | import com.jt5.xposed.chromepie.view.BaseItem; 32 | import com.jt5.xposed.chromepie.view.PieMenu; 33 | 34 | import java.util.ArrayList; 35 | import java.util.Arrays; 36 | import java.util.Collections; 37 | import java.util.HashSet; 38 | import java.util.List; 39 | import java.util.Map; 40 | import java.util.Set; 41 | 42 | import de.robv.android.xposed.XC_MethodHook; 43 | import de.robv.android.xposed.XC_MethodHook.Unhook; 44 | import de.robv.android.xposed.XSharedPreferences; 45 | import de.robv.android.xposed.XposedBridge; 46 | import de.robv.android.xposed.XposedHelpers; 47 | 48 | /** 49 | * Controller for Quick Controls pie menu 50 | */ 51 | public class PieControl implements PieMenu.PieController { 52 | 53 | private static final String TAG = "ChromePie:PieControl: "; 54 | public static final int MAX_SLICES = 6; 55 | 56 | private static final List NO_TAB_ACTIONS = Collections.unmodifiableList( 57 | Arrays.asList("new_tab", "new_incognito_tab", "fullscreen", "settings", "exit", 58 | "go_to_home", "show_tabs", "recent_apps", "toggle_data_saver", "downloads", 59 | "expand_notifications", "bookmarks", "history", "most_visited", "recent_tabs")); 60 | private static final List CUSTOM_TAB_ACTIONS = Collections.unmodifiableList( 61 | Arrays.asList("back", "forward", "refresh", "close_tab", "add_bookmark", "add_to_home", 62 | "find_in_page", "desktop_site", "fullscreen", "scroll_to_top", "show_tabs", 63 | "scroll_to_bottom", "share", "direct_share", "print", "settings", "go_to_home", 64 | "exit", "reader_mode", "recent_apps", "toggle_data_saver", 65 | "expand_notifications")); 66 | 67 | private final Activity mActivity; 68 | private final ChromeHelper mHelper; 69 | private PieMenu mPie; 70 | private final Resources mXResources; 71 | private final XSharedPreferences mXPreferences; 72 | private Unhook mFinishPageLoadHook; 73 | private final List mEnabledTriggers; 74 | private final boolean mApplyThemeColor; 75 | private int mThemeColor; 76 | 77 | PieControl(Activity activity, Resources res, XSharedPreferences prefs) { 78 | mActivity = activity; 79 | if (Utils.isDocumentModeEnabled(mActivity)) { 80 | mHelper = new ChromeDocumentHelper(mActivity); 81 | } else { 82 | mHelper = new ChromeHelper(mActivity); 83 | } 84 | Utils.initialise(mActivity.getClassLoader(), mHelper); 85 | mXResources = res; 86 | mXPreferences = prefs; 87 | Utils.reloadPreferences(mXPreferences); 88 | mEnabledTriggers = initTriggerPositions(); 89 | mApplyThemeColor = mXPreferences.getBoolean("apply_theme_color", true); 90 | applyFullscreen(); 91 | } 92 | 93 | void attachToContainer(ViewGroup container) { 94 | if (mPie == null) { 95 | mPie = new PieMenu(mActivity, mXResources, mXPreferences); 96 | LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 97 | mPie.setLayoutParams(lp); 98 | populateMenu(); 99 | mPie.setController(this); 100 | mPie.setDefaultColors(mXResources); 101 | } 102 | container.addView(mPie); 103 | } 104 | 105 | private void removeFromParent() { 106 | if (mPie.getParent() != null) { 107 | ((ViewGroup) mPie.getParent()).removeView(mPie); 108 | } 109 | } 110 | 111 | void destroy() { 112 | removeFromParent(); 113 | mPie.clearItems(); 114 | mPie = null; 115 | if (mFinishPageLoadHook != null) { 116 | mFinishPageLoadHook.unhook(); 117 | mFinishPageLoadHook = null; 118 | } 119 | } 120 | 121 | private void applyFullscreen() { 122 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mActivity); 123 | boolean defValue = false; 124 | if (prefs.contains("chromepie_apply_fullscreen")) { 125 | defValue = prefs.getBoolean("chromepie_apply_fullscreen", false); 126 | prefs.edit().remove("chromepie_apply_fullscreen").apply(); 127 | } 128 | if (mXPreferences.getBoolean("launch_in_fullscreen", defValue)) { 129 | mHelper.setFullscreen(true); 130 | } 131 | } 132 | 133 | private List initTriggerPositions() { 134 | Set triggerSet = mXPreferences.getStringSet("trigger_side_set", 135 | new HashSet<>(Arrays.asList("0", "1", "2"))); 136 | List triggerList = new ArrayList<>(); 137 | for (String trigger : triggerSet) { 138 | triggerList.add(PieMenu.Trigger.values()[Integer.valueOf(trigger)]); 139 | } 140 | return triggerList; 141 | } 142 | 143 | @Override 144 | public void onOpen() { 145 | if (mHelper.getCurrentTab() == null) { 146 | if (mHelper.isDocumentMode()) { 147 | return; 148 | } 149 | } else if (mFinishPageLoadHook == null) { 150 | hookFinishPageLoad(); 151 | } 152 | 153 | if (mApplyThemeColor) { 154 | int color = mHelper.getThemeColor(); 155 | if (mThemeColor != color) { 156 | mThemeColor = color; 157 | if (mHelper.shouldUseThemeColor(mThemeColor)) { 158 | mPie.setThemeColors(color); 159 | } else { 160 | mPie.setDefaultColors(mXResources); 161 | } 162 | } 163 | } 164 | 165 | final int tabCount = mHelper.getTabCount(); 166 | final List items = mPie.getItems(); 167 | for (BaseItem item : items) { 168 | boolean shouldEnable = mHelper.isCustomTabs() ? CUSTOM_TAB_ACTIONS.contains(item.getId()) 169 | : tabCount != 0 || NO_TAB_ACTIONS.contains(item.getId()); 170 | item.setEnabled(shouldEnable); 171 | if (!shouldEnable || item.getView() == null) { 172 | continue; 173 | } 174 | ((PieItem) item).onOpen(mHelper, mXResources); 175 | } 176 | } 177 | 178 | @Override 179 | public void onClick(PieItem item) { 180 | item.onClick(mHelper); 181 | } 182 | 183 | @Override 184 | public boolean shouldShowMenu(PieMenu.Trigger triggerPosition) { 185 | return mEnabledTriggers.contains(triggerPosition) 186 | && !mHelper.isInFullscreenVideo() 187 | && !mHelper.touchScrollInProgress() 188 | && (!mHelper.isChromeHomeEnabled() || !mHelper.isBottomSheetVisible()) 189 | && (mHelper.isCustomTabs() || ((mHelper.isInOverview() == (mHelper.getTabCount() == 0)) 190 | && (mHelper.getUrlBar() == null || !mHelper.getUrlBar().hasFocus()))); 191 | } 192 | 193 | @Override 194 | public void requestTabFocus() { 195 | mHelper.requestTabFocus(); 196 | } 197 | 198 | @Override 199 | public int getTopControlsHeight() { 200 | return mHelper.getTopControlsHeight(); 201 | } 202 | 203 | @Override 204 | public int getBottomControlsHeight() { 205 | return mHelper.getBottomControlsHeight(); 206 | } 207 | 208 | private void populateMenu() { 209 | final List values = Arrays.asList(mXResources.getStringArray(R.array.pie_item_values)); 210 | final TypedArray drawables = mXResources.obtainTypedArray(R.array.pie_item_dark_drawables); 211 | final String[] actions = mXResources.getStringArray(R.array.pie_item_actions); 212 | mPie.clearItems(); 213 | Map keyMap = mXPreferences.getAll(); 214 | if (keyMap.isEmpty()) { 215 | XposedBridge.log(TAG + "Failed to load preferences, using default values"); 216 | keyMap = Utils.createDefaultsMap(mXResources); 217 | } 218 | for (int i = 1; i <= MAX_SLICES; i++) { 219 | Boolean enabled = (Boolean) keyMap.get("screen_slice_" + i); 220 | if (enabled != null && enabled) { 221 | String value = (String) keyMap.get("slice_" + i + "_item_" + i); 222 | BaseItem item = initItem(values, drawables, actions, value); 223 | mPie.addItem(item); 224 | for (int j = 1; j <= MAX_SLICES; j++) { 225 | if (i == j) { 226 | continue; 227 | } 228 | value = (String) keyMap.get("slice_" + i + "_item_" + j); 229 | item.addItem(initItem(values, drawables, actions, value)); 230 | } 231 | } 232 | } 233 | drawables.recycle(); 234 | } 235 | 236 | private BaseItem initItem(List values, TypedArray drawables, String[] actions, String value) { 237 | if (value != null && !value.equals("none")) { 238 | int index = values.indexOf(value); 239 | if (index >= 0) { 240 | String action = actions[index]; 241 | return makeItem(value, drawables.getResourceId(index, R.drawable.null_icon), mHelper.getResIdentifier(action)); 242 | } 243 | } 244 | return makeFiller(); 245 | } 246 | 247 | private BaseItem makeItem(String id, int iconRes, int action) { 248 | int itemSize = mXResources.getDimensionPixelSize(R.dimen.qc_item_size); 249 | View view; 250 | if (id.equals("show_tabs") && mHelper.getTabModelCount() != -1) { 251 | view = makeTabsView(iconRes); 252 | } else { 253 | view = new ImageView(mActivity); 254 | ((ImageView) view).setImageDrawable(mXResources.getDrawable(iconRes)); 255 | ((ImageView) view).setScaleType(ScaleType.CENTER); 256 | view.setMinimumWidth(itemSize); 257 | view.setMinimumHeight(itemSize); 258 | } 259 | view.setLayoutParams(new LayoutParams(itemSize, itemSize)); 260 | try { 261 | return (PieItem) Class.forName(ChromePie.PACKAGE_NAME + ".Item_" + id) 262 | .getConstructor(View.class, String.class, int.class).newInstance(view, id, action); 263 | } catch (Throwable t) { 264 | return new PieItem(view, id, action); 265 | } 266 | } 267 | 268 | private BaseItem makeFiller() { 269 | return new BaseItem(null, ""); 270 | } 271 | 272 | private View makeTabsView(int iconRes) { 273 | View view = mActivity.getLayoutInflater().inflate(mXResources.getLayout(R.layout.qc_tabs_view), null); 274 | TextView count = (TextView) view.findViewById(R.id.count_label); 275 | count.setBackground(mXResources.getDrawable(R.drawable.tab_nr)); 276 | count.setText(Integer.toString(mHelper.getTabCount())); 277 | ImageView icon = (ImageView) view.findViewById(R.id.count_icon); 278 | icon.setImageDrawable(mXResources.getDrawable(iconRes)); 279 | icon.setScaleType(ScaleType.CENTER); 280 | return view; 281 | } 282 | 283 | private void hookFinishPageLoad() { 284 | XC_MethodHook pageLoadHook = new XC_MethodHook() { 285 | @Override 286 | protected void afterHookedMethod(final MethodHookParam param) throws Throwable { 287 | List items = mPie.findItemsById("refresh"); 288 | if (!items.isEmpty()) { 289 | for (PieItem item : items) { 290 | ((ImageView) item.getView()).setImageDrawable(mXResources.getDrawable(R.drawable.ic_refresh_white)); 291 | } 292 | mPie.invalidate(); 293 | } 294 | } 295 | }; 296 | 297 | try { 298 | mFinishPageLoadHook = XposedBridge.hookMethod(XposedHelpers.findMethodBestMatch( 299 | mHelper.getCurrentTab().getClass(), "didFinishPageLoad"), pageLoadHook); 300 | } catch (Throwable t) { 301 | Utils.log(TAG + t); 302 | } 303 | } 304 | 305 | } 306 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/Utils.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.content.res.XmlResourceParser; 6 | import android.graphics.Color; 7 | import android.os.StrictMode; 8 | 9 | import org.apache.commons.lang3.BooleanUtils; 10 | import org.apache.commons.lang3.ClassUtils; 11 | import org.xmlpull.v1.XmlPullParser; 12 | 13 | import java.lang.reflect.Field; 14 | import java.lang.reflect.Method; 15 | import java.lang.reflect.Modifier; 16 | import java.util.Collections; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | 20 | import de.robv.android.xposed.XSharedPreferences; 21 | import de.robv.android.xposed.XposedBridge; 22 | import de.robv.android.xposed.XposedHelpers; 23 | 24 | public class Utils { 25 | 26 | private static final String TAG = "ChromePie:Utils "; 27 | 28 | private static final Map fieldCache = new HashMap<>(); 29 | private static final Map methodCache = new HashMap<>(); 30 | 31 | private static Boolean sIsObfuscated; 32 | 33 | static Class CLASS_TAB_MODEL_UTILS; 34 | static Class CLASS_LOAD_URL_PARAMS; 35 | static Class CLASS_DEVICE_UTILS; 36 | static Class CLASS_FEATURE_UTILS; 37 | static Class CLASS_DISTILLER_URL_UTILS; 38 | static Class CLASS_DISTILLER_TAB_UTILS; 39 | static Class CLASS_SERVICE_BRIDGE; 40 | static Class CLASS_CHROME_APPLICATION; 41 | static Class CLASS_SHORTCUT_HELPER; 42 | static Class CLASS_TAB_LAUNCH_TYPE; 43 | static Class CLASS_SHARE_HELPER; 44 | static Class CLASS_CONTENT_VIDEO_VIEW; 45 | static Class CLASS_DATA_REDUCTION_SETTINGS; 46 | 47 | static void initialise(ClassLoader classLoader, ChromeHelper helper) { 48 | String[] tabModelUtils = { 49 | "org.chromium.chrome.browser.tabmodel.TabModelUtils", 50 | "com.google.android.apps.chrome.tabmodel.TabModelUtils" 51 | }; 52 | String[] loadUrlParams = { 53 | "org.chromium.content_public.browser.LoadUrlParams", 54 | "org.chromium.content.browser.LoadUrlParams" 55 | }; 56 | String[] deviceUtils = { 57 | "org.chromium.ui.base.DeviceFormFactor", 58 | "org.chromium.content.browser.DeviceUtils" 59 | }; 60 | String[] featureUtilities = { 61 | "org.chromium.chrome.browser.util.FeatureUtilities", 62 | "com.google.android.apps.chrome.utilities.FeatureUtilities" 63 | }; 64 | String[] distillerUrlUtils = { 65 | "org.chromium.components.dom_distiller.core.DomDistillerUrlUtils" 66 | }; 67 | String[] distillerTabUtils = { 68 | "org.chromium.chrome.browser.dom_distiller.DomDistillerTabUtils" 69 | }; 70 | String[] serviceBridge = { 71 | "org.chromium.chrome.browser.preferences.PrefServiceBridge", 72 | "com.google.android.apps.chrome.preferences.ChromeNativePreferences" 73 | }; 74 | String[] chromeApplication = { 75 | "org.chromium.chrome.browser.ChromeApplication", 76 | "org.chromium.chrome.browser.ChromeMobileApplication", 77 | "com.google.android.apps.chrome.ChromeMobileApplication" 78 | }; 79 | String[] shortcutHelper = { 80 | "org.chromium.chrome.browser.BookmarkUtils", 81 | "org.chromium.chrome.browser.ShortcutHelper" 82 | }; 83 | String[] tabLaunchType = { 84 | "org.chromium.chrome.browser.tabmodel.TabModel$TabLaunchType", 85 | "com.google.android.apps.chrome.tabmodel.TabModel$TabLaunchType" 86 | }; 87 | String[] shareHelper = { 88 | "org.chromium.chrome.browser.share.ShareHelper" 89 | }; 90 | String[] contentVideoView = { 91 | "org.chromium.content.browser.ContentVideoView" 92 | }; 93 | String[] dataReductionSettings = { 94 | "org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings" 95 | }; 96 | 97 | CLASS_TAB_MODEL_UTILS = getClass(classLoader, tabModelUtils); 98 | CLASS_LOAD_URL_PARAMS = getClass(classLoader, loadUrlParams); 99 | CLASS_DEVICE_UTILS = getClass(classLoader, deviceUtils); 100 | CLASS_FEATURE_UTILS = getClass(classLoader, featureUtilities); 101 | CLASS_DISTILLER_URL_UTILS = getClass(classLoader, distillerUrlUtils); 102 | CLASS_DISTILLER_TAB_UTILS = getClass(classLoader, distillerTabUtils); 103 | CLASS_SERVICE_BRIDGE = getClass(classLoader, serviceBridge); 104 | CLASS_CHROME_APPLICATION = getClass(classLoader, chromeApplication); 105 | CLASS_SHORTCUT_HELPER = getClass(classLoader, shortcutHelper); 106 | CLASS_TAB_LAUNCH_TYPE = getClass(classLoader, tabLaunchType); 107 | CLASS_SHARE_HELPER = getClass(classLoader, shareHelper); 108 | CLASS_CONTENT_VIDEO_VIEW = getClass(classLoader, contentVideoView); 109 | CLASS_DATA_REDUCTION_SETTINGS = getClass(classLoader, dataReductionSettings); 110 | 111 | sIsObfuscated = Object.class.equals(helper.getTabModel().getClass()); 112 | } 113 | 114 | static void reloadPreferences(XSharedPreferences prefs) { 115 | StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 116 | try { 117 | prefs.reload(); 118 | } finally { 119 | StrictMode.setThreadPolicy(oldPolicy); 120 | } 121 | } 122 | 123 | static Boolean isDocumentModeEnabled(Context context) { 124 | Class featureUtils; 125 | try { 126 | featureUtils = getClass(context.getClassLoader(), new String[] { 127 | "org.chromium.chrome.browser.util.FeatureUtilities", 128 | "com.google.android.apps.chrome.utilities.FeatureUtilities" 129 | }); 130 | return (Boolean) callStaticMethod(featureUtils, "isDocumentMode", context); 131 | } catch (NoSuchMethodError e) {} 132 | try { 133 | featureUtils = XposedHelpers.findClass("com.google.android.apps.chrome.utilities.FeatureUtilitiesInternal", context.getClassLoader()); 134 | return (Boolean) callStaticMethod(featureUtils, "isDocumentMode", context); 135 | } catch (XposedHelpers.ClassNotFoundError | NoSuchMethodError e) {} 136 | return false; 137 | } 138 | 139 | public static boolean isObfuscated() { 140 | return BooleanUtils.isNotFalse(sIsObfuscated); 141 | } 142 | 143 | public static int getDarkenedColor(int color, float factor) { 144 | float[] statusColor = new float[3]; 145 | Color.colorToHSV(color, statusColor); 146 | statusColor[2] *= factor; 147 | return Color.HSVToColor(statusColor); 148 | } 149 | 150 | public static int applyColorTint(int color, float factor) { 151 | int r1 = Color.red(color); 152 | int g1 = Color.green(color); 153 | int b1 = Color.blue(color); 154 | int r2 = (int) (r1 + (factor * (255 - r1))); 155 | int g2 = (int) (g1 + (factor * (255 - g1))); 156 | int b2 = (int) (b1 + (factor * (255 - b1))); 157 | return Color.rgb(r2, g2, b2); 158 | } 159 | 160 | public static int applyColorAlpha(int color, int alpha) { 161 | return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)); 162 | } 163 | 164 | public static void log(String text) { 165 | if (isObfuscated()) return; 166 | XposedBridge.log(text); 167 | } 168 | 169 | static Map createDefaultsMap(Resources resources) { 170 | Map map = new HashMap<>(); 171 | XmlResourceParser parser = resources.getXml(R.xml.aosp_preferences); 172 | String namespace = "http://schemas.android.com/apk/res/android"; 173 | try { 174 | int eventType = parser.getEventType(); 175 | while (eventType != XmlPullParser.END_DOCUMENT) { 176 | if (eventType == XmlPullParser.START_TAG) { 177 | if (parser.getName().equals("SwitchPreference")) { 178 | String key = parser.getAttributeValue(namespace, "key"); 179 | boolean value = parser.getAttributeBooleanValue(namespace, "defaultValue", true); 180 | map.put(key, value); 181 | } else if (parser.getName().equals("ListPreference")) { 182 | String key = parser.getAttributeValue(namespace, "key"); 183 | String value = parser.getAttributeValue(namespace, "defaultValue"); 184 | map.put(key, value); 185 | } 186 | } 187 | eventType = parser.next(); 188 | } 189 | } catch (Exception e) { 190 | XposedBridge.log(TAG + e); 191 | parser.close(); 192 | return Collections.emptyMap(); 193 | } 194 | parser.close(); 195 | return map; 196 | } 197 | 198 | private static Class getClass(ClassLoader classLoader, String[] classes) { 199 | for (String clazz : classes) { 200 | try { 201 | return XposedHelpers.findClass(clazz, classLoader); 202 | } catch (XposedHelpers.ClassNotFoundError e) { 203 | 204 | } 205 | } 206 | return null; 207 | } 208 | 209 | static Object callMethod(Object obj, String methodName, Object... args) { 210 | if (obj == null) { 211 | throw new NoSuchMethodError("NullPointerException for method: " + methodName); 212 | } 213 | try { 214 | try { 215 | return XposedHelpers.callMethod(obj, methodName, args); 216 | } catch (NoSuchMethodError e) { 217 | return findMethodBestMatch(obj.getClass(), methodName, XposedHelpers.getParameterTypes(args)).invoke(obj, args); 218 | } catch (NoClassDefFoundError e) { 219 | return findMethodExact(obj.getClass(), methodName, getPrimitiveParameterTypes(args)).invoke(obj, args); 220 | } 221 | } catch (Throwable t) { 222 | throw new NoSuchMethodError(t.getMessage()); 223 | } 224 | } 225 | 226 | static Object callStaticMethod(Class clazz, String methodName, Object... args) { 227 | if (clazz == null) { 228 | throw new NoSuchMethodError("ClassNotFoundError for static method: " + methodName); 229 | } 230 | try { 231 | try { 232 | return XposedHelpers.callStaticMethod(clazz, methodName, args); 233 | } catch (NoSuchMethodError e) { 234 | return findMethodBestMatch(clazz, methodName, XposedHelpers.getParameterTypes(args)).invoke(null, args); 235 | } catch (NoClassDefFoundError e) { 236 | return findMethodExact(clazz, methodName, getPrimitiveParameterTypes(args)).invoke(null, args); 237 | } 238 | } catch (Throwable t) { 239 | throw new NoSuchMethodError(t.getMessage()); 240 | } 241 | } 242 | 243 | private static Method findMethodBestMatch(Class clazz, String methodName, Class[] parameterTypes) { 244 | String fullMethodName = clazz.getName() + '#' + methodName + getParametersString(parameterTypes) + "#bestmatch"; 245 | 246 | if (methodCache.containsKey(fullMethodName)) { 247 | Method method = methodCache.get(fullMethodName); 248 | if (method == null) 249 | throw new NoSuchMethodError(fullMethodName); 250 | return method; 251 | } 252 | 253 | Method bestMatch = null; 254 | Class clz = clazz; 255 | boolean considerPrivateMethods = true; 256 | do { 257 | for (Method method : clz.getDeclaredMethods()) { 258 | // don't consider private methods of superclasses 259 | if (!considerPrivateMethods && Modifier.isPrivate(method.getModifiers())) 260 | continue; 261 | 262 | // compare name and parameters 263 | if ((method.getName().equals(methodName) || method.getName().startsWith(methodName + "$")) 264 | && ClassUtils.isAssignable(parameterTypes, method.getParameterTypes(), true)) { 265 | // get accessible version of method 266 | bestMatch = method; 267 | break; 268 | } 269 | } 270 | considerPrivateMethods = false; 271 | } while ((clz = clz.getSuperclass()) != null); 272 | 273 | if (bestMatch != null) { 274 | bestMatch.setAccessible(true); 275 | methodCache.put(fullMethodName, bestMatch); 276 | return bestMatch; 277 | } else { 278 | NoSuchMethodError e = new NoSuchMethodError(fullMethodName); 279 | methodCache.put(fullMethodName, null); 280 | throw e; 281 | } 282 | } 283 | 284 | private static Method findMethodExact(Class clazz, String methodName, Class[] parameterTypes) { 285 | Class clz = clazz; 286 | do { 287 | try { 288 | return XposedHelpers.findMethodExact(clz, methodName, parameterTypes); 289 | } catch (NoSuchMethodError nsme) { 290 | 291 | } 292 | } while ((clz = clz.getSuperclass()) != null); 293 | throw new NoSuchMethodError(clazz.getName() + '#' + methodName + getParametersString(parameterTypes)); 294 | } 295 | 296 | /** 297 | * Return an array with the classes of the given objects. If an object 298 | * is a wrapper for a primitive type, then the primitive type is used 299 | */ 300 | private static Class[] getPrimitiveParameterTypes(Object... args) { 301 | Class[] clazzes = new Class[args.length]; 302 | for (int i = 0; i < args.length; i++) { 303 | if (args[i] != null) { 304 | if (ClassUtils.isPrimitiveWrapper(args[i].getClass())) { 305 | clazzes[i] = ClassUtils.wrapperToPrimitive(args[i].getClass()); 306 | } else { 307 | clazzes[i] = args[i].getClass(); 308 | } 309 | } 310 | } 311 | return clazzes; 312 | } 313 | 314 | private static String getParametersString(Class... clazzes) { 315 | StringBuilder sb = new StringBuilder("("); 316 | boolean first = true; 317 | for (Class clazz : clazzes) { 318 | if (first) 319 | first = false; 320 | else 321 | sb.append(","); 322 | 323 | if (clazz != null) 324 | sb.append(clazz.getCanonicalName()); 325 | else 326 | sb.append("null"); 327 | } 328 | sb.append(")"); 329 | return sb.toString(); 330 | } 331 | 332 | static Object getObjectField(Object obj, String fieldName) { 333 | try { 334 | return XposedHelpers.getObjectField(obj, fieldName); 335 | } catch (NoSuchFieldError e) { 336 | 337 | } 338 | try { 339 | return findField(obj.getClass(), fieldName).get(obj); 340 | } catch (IllegalAccessException e) { 341 | // should not happen 342 | XposedBridge.log(e); 343 | throw new IllegalAccessError(e.getMessage()); 344 | } catch (IllegalArgumentException e) { 345 | throw e; 346 | } 347 | } 348 | 349 | static boolean getBooleanField(Object obj, String fieldName) { 350 | try { 351 | return XposedHelpers.getBooleanField(obj, fieldName); 352 | } catch (NoSuchFieldError e) { 353 | 354 | } 355 | try { 356 | return findField(obj.getClass(), fieldName).getBoolean(obj); 357 | } catch (IllegalAccessException e) { 358 | // should not happen 359 | XposedBridge.log(e); 360 | throw new IllegalAccessError(e.getMessage()); 361 | } catch (IllegalArgumentException e) { 362 | throw e; 363 | } 364 | } 365 | 366 | static Object getStaticObjectField(Class clazz, String fieldName) { 367 | try { 368 | return XposedHelpers.getStaticObjectField(clazz, fieldName); 369 | } catch (NoSuchFieldError e) { 370 | 371 | } 372 | try { 373 | return findField(clazz, fieldName).get(null); 374 | } catch (IllegalAccessException e) { 375 | // should not happen 376 | XposedBridge.log(e); 377 | throw new IllegalAccessError(e.getMessage()); 378 | } catch (IllegalArgumentException e) { 379 | throw e; 380 | } 381 | } 382 | 383 | private static Field findField(Class clazz, String fieldName) { 384 | String fullFieldName = clazz.getName() + '#' + fieldName; 385 | 386 | if (fieldCache.containsKey(fullFieldName)) { 387 | Field field = fieldCache.get(fullFieldName); 388 | if (field == null) 389 | throw new NoSuchFieldError(fullFieldName); 390 | return field; 391 | } 392 | 393 | try { 394 | Field field = findFieldRecursiveImpl(clazz, fieldName); 395 | field.setAccessible(true); 396 | fieldCache.put(fullFieldName, field); 397 | return field; 398 | } catch (NoSuchFieldException | NoClassDefFoundError e) { 399 | fieldCache.put(fullFieldName, null); 400 | throw new NoSuchFieldError(fullFieldName); 401 | } 402 | } 403 | 404 | private static Field findFieldRecursiveImpl(Class clazz, String fieldName) throws NoSuchFieldException { 405 | try { 406 | return clazz.getDeclaredField(fieldName); 407 | } catch (NoSuchFieldException e) { 408 | Class clz = clazz; 409 | boolean considerPrivateFields = true; 410 | do { 411 | for (Field field : clz.getDeclaredFields()) { 412 | // don't consider private fields of superclasses 413 | if (!considerPrivateFields && Modifier.isPrivate(field.getModifiers())) 414 | continue; 415 | 416 | if (field.getName().equals(fieldName) || field.getName().startsWith(fieldName + "$")) 417 | return field; 418 | } 419 | considerPrivateFields = false; 420 | } while ((clz = clz.getSuperclass()) != null); 421 | throw e; 422 | } 423 | } 424 | 425 | } 426 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/broadcastreceiver/PieReceiver.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie.broadcastreceiver; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.BroadcastReceiver; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.SharedPreferences; 8 | import android.os.Build; 9 | 10 | import java.lang.reflect.Method; 11 | 12 | public class PieReceiver extends BroadcastReceiver { 13 | 14 | public static final String FULLSCREEN_UPDATED_INTENT = "com.jt5.xposed.chromepie.intent.FULLSCREEN_UPDATED"; 15 | public static final String EXPAND_NOTIFICATIONS_INTENT = "com.jt5.xposed.chromepie.intent.EXPAND_NOTIFICATIONS"; 16 | 17 | @SuppressLint("WorldReadableFiles") 18 | @SuppressWarnings("deprecation") 19 | @Override 20 | public void onReceive(Context context, Intent intent) { 21 | if (intent.getAction().equals(FULLSCREEN_UPDATED_INTENT)) { 22 | SharedPreferences prefs = context.getSharedPreferences( 23 | context.getPackageName() + "_preferences", Context.MODE_WORLD_READABLE); 24 | boolean isFullscreen = intent.getBooleanExtra("IS_FULLSCREEN", false); 25 | prefs.edit().putBoolean("launch_in_fullscreen", isFullscreen).apply(); 26 | } else if (intent.getAction().equals(EXPAND_NOTIFICATIONS_INTENT)) { 27 | try { 28 | Object statusBarService = context.getSystemService("statusbar"); 29 | Class statusBarManager = Class.forName("android.app.StatusBarManager"); 30 | Method expand; 31 | if (Build.VERSION.SDK_INT >= 17) { 32 | expand = statusBarManager.getMethod("expandNotificationsPanel"); 33 | } else { 34 | expand = statusBarManager.getMethod("expand"); 35 | } 36 | expand.invoke(statusBarService); 37 | } catch (Throwable t) { 38 | 39 | } 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/settings/ItemsPreferenceFragment.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie.settings; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.preference.ListPreference; 7 | import android.preference.PreferenceFragment; 8 | import android.preference.PreferenceScreen; 9 | import android.view.Menu; 10 | import android.view.MenuItem; 11 | 12 | import com.jt5.xposed.chromepie.R; 13 | import com.jt5.xposed.chromepie.settings.preference.PieListPreference; 14 | 15 | public class ItemsPreferenceFragment extends PreferenceFragment { 16 | 17 | private int mSlice; 18 | private int mCount; 19 | 20 | @Override 21 | public void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | addPreferencesFromResource(R.xml.preference_screen); 24 | mSlice = getArguments().getInt("slice"); 25 | mCount = getArguments().getInt("count"); 26 | setHasOptionsMenu(true); 27 | getActivity().getActionBar().setDisplayHomeAsUpEnabled(true); 28 | getActivity().getActionBar().setTitle(getResources().getString(R.string.slice) + " " + mSlice); 29 | loadPreferences(); 30 | } 31 | 32 | private void loadPreferences() { 33 | PreferenceScreen screen = getPreferenceScreen(); 34 | // add main item first so that dependencies can be set 35 | PieListPreference listPref = new PieListPreference(getActivity(), mSlice, mSlice); 36 | screen.addPreference(listPref); 37 | 38 | for (int item = 1; item <= mCount; item++) { 39 | if (item == mSlice) { 40 | continue; 41 | } 42 | listPref = new PieListPreference(getActivity(), item, mSlice); 43 | screen.addPreference(listPref); 44 | listPref.setDependency("slice_" + mSlice + "_item_" + mSlice); 45 | } 46 | } 47 | 48 | void finishFragment() { 49 | Intent data = new Intent(); 50 | data.putExtra("slice", mSlice); 51 | data.putExtra("entry", ((ListPreference) findPreference("slice_" + mSlice + "_item_" + mSlice)).getEntry()); 52 | getActivity().setResult(Activity.RESULT_OK, data); 53 | getActivity().finish(); 54 | } 55 | 56 | @Override 57 | public boolean onOptionsItemSelected(MenuItem item) { 58 | switch (item.getItemId()) { 59 | case android.R.id.home: 60 | finishFragment(); 61 | return true; 62 | } 63 | return super.onOptionsItemSelected(item); 64 | } 65 | 66 | @Override 67 | public void onPrepareOptionsMenu(Menu menu) { 68 | menu.removeItem(R.id.menu_load_defaults); 69 | menu.removeItem(R.id.actionbar_kill); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/settings/MenuPreferenceFragment.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie.settings; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.SharedPreferences; 8 | import android.content.SharedPreferences.Editor; 9 | import android.os.Bundle; 10 | import android.preference.Preference; 11 | import android.preference.Preference.OnPreferenceClickListener; 12 | import android.preference.PreferenceActivity; 13 | import android.preference.PreferenceCategory; 14 | import android.preference.PreferenceFragment; 15 | import android.preference.PreferenceManager; 16 | import android.preference.PreferenceScreen; 17 | import android.view.MenuItem; 18 | import android.widget.BaseAdapter; 19 | 20 | import com.jt5.xposed.chromepie.PieControl; 21 | import com.jt5.xposed.chromepie.R; 22 | import com.jt5.xposed.chromepie.settings.preference.PieMainPreference; 23 | 24 | import java.util.Map; 25 | 26 | public class MenuPreferenceFragment extends PreferenceFragment { 27 | 28 | private static final int EDIT_ITEMS_REQUEST = 1; 29 | 30 | private SharedPreferences mSharedPrefs; 31 | private PreferenceCategory mPieMenuCat; 32 | 33 | @SuppressLint("WorldReadableFiles") 34 | @SuppressWarnings("deprecation") 35 | @Override 36 | public void onCreate(Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | getPreferenceManager().setSharedPreferencesMode(Context.MODE_WORLD_READABLE); 39 | addPreferencesFromResource(R.xml.menu_preferences); 40 | mSharedPrefs = getActivity().getSharedPreferences( 41 | getPreferenceManager().getSharedPreferencesName(), Context.MODE_WORLD_READABLE); 42 | 43 | setHasOptionsMenu(true); 44 | getActivity().getActionBar().setDisplayHomeAsUpEnabled(true); 45 | getActivity().getActionBar().setTitle(getResources().getString(R.string.edit_pie_menu_title)); 46 | mPieMenuCat = (PreferenceCategory) findPreference("pie_slices_cat"); 47 | 48 | final Preference newSlice = findPreference("new_slice"); 49 | newSlice.setOnPreferenceClickListener(new OnPreferenceClickListener() { 50 | @Override 51 | public boolean onPreferenceClick(Preference preference) { 52 | if (mPieMenuCat.getPreferenceCount() < PieControl.MAX_SLICES) { 53 | PieMainPreference mainPref = new PieMainPreference(getActivity(), (mPieMenuCat.getPreferenceCount() + 1)); 54 | mPieMenuCat.addPreference(mainPref); 55 | } 56 | return true; 57 | } 58 | }); 59 | 60 | loadPreferences(); 61 | 62 | } 63 | 64 | @SuppressWarnings("deprecation") 65 | private void loadDefaultValues(boolean readAgain) { 66 | PreferenceManager.setDefaultValues(getActivity(), getPreferenceManager().getSharedPreferencesName(), 67 | Context.MODE_WORLD_READABLE, R.xml.aosp_preferences, readAgain); 68 | 69 | if (readAgain) { 70 | Editor editor = mSharedPrefs.edit(); 71 | for (int i = 1; i < PieControl.MAX_SLICES; i++) { 72 | editor.putBoolean("screen_slice_" + i, true); 73 | } 74 | editor.putBoolean("screen_slice_" + PieControl.MAX_SLICES, false).apply(); 75 | } 76 | } 77 | 78 | private void loadPreferences() { 79 | Map keys = mSharedPrefs.getAll(); 80 | for (Map.Entry entry : keys.entrySet()) { 81 | String key = entry.getKey(); 82 | if (key.startsWith("screen_") && (Boolean) entry.getValue()) { 83 | int slice = Character.getNumericValue(key.charAt(key.length() - 1)); 84 | PieMainPreference mainPref = new PieMainPreference(getActivity(), slice); 85 | mPieMenuCat.addPreference(mainPref); 86 | } 87 | } 88 | } 89 | 90 | @Override 91 | public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 92 | if (preference instanceof PieMainPreference) { 93 | Bundle extras = new Bundle(); 94 | extras.putInt("slice", ((PieMainPreference) preference).getSlice()); 95 | extras.putInt("count", mPieMenuCat.getPreferenceCount()); 96 | ((PreferenceActivity) getActivity()).startWithFragment( 97 | ItemsPreferenceFragment.class.getName(), extras, this, EDIT_ITEMS_REQUEST); 98 | return true; 99 | } 100 | return false; 101 | } 102 | 103 | @Override 104 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 105 | if (requestCode == EDIT_ITEMS_REQUEST && resultCode == Activity.RESULT_OK) { 106 | int slice = data.getIntExtra("slice", 1); 107 | String summary = data.getStringExtra("entry"); 108 | PieMainPreference pref = (PieMainPreference) findPreference("screen_slice_" + slice); 109 | pref.setSummary(summary); 110 | } 111 | ((BaseAdapter) getPreferenceScreen().getRootAdapter()).notifyDataSetChanged(); 112 | } 113 | 114 | @Override 115 | public boolean onOptionsItemSelected(MenuItem item) { 116 | switch (item.getItemId()) { 117 | case R.id.menu_load_defaults: 118 | mPieMenuCat.removeAll(); 119 | loadDefaultValues(true); 120 | loadPreferences(); 121 | return true; 122 | case R.id.actionbar_kill: 123 | ((PieSettings) getActivity()).killProcesses(false); 124 | return true; 125 | case android.R.id.home: 126 | getActivity().finish(); 127 | return true; 128 | default: 129 | return super.onOptionsItemSelected(item); 130 | } 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/settings/PiePreferenceFragment.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie.settings; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.Activity; 5 | import android.content.ComponentName; 6 | import android.content.Context; 7 | import android.content.SharedPreferences; 8 | import android.content.pm.PackageManager; 9 | import android.os.Bundle; 10 | import android.preference.Preference; 11 | import android.preference.Preference.OnPreferenceChangeListener; 12 | import android.preference.Preference.OnPreferenceClickListener; 13 | import android.preference.PreferenceActivity; 14 | import android.preference.PreferenceFragment; 15 | import android.preference.PreferenceManager; 16 | import android.view.Menu; 17 | import android.view.MenuItem; 18 | 19 | import com.jt5.xposed.chromepie.R; 20 | 21 | public class PiePreferenceFragment extends PreferenceFragment { 22 | 23 | @SuppressLint("WorldReadableFiles") 24 | @SuppressWarnings("deprecation") 25 | @Override 26 | public void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | getPreferenceManager().setSharedPreferencesMode(Context.MODE_WORLD_READABLE); 29 | addPreferencesFromResource(R.xml.main_preferences); 30 | SharedPreferences prefs = getActivity().getSharedPreferences( 31 | getPreferenceManager().getSharedPreferencesName(), Context.MODE_WORLD_READABLE); 32 | 33 | // Committing a value to shared preferences ensures they are 34 | // world readable in case readability was reset somehow 35 | boolean readable = prefs.getBoolean("readable", true); 36 | prefs.edit().putBoolean("readable", !readable).commit(); 37 | setHasOptionsMenu(true); 38 | 39 | // If SharedPreferences does not contain this preference, 40 | // we can presume this is a new install 41 | if (!prefs.contains("screen_slice_1")) { 42 | PreferenceManager.setDefaultValues(getActivity(), getPreferenceManager().getSharedPreferencesName(), 43 | Context.MODE_WORLD_READABLE, R.xml.aosp_preferences, false); 44 | } 45 | 46 | final Preference killChrome = findPreference("kill_chrome"); 47 | killChrome.setOnPreferenceClickListener(new OnPreferenceClickListener() { 48 | @Override 49 | public boolean onPreferenceClick(Preference preference) { 50 | ((PieSettings) getActivity()).killProcesses(true); 51 | return true; 52 | } 53 | }); 54 | 55 | final Preference hideIcon = findPreference("hide_launcher_icon"); 56 | hideIcon.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { 57 | @Override 58 | public boolean onPreferenceChange(Preference preference, Object newValue) { 59 | int state = (Boolean) newValue ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED : 60 | PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 61 | PackageManager pm = getActivity().getPackageManager(); 62 | pm.setComponentEnabledSetting(new ComponentName(getActivity(), 63 | "com.jt5.xposed.chromepie.settings.PieSettings_Alias"), state, PackageManager.DONT_KILL_APP); 64 | return true; 65 | } 66 | }); 67 | 68 | final Preference editMenu = findPreference("edit_pie_menu"); 69 | editMenu.setOnPreferenceClickListener(new OnPreferenceClickListener() { 70 | @Override 71 | public boolean onPreferenceClick(Preference preference) { 72 | ((PreferenceActivity) getActivity()).startWithFragment( 73 | MenuPreferenceFragment.class.getName(), null, null, Activity.RESULT_CANCELED); 74 | return true; 75 | } 76 | }); 77 | } 78 | 79 | @Override 80 | public boolean onOptionsItemSelected(MenuItem item) { 81 | switch (item.getItemId()) { 82 | case R.id.actionbar_kill: 83 | ((PieSettings) getActivity()).killProcesses(false); 84 | return true; 85 | default: 86 | return super.onOptionsItemSelected(item); 87 | } 88 | } 89 | 90 | @Override 91 | public void onPrepareOptionsMenu(Menu menu) { 92 | menu.removeItem(R.id.menu_load_defaults); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/settings/PieSettings.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie.settings; 2 | 3 | import android.app.ActivityManager; 4 | import android.app.AlertDialog; 5 | import android.app.AlertDialog.Builder; 6 | import android.app.Fragment; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.content.pm.ActivityInfo; 10 | import android.content.pm.PackageManager; 11 | import android.content.pm.ResolveInfo; 12 | import android.net.Uri; 13 | import android.os.Bundle; 14 | import android.os.Parcelable; 15 | import android.preference.PreferenceActivity; 16 | import android.text.method.LinkMovementMethod; 17 | import android.view.Menu; 18 | import android.view.MenuItem; 19 | import android.view.View; 20 | import android.widget.TextView; 21 | import android.widget.Toast; 22 | 23 | import com.jt5.xposed.chromepie.R; 24 | 25 | import java.util.ArrayList; 26 | import java.util.Arrays; 27 | import java.util.Collections; 28 | import java.util.HashSet; 29 | import java.util.List; 30 | import java.util.Set; 31 | 32 | public class PieSettings extends PreferenceActivity { 33 | 34 | private Fragment mCurrentFragment; 35 | 36 | public static final List CHROME_ACTIVITY_CLASSES = Arrays.asList( 37 | "org.chromium.chrome.browser.ChromeTabbedActivity", 38 | "org.chromium.chrome.browser.document.DocumentActivity", 39 | "org.chromium.chrome.browser.document.IncognitoDocumentActivity", 40 | "org.chromium.chrome.browser.customtabs.CustomTabActivity", 41 | "com.google.android.apps.chrome.ChromeTabbedActivity", 42 | "com.google.android.apps.chrome.document.DocumentActivity", 43 | "com.google.android.apps.chrome.document.IncognitoDocumentActivity", 44 | "com.google.android.apps.chrome.Main" 45 | ); 46 | 47 | @Override 48 | protected void onCreate(Bundle savedInstanceState) { 49 | super.onCreate(savedInstanceState); 50 | if (getIntent().getExtras() == null || 51 | getIntent().getExtras().getString(PreferenceActivity.EXTRA_SHOW_FRAGMENT) == null) { 52 | getFragmentManager().beginTransaction().replace(android.R.id.content, new PiePreferenceFragment()).commit(); 53 | } 54 | } 55 | 56 | @Override 57 | public void onBackPressed() { 58 | if (mCurrentFragment != null && mCurrentFragment instanceof ItemsPreferenceFragment) { 59 | ((ItemsPreferenceFragment) mCurrentFragment).finishFragment(); 60 | } else { 61 | super.onBackPressed(); 62 | } 63 | mCurrentFragment = null; 64 | } 65 | 66 | @Override 67 | public void onAttachFragment(Fragment fragment) { 68 | super.onAttachFragment(fragment); 69 | mCurrentFragment = fragment; 70 | } 71 | 72 | @Override 73 | protected boolean isValidFragment(String fragmentName) { 74 | return ItemsPreferenceFragment.class.getName().equals(fragmentName) || 75 | MenuPreferenceFragment.class.getName().equals(fragmentName); 76 | } 77 | 78 | @Override 79 | public boolean onCreateOptionsMenu(Menu menu) { 80 | getMenuInflater().inflate(R.menu.main_menu, menu); 81 | return true; 82 | } 83 | 84 | @Override 85 | public boolean onOptionsItemSelected(MenuItem item) { 86 | switch (item.getItemId()) { 87 | case R.id.menu_help: 88 | showHelpDialog(); 89 | return true; 90 | default: 91 | return super.onOptionsItemSelected(item); 92 | } 93 | } 94 | 95 | private void showHelpDialog() { 96 | View helpView = getLayoutInflater().inflate(R.layout.help_dialog, null); 97 | 98 | ((TextView) helpView.findViewById(R.id.about_thread)).setMovementMethod(LinkMovementMethod.getInstance()); 99 | 100 | // Display the correct version 101 | try { 102 | ((TextView) helpView.findViewById(R.id.version)).setText(getString(R.string.app_version, 103 | getPackageManager().getPackageInfo(getPackageName(), 0).versionName)); 104 | } catch (PackageManager.NameNotFoundException e) { 105 | 106 | } 107 | 108 | // Prepare and show the dialog 109 | Builder dlgBuilder = new AlertDialog.Builder(this); 110 | dlgBuilder.setTitle(R.string.app_name); 111 | dlgBuilder.setCancelable(true); 112 | dlgBuilder.setIcon(R.drawable.ic_launcher); 113 | dlgBuilder.setPositiveButton(android.R.string.ok, null); 114 | dlgBuilder.setView(helpView); 115 | dlgBuilder.show(); 116 | } 117 | 118 | void killProcesses(boolean launch) { 119 | List intents = getLaunchIntents(); 120 | if (intents.isEmpty()) { 121 | Toast.makeText(this, getResources().getString(R.string.chrome_not_found), Toast.LENGTH_SHORT).show(); 122 | } else { 123 | if (launch) { 124 | if (intents.size() == 1) { 125 | startActivity(intents.get(0)); 126 | } else { 127 | Intent chooserIntent = Intent.createChooser(intents.remove(intents.size() - 1), 128 | getResources().getString(R.string.chrome_app_chooser)); 129 | chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[intents.size()])); 130 | startActivity(chooserIntent); 131 | } 132 | } else { 133 | Toast.makeText(this, getResources().getString(R.string.chrome_killed), Toast.LENGTH_SHORT).show(); 134 | } 135 | } 136 | } 137 | 138 | private List getLaunchIntents() { 139 | ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 140 | List intents = new ArrayList<>(); 141 | for (String packageName : getPackages()) { 142 | Intent launch = getPackageManager().getLaunchIntentForPackage(packageName); 143 | if (launch != null) { 144 | am.killBackgroundProcesses(packageName); 145 | intents.add(launch); 146 | } 147 | } 148 | return intents; 149 | } 150 | 151 | private Set getPackages() { 152 | Set packages = new HashSet<>(); 153 | Intent intent = new Intent(Intent.ACTION_VIEW); 154 | intent.setData(Uri.parse("http://www.google.com")); 155 | List browsers = getPackageManager().queryIntentActivities(intent, 0); 156 | 157 | for (ResolveInfo resInfo : browsers) { 158 | String pkg = resInfo.activityInfo.packageName; 159 | try { 160 | ActivityInfo[] activities = getPackageManager().getPackageInfo(pkg, PackageManager.GET_ACTIVITIES).activities; 161 | List activityNames = new ArrayList<>(); 162 | for (ActivityInfo actInfo : activities) { 163 | activityNames.add(actInfo.name); 164 | } 165 | if (!Collections.disjoint(CHROME_ACTIVITY_CLASSES, activityNames)) { 166 | packages.add(pkg); 167 | } 168 | } catch (PackageManager.NameNotFoundException ignored) {} 169 | } 170 | return packages; 171 | } 172 | 173 | } 174 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/settings/preference/PieListPreference.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie.settings.preference; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.preference.ListPreference; 6 | 7 | import com.jt5.xposed.chromepie.R; 8 | 9 | public class PieListPreference extends ListPreference { 10 | 11 | public PieListPreference(Context context, int item, int slice) { 12 | super(context); 13 | initialise(item, slice); 14 | } 15 | 16 | @Override 17 | public void setValue(String value) { 18 | String oldValue = getValue(); 19 | super.setValue(value); 20 | if (!value.equals(oldValue)) { 21 | updateState(value); 22 | notifyDependencyChange(shouldDisableDependents()); 23 | } 24 | } 25 | 26 | @Override 27 | public boolean shouldDisableDependents() { 28 | boolean shouldDisableDependents = super.shouldDisableDependents(); 29 | String value = getValue(); 30 | return shouldDisableDependents || value == null || value.equals("none"); 31 | } 32 | 33 | private void initialise(int item, int slice) { 34 | setKey("slice_" + slice + "_item_" + item); 35 | setTitle(getContext().getResources().getString(R.string.pie_item) + " " + item); 36 | if (item == slice) { 37 | setTitle(getTitle() + " (" + getContext().getResources().getString(R.string.main_item) + ")"); 38 | } 39 | setEntries(R.array.pie_item_entries); 40 | setEntryValues(R.array.pie_item_values); 41 | setIcon(R.drawable.null_icon); 42 | setDefaultValue("none"); 43 | setOrder(item); 44 | } 45 | 46 | private void updateState(String newValue) { 47 | setSummary(getEntry()); 48 | int index = findIndexOfValue(newValue); 49 | if (index >= 0) { 50 | TypedArray drawables = getContext().getResources().obtainTypedArray(R.array.pie_item_dark_drawables); 51 | setIcon(drawables.getResourceId(index, R.drawable.null_icon)); 52 | drawables.recycle(); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/settings/preference/PieMainPreference.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie.settings.preference; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import android.annotation.SuppressLint; 7 | import android.content.Context; 8 | import android.content.SharedPreferences; 9 | import android.content.SharedPreferences.Editor; 10 | import android.content.res.Resources; 11 | import android.preference.Preference; 12 | import android.preference.PreferenceCategory; 13 | import android.preference.PreferenceManager; 14 | import android.view.View; 15 | 16 | import com.jt5.xposed.chromepie.PieControl; 17 | import com.jt5.xposed.chromepie.R; 18 | 19 | public class PieMainPreference extends Preference implements View.OnClickListener { 20 | 21 | private PreferenceCategory mPreferenceCategory; 22 | private int mSlice; 23 | private SharedPreferences mSharedPrefs; 24 | private Boolean mIsRemoved = false; 25 | private final Resources mResources; 26 | 27 | public PieMainPreference(Context context, int slice) { 28 | super(context); 29 | mSlice = slice; 30 | mResources = getContext().getResources(); 31 | initialise(); 32 | } 33 | 34 | @Override 35 | protected void onBindView(View view) { 36 | super.onBindView(view); 37 | View remover = view.findViewById(R.id.click_remove); 38 | remover.setOnClickListener(this); 39 | } 40 | 41 | @SuppressLint("WorldReadableFiles") 42 | @SuppressWarnings("deprecation") 43 | @Override 44 | protected void onAttachedToHierarchy(PreferenceManager preferenceManager) { 45 | super.onAttachedToHierarchy(preferenceManager); 46 | preferenceManager.setSharedPreferencesMode(Context.MODE_WORLD_READABLE); 47 | mSharedPrefs = getContext().getSharedPreferences( 48 | preferenceManager.getSharedPreferencesName(), Context.MODE_WORLD_READABLE); 49 | persistBoolean(true); 50 | mPreferenceCategory = (PreferenceCategory) preferenceManager.findPreference("pie_slices_cat"); 51 | preferenceManager.findPreference("new_slice").setEnabled( 52 | mPreferenceCategory.getPreferenceCount() < PieControl.MAX_SLICES); 53 | updateSummary(); 54 | } 55 | 56 | @Override 57 | public void onClick(View v) { 58 | if (!mIsRemoved) { 59 | mIsRemoved = true; 60 | v.setOnClickListener(null); 61 | mPreferenceCategory.removePreference(this); 62 | } 63 | } 64 | 65 | private void initialise() { 66 | setKey("screen_slice_" + mSlice); 67 | setTitle(mResources.getString(R.string.slice) + " " + mSlice); 68 | setSummary(mResources.getString(R.string.none)); 69 | setOrder(mSlice); 70 | setWidgetLayoutResource(R.layout.mainpref_remove); 71 | } 72 | 73 | private void updateSummary() { 74 | List values = Arrays.asList(mResources.getStringArray(R.array.pie_item_values)); 75 | String value = mSharedPrefs.getString("slice_" + mSlice + "_item_" + mSlice, "none"); 76 | int index = values.indexOf(value); 77 | if (index >= 0) { 78 | String[] entries = mResources.getStringArray(R.array.pie_item_entries); 79 | setSummary(entries[index]); 80 | } 81 | } 82 | 83 | public int getSlice() { 84 | return mSlice; 85 | } 86 | 87 | private void preferenceRemoved(int newSlice) { 88 | mSlice = newSlice; 89 | setKey("screen_slice_" + mSlice); 90 | setTitle(mResources.getString(R.string.slice) + " " + mSlice); 91 | setOrder(mSlice); 92 | updateSummary(); 93 | } 94 | 95 | @Override 96 | protected void onPrepareForRemoval() { 97 | super.onPrepareForRemoval(); 98 | Editor editor = mSharedPrefs.edit(); 99 | int count = mPreferenceCategory.getPreferenceCount(); 100 | 101 | for (int i = mSlice; i < count; i++) { 102 | for (int j = 1; j <= PieControl.MAX_SLICES; j++) { 103 | editor.putString("slice_" + i + "_item_" + j, 104 | mSharedPrefs.getString("slice_" + (i + 1) + "_item_" + j, "none")); 105 | } 106 | 107 | // apply changes now so that the summary can be updated 108 | editor.apply(); 109 | PieMainPreference mainPref = (PieMainPreference) mPreferenceCategory.getPreference(i); 110 | mainPref.preferenceRemoved(i); 111 | } 112 | 113 | // remove final screen's preferences after they have been shifted 114 | for (int i = 1; i <= PieControl.MAX_SLICES; i++) { 115 | editor.remove("slice_" + count + "_item_" + i); 116 | } 117 | editor.putBoolean("screen_slice_" + count, false).apply(); 118 | 119 | getPreferenceManager().findPreference("new_slice").setEnabled( 120 | mPreferenceCategory.getPreferenceCount() <= PieControl.MAX_SLICES); 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/settings/preference/PieSeekBarPreference.java: -------------------------------------------------------------------------------- 1 | package com.jt5.xposed.chromepie.settings.preference; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.preference.DialogPreference; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | import android.widget.SeekBar; 9 | import android.widget.TextView; 10 | 11 | import com.jt5.xposed.chromepie.R; 12 | 13 | public class PieSeekBarPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener { 14 | 15 | private int mProgress; 16 | private int mOldValue; 17 | private int mMax; 18 | private int mMin; 19 | private boolean mTrackingTouch; 20 | private TextView mTextValue; 21 | 22 | public PieSeekBarPreference(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | loadAttributes(attrs); 25 | setDialogLayoutResource(R.layout.seekbar_preference); 26 | } 27 | 28 | private void loadAttributes(AttributeSet attrs) { 29 | mMin = attrs.getAttributeIntValue(null, "minimum", 0); 30 | int max = attrs.getAttributeIntValue(null, "maximum", 100) - mMin; 31 | setMax(max); 32 | } 33 | 34 | @Override 35 | protected void onBindDialogView(View view) { 36 | super.onBindDialogView(view); 37 | mTextValue = (TextView) view.findViewById(R.id.seekbar_pref_value); 38 | SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekbar_pref_seekbar); 39 | seekBar.setOnSeekBarChangeListener(this); 40 | seekBar.setMax(mMax); 41 | seekBar.setProgress(mProgress); 42 | mOldValue = mProgress + mMin; 43 | } 44 | 45 | @Override 46 | protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { 47 | setProgress(restoreValue ? getPersistedInt(mProgress) : (Integer) defaultValue); 48 | setSummary((mProgress + mMin) + "dp"); 49 | } 50 | 51 | @Override 52 | protected Object onGetDefaultValue(TypedArray a, int index) { 53 | return a.getInt(index, 0); 54 | } 55 | 56 | public void setMax(int max) { 57 | if (max != mMax) { 58 | mMax = max; 59 | notifyChanged(); 60 | } 61 | } 62 | 63 | public void setProgress(int progress) { 64 | setProgress(progress - mMin, true); 65 | } 66 | 67 | private void setProgress(int progress, boolean notifyChanged) { 68 | if (progress > mMax) { 69 | progress = mMax; 70 | } 71 | if (progress < 0) { 72 | progress = 0; 73 | } 74 | if (progress != mProgress) { 75 | mProgress = progress; 76 | persistInt(mProgress + mMin); 77 | if (notifyChanged) { 78 | notifyChanged(); 79 | } 80 | } 81 | } 82 | 83 | public int getProgress() { 84 | return mProgress; 85 | } 86 | 87 | /** 88 | * Persist the seekBar's progress value if callChangeListener 89 | * returns true, otherwise set the seekBar's progress to the stored value 90 | */ 91 | void syncProgress(SeekBar seekBar) { 92 | int progress = seekBar.getProgress(); 93 | if (progress != mProgress) { 94 | if (callChangeListener(progress)) { 95 | setProgress(progress, false); 96 | } else { 97 | seekBar.setProgress(mProgress); 98 | } 99 | } 100 | } 101 | 102 | @Override 103 | protected void onDialogClosed(boolean positiveResult) { 104 | if (!positiveResult) { 105 | setProgress(mOldValue); 106 | } 107 | setSummary((mProgress + mMin) + "dp"); 108 | } 109 | 110 | @Override 111 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 112 | if (fromUser && !mTrackingTouch) { 113 | syncProgress(seekBar); 114 | } 115 | mTextValue.setText((progress + mMin) + "dp"); 116 | } 117 | 118 | @Override 119 | public void onStartTrackingTouch(SeekBar seekBar) { 120 | mTrackingTouch = true; 121 | } 122 | 123 | @Override 124 | public void onStopTrackingTouch(SeekBar seekBar) { 125 | mTrackingTouch = false; 126 | if (seekBar.getProgress() != mProgress) { 127 | syncProgress(seekBar); 128 | } 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /src/com/jt5/xposed/chromepie/view/BaseItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.jt5.xposed.chromepie.view; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | import android.view.View; 23 | import android.widget.ImageView; 24 | 25 | /** 26 | * Pie menu item 27 | */ 28 | public class BaseItem { 29 | 30 | private final View mView; 31 | private final int level; 32 | private float start; 33 | private float sweep; 34 | private float animate; 35 | private int inner; 36 | private int outer; 37 | private boolean mSelected; 38 | private boolean mEnabled; 39 | private List mItems; 40 | private final int mMenuActionId; 41 | private final String mId; 42 | 43 | public BaseItem(View view, String id) { 44 | this(view, id, 0); 45 | } 46 | 47 | protected BaseItem(View view, String id, int action) { 48 | this(view, id, action, 1); 49 | } 50 | 51 | private BaseItem(View view, String id, int action, int level) { 52 | mView = view; 53 | mId = id; 54 | mMenuActionId = action; 55 | this.level = level; 56 | mEnabled = true; 57 | } 58 | 59 | protected boolean hasItems() { 60 | return mItems != null; 61 | } 62 | 63 | protected List getItems() { 64 | return mItems; 65 | } 66 | 67 | public void addItem(BaseItem item) { 68 | if (mItems == null) { 69 | mItems = new ArrayList<>(); 70 | } 71 | mItems.add(item); 72 | } 73 | 74 | public void setAlpha(float alpha) { 75 | final int alphaInt = Math.round(alpha * (mEnabled ? 255 : 77)); 76 | if (mView != null) { 77 | ((ImageView) mView).setImageAlpha(alphaInt); 78 | } 79 | } 80 | 81 | void setAnimationAngle(float a) { 82 | animate = a; 83 | } 84 | 85 | public float getAnimationAngle() { 86 | return animate; 87 | } 88 | 89 | public void setEnabled(boolean enabled) { 90 | mEnabled = enabled; 91 | } 92 | 93 | protected boolean isEnabled() { 94 | return mEnabled; 95 | } 96 | 97 | public String getId() { 98 | return mId; 99 | } 100 | 101 | protected int getMenuActionId() { 102 | return mMenuActionId; 103 | } 104 | 105 | protected void setSelected(boolean s) { 106 | mSelected = s; 107 | if (mView != null) { 108 | mView.setSelected(s); 109 | } 110 | } 111 | 112 | boolean isSelected() { 113 | return mSelected; 114 | } 115 | 116 | protected int getLevel() { 117 | return level; 118 | } 119 | 120 | void setGeometry(float st, float sw, int inside, int outside) { 121 | start = st; 122 | sweep = sw; 123 | inner = inside; 124 | outer = outside; 125 | } 126 | 127 | float getStart() { 128 | return start; 129 | } 130 | 131 | protected float getStartAngle() { 132 | return start + animate; 133 | } 134 | 135 | float getSweep() { 136 | return sweep; 137 | } 138 | 139 | int getInnerRadius() { 140 | return inner; 141 | } 142 | 143 | int getOuterRadius() { 144 | return outer; 145 | } 146 | 147 | public View getView() { 148 | return mView; 149 | } 150 | 151 | } 152 | --------------------------------------------------------------------------------