====== CM Grouper from source ====== Grouper is an N7 tablet with only wifi and without integrated 3G support, that means that [[ https://en.wikipedia.org/wiki/Baseband_processor | Baseband Processor]] related insecurity does not bother you on this device. It has been included in AOSP project for a long time. With easy-to-acquire source code and binary blobs it has become very popular amongs rom fiddlers and hackers. === Useful CM compiling related links === * [[ http://www.cmxlog.com/12.1/ | Nightly LOG - see changes what was applied to the source code related to grouper ]] * [[ https://wiki.cyanogenmod.org/w/Build_for_grouper | CMwiki entry for building grouper from source ]] ===== Cherry-picking SlimRecents to CM 12.1 ===== This guide is example of **succesfull cherry-pick** of slightly advanced feature to android OS. Purpose of this guide is to show an easy approach to cherry-picking more complex features in case you have almost no experience with Android, git and programming itself. I would like to declare this approach as **[[https://en.wikipedia.org/wiki/Cargo_cult_programming | cargo-cult]] cherry picking** due to methodology used in this guide. It is not straight-forward guide how to pick feature, instead it shows how to sucesfully resolve conflicts. It also shows a few dead ends as example of what you (and I) could overlook. I do not declare that this implementation of slimrecent is good or anything near to it. It is just guide/tutorial on how to cherry-pick slightly more complex feature, nothing more. ==== Setting-up enviroment ==== First you need to set up nice working enviroment (ugly part will come pretty fast). This guide was tested on Nexus 2012 (wifi) (aka grouper) with CM12.1 as source. * follow [[ https://wiki.cyanogenmod.org/w/Build_for_grouper | build from source guide ]] * dont forget to [[ https://wiki.cyanogenmod.org/w/Build_for_grouper#Extract_proprietary_blobs | extract proprietary blobs ]] * try to compile clean code (without cherry-pick) first and **test it on your device** , if something doesnt work try to read [[ https://wiki.cyanogenmod.org/w/Build_for_grouper | build from source guide ]] carefully. ==== Find commit you want to cherry pick ==== * In our case it is [[ https://github.com/SlimRoms/frameworks_base/commit/2b4aea893a916cf7f60b3c809f5a7bc616041058 | this ]] commit. * It is very helpful to see this commit already cherry-picked in another project, in my case I used [[ https://github.com/TeamTwisted/platform_frameworks_base/commit/cd5c1f92fc6ffafdca99b49299f6c3f53b40f6b4 | TeamTwisted ]] and [[ https://github.com/CarbonROM/android_frameworks_base/commit/a381fab30e1b9f138450c51c2eff215a069 b059e | CarbonROM ]] as guides. Best scenario is to find ROMs which are very similar to your source code (so with almost no features implemented). * By checking commited files history it is obvious that they performed clean-up after cherry-pick: [[https://github.com/TeamTwisted/platform_frameworks_base/commit/d36aef4a59e926b5e46e2794a6d8afb867e98fda | TT cleanup ]] , [[ https://github.com/CarbonROM/android_frameworks_base/commit/8954377a52661d82aff8f53031b684eb27b f94ed | CR cleanup ]] in CR they cleaned up after more commits, so there is some unrelated stuff too. ==== Getting new repo ==== If you read [[https://github.com/SlimRoms/frameworks_base/commit/2b4aea893a916cf7f60b3c809f5a7bc616041058 | original commit description ]], you will notice that **this patch needs a new repo: frameworks_opt_cards which is a central repo to get any kind of googles cards style.** (it is first note in commit description). Add frameworks_opt_cards repo: you need to edit **~/android/system/.repo/manifests/default.xml** * First add SlimRoms remote 1 2 3 4 8 9 12 13 15 16 18 19 .... .... .... * Than you can easily add frameworks_opt_cards repo .... .... .... 594 595 596 ==== Cherry pick ==== Now comes the first attempt to cherry pick slimrecents commit from SlimRoms following [[http://forum.xda-developers.com/showthread.php?t=2763236 | this useful guide]]: $cd ~/android/system/frameworks/base $git fetch https://github.com/SlimRoms/frameworks_base.git It should take some time.. After we fetch the repo it's finally time to perform cherry-pick $git cherry-pick 2b4aea893a916cf7f60b3c809f5a7bc616041058 After few seconds you should get something that looks approximately like this error: could not apply 2b4aea8... Frameworks: Slim Recents app screen (1/2) hint: after resolving the conflicts, mark the corrected paths hint: with 'git add ' or 'git rm ' hint: and commit the result with 'git commit' Git told you by this that there are some conflicts which need to be resolved manually. By typing $git status You get long list of changes to be commited and on the bottom there are few files in red color, in this case: Unmerged paths: (use "git add/rm ..." as appropriate to mark resolution) both modified: core/java/android/view/IWindowManager.aidl deleted by us: core/res/res/values/slim_symbols.xml both modified: packages/SystemUI/Android.mk both modified: packages/SystemUI/res/values/config.xml deleted by us: packages/SystemUI/res/values/slim_colors.xml both modified: packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java both modified: packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java In these files you need to resolve conflicts manually. ==== Resolving conflicts ==== * **both modified: core/java/android/view/IWindowManager.aidl** <<<<<<< HEAD 283 ======= 284 285 /** 286 * Toggle global menu 287 * 288 * @hide 289 */ 290 void toggleGlobalMenu(); 291 292 /** 293 * Get current system ui visibility mode. 294 * 295 * @hide 296 */ 297 int getSystemUIVisibility(); 298 >>>>>>> 2b4aea8... Frameworks: Slim Recents app screen (1/2) 299 } Probably no big deal, lets try to implement those few lines, probably no one gets hurt. * **deleted by us: core/res/res/values/slim_symbols.xml** When you look into file you see some symbol definitions, probably nothing to edit. * **both modified: packages/SystemUI/Android.mk** 13 <<<<<<< HEAD 14 org.cyanogenmod.platform.sdk 15 ======= 16 android-opt-cards 17 >>>>>>> 2b4aea8... Frameworks: Slim Recents app screen (1/2) It looks like that in slimrecent they dont use org.cyanogenmod.platform.sdk package (how unexpected.. ) and in SR they need android-opt-cards (which author mentioned in the initial commit for SlimRecents). Let both live freely. * **both modified: packages/SystemUI/res/values/config.xml** 326 <<<<<<< HEAD 327 ======= 328 329 false 330 0 331 0 332 0 333 334 337 8 338 339 340 2 341 342 >>>>>>> 2b4aea8... Frameworks: Slim Recents app screen (1/2) That looks interesting, lets take a closer look: in [[ https://github.com/SlimRoms/frameworks_base/commit/2b4aea893a916cf7f60b3c809f5a7bc616041058#diff-473b9c9242f2ee3e82f522c2a0c5c955 | github entry of cherrypicked commit ]] we see that only value which was modified (added in this case) was **expanded_items_default**. Other stuff looks like unrelated, so lets delete it. If it is something important, we will probably notice soon. * **deleted by us: packages/SystemUI/res/values/slim_colors.xml** 1 2 18 19 20 21 #96FFFFFF 22 #ffffffff 23 24 25 #ff747474 26 27 28 #ff4d4d4d 29 #ffb3b3b3 30 31 32 #80000000 33 34 35 #ffffffff 36 #00ffffff 37 #00ffffff 38 39 #ff000000 40 41 42 #7e3c3c3c 43 44 Looks like Cyanogenmod deprecated this config, as we see in [[ https://github.com/SlimRoms/frameworks_base/commit/2b4aea893a916cf7f60b3c809f5a7bc6160410 58#diff-04f61a8bb1b06f353136985680365044 | github entry of cherrypicked commit ]] only few things were added, lets delete stuff which is probably unrelated analogously to previous file. Now it looks like this: 1 2 18 19 20 21 #ff4d4d4d 22 #ffb3b3b3 23 24 25 #80000000 26 27 28 #ffffffff 29 #00ffffff 30 #00ffffff 31 32 #ff000000 33 34 35 #7e3c3c3c 36 37 * **both modified: packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java** 101 <<<<<<< HEAD 102 ======= 103 import com.android.systemui.slimrecent.RecentController; 104 import com.android.systemui.statusbar.phone.NavigationBarOverlay; 105 import com.android.systemui.statusbar.policy.PieController; 106 >>>>>>> 2b4aea8... Frameworks: Slim Recents app screen (1/2) RecentControler and NavigationBarOverlay looks valid as it is only thing which was added by [[ https://github.com/SlimRoms/frameworks_base/commit/2b4aea893a916cf7f60b3c809f5a7bc616041058#diff-0aea907bd3e33bcbf74eea740bbadc60 | commit]] Lets delete the rest. * **both modified: packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java** 486 <<<<<<< HEAD 487 ======= 488 resolver.registerContentObserver(Settings.System.getUriFor( 489 Settings.System.HEADS_UP_SNOOZE_TIME), 490 false, this, UserHandle.USER_ALL); 491 resolver.registerContentObserver(Settings.System.getUriFor( 492 Settings.System.PIE_CONTROLS), false, this, 493 UserHandle.USER_ALL); 494 resolver.registerContentObserver(Settings.System.getUriFor( 495 Settings.System.USE_SLIM_RECENTS), false, this, 496 UserHandle.USER_ALL); 497 resolver.registerContentObserver(Settings.System.getUriFor( 498 Settings.System.RECENT_CARD_BG_COLOR), false, this, 499 UserHandle.USER_ALL); 500 resolver.registerContentObserver(Settings.System.getUriFor( 501 Settings.System.RECENT_CARD_TEXT_COLOR), false, this, 502 UserHandle.USER_ALL); 503 >>>>>>> 2b4aea8... Frameworks: Slim Recents app screen (1/2) Here once again - we probably need only SlimRecents related stuff, that means: **USE_SLIM_RECENTS ; RECENT_CARD_BG_COLOR ; RECENT_CARD_TEXT_COLOR** 546 <<<<<<< HEAD 547 ======= 548 } else if (uri.equals(Settings.System.getUriFor( 549 Settings.System.NAVIGATION_BAR_CAN_MOVE))) { 550 prepareNavigationBarView(); 551 } else if (uri.equals(Settings.System.getUriFor( 552 Settings.System.USE_SLIM_RECENTS))) { 553 updateRecents(); 554 } else if (uri.equals(Settings.System.getUriFor( 555 Settings.System.RECENT_CARD_BG_COLOR)) 556 || uri.equals(Settings.System.getUriFor( 557 Settings.System.RECENT_CARD_TEXT_COLOR))) { 558 rebuildRecentsScreen(); 559 >>>>>>> 2b4aea8... Frameworks: Slim Recents app screen (1/2) Here it looks like it is little bit out of context (things which are near do not look like related stuff). 532 if (oldClockView != mClockView) { 533 // if the new clock position is outside the system icon area, make the alp ha 534 // and visibility match the system icon area alpha/visibility 535 if (isClockLocationOutsideSystemIconArea(mClockLocation)) { 536 mClockView.setAlpha(mSystemIconArea.getAlpha()); 537 mClockView.setVisibility(mSystemIconArea.getVisibility()); 538 } 539 540 // if the old clock position it outside the system icon area, make it opaq ue 541 // and set visibility to gone 542 if (isClockLocationOutsideSystemIconArea(oldClockLocation)) { 543 oldClockView.setAlpha(1f); 544 oldClockView.setVisibility(View.GONE); 545 } 546 <<<<<<< HEAD 547 ======= 548 } else if (uri.equals(Settings.System.getUriFor( 549 Settings.System.NAVIGATION_BAR_CAN_MOVE))) { 550 prepareNavigationBarView(); 551 } else if (uri.equals(Settings.System.getUriFor( 552 Settings.System.USE_SLIM_RECENTS))) { 553 updateRecents(); 554 } else if (uri.equals(Settings.System.getUriFor( 555 Settings.System.RECENT_CARD_BG_COLOR)) 556 || uri.equals(Settings.System.getUriFor( 557 Settings.System.RECENT_CARD_TEXT_COLOR))) { 558 rebuildRecentsScreen(); 559 >>>>>>> 2b4aea8... Frameworks: Slim Recents app screen (1/2) 560 } 561 562 boolean navLeftInLandscape = Settings.System.getIntForUser(resolver, 563 Settings.System.NAVBAR_LEFT_IN_LANDSCAPE, 0, UserHandle.USER_CURRENT) == 1; 564 if (mNavigationBarView != null) { 565 mNavigationBarView.setLeftInLandscape(navLeftInLandscape); 566 } "if (oldClockView != mClockView)" and "else if uri.equals" dont look like they are even closely related. Let search for some "uri.equals" in CM original code -> nothing. Lets look into [[ https://github.com/SlimRoms/frameworks_base/blob/2b4aea893a916cf7f60b3c809f5a7bc616041058/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java | SR git source code at the time of commit ]]. From SR source code we can see that it is under **public void onChange(boolean selfChange, Uri uri)** void. We have **public void onChange** with variable **selfChange** but without variable **uri**, and code uses parameter uri. That means we need to add new void to our source code and put that few lines into it, or try to delete it and see the result. First we try to delete it, if it causes some troubles we could try to implement new onChange function. * **Now lets try to compile** $ cd ~/android/system/ $ source build/envsetup.sh $ breakfast grouper $ croot $ brunch grouper after a while.. .... HOST_OS_EXTRA=Linux-3.13.0-32-generic-x86_64-with-Ubuntu-14.04-trusty HOST_BUILD_TYPE=release BUILD_ID=LMY48Y OUT_DIR=/home/maker/android/system/out ============================================ "ebtables is disabled on this build" make: Entering directory `/home/maker/android/system' frameworks/base/packages/SystemUI/Android.mk:14: *** missing separator. Stop. make: Leaving directory `/home/maker/android/system' #### make failed to build some targets (04:04 (mm:ss)) #### Little mistake .. $ vi frameworks/base/packages/SystemUI/Android.mk before: ... 9 LOCAL_STATIC_JAVA_LIBRARIES := Keyguard \ 10 android-support-v7-palette \ 11 android-support-v4 \ 12 android-visualizer \ 13 org.cyanogenmod.platform.sdk 14 android-opt-cards ... after: ... 13 org.cyanogenmod.platform.sdk \ 14 android-opt-cards * **And again** $ brunch grouper after a while.. ... frameworks/base/core/res/res/values/slim_symbols.xml:116: error: Symbol 'ic_shortcut_action_pie' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:117: error: Symbol 'ic_shortcut_action_power' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:118: error: Symbol 'ic_shortcut_action_power_menu' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:119: error: Symbol 'ic_shortcut_action_quicksettings' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:120: error: Symbol 'ic_shortcut_action_recent' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:121: error: Symbol 'ic_shortcut_action_ring_vib_silent' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:122: error: Symbol 'ic_shortcut_action_screenshot' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:123: error: Symbol 'ic_shortcut_action_search' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:100: error: Symbol 'ic_shortcut_action_silent' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:101: error: Symbol 'ic_shortcut_action_theme_switch' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:102: error: Symbol 'ic_shortcut_action_torch' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:103: error: Symbol 'ic_shortcut_action_vib' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:125: error: Symbol 'ic_shortcut_action_volume_panel' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:78: error: Symbol 'disable_navigation_pie_error' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:72: error: Symbol 'disable_pie_navigation_error' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:76: error: Symbol 'global_actions_nav_bar_mode_off_status' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:75: error: Symbol 'global_actions_nav_bar_mode_on_status' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:70: error: Symbol 'global_actions_pie_mode_off_status' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:69: error: Symbol 'global_actions_pie_mode_on_status' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:129: error: Symbol 'notification_flashlight_on_summary' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:128: error: Symbol 'notification_flashlight_on_title' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:41: error: Symbol 'permission' declared with not defined frameworks/base/core/res/res/values/slim_symbols.xml:61: error: Symbol 'reboot_system' declared with not defined make: *** [/home/maker/android/system511/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk] Error 1 make: *** Deleting file `/home/maker/android/system511/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk' make: Leaving directory `/home/maker/android/system511' #### make failed to build some targets (02:42 (mm:ss)) #### Looks like slim_symbols.xml need some changes.. $ vi frameworks/base/core/res/res/values/slim_symbols.xml 1 2 18 19 20 21 22 23 24 25 26 27 28 29 this should do the trick.. * **And again** $ brunch grouper make: *** No rule to make target `/home/maker/android/system511/out/target/common/obj/JAVA_LIBRARIES/android-opt-cards_intermediates/javalib.jar', needed by `/home/maker/android/system511/out/target/common/obj/APPS/SystemUI_intermediates/classes-full-debug.jar'. Stop. make: *** Waiting for unfinished jobs.... Lets try if it isnt some compilation garbage.. $ make clean $ breakfast grouper $ croot $ brunch grouper **and delete all files in ccache** still same .. lets think for a while.. **whoops.. we (I) forgot** to sync new repo.. no pain no gain. == syncing new repo == $ repo sync == continue with cherry-pick== now we should be back on track.. $ source build/envsetup $ breakfast grouper $ croot $ brunch grouper if you really deleted all your ccache and commited **make clean** command now its time for you to grab a beer and have some **[[https://en.wikipedia.org/wiki/Real_life#Distinct_from_the_Internet | real-life]]**. if not then you're lucky and next compilation should take less time. .... target Java: SettingsProvider (/home/maker/android/system/out/target/common/obj/APPS/SettingsProvider_intermediates/classes) Install: /home/maker/android/system/out/target/product/grouper/system/priv-app/SharedStorageBackup/SharedStorageBackup.apk target Static Jar: Keyguard (/home/maker/android/system/out/target/common/obj/JAVA_LIBRARIES/Keyguard_intermediates/javalib.jar) target Package: Tag (/home/maker/android/system/out/target/product/grouper/obj/APPS/Tag_intermediates/package.apk) frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java:163: error: WindowManagerService is not abstract and does not override abstract method toggleGlobalMenu() in IWindowManager Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. public class WindowManagerService extends IWindowManager.Stub ^ Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. Note: Some input files use unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 1 error make: packages/apps/Tag/res/drawable-hdpi/tag_scan_illustration.png: libpng warning: iCCP: Not recognizing known sRGB profile that has been edited *** [/home/maker/android/system511/out/target/common/obj/JAVA_LIBRARIES/services.core_intermediates/classes-full-debug.jar] Error 41 make: *** Waiting for unfinished jobs.... Warning: AndroidManifest.xml already defines versionCode (in http://schemas.android.com/apk/res/android); using existing value in manifest. Warning: AndroidManifest.xml already defines versionName (in http://schemas.android.com/apk/res/android); using existing value in manifest. DroidDoc took 17 sec. to write docs to /home/maker/android/system/out/target/common/docs/system-api-stubs make: Leaving directory `/home/maker/android/system' #### make failed to build some targets (02:58:55 (hh:mm:ss)) #### lets check [[ https://github.com/SlimRoms/frameworks_base/blob/2b4aea893a916cf7f60b3c809f5a7bc616041058/services/core/java/com/android/server/wm/WindowManagerService.java | SlimRom version of file ]] .... @Override public float getCurrentAnimatorScale() { synchronized(mWindowMap) { return mAnimationsDisabled ? 0 : mAnimatorDurationScaleSetting; } } /* @hide */ @Override public void toggleGlobalMenu() { mPolicy.toggleGlobalMenu(); } void dispatchNewAnimatorScaleLocked(Session session) { mH.obtainMessage(H.NEW_ANIMATOR_SCALE, session).sendToTarget(); } @Override public void registerPointerEventListener(PointerEventListener listener) { mPointerEventDispatcher.registerInputEventListener(listener); } ... lets **add void toggleGlobalMenu()** and see result. frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java:5676: error: cannot find symbol mPolicy.toggleGlobalMenu(); ^ symbol: method toggleGlobalMenu() location: variable mPolicy of type WindowManagerPolicy Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. Note: Some input files use unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 1 error make: *** [/home/maker/android/system/out/target/common/obj/JAVA_LIBRARIES/services.core_intermediates/classes-full-debug.jar] Error 41 make: *** Waiting for unfinished jobs.... .... .... make: Leaving directory `/home/maker/android/system' #### make failed to build some targets (06:25 (mm:ss)) #### So something in WindowManagePolicy and that GlobalMenu.. $ cd ~/android/system/frameworks/base $ find . -name WindowManagerPolicy* ./core/java/com/android/internal/view/WindowManagerPolicyThread.java ./core/java/android/view/WindowManagerPolicyControl.java ./core/java/android/view/WindowManagerPolicy.java Lets look at [[ https://github.com/SlimRoms/frameworks_base/blob/2b4aea893a916cf7f60b3c809f5a7bc616041058/core/java/android/view/WindowManagerPolicy.java | WindowManagerPolicy.java - slimrom version ]] .... .... /** * Notifies the keyguard to start fading out. * * @param startTime the start time of the animation in uptime milliseconds * @param fadeoutDuration the duration of the exit animation, in milliseconds */ public void startKeyguardExitAnimation(long startTime, long fadeoutDuration); /** * Toggle global menu * * @hide */ public void toggleGlobalMenu(); } just add toggleGlobalMenu as implemented in SlimRom and see what happens. frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java:150: error: PhoneWindowManager is not abstract and does not override abstract method toggleGlobalMenu() in WindowManagerPolicy public class PhoneWindowManager implements WindowManagerPolicy { ^ Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. 1 error Global menu everywhere !!! .. **it is NOT** part of original slimrecents commit -> lets try to get rid of it.. s&d: $ cd ~/android/system/frameworks/base $ grep -RE toggleGlobalMenu core/java/android/view/IWindowManager.aidl: void toggleGlobalMenu(); core/java/android/view/WindowManagerPolicy.java: public void toggleGlobalMenu(); search is finished, now you juts get rid of it.. * **and brunch again** Package Complete: /home/maker/android/system/out/target/product/grouper/cm-12.1-20151229-UNOFFICIAL-grouper.zip make: Leaving directory `/home/maker/android/system' #### make completed successfully (33:21 (mm:ss)) #### Now is time for runtime.. And everything looks like Oook. ==checking for problems/bugs== $ adb logcat E/WindowManager( 520): Unknown window type: 2033 boot into some official snapsoht: no errors in the logcat, probably fault on our implementation side. But the feature works, so who cares. When you try to google it, you see that [[http://forum.xda-developers.com/showpost.php?s=c11ea2ed26ebc2a0a04b569ddc859010&p=62266793&postcount=1222 | you're not alone]]. ==== Commiting cherry-pick ==== $ cd frameworks/base/ $ git status $ git add --all $ git commit ==== Conclusion ==== If you went through whole tutorial, you sucesfully implemented SlimRecents to your ROM in [[https://en.wikipedia.org/wiki/Cargo_cult_programming | cargo-cult]] fashion. To be nice-coded you should: * Go through codes and understand a little logic behind whole slimrecent feature * Try to make some nice settings button to switch between normal Recents and SlimRecents, or remove normal recents - now it is a dead code in your rom * Get rid of error "Unknown Window type" by solving it. ===== Debundling build & GAPPS ===== Cyanogenmod comes with many bundled features which i never use. If you want to remove them here are list of things which i found to be probably safe to remove. For further reading [[ https://wiki.cyanogenmod.org/w/Barebones | Barebones entry on CM wiki]] is pretty useful. ==== Debundling CM build ==== i used nice script for finding correct .mk files which needed to be modified (thx. 2 **[[user:da3m0n22]]**) grep -RE $UnwantedPackage --include *.mk **Dont forget to remove already compiled packages in /out directory** compiled app adresses: * out/target/product/grouper/system/app/ * out/target/product/grouper/system/priv-app/ === ThemeChooser === * removed vendor/cm/config/theme_common.mk * in vendor/cm/config/common.mk removed include vendor/cm/config/themes_common.mk (line 130) * [[project:android:grouper#removing_themechooser_from_settings | remove it from settings]] === Wallpapers === * in vendor/cm/config/common_full.mk removed 9 Galaxy4 \ 10 HoloSpiralWallpaper \ 11 LiveWallpapers \ 12 LiveWallpapersPicker \ 13 MagicSmokeWallpapers \ 14 NoiseField \ 15 PhaseBeam \ 16 VisualizationWallpapers \ === CM related stuff === * in vendor/cm/config/common.mk removed 147 CMWallpapers \ 151 CMUpdater \ 152 CMAccount \ === SetupWizard & OneTimeInit === * in build/target/product/generic_no_telephony.mk removed 26 OneTimeInitializer \ * in vendor/cm/config/common.mk 151 CyanogenSetupWizard \ **Do not forget to**: * turn settings -> location off * turn settings -> wifi off * turn settings -> privacy -> send debug data off === WAPPushManager === marked as invasive from: https://blog.torproject.org/blog/mission-impossible-hardening-android-security-and-privacy * in build/target/product/full_base.mk remove 24 WAPPushManager dont forget to delete "/" sign in line 23 ==== Debundling GAPPS ==== I used [[http://opengapps.org/ | OpenGApps ]] Pico package as starting point. After installing GApps zip file through [[https://twrp.me/ | TWRP ]] i removed in agreement with this [[ https://blog.torproject.org/blog/mission-impossible-hardening-android-security-and-privacy#Installation | TOR outdated but still helpful guide]] those applications: * in /system/app/: GoogleCalendarSyncAdapter GoogleContactsSyncAdapter * in /system/priv-app GooglePartnerSetup GoogleOneTimeInitializer GoogleFeedback GoogleBackupTransport I also tried to remove **SetupWizard** in priv-apps. Result was booting rom which was in pretty unstable state, logcat was still mumbling something about I/WindowManager( 475): Not starting activity because user setup is in progress: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 } And I didnt want to argue with GApps that user setup is really not in progress so i putted SetupWizard back and everything was fine. in Settings -> Accounts -> Google -> click on your_mail@gmail.com and **Turn Sync OFF**. === Debundling links, tips & tricks === * **[[ https://github.com/opengapps/opengapps/wiki/Advanced-Features-and-Options#include-and-exclude-google-applications | This Gapps feature ]]** looks interesting for more automatized way of doing cleanup. * How to get info about app from app ID:#vi /data/system/packages.xml (thx 2 [[https://android.stackexchange.com/questions/8452/how-to-know-app-name-by-uid/8465#8465 | Lie Ryan]]) * [[https://github.com/ukanth/afwall | AfWall]] could be useful for detection of leaking apps, but it's good to know that it is not [[https://github.com/ukanth/afwall/wiki/Apps-leak-user-privacy-data-during-boot | unbreakable]] ==== Conclusion ==== Even after all those gently hints to google like "Turn sync off" and removing applications for GoogleSync Google just love to hear from to you, or better interpreted: carefully listens to your needs. (CONNECT android.clients.google.com:443 ; CONNECT play.googleapis.com:443). After blacklisting Google Play Store in AfWall it looks like device is almost silent. (only GET http://connectivitycheck.android.com remains and it is plaintext probably with almost no data and few DNS queries, ussually for NTP servers). Field data is in nice correlation with **[[user:jenda/et#android| Jenda's observations]]** ===== Modify Settings(.apk) source ===== When you modify your rom heavily it is good to accordingly modify Settings.apk. For security enhanced compilations it is fe good to have wifi off at boot time etc. When I was searching for some guide to safe my time spent on project I found only [[ http://forum.xda-developers.com/showthread.php?t=2184207 | this outdated gudie]] which was not much useful to me, so i decided to write something little bit more up to date. As ussual in this wiki entry features are written down as examples and shows the way how to perform similiar operation, i hope that this format will help to perform those operations even after things change a little bit in newer versions of source code. **interesting file list** * **Settings layout file** - packages/apps/Settings/res/xml/dashboard_categories.xml * **Development settings layout file** - packages/apps/Settings/res/xml/development_prefs.xml * **Development settings main file** - packages/apps/Settings/src/com/android/settings/DevelopmentSettings.java ==== Removing ThemeChooser from Settings ==== this thread is continuation of [[project:android:grouper#debundling_cm_build | Debundling CM build]] where I shown how to remove ThemeChooser. After removal there is still entry in Settings which points to non-existing apk. First it is necessary to locate ThemeChooser in settings. In Settings it is named Themes as we can see if we open Settings in unmodified android device: {{:project:android:settings.jpg?200|}} $ cd packages/apps/Settings $ grep -RE Themes res/values-en-rIN/cm_strings.xml: Themes res/values-en-rAU/cm_strings.xml: Themes res/xml/dashboard_categories.xml: res/values/cm_strings.xml: res/values/cm_strings.xml: Themes Now we know what we want to find: $ grep -RE themes_settings res/values-sr/cm_strings.xml: Теме res/values-ru/cm_strings.xml: Темы ..... ..... ..... res/values-ca/cm_strings.xml: Temes res/values-eo/cm_strings.xml: Etosoj grep: .git/shallow: No such file or directory Little refinement: $ grep -RE themes_settings --exclude-dir=*values-* res/xml/dashboard_categories.xml: android:title="@string/themes_settings_title" res/values/cm_strings.xml: Themes grep: .git/shallow: No such file or directory if we open **res/xml/dashboard_categories** we can see easily that it is file for which we're looking for. commenting out Themes entry will do the trick 118 119 120 121 130 and we're done. ==== Advanced Reboot by default ==== When I'm using [[https://github.com/Tasssadar/multirom | Multirom]] for testing builds and still keep my N7 useful i found Advanced Reboot feature pretty handy so I decided to have it On by default. It shows to be rather tricky in the process. Locate - analogously to themechooser: $ cd packages/apps/Settings $ grep -RE Advanced\ reboot --exclude-dir=*values-* res/values/cm_strings.xml: res/values/cm_strings.xml: Advanced reboot grep: .git/shallow: No such file or directory $ grep -RE advanced_reboot --exclude-dir=*values-* res/xml/development_prefs.xml: android:key="advanced_reboot" res/xml/development_prefs.xml: android:title="@string/advanced_reboot_title" res/xml/development_prefs.xml: android:summary="@string/advanced_reboot_summary" /> res/values/cm_strings.xml: Advanced reboot res/values/cm_strings.xml: When unlocked, include options in the power menu for rebooting into recovery, bootloader or performing a soft reboot src/com/android/settings/DevelopmentSettings.java: private static final String ADVANCED_REBOOT_KEY = "advanced_reboot"; grep: .git/shallow: No such file or directory this leaves us to: res/xml/development_prefs.xml and src/com/android/settings/DevelopmentSettings.java files. If we take closer look to development_prefs.xml we can see that it is file specifying only layout and nothing more. That leaves us DevelopmentSettings.java as only file to be examined. After litte research we could find that the're mAdvancedReboot, ADVANCED_REBOOT and so on. mAdvanced reboot is of type SwitchPreference, which makes it interesting. after litte research I located those lines: 682 private void updateAdvancedRebootOptions() { 683 mAdvancedReboot.setChecked(Settings.Secure.getInt(getActivity().getContentResolver (), 684 Settings.Secure.ADVANCED_REBOOT, 0) != 0); 685 } setChecked looks pretty much like something we want to fiddle. If we look at adb_notify (Debugging notify option) which is **on by default**: 613 mAdbNotify.setChecked(Settings.Secure.getInt(cr, 614 Settings.Secure.ADB_NOTIFY, 1) != 0); We can probably figure out what to do: 682 private void updateAdvancedRebootOptions() { 683 mAdvancedReboot.setChecked(Settings.Secure.getInt(getActivity().getContentResolver (), 684 Settings.Secure.ADVANCED_REBOOT, 1) != 0); 685 } After compiling with this setting and running we can see that **ADVANCED REBOOT DOES NOT WORK**. If we turn on Developer options we can see that we **Only switched radio button to checked, but leave value of it unchanged**, pretty nasty state. After little poking around and finding lot of dead ends i decided to **look to original commits**. I should do that probably on the first place. Locating original commit: * search on github for file with lines definitely related to our problematics fe [[ https://github.com/CyanogenMod/android_packages_apps_Settings/blob/cm-12.1/res/xml/development_prefs.xml | Development layout config]] * [[ https://github.com/CyanogenMod/android_packages_apps_Settings/blame/cm-12.1/res/xml/development_prefs.xml#L36 | Blame somebody ]] for the line which is related to our problem. In this case it looks like this commit has a brother somewhere, probably named **[[https://github.com/CyanogenMod/android_frameworks_base/commit/1b32656c53ed33fb18bae0c0151282d6b9fbbcc0 | Add Advanced reboot (2 of 2)]]**. After reviewing the code I found few pretty interesting lines in [[https://github.com/CyanogenMod/android_frameworks_base/blob/cm-12.1/services/core/java/com/android/server/power/ShutdownThread.java | ShutdownThread.java]] file: 148 private static boolean isAdvancedRebootPossible(final Context context) { 149 KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SE RVICE); 150 boolean keyguardLocked = km.inKeyguardRestrictedInputMode() && km.isKeyguardSecure( ); 151 boolean advancedRebootEnabled = Settings.Secure.getInt(context.getContentResolver() , 152 Settings.Secure.ADVANCED_REBOOT, 0) == 1; 153 boolean isPrimaryUser = UserHandle.getCallingUserId() == UserHandle.USER_OWNER; 154 155 return advancedRebootEnabled && !keyguardLocked && isPrimaryUser; If we check [[ http://developer.android.com/reference/android/provider/Settings.Secure.html#getInt%28android.content.ContentResolver,%20java.lang.String,%20int%29 | settings.secure.getInt() reference]] we know for sure what to do: 148 private static boolean isAdvancedRebootPossible(final Context context) { 149 KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SE RVICE); 150 boolean keyguardLocked = km.inKeyguardRestrictedInputMode() && km.isKeyguardSecure( ); 151 boolean advancedRebootEnabled = Settings.Secure.getInt(context.getContentResolver() , 152 Settings.Secure.ADVANCED_REBOOT, 1) == 1; 153 boolean isPrimaryUser = UserHandle.getCallingUserId() == UserHandle.USER_OWNER; 154 155 return advancedRebootEnabled && !keyguardLocked && isPrimaryUser; After compilation and testing we find out that **Advanced reboot is ON** even in fact, not only in menu. ==== Adaptive brightness off by default ==== I dont know if it works on other devices, but on my N7 this feature drives me mad. It was pretty tricky for me to find this one. Locate - analogous to themechooser: $ cd packages/apps/Settings $ grep -RsE Adaptive\ brightness --exclude-dir=*values-* res/xml/display.xml: res/values/strings.xml: Adaptive brightness $ grep -RsE auto_brightness --exclude-dir=*values-* res/xml/display.xml: android:key="auto_brightness" res/xml/display.xml: android:title="@string/auto_brightness_title" res/xml/display.xml: settings:keywords="@string/keywords_display_auto_brightness" res/xml/display.xml: android:summary="@string/auto_brightness_summary" res/values/strings.xml: Adaptive brightness res/values/strings.xml: Optimize brightness level for available light res/values/strings.xml: dim screen touchscreen battery src/com/android/settings/DisplaySettings.java: private static final String KEY_AUTO_BRIGHTNESS = "auto_brightness"; closer look on **DisplaySettings.java** ... 663 if (preference == mAutoBrightnessPreference) { 664 boolean auto = (Boolean) objValue; 665 Settings.System.putInt(getContentResolver(), SCREEN_BRIGHTNESS_MODE, 666 auto ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : SCREEN_BRIGHTNESS_MODE_MANUAL); 667 } .... after unsuccessful attempts to locate something relevant to **SCREEN_BRIGHTNESS_MODE** in Settings.apk I performed search in android source root directory, which aslo found nothing. After a lot of unsuccessful attempts to find source of default settings i finaly found magic keyword **def_screen_brightness_automatic_mode** in frameworks/base/packages/SettingsProvider/res/values/defaults.xml the problem was that here it was off, but in **overlay**: $ vi device/asus/grouper/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml 19 20 21 120000 22 23 true 24 25 27 3600000 28 situation was different, when I rewrited true on **line 23** to false it was solved. ===== Modify Browser(.apk) source ===== ====Addition of search engine==== If you're using default browser in **noscript** & **no cookies** setting, you'll find out that when you search by Google it switches to czech mutation if you're connecting from Czech republic. If you switch to DuckDuckGo you'll find out, that search engine is set to javascript version. Solution is addition of search engine to source code. $ cd packages/apps/Browser/ $ grep -RsE DuckDuck res/values/all_search_engines.xml: DuckDuckGo res/values/all_search_engines.xml: DuckDuckGo (UK) $ vi .... 750 751 752 DuckDuckGo 753 duckduckgo.com 754 https://duckduckgo.com/favicon.ico 755 https://duckduckgo.com/?q={searchTerms}&t=cyanogenmod 756 UTF-8 757 758 .... $ grep -RsE duckduck res/values-en-rGB/donottranslate-search_engines.xml: duckduckgo res/values-en-rGB/donottranslate-search_engines.xml: duckduckgo_en_gb res/values-de-rDE/donottranslate-search_engines.xml: duckduckgo res/values-ru-rRU/donottranslate-search_engines.xml: duckduckgo res/values-es-rES/donottranslate-search_engines.xml: duckduckgo res/values/all_search_engines.xml: res/values/all_search_engines.xml: duckduckgo.com res/values/all_search_engines.xml: https://duckduckgo.com/favicon.ico res/values/all_search_engines.xml: https://duckduckgo.com/?q={searchTerms}&t=cyanogenmod res/values/all_search_engines.xml: res/values/all_search_engines.xml: duckduckgo.com res/values/all_search_engines.xml: https://duckduckgo.com/favicon.ico res/values/all_search_engines.xml: https://duckduckgo.com/?q={searchTerms}%20r:uk&t=cyanogenmod res/values/donottranslate-search_engines.xml: duckduckgo res/values-en-rUS/donottranslate-search_engines.xml: duckduckgo I've learned by trial and error that you need to add your custom search engine in **all_search_engines.xml**, **donottranslate-search_engines.xml** and to **donottranslate-search_engines.xml** in locale values in Browser folder: res/values/all_search_engines.xml res/values/donottranslate-search_engines.xml res/values-en-rUS/donottranslate-search_engines.xml $ vi res/values/all_search_engines.xml ...... 759 760 DuckDuckGo NoJavaScript 761 duckduckgo.com 762 https://duckduckgo.com/favicon.ico 763 https://duckduckgo.com/html/?q={searchTerms} 764 UTF-8 765 766 ...... $ vi res/values/donottranslate-search_engines.xml ... 29 duckduckgonojs ... $ vi res/values-en-rUS/donottranslate-search_engines.xml ... 29 duckduckgonojs ... voilà {{:project:android:screenshot_2016-01-22-08-38-19.png?400|}} ====Addition of browser user-agent==== There are few predefined spoofed user-agents in browser, this is way how to add one more to them. changes in short (base dir is ~/android/system/packages/apps/Browser): $vi res/xml/advanced_preferences.xml .... 28 .... $ vi src/com/android/browser/BrowserSettings.java .... 81 82 private static final String UBUNTU_USERAGENT = "Mozilla/5.0 (X11; Ubuntu; " + 83 "Linux x86_64; rv:43.0) Gecko/20100101 " + 84 "Firefox/43.0"; 85 86 private static final String USER_AGENTS[] = { null, 87 DESKTOP_USERAGENT, 88 IPHONE_USERAGENT, 89 IPAD_USERAGENT, 90 FROYO_USERAGENT, 91 HONEYCOMB_USERAGENT, 92 UBUNTU_USERAGENT, 93 }; 94 .... $ vi res/values/strings.xml .... 579 580 581 Android 582 Desktop 583 iPhone 584 iPad 585 Froyo-N1 586 Honeycomb-Xoom 587 Ubuntu-Firefox 588 589 590 591 0 592 1 593 2 594 3 595 4 596 5 597 6 598 .... This solution have **three major issues** - you also need to [[ user:jenda:et#cyanogenmod | turn off connectivitycheck ]] , change NTP server and add fix "turn time-sync off" (so you can't be identified by requests to android.pool.ntp.org), last issue is with **http-accept header**, i dont know how to solve last issue, if somebody does please [[user:yan | contact me]]. ===== First start traffic analysis ===== Also cyanogenmod itself want to talk a little bit after first boot even after debundling and turning reports off. === Recorded HTTP/HTTPS traffic === CONNECT shopvac.cyngn.com:443 HTTP/1.1 Host: shopvac.cyngn.com User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; Nexus 7 Build/LMY48Y) CONNECT account.cyngn.com:443 HTTP/1.1 Host: account.cyngn.com User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; Nexus 7 Build/LMY48Y) CONNECT stats.cyanogenmod.org:443 HTTP/1.1 Host: stats.cyanogenmod.org User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; Nexus 7 Build/LMY48Y) GET http://connectivitycheck.android.com/generate_204 HTTP/1.1 User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; Nexus 7 Build/LMY48Y) Host: connectivitycheck.android.com * **connectivitycheck** remains even after Afwall, but ends after one HTTP response. * **stats.cyanogenmod.org** and **account.cyngn.com** is produced probably under AppID 1000 (Android system) === List of experimental setups === All setups were clean install of custom built CM (configuration - [[project:android:grouper#debundling_cm_build | debundled]] with [[project:android:grouper#cherry-picking_slimrecents_to_cm_121 |slimrecents pick]]). This was their first connection to the network. After previous experiments all setups were without GApps. Nightly Build performed the same way. After initial boot: Location service was turned off Timezone was set to sarajevo CyanogenMod statistics were turned OFF in case of AfWall ON setups AfWall was instaled from disc. In all cases DNS requests were seen. **AfWall off** * Starts with connectivitycheck * Continues with account.cyngn.com:443 (CONNECT, than Application data) * shopvac.cyngn.com:443 (CONNECT, than Application Data) * stats.cyanogenmod.org:443 (CONNECT, than Application Data) **AfWall on** * Starts with connectivitycheck (After respond Android does not answer anymore - lot of [TCP Retransmission]) * Continues with stats.cyanogenmod.org:443 (CONNECT, than respond (connection establised), than SSL [TCP Retransmission] - Android does not answer anymore) **AfWall on, reboot before connect, Kernel Allowed by afwall** * Connectivitycheck (After respond Android does not answer anymore - lot of [TCP Retransmission]) * Android System packets blocked by AfWall **AfWall on, reboot before connect, Kernel Allowed by afwall, Android System Allowed by afwall** * Starts with connectivitycheck * Continues with stats.cyanogenmod.org:443 (CONNECT, than Application Data) * Once again stats.cyanogenmod.org:443 (CONNECT, than Application Data) * Continues with account.cyngn.com:443 (CONNECT, than Application data) * shopvac.cyngn.com:443 (CONNECT, than Application Data) ** AfWall on, not first boot, everything disabled in afwall ** * Connectivitycheck still persists. * Only DNS requests for android ntp server were seen. ** AfWall on, not first boot, everything disabled in afwall except linux kernel ** * Connectivitycheck still persists. * Only DNS requests for android ntp server, and stats.cyanogenmod.org, account.cyngn.com and shopvac.cyngn.com were seen, but no HTTP/HTTPS traffic. === Source search === only wanted to try it, i was lazy to search whole source code, maybe it could give more hits. ~$ cd android/system $ grep -RE shopvac\.cyngn\.com grep: build/.git/shallow: No such file or directory grep: ndk/.git/shallow: No such file or directory grep: ndk/.git/packed-refs: No such file or directory grep: abi/cpp/.git/shallow: No such file or directory ... ... grep: packages/apps/AudioFX/.git/shallow: No such file or directory grep: packages/apps/Contacts/.git/shallow: No such file or directory grep: packages/apps/Bluetooth/.git/shallow: No such file or directory packages/apps/Settings/res/values/config.xml https://shopvac.cyngn.com/community/heartbeat grep: packages/apps/Settings/.git/shallow: No such file or directory grep: packages/apps/Stk/.git/shallow: No such file or directory .... .... grep: packages/wallpapers/MusicVisualization/.git/shallow: No such file or directory grep: packages/wallpapers/NoiseField/.git/shallow: No such file or directory grep: packages/wallpapers/PhaseBeam/.git/shallow: No such file or directory grep: .repo/manifests/.git/shallow: No such file or directory ^C $ vi packages/apps/Settings/res/values/config.xml 100 101 https://stats.cyanogenmod.org/submit 102 https://shopvac.cyngn.com/communit/heartbeat 103 https://account.cyngn.com/api/v1/community/heartbeat_token After digging a while few changes from true to false in one AndroidManifest helped a bit: **~/android/system/packages/apps/Settings/AndroidManifest.xml** 2278 2279 2283 2284 2285 2286 2287 2288 2289 2293 === LTO - GPS === New friend emerged after applying fix above: GET http://gllto.glpals.com/7day/latest/lto.dat HTTP/1.1 Accept: */*, application/vnd.wap.mms-message, application/vnd.wap.sic x-wap-profile: http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212# Host: gllto.glpals.com Connection: Keep-Alive User-Agent: Android ~/android/system$ grep -RE gllto ... Binary file vendor/broadcom/grouper/proprietary/glgps matches device/asus/grouper/gps.conf:XTRA_SERVER_1=http://gllto.glpals.com/7day/latest/lto.dat device/asus/grouper/gps.conf:XTRA_SERVER_2=http://gllto.glpals.com/7day/latest/lto.dat device/asus/grouper/gps.conf:XTRA_SERVER_3=http://gllto.glpals.com/2day/latest/lto.dat It is [[https://www.broadcom.com/products/wireless-connectivity/gps/lto-agps | Long Term Orbit technology]] from [[https://www.broadcom.com | Broadcom]], turned ON by default. Link Adresses: ~/android/system$ cat device/asus/grouper/gps.conf NTP_SERVER=north-america.pool.ntp.org XTRA_SERVER_1=http://gllto.glpals.com/7day/latest/lto.dat XTRA_SERVER_2=http://gllto.glpals.com/7day/latest/lto.dat XTRA_SERVER_3=http://gllto.glpals.com/2day/latest/lto.dat GPS configuration (**LTO OFF/ON**): ~/android/system511$ cat vendor/broadcom/grouper/proprietary/gpsconfig.xml ==== conclusion ==== After setting **ReportingService OFF** and **LTO Sync OFF** first time connection of tablet to wifi consist only of connectivitycheck at the start and than dns request for NTP servers (10 minutes cap). (AfWall not installed). Turning off sending statistics in GUI probably restrict amount of statistics traffic slightly down, but to turn it off completely you need to edit according config. GPS on N7 2012 have feature named [[ttps://www.broadcom.com/products/wireless-connectivity/gps/lto-agps | LTO]] which downloads data package once upon a time. Android in tested version have **connectivitycheck** procedure which comes from (based on adb logcat) **NetworkManager** and which probably **Ignores aFWall**, but it gives almost same set of information that any other http connection would give. As you're connecting to net you ussualy to go browsing, you will leak User-Agent identification regardless on connectivitycheck procedure. Those two problems should be solved same time.