Grouper is an N7 tablet with only wifi and without integrated 3G support, that means that 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.
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 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.
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.
If you read 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
1 <?xml version="1.0" encoding="UTF-8"?> 2 <manifest> 3 4 <remote name="aosp" 5 fetch="https://android.googlesource.com" 6 review="android-review.googlesource.com" 7 revision="refs/tags/android-5.1.1_r26" /> 8 9 <remote name="github" 10 fetch=".." 11 review="review.cyanogenmod.org" /> 12 13 <remote name="private" 14 fetch="ssh://git@github.com" /> 15 16 <remote name="slimrom" 17 fetch="https://github.com/SlimRoms/" /> 18 19 <default revision="refs/heads/cm-12.1" 20 remote="github" 21 sync-c="true" 22 sync-j="4" /> .... .... ....
.... .... .... 594 <project path="vendor/cm" name="CyanogenMod/android_vendor_cm" /> 595 <project path="vendor/cmsdk" name="CyanogenMod/cm_platform_sdk" /> 596 <project path="frameworks/opt/cards" name="frameworks_opt_cards" remote="slimrom" revision="lp5.1" />
Now comes the first attempt to cherry pick slimrecents commit from SlimRoms following 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 <paths>' or 'git rm <paths>' 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 <file>..." 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.
<<<<<<< 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.
When you look into file you see some symbol definitions, probably nothing to edit.
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.
326 <<<<<<< HEAD 327 ======= 328 329 <bool name="config_enablePerfBoostForShutterAnimation">false</bool> 330 <integer name="shutteranimationboost_timeout_param">0</integer> 331 <integer name="shutteranimationboost_schedboost_param">0</integer> 332 <integer name="shutteranimationboost_cpuboost_param">0</integer> 333 334 <!-- Sensivity of pie gestures controlls. 335 Must be minimum 1 and maximum 10 (See @EdgeServiceConstants.java). 336 Default for pie is high sensivity --> 337 <integer name="pie_gesture_sensivity">8</integer> 338 339 <!-- Default value how much apps show the app screenshot on recents view entry --> 340 <integer name="expanded_items_default">2</integer> 341 342 >>>>>>> 2b4aea8... Frameworks: Slim Recents app screen (1/2)
That looks interesting, lets take a closer look: in 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.
1 <?xml version="1.0" encoding="utf-8"?> 2 <!-- 3 Copyright (C) 2015 The SlimRoms Project 4 Copyright (C) 2014 The CyanogenMod Project 5 6 Licensed under the Apache License, Version 2.0 (the "License"); 7 you may not use this file except in compliance with the License. 8 You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 See the License for the specific language governing permissions and 16 limitations under the License. 17 --> 18 <resources> 19 20 <!-- tint of the Visualizer tile --> 21 <color name="visualizer_fill_color">#96FFFFFF</color> 22 <color name="battery_level_color">#ffffffff</color> 23 24 <!-- Quick tile text color when the tile is disabled --> 25 <color name="qs_tile_text_disabled">#ff747474</color> 26 27 <!-- Recents --> 28 <color name="recents_empty_dark_color">#ff4d4d4d</color> 29 <color name="recents_empty_light_color">#ffb3b3b3</color> 30 31 <!-- Slim recent --> 32 <color name="recent_background">#80000000</color> 33 34 <!-- Card Color --> 35 <color name="card_background">#ffffffff</color> 36 <color name="card_background_header">#00ffffff</color> 37 <color name="card_backgroundExpand">#00ffffff</color> 38 39 <color name="card_text_color_header">#ff000000</color> 40 41 <!-- Used by selector --> 42 <color name="card_pressed">#7e3c3c3c</color> 43 44 </resources>
Looks like Cyanogenmod deprecated this config, as we see in 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 <?xml version="1.0" encoding="utf-8"?> 2 <!-- 3 Copyright (C) 2015 The SlimRoms Project 4 Copyright (C) 2014 The CyanogenMod Project 5 6 Licensed under the Apache License, Version 2.0 (the "License"); 7 you may not use this file except in compliance with the License. 8 You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 See the License for the specific language governing permissions and 16 limitations under the License. 17 --> 18 <resources> 19 20 <!-- Recents --> 21 <color name="recents_empty_dark_color">#ff4d4d4d</color> 22 <color name="recents_empty_light_color">#ffb3b3b3</color> 23 24 <!-- Slim recent --> 25 <color name="recent_background">#80000000</color> 26 27 <!-- Card Color --> 28 <color name="card_background">#ffffffff</color> 29 <color name="card_background_header">#00ffffff</color> 30 <color name="card_backgroundExpand">#00ffffff</color> 31 32 <color name="card_text_color_header">#ff000000</color> 33 34 <!-- Used by selector --> 35 <color name="card_pressed">#7e3c3c3c</color> 36 37 </resources>
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 commit
Lets delete the rest.
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 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.
$ 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
$ brunch grouper
after a while..
... frameworks/base/core/res/res/values/slim_symbols.xml:116: error: Symbol 'ic_shortcut_action_pie' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:117: error: Symbol 'ic_shortcut_action_power' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:118: error: Symbol 'ic_shortcut_action_power_menu' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:119: error: Symbol 'ic_shortcut_action_quicksettings' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:120: error: Symbol 'ic_shortcut_action_recent' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:121: error: Symbol 'ic_shortcut_action_ring_vib_silent' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:122: error: Symbol 'ic_shortcut_action_screenshot' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:123: error: Symbol 'ic_shortcut_action_search' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:100: error: Symbol 'ic_shortcut_action_silent' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:101: error: Symbol 'ic_shortcut_action_theme_switch' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:102: error: Symbol 'ic_shortcut_action_torch' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:103: error: Symbol 'ic_shortcut_action_vib' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:125: error: Symbol 'ic_shortcut_action_volume_panel' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:78: error: Symbol 'disable_navigation_pie_error' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:72: error: Symbol 'disable_pie_navigation_error' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:76: error: Symbol 'global_actions_nav_bar_mode_off_status' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:75: error: Symbol 'global_actions_nav_bar_mode_on_status' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:70: error: Symbol 'global_actions_pie_mode_off_status' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:69: error: Symbol 'global_actions_pie_mode_on_status' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:129: error: Symbol 'notification_flashlight_on_summary' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:128: error: Symbol 'notification_flashlight_on_title' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:41: error: Symbol 'permission' declared with <java-symbol> not defined frameworks/base/core/res/res/values/slim_symbols.xml:61: error: Symbol 'reboot_system' declared with <java-symbol> 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 <?xml version="1.0" encoding="utf-8"?> 2 <!-- 3 /* Copyright 2013-2015, SlimRoms project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 --> 18 <resources> 19 20 <!-- Slim recent app screen--> 21 <java-symbol type="integer" name="config_recentDefaultDur" /> 22 <java-symbol type="integer" name="config_recentExitDur" /> 23 <java-symbol type="style" name="Animation.RecentScreen" /> 24 <java-symbol type="style" name="Animation.RecentScreen.Left" /> 25 <java-symbol type="anim" name="recent_screen_enter" /> 26 <java-symbol type="anim" name="recent_screen_enter_left" /> 27 <java-symbol type="anim" name="recent_screen_fade_out" /> 28 29 </resources>
this should do the trick..
$ 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.
$ repo sync
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 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 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 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..
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.
$ 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 you're not alone.
$ cd frameworks/base/ $ git status $ git add --all $ git commit
If you went through whole tutorial, you sucesfully implemented SlimRecents to your ROM in cargo-cult fashion. To be nice-coded you should:
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 Barebones entry on CM wiki is pretty useful.
i used nice script for finding correct .mk files which needed to be modified (thx. 2 da3m0n22)
grep -RE $UnwantedPackage --include *.mk
Dont forget to remove already compiled packages in /out directory
compiled app adresses:
9 Galaxy4 \ 10 HoloSpiralWallpaper \ 11 LiveWallpapers \ 12 LiveWallpapersPicker \ 13 MagicSmokeWallpapers \ 14 NoiseField \ 15 PhaseBeam \ 16 VisualizationWallpapers \
147 CMWallpapers \ 151 CMUpdater \ 152 CMAccount \
26 OneTimeInitializer \
151 CyanogenSetupWizard \
Do not forget to:
marked as invasive from: https://blog.torproject.org/blog/mission-impossible-hardening-android-security-and-privacy
24 WAPPushManager
dont forget to delete “/” sign in line 23
I used OpenGApps Pico package as starting point.
After installing GApps zip file through TWRP i removed in agreement with this TOR outdated but still helpful guide those applications:
GoogleCalendarSyncAdapter GoogleContactsSyncAdapter
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.
#vi /data/system/packages.xml
(thx 2 Lie Ryan)
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 Jenda's observations
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 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
this thread is continuation of 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:
$ cd packages/apps/Settings $ grep -RE Themes res/values-en-rIN/cm_strings.xml: <string name="themes_settings_title">Themes</string> res/values-en-rAU/cm_strings.xml: <string name="themes_settings_title">Themes</string> res/xml/dashboard_categories.xml: <!-- Themes --> res/values/cm_strings.xml: <!-- Themes Settings --> res/values/cm_strings.xml: <string name="themes_settings_title">Themes</string>
Now we know what we want to find:
$ grep -RE themes_settings res/values-sr/cm_strings.xml: <string name="themes_settings_title">Теме</string> res/values-ru/cm_strings.xml: <string name="themes_settings_title">Темы</string> ..... ..... ..... res/values-ca/cm_strings.xml: <string name="themes_settings_title">Temes</string> res/values-eo/cm_strings.xml: <string name="themes_settings_title">Etosoj</string> 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: <string name="themes_settings_title">Themes</string> 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 <!-- Themes --> 120 <!-- NOTE: Intent.parseIntent looks for "categories" tag and not "category" --> 121 <!-- <dashboard-tile 122 android:id="@+id/theme_settings" 123 android:title="@string/themes_settings_title" 124 android:icon="@drawable/ic_settings_themes"> 125 <intent 126 android:action="android.intent.action.MAIN" > 127 <categories android:name="cyanogenmod.intent.category.APP_THEMES" /> 128 </intent> 129 </dashboard-tile> --> 130
and we're done.
When I'm using 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: <!-- Advanced reboot options --> res/values/cm_strings.xml: <string name="advanced_reboot_title">Advanced reboot</string> 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: <string name="advanced_reboot_title">Advanced reboot</string> res/values/cm_strings.xml: <string name="advanced_reboot_summary">When unlocked, include options in the power menu for rebooting into recovery, bootloader or performing a soft reboot</string> 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:
In this case it looks like this commit has a brother somewhere, probably named Add Advanced reboot (2 of 2).
After reviewing the code I found few pretty interesting lines in 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 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.
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: <!-- Adaptive brightness --> res/values/strings.xml: <string name="auto_brightness_title">Adaptive brightness</string>
$ 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: <string name="auto_brightness_title">Adaptive brightness</string> res/values/strings.xml: <string name="auto_brightness_summary">Optimize brightness level for available light</string> res/values/strings.xml: <string name="keywords_display_auto_brightness">dim screen touchscreen battery</string> 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 <resources> 20 <!-- 2 minutes for default screen timeout --> 21 <integer name="def_screen_off_timeout">120000</integer> 22 <!-- Set the automatic brightness mode on by default --> 23 <bool name="def_screen_brightness_automatic_mode">true</bool> 24 25 <!-- Value for Settings.Global.LOW_BATTERY_SOUND_TIMEOUT: 26 Mute battery sounds on tablets after one hour with screen off --> 27 <integer name="def_low_battery_sound_timeout">3600000</integer> 28 </resources>
situation was different, when I rewrited true on line 23 to false it was solved.
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: <item>DuckDuckGo</item> res/values/all_search_engines.xml: <item>DuckDuckGo (UK)</item>
$ vi .... 750 </string-array> 751 <string-array name="duckduckgo" translatable="false"> 752 <item>DuckDuckGo</item> 753 <item>duckduckgo.com</item> 754 <item>https://duckduckgo.com/favicon.ico</item> 755 <item>https://duckduckgo.com/?q={searchTerms}&t=cyanogenmod</item> 756 <item>UTF-8</item> 757 <item></item> 758 </string-array> ....
$ grep -RsE duckduck res/values-en-rGB/donottranslate-search_engines.xml: <item>duckduckgo</item> res/values-en-rGB/donottranslate-search_engines.xml: <item>duckduckgo_en_gb</item> res/values-de-rDE/donottranslate-search_engines.xml: <item>duckduckgo</item> res/values-ru-rRU/donottranslate-search_engines.xml: <item>duckduckgo</item> res/values-es-rES/donottranslate-search_engines.xml: <item>duckduckgo</item> res/values/all_search_engines.xml: <string-array name="duckduckgo" translatable="false"> res/values/all_search_engines.xml: <item>duckduckgo.com</item> res/values/all_search_engines.xml: <item>https://duckduckgo.com/favicon.ico</item> res/values/all_search_engines.xml: <item>https://duckduckgo.com/?q={searchTerms}&t=cyanogenmod</item> res/values/all_search_engines.xml: <string-array name="duckduckgo_en_gb" translatable="false"> res/values/all_search_engines.xml: <item>duckduckgo.com</item> res/values/all_search_engines.xml: <item>https://duckduckgo.com/favicon.ico</item> res/values/all_search_engines.xml: <item>https://duckduckgo.com/?q={searchTerms}%20r:uk&t=cyanogenmod</item> res/values/donottranslate-search_engines.xml: <item>duckduckgo</item> res/values-en-rUS/donottranslate-search_engines.xml: <item>duckduckgo</item>
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 <string-array name="duckduckgonojs" translatable="false"> 760 <item>DuckDuckGo NoJavaScript</item> 761 <item>duckduckgo.com</item> 762 <item>https://duckduckgo.com/favicon.ico</item> 763 <item>https://duckduckgo.com/html/?q={searchTerms}</item> 764 <item>UTF-8</item> 765 <item></item> 766 </string-array> ......
$ vi res/values/donottranslate-search_engines.xml ... 29 <item>duckduckgonojs</item> ...
$ vi res/values-en-rUS/donottranslate-search_engines.xml ... 29 <item>duckduckgonojs</item> ...
voilà
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 <ListPreference 29 android:key="user_agent" 30 android:title="@string/pref_content_ua" 31 android:entries="@array/pref_development_ua_choices" 32 android:entryValues="@array/pref_development_ua_values" 33 android:defaultValue="6"/> ....
$ 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 <!-- Do not tranlsate. Development option --> 580 <string-array name="pref_development_ua_choices" translatable="false"> 581 <item>Android</item> 582 <item>Desktop</item> 583 <item>iPhone</item> 584 <item>iPad</item> 585 <item>Froyo-N1</item> 586 <item>Honeycomb-Xoom</item> 587 <item>Ubuntu-Firefox</item> 588 </string-array> 589 <!-- Do not tranlsate. Development option --> 590 <string-array name="pref_development_ua_values" translatable="false"> 591 <item>0</item> 592 <item>1</item> 593 <item>2</item> 594 <item>3</item> 595 <item>4</item> 596 <item>5</item> 597 <item>6</item> 598 </string-array> ....
This solution have three major issues - you also need to 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 contact me.
Also cyanogenmod itself want to talk a little bit after first boot even after debundling and turning reports off.
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
All setups were clean install of custom built CM (configuration - debundled with 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
AfWall on
AfWall on, reboot before connect, Kernel Allowed by afwall
AfWall on, reboot before connect, Kernel Allowed by afwall, Android System Allowed by afwall
AfWall on, not first boot, everything disabled in afwall
AfWall on, not first boot, everything disabled in afwall except linux kernel
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 <string name="stats_cyanogen_url">https://shopvac.cyngn.com/community/heartbeat</string> 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 <!-- Metrics server endpoints --> 101 <string name="stats_cm_url">https://stats.cyanogenmod.org/submit</string> 102 <string name="stats_cyanogen_url">https://shopvac.cyngn.com/communit/heartbeat</string> 103 <string name="stats_cyanogen_token_url">https://account.cyngn.com/api/v1/community/heartbeat_token</string>
After digging a while few changes from true to false in one AndroidManifest helped a bit:
~/android/system/packages/apps/Settings/AndroidManifest.xml
2278 <!-- Anonymous Statistics --> 2279 <receiver android:name=".cmstats.ReportingServiceManager" 2280 android:enabled="false" 2281 android:exported="false" 2282 android:label="ReportingServiceManager"> 2283 <intent-filter> 2284 <action android:name="android.intent.action.BOOT_COMPLETED" /> 2285 <action android:name="com.android.settings.action.TRIGGER_REPORT_METRICS" /> 2286 </intent-filter> 2287 </receiver> 2288 2289 <service android:label="ReportingService" 2290 android:enabled="false" 2291 android:exported="false" 2292 android:name=".cmstats.ReportingService"> 2293 </service>
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 </code>
~/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 Long Term Orbit technology from 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 <?xml version="1.0" encoding="utf-8"?> <glgps xmlns="http://www.glpals.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.glpals.com/ glconfig.xsd" > <!--HAL Confguration --> <hal acPortName="/dev/ttyHS1" lBaudRate="115200" cLogEnabled="false" acLogDirectory="/data/gps/log/" gpioNStdbyPath="/sys/class/gpio/gpio162/value" gpioDelayMs="120" acNvStoDir="/data/gps/" acNmeaOutName="/data/gps/nmea_out" ctrlPipe="/data/gps/glgpsctrl" SyncLto="true" ltoFileName="lto2.dat" acLtoDir="/data/gps/" LbsSyncLtoThresholdDays="1" /> <gll LogPriMask="LOG_INFO" LogFacMask="LOG_DEFAULT" FrqPlan="FRQ_PLAN_26MHZ_2PPM" RfType="GL_RF_4751_DANUBE_EXT_LNA" /> <job id="Periodic"> <task> <req_pos/> </task> </job> </glgps>
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 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.