diff --git a/host/migration/Android.mk b/host/migration/Android.mk new file mode 100644 index 0000000..7c83e9d --- /dev/null +++ b/host/migration/Android.mk @@ -0,0 +1,9 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_MODULE:= migration-interface + +include $(BUILD_HOST_JAVA_LIBRARY) diff --git a/host/migration/README.md b/host/migration/README.md new file mode 100644 index 0000000..441b75a --- /dev/null +++ b/host/migration/README.md @@ -0,0 +1,13 @@ +## CMSettings Migration Test +The tests host library contains a simple interface which calls down to a client jar on the device +to take a snapshot of the current settings, forces an update with the current build in the tree, +then verifies the settings post migration. + +To run the test (on a live device): + + ``` java -cp /Volumes/CM/CM13/out/host/darwin-x86/framework/migration-interface.jar MigrationTest \ + --settings --bootimg --systemimg ``` + +To generate example settings to be written against 12.1 device during migration: + + ```java -cp /Volumes/CM/CM13/out/host//framework/migration-interface.jar GenerateExampleSettings " diff --git a/host/migration/example-cm12.1-settings.txt b/host/migration/example-cm12.1-settings.txt new file mode 100644 index 0000000..7534be3 --- /dev/null +++ b/host/migration/example-cm12.1-settings.txt @@ -0,0 +1,121 @@ +# Settings which are to be moved to CMSettings +# Automatically generated by vendor/cmsdk/host/migration/src/GenerateExampleSettingsGenerateExampleSettings.java. +Row: 0 name=status_bar_battery_style, type=s, value=2, type=s +Row: 1 name=enable_forward_lookup, type=s, value=1, type=s +Row: 2 name=enable_people_lookup, type=s, value=1, type=s +Row: 3 name=enable_reverse_lookup, type=s, value=1, type=s +Row: 4 name=qs_quick_pulldown, type=s, value=1, type=s +Row: 5 name=display_auto_outdoor_mode, type=s, value=-1, type=s +Row: 6 name=home_wake_screen, type=s, value=1, type=s +Row: 7 name=back_wake_screen, type=s, value=0, type=s +Row: 8 name=menu_wake_screen, type=s, value=0, type=s +Row: 9 name=assist_wake_screen, type=s, value=0, type=s +Row: 10 name=app_switch_wake_screen, type=s, value=0, type=s +Row: 11 name=status_bar_clock, type=s, value=2, type=s +Row: 12 name=status_bar_show_battery_percent, type=s, value=1, type=s +Row: 13 name=reverse_lookup_provider, type=s, value=OpenCnam, type=s +Row: 14 name=live_display_hinted, type=s, value=1, type=s +Row: 15 name=status_bar_ime_switcher, type=s, value=1, type=s +Row: 16 name=edge_service_for_gestures, type=s, value=1, type=s +Row: 17 name=people_lookup_provider, type=s, value=WhitePages, type=s +Row: 18 name=forward_lookup_provider, type=s, value=Google, type=s +Row: 19 name=status_bar_show_weather, type=s, value=1, type=s +Row: 20 name=system_profiles_enabled, type=s, value=1, type=s +Row: 21 name=proximity_on_wake, type=s, value=0, type=s +Row: 22 name=display_low_power, type=s, value=1, type=s +Row: 23 name=display_color_enhance, type=s, value=1, type=s +Row: 24 name=increasing_ring_ramp_up_time, type=s, value=10, type=s +Row: 25 name=increasing_ring_start_vol, type=s, value=0.487, type=s +Row: 26 name=display_temperature_night, type=s, value=2800, type=s +Row: 27 name=camera_launch, type=s, value=1, type=s +Row: 28 name=nav_buttons, type=s, value=empty|back|home|recent|empty|menu0, type=s +Row: 29 name=increasing_ring, type=s, value=1, type=s +Row: 30 name=volume_adjust_sounds_enabled, type=s, value=1, type=s +Row: 31 name=display_temperature_mode, type=s, value=2, type=s +Row: 32 name=display_temperature_day, type=s, value=5600, type=s +Row: 33 name=display_color_adjustment, type=s, value=0.999982 0.999982 0.999982, type=s +Row: 34 name=double_tap_sleep_gesture, type=s, value=1, type=s +Row: 35 name=recents_show_search_bar, type=s, value=0, type=s +Row: 36 name=battery_light_enabled, type=s, value=1, type=s +Row: 37 name=battery_light_pulse, type=s, value=1, type=s +Row: 38 name=battery_light_low_color, type=s, value=-55513, type=s +Row: 39 name=battery_light_medium_color, type=s, value=-113, type=s +Row: 40 name=battery_light_full_color, type=s, value=-16722688, type=s +Row: 41 name=notification_light_pulse_default_color, type=s, value=-848184, type=s +Row: 42 name=notification_light_pulse_default_led_on, type=s, value=1000, type=s +Row: 43 name=notification_light_pulse_default_led_off, type=s, value=6000, type=s +Row: 44 name=notification_light_screen_on_enable, type=s, value=0, type=s +Row: 45 name=notification_light_pulse_call_color, type=s, value=-4288625, type=s +Row: 46 name=notification_light_pulse_call_led_on, type=s, value=1000, type=s +Row: 47 name=notification_light_pulse_call_led_off, type=s, value=6000, type=s +Row: 48 name=notification_light_pulse_vmail_color, type=s, value=-4568759, type=s +Row: 49 name=notification_light_pulse_vmail_led_on, type=s, value=1000, type=s +Row: 50 name=notification_light_pulse_vmail_led_off, type=s, value=6000, type=s +Row: 51 name=notification_light_pulse_custom_enable, type=s, value=0, type=s +Row: 52 name=lockscreen_scramble_pin_layout, type=s, value=1, type=s +Row: 53 name=navigation_bar_left, type=s, value=0, type=s +Row: 54 name=navigation_bar_menu_arrow_keys, type=s, value=0, type=s +Row: 55 name=camera_sleep_on_release, type=s, value=0, type=s +Row: 56 name=camera_wake_screen, type=s, value=0, type=s +Row: 57 name=volume_wake_screen, type=s, value=0, type=s +Row: 58 name=volbtn_music_controls, type=s, value=1, type=s +Row: 59 name=volume_keys_control_ring_stream, type=s, value=1, type=s +Row: 60 name=swap_volume_keys_on_rotation, type=s, value=0, type=s +Row: 61 name=status_bar_brightness_control, type=s, value=0, type=s +Row: 62 name=status_bar_notif_count, type=s, value=1, type=s +Row: 63 name=dev_force_show_navbar, type=s, value=0, type=s +Row: 64 name=stats_collection, type=s, value=1, type=s +Row: 65 name=advanced_mode, type=s, value=1, type=s +Row: 66 name=default_theme_package, type=s, value=com.cyngn.hexo, type=s +Row: 67 name=default_theme_components, type=s, value=mods_overlays|mods_status_bar|mods_navigation_bar|mods_icons|mods_homescreen|mods_fonts, type=s +Row: 68 name=live_display_color_matrix, type=s, value=NULL, type=NULL +Row: 69 name=navigation_ring_targets_0, type=s, value=assist, type=s +Row: 70 name=navigation_ring_targets_1, type=s, value=assist, type=s +Row: 71 name=navigation_ring_targets_2, type=s, value=assist, type=s +Row: 72 name=theme_prev_boot_api_level, type=s, value=22, type=s +Row: 73 name=qs_show_brightness_slider, type=s, value=1, type=s +Row: 74 name=recents_long_press_activity, type=s, value=torch, type=s +Row: 75 name=lockscreen_target_actions, type=s, value=default|#Intent;actionandroid.intent.action.MAIN;categoryandroid.intent.category.LAUNCHER;componentcom.snapchat.android/.LandingPageActivity;end, type=s +Row: 76 name=device_hostname, type=s, value=android-932989077997886b, type=s +Row: 77 name=sysui_qs_main_tiles, type=s, value=1, type=s +Row: 78 name=privacy_guard_default, type=s, value=1, type=s +Row: 79 name=protected_components, type=s, value=null, type=s +Row: 80 name=adb_notify, type=s, value=1, type=s +Row: 81 name=development_shortcut, type=s, value=0, type=s +Row: 82 name=app_perf_profiles_enabled, type=s, value=1, type=s +Row: 83 name=performance_profile, type=s, value=1, type=s +Row: 84 name=sysui_qs_tiles, type=s, value=wifi, type=s +Row: 85 name=volume_link_notification, type=s, value=0, type=s +Row: 86 name=power_notifications_ringtone, type=s, value=content://settings/system/notification_sound, type=s +Row: 87 name=power_notifications_vibrate, type=s, value=0, type=s +Row: 88 name=power_notifications_enabled, type=s, value=0, type=s +Row: 89 name=wake_when_plugged_or_unplugged, type=s, value=1, type=s +Row: 90 name=zen_disable_ducking_during_media_playback, type=s, value=0, type=s +Row: 91 name=bluetooth_accept_all_files, type=s, value=0, type=s +Row: 92 name=call_recording_format, type=s, value=0, type=s +Row: 93 name=dialer_opencnam_account_sid, type=s, value=0, type=s +Row: 94 name=dialer_opencnam_auth_token, type=s, value=0, type=s +Row: 95 name=enable_mwi_notification, type=s, value=0, type=s +Row: 96 name=key_app_switch_action, type=s, value=0, type=s +Row: 97 name=key_app_switch_long_press_action, type=s, value=0, type=s +Row: 98 name=key_assist_action, type=s, value=0, type=s +Row: 99 name=key_assist_long_press_action, type=s, value=0, type=s +Row: 100 name=key_home_double_tap_action, type=s, value=0, type=s +Row: 101 name=key_home_long_press_action, type=s, value=0, type=s +Row: 102 name=key_menu_action, type=s, value=0, type=s +Row: 103 name=key_menu_long_press_action, type=s, value=0, type=s +Row: 104 name=notification_light_brightness_level, type=s, value=0, type=s +Row: 105 name=notification_light_multiple_leds_enable, type=s, value=0, type=s +Row: 106 name=notification_light_pulse_custom_values, type=s, value=0, type=s +Row: 107 name=advanced_reboot, type=s, value=0, type=s +Row: 108 name=button_backlight_timeout, type=s, value=0, type=s +Row: 109 name=button_brightness, type=s, value=255, type=s +Row: 110 name=keyboard_brightness, type=s, value=255, type=s +Row: 111 name=kill_app_longpress_back, type=s, value=0, type=s +Row: 112 name=power_menu_actions, type=s, value=blah, type=s +Row: 113 name=wifi_auto_priority, type=s, value=0, type=s +Row: 114 name=ring_home_button_behavior, type=s, value=1, type=s +Row: 115 name=show_alarm_icon, type=s, value=1, type=s +Row: 116 name=status_bar_am_pm, type=s, value=1, type=s +Row: 117 name=status_bar_quick_qs_pulldown, type=s, value=1, type=s +Row: 118 name=t9_search_input_locale, type=s, value=enUS, type=s \ No newline at end of file diff --git a/host/migration/src/CMSettings.java b/host/migration/src/CMSettings.java new file mode 100644 index 0000000..0d57b0d --- /dev/null +++ b/host/migration/src/CMSettings.java @@ -0,0 +1,1126 @@ +/** + * Copyright (c) 2015, The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.Arrays; + +/** + * CMSettings contains CM specific preferences in System, Secure, and Global. + */ +public final class CMSettings { + public static final String AUTHORITY = "cmsettings"; + + /** + * System settings, containing miscellaneous CM system preferences. This table holds simple + * name/value pairs. There are convenience functions for accessing individual settings entries. + */ + public static final class System { + // region System Settings + + /** + * Quick Settings Quick Pulldown + * 0 = off, 1 = right, 2 = left + * @hide + */ + public static final String QS_QUICK_PULLDOWN = "qs_quick_pulldown"; + + /** + * Whether to attach a queue to media notifications. + * 0 = 0ff, 1 = on + * @hide + */ + public static final String NOTIFICATION_PLAY_QUEUE = "notification_play_queue"; + + /** + * Whether the HighTouchSensitivity is activated or not. + * 0 = off, 1 = on + * @hide + */ + public static final String HIGH_TOUCH_SENSITIVITY_ENABLE = + "high_touch_sensitivity_enable"; + + /** + * Show the pending notification counts as overlays on the status bar + * @hide + */ + public static final String SYSTEM_PROFILES_ENABLED = "system_profiles_enabled"; + + /** + * Whether to hide the clock, show it in the right or left + * position or show it in the center + * 0: don't show the clock + * 1: show the clock in the right position (LTR) + * 2: show the clock in the center + * 3: show the clock in the left position (LTR) + * default: 1 + * @hide + */ + public static final String STATUS_BAR_CLOCK = "status_bar_clock"; + + /** + * Display style of AM/PM next to clock in status bar + * 0: Normal display (Eclair stock) + * 1: Small display (Froyo stock) + * 2: No display (Gingerbread/ICS stock) + * default: 2 + * @hide + */ + public static final String STATUS_BAR_AM_PM = "status_bar_am_pm"; + + /** + * Display style of the status bar battery information + * 0: Display the battery an icon in portrait mode + * 2: Display the battery as a circle + * 4: Hide the battery status information + * 5: Display the battery an icon in landscape mode + * 6: Display the battery as plain text + * default: 0 + * @hide + */ + public static final String STATUS_BAR_BATTERY_STYLE = "status_bar_battery_style"; + + /** + * Status bar battery % + * 0: Hide the battery percentage + * 1: Display the battery percentage inside the icon + * 2: Display the battery percentage next to the icon + * @hide + */ + public static final String STATUS_BAR_SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent"; + // endregion + + /** + * Whether the phone ringtone should be played in an increasing manner + * @hide + */ + public static final String INCREASING_RING = "increasing_ring"; + + /** + * Start volume fraction for increasing ring volume + * @hide + */ + public static final String INCREASING_RING_START_VOLUME = "increasing_ring_start_vol"; + + /** + * Ramp up time (seconds) for increasing ring + * @hide + */ + public static final String INCREASING_RING_RAMP_UP_TIME = "increasing_ring_ramp_up_time"; + + /** + * Volume Adjust Sounds Enable, This is the noise made when using volume hard buttons + * Defaults to 1 - sounds enabled + * @hide + */ + public static final String VOLUME_ADJUST_SOUNDS_ENABLED = "volume_adjust_sounds_enabled"; + + /** + * Navigation controls to Use + * @hide + */ + public static final String NAV_BUTTONS = "nav_buttons"; + + /** + * Volume key controls ringtone or media sound stream + * @hide + */ + public static final String VOLUME_KEYS_CONTROL_RING_STREAM = + "volume_keys_control_ring_stream"; + + /** + * boolean value. toggles using arrow key locations on nav bar + * as left and right dpad keys + * @hide + */ + public static final String NAVIGATION_BAR_MENU_ARROW_KEYS = "navigation_bar_menu_arrow_keys"; + + /** + * Action to perform when the home key is long-pressed. + * (Default can be configured via config_longPressOnHomeBehavior) + * 0 - Nothing + * 1 - Menu + * 2 - App-switch + * 3 - Search + * 4 - Voice search + * 5 - In-app search + * 6 - Launch Camera + * 7 - Action Sleep + * 8 - Last app + * @hide + */ + public static final String KEY_HOME_LONG_PRESS_ACTION = "key_home_long_press_action"; + + /** + * Action to perform when the home key is double-tapped. + * (Default can be configured via config_doubleTapOnHomeBehavior) + * (See KEY_HOME_LONG_PRESS_ACTION for valid values) + * @hide + */ + public static final String KEY_HOME_DOUBLE_TAP_ACTION = "key_home_double_tap_action"; + + /** + * Whether to wake the screen with the back key, the value is boolean. + * @hide + */ + public static final String BACK_WAKE_SCREEN = "back_wake_screen"; + + /** + * Whether to wake the screen with the menu key, the value is boolean. + * @hide + */ + public static final String MENU_WAKE_SCREEN = "menu_wake_screen"; + + /** + * Whether to wake the screen with the volume keys, the value is boolean. + * @hide + */ + public static final String VOLUME_WAKE_SCREEN = "volume_wake_screen"; + + /** + * Action to perform when the menu key is pressed. (Default is 1) + * (See KEY_HOME_LONG_PRESS_ACTION for valid values) + * @hide + */ + public static final String KEY_MENU_ACTION = "key_menu_action"; + + /** + * Action to perform when the menu key is long-pressed. + * (Default is 0 on devices with a search key, 3 on devices without) + * (See KEY_HOME_LONG_PRESS_ACTION for valid values) + * @hide + */ + public static final String KEY_MENU_LONG_PRESS_ACTION = "key_menu_long_press_action"; + + /** + * Action to perform when the assistant (search) key is pressed. (Default is 3) + * (See KEY_HOME_LONG_PRESS_ACTION for valid values) + * @hide + */ + public static final String KEY_ASSIST_ACTION = "key_assist_action"; + + /** + * Action to perform when the assistant (search) key is long-pressed. (Default is 4) + * (See KEY_HOME_LONG_PRESS_ACTION for valid values) + * @hide + */ + public static final String KEY_ASSIST_LONG_PRESS_ACTION = "key_assist_long_press_action"; + + /** + * Action to perform when the app switch key is pressed. (Default is 2) + * (See KEY_HOME_LONG_PRESS_ACTION for valid values) + * @hide + */ + public static final String KEY_APP_SWITCH_ACTION = "key_app_switch_action"; + + /** + * Action to perform when the app switch key is long-pressed. (Default is 0) + * (See KEY_HOME_LONG_PRESS_ACTION for valid values) + * @hide + */ + public static final String KEY_APP_SWITCH_LONG_PRESS_ACTION = "key_app_switch_long_press_action"; + + /** + * Whether to wake the screen with the home key, the value is boolean. + * @hide + */ + public static final String HOME_WAKE_SCREEN = "home_wake_screen"; + + /** + * Whether to wake the screen with the assist key, the value is boolean. + * @hide + */ + public static final String ASSIST_WAKE_SCREEN = "assist_wake_screen"; + + /** + * Whether to wake the screen with the app switch key, the value is boolean. + * @hide + */ + public static final String APP_SWITCH_WAKE_SCREEN = "app_switch_wake_screen"; + + /** + * Whether to wake the screen with the camera key half-press. + * @hide + */ + public static final String CAMERA_WAKE_SCREEN = "camera_wake_screen"; + + /** + * Whether or not to send device back to sleep if Camera button is released ("Peek") + * @hide + */ + public static final String CAMERA_SLEEP_ON_RELEASE = "camera_sleep_on_release"; + + /** + * Whether to launch secure camera app when key is longpressed + * @hide + */ + public static final String CAMERA_LAUNCH = "camera_launch"; + + /** + * Swap volume buttons when the screen is rotated + * 0 - Disabled + * 1 - Enabled (screen is rotated by 90 or 180 degrees: phone, hybrid) + * 2 - Enabled (screen is rotated by 180 or 270 degrees: tablet) + * @hide + */ + public static final String SWAP_VOLUME_KEYS_ON_ROTATION = "swap_volume_keys_on_rotation"; + + /** + * Whether the battery light should be enabled (if hardware supports it) + * The value is boolean (1 or 0). + * @hide + */ + public static final String BATTERY_LIGHT_ENABLED = "battery_light_enabled"; + + /** + * Whether the battery LED should repeatedly flash when the battery is low + * on charge. The value is boolean (1 or 0). + * @hide + */ + public static final String BATTERY_LIGHT_PULSE = "battery_light_pulse"; + + /** + * What color to use for the battery LED while charging - low + * @hide + */ + public static final String BATTERY_LIGHT_LOW_COLOR = "battery_light_low_color"; + + /** + * What color to use for the battery LED while charging - medium + * @hide + */ + public static final String BATTERY_LIGHT_MEDIUM_COLOR = "battery_light_medium_color"; + + /** + * What color to use for the battery LED while charging - full + * @hide + */ + public static final String BATTERY_LIGHT_FULL_COLOR = "battery_light_full_color"; + + /** + * Sprint MWI Quirk: Show message wait indicator notifications + * @hide + */ + public static final String ENABLE_MWI_NOTIFICATION = "enable_mwi_notification"; + + /** + * Check the proximity sensor during wakeup + * @hide + */ + public static final String PROXIMITY_ON_WAKE = "proximity_on_wake"; + + /** + * Enable looking up of phone numbers of nearby places + * + * @hide + */ + public static final String ENABLE_FORWARD_LOOKUP = "enable_forward_lookup"; + + /** + * Enable looking up of phone numbers of people + * + * @hide + */ + public static final String ENABLE_PEOPLE_LOOKUP = "enable_people_lookup"; + + /** + * Enable looking up of information of phone numbers not in the contacts + * + * @hide + */ + public static final String ENABLE_REVERSE_LOOKUP = "enable_reverse_lookup"; + + /** + * The forward lookup provider + * + * @hide + */ + public static final String FORWARD_LOOKUP_PROVIDER = "forward_lookup_provider"; + + /** + * The people lookup provider + * + * @hide + */ + public static final String PEOPLE_LOOKUP_PROVIDER = "people_lookup_provider"; + + /** + * The reverse lookup provider + * + * @hide + */ + public static final String REVERSE_LOOKUP_PROVIDER = "reverse_lookup_provider"; + + /** + * The OpenCNAM paid account ID + * + * @hide + */ + public static final String DIALER_OPENCNAM_ACCOUNT_SID = "dialer_opencnam_account_sid"; + + /** + * The OpenCNAM authentication token + * + * @hide + */ + public static final String DIALER_OPENCNAM_AUTH_TOKEN = "dialer_opencnam_auth_token"; + + /** + * Whether wifi settings will connect to access point automatically + * 0 = automatically + * 1 = manually + * @hide + */ + public static final String WIFI_AUTO_CONNECT_TYPE = "wifi_auto_connect_type"; + + /** + * Color temperature of the display during the day + * @hide + */ + public static final String DISPLAY_TEMPERATURE_DAY = "display_temperature_day"; + + /** + * Color temperature of the display at night + * @hide + */ + public static final String DISPLAY_TEMPERATURE_NIGHT = "display_temperature_night"; + + /** + * Display color temperature adjustment mode, one of DAY (default), NIGHT, or AUTO. + * @hide + */ + public static final String DISPLAY_TEMPERATURE_MODE = "display_temperature_mode"; + + /** + * Automatic outdoor mode + * @hide + */ + public static final String DISPLAY_AUTO_OUTDOOR_MODE = "display_auto_outdoor_mode"; + + /** + * Use display power saving features such as CABC or CABL + * @hide + */ + public static final String DISPLAY_LOW_POWER = "display_low_power"; + + /** + * Use color enhancement feature of display + * @hide + */ + public static final String DISPLAY_COLOR_ENHANCE = "display_color_enhance"; + + /** + * Manual display color adjustments (RGB values as floats, separated by spaces) + * @hide + */ + public static final String DISPLAY_COLOR_ADJUSTMENT = "display_color_adjustment"; + + /** + * Did we tell about how they can stop breaking their eyes? + * @hide + */ + public static final String LIVE_DISPLAY_HINTED = "live_display_hinted"; + + /** + * Enable statusbar double tap gesture on to put device to sleep + * @hide + */ + public static final String DOUBLE_TAP_SLEEP_GESTURE = "double_tap_sleep_gesture"; + + /** + * Boolean value on whether to show weather in the statusbar + * @hide + */ + public static final String STATUS_BAR_SHOW_WEATHER = "status_bar_show_weather"; + + /** + * Show search bar in recents + * @hide + */ + public static final String RECENTS_SHOW_SEARCH_BAR = "recents_show_search_bar"; + + /** + * Whether navigation bar is placed on the left side in landscape mode + * @hide + */ + public static final String NAVBAR_LEFT_IN_LANDSCAPE = "navigation_bar_left"; + + /** + * Locale for secondary overlay on dialer for t9 search input + * @hide + */ + public static final String T9_SEARCH_INPUT_LOCALE = "t9_search_input_locale"; + + /** + * If all file types can be accepted over Bluetooth OBEX. + * @hide + */ + public static final String BLUETOOTH_ACCEPT_ALL_FILES = + "bluetooth_accept_all_files"; + + /** + * Whether to scramble a pin unlock layout + * @hide + */ + public static final String LOCKSCREEN_PIN_SCRAMBLE_LAYOUT = + "lockscreen_scramble_pin_layout"; + + /** + * @hide + */ + public static final String SHOW_ALARM_ICON = "show_alarm_icon"; + + /** + * Whether to show the IME switcher in the status bar + * @hide + */ + public static final String STATUS_BAR_IME_SWITCHER = "status_bar_ime_switcher"; + + /** Whether to allow one finger quick settings expansion on the right side of the statusbar. + * + * @hide + */ + public static final String STATUS_BAR_QUICK_QS_PULLDOWN = "status_bar_quick_qs_pulldown"; + + /** Whether to show the brightness slider in quick settings panel. + * + * @hide + */ + public static final String QS_SHOW_BRIGHTNESS_SLIDER = "qs_show_brightness_slider"; + + /** + * Whether to control brightness from status bar + * + * @hide + */ + public static final String STATUS_BAR_BRIGHTNESS_CONTROL = "status_bar_brightness_control"; + + /** + * Whether or not volume button music controls should be enabled to seek media tracks + * @hide + */ + public static final String VOLBTN_MUSIC_CONTROLS = "volbtn_music_controls"; + + /** + * Use EdgeGesture Service for system gestures in PhoneWindowManager + * @hide + */ + public static final String USE_EDGE_SERVICE_FOR_GESTURES = "edge_service_for_gestures"; + + /** + * Show the pending notification counts as overlays on the status bar + * @hide + */ + public static final String STATUS_BAR_NOTIF_COUNT = "status_bar_notif_count"; + + /** + * Call recording format value + * 0: AMR_WB + * 1: MPEG_4 + * Default: 0 + * @hide + */ + public static final String CALL_RECORDING_FORMAT = "call_recording_format"; + + /** + * Contains the notifications light maximum brightness to use. + * @hide + */ + public static final String NOTIFICATION_LIGHT_BRIGHTNESS_LEVEL = + "notification_light_brightness_level"; + + /** + * Whether to use the all the LEDs for the notifications or just one. + * @hide + */ + public static final String NOTIFICATION_LIGHT_MULTIPLE_LEDS_ENABLE = + "notification_light_multiple_leds_enable"; + + /** + * Whether to allow notifications with the screen on or DayDreams. + * The value is boolean (1 or 0). Default will always be false. + * @hide + */ + public static final String NOTIFICATION_LIGHT_SCREEN_ON = + "notification_light_screen_on_enable"; + + /** + * What color to use for the notification LED by default + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR = + "notification_light_pulse_default_color"; + + /** + * How long to flash the notification LED by default + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON = + "notification_light_pulse_default_led_on"; + + /** + * How long to wait between flashes for the notification LED by default + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF = + "notification_light_pulse_default_led_off"; + + /** + * What color to use for the missed call notification LED + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_CALL_COLOR = + "notification_light_pulse_call_color"; + + /** + * How long to flash the missed call notification LED + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_CALL_LED_ON = + "notification_light_pulse_call_led_on"; + + /** + * How long to wait between flashes for the missed call notification LED + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_CALL_LED_OFF = + "notification_light_pulse_call_led_off"; + /** + * What color to use for the voicemail notification LED + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR = + "notification_light_pulse_vmail_color"; + + /** + * How long to flash the voicemail notification LED + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_VMAIL_LED_ON = + "notification_light_pulse_vmail_led_on"; + + /** + * How long to wait between flashes for the voicemail notification LED + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_VMAIL_LED_OFF = + "notification_light_pulse_vmail_led_off"; + + /** + * Whether to use the custom LED values for the notification pulse LED. + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE = + "notification_light_pulse_custom_enable"; + + /** + * Which custom LED values to use for the notification pulse LED. + * @hide + */ + public static final String NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES = + "notification_light_pulse_custom_values"; + + /** + * @hide + */ + public static final String[] LEGACY_SYSTEM_SETTINGS = new String[]{ + CMSettings.System.QS_QUICK_PULLDOWN, + CMSettings.System.NAV_BUTTONS, + CMSettings.System.KEY_HOME_LONG_PRESS_ACTION, + CMSettings.System.KEY_HOME_DOUBLE_TAP_ACTION, + CMSettings.System.BACK_WAKE_SCREEN, + CMSettings.System.MENU_WAKE_SCREEN, + CMSettings.System.VOLUME_WAKE_SCREEN, + CMSettings.System.KEY_MENU_ACTION, + CMSettings.System.KEY_MENU_LONG_PRESS_ACTION, + CMSettings.System.KEY_ASSIST_ACTION, + CMSettings.System.KEY_ASSIST_LONG_PRESS_ACTION, + CMSettings.System.KEY_APP_SWITCH_ACTION, + CMSettings.System.KEY_APP_SWITCH_LONG_PRESS_ACTION, + CMSettings.System.HOME_WAKE_SCREEN, + CMSettings.System.ASSIST_WAKE_SCREEN, + CMSettings.System.APP_SWITCH_WAKE_SCREEN, + CMSettings.System.CAMERA_WAKE_SCREEN, + CMSettings.System.CAMERA_SLEEP_ON_RELEASE, + CMSettings.System.CAMERA_LAUNCH, + CMSettings.System.SWAP_VOLUME_KEYS_ON_ROTATION, + CMSettings.System.BATTERY_LIGHT_ENABLED, + CMSettings.System.BATTERY_LIGHT_PULSE, + CMSettings.System.BATTERY_LIGHT_LOW_COLOR, + CMSettings.System.BATTERY_LIGHT_MEDIUM_COLOR, + CMSettings.System.BATTERY_LIGHT_FULL_COLOR, + CMSettings.System.ENABLE_MWI_NOTIFICATION, + CMSettings.System.PROXIMITY_ON_WAKE, + CMSettings.System.ENABLE_FORWARD_LOOKUP, + CMSettings.System.ENABLE_PEOPLE_LOOKUP, + CMSettings.System.ENABLE_REVERSE_LOOKUP, + CMSettings.System.FORWARD_LOOKUP_PROVIDER, + CMSettings.System.PEOPLE_LOOKUP_PROVIDER, + CMSettings.System.REVERSE_LOOKUP_PROVIDER, + CMSettings.System.DIALER_OPENCNAM_ACCOUNT_SID, + CMSettings.System.DIALER_OPENCNAM_AUTH_TOKEN, + CMSettings.System.DISPLAY_TEMPERATURE_DAY, + CMSettings.System.DISPLAY_TEMPERATURE_NIGHT, + CMSettings.System.DISPLAY_TEMPERATURE_MODE, + CMSettings.System.DISPLAY_AUTO_OUTDOOR_MODE, + CMSettings.System.DISPLAY_LOW_POWER, + CMSettings.System.DISPLAY_COLOR_ENHANCE, + CMSettings.System.DISPLAY_COLOR_ADJUSTMENT, + CMSettings.System.LIVE_DISPLAY_HINTED, + CMSettings.System.DOUBLE_TAP_SLEEP_GESTURE, + CMSettings.System.STATUS_BAR_SHOW_WEATHER, + CMSettings.System.RECENTS_SHOW_SEARCH_BAR, + CMSettings.System.NAVBAR_LEFT_IN_LANDSCAPE, + CMSettings.System.T9_SEARCH_INPUT_LOCALE, + CMSettings.System.BLUETOOTH_ACCEPT_ALL_FILES, + CMSettings.System.LOCKSCREEN_PIN_SCRAMBLE_LAYOUT, + CMSettings.System.SHOW_ALARM_ICON, + CMSettings.System.STATUS_BAR_IME_SWITCHER, + CMSettings.System.QS_SHOW_BRIGHTNESS_SLIDER, + CMSettings.System.STATUS_BAR_BRIGHTNESS_CONTROL, + CMSettings.System.VOLBTN_MUSIC_CONTROLS, + CMSettings.System.SWAP_VOLUME_KEYS_ON_ROTATION, + CMSettings.System.USE_EDGE_SERVICE_FOR_GESTURES, + CMSettings.System.STATUS_BAR_NOTIF_COUNT, + CMSettings.System.CALL_RECORDING_FORMAT, + CMSettings.System.NOTIFICATION_LIGHT_BRIGHTNESS_LEVEL, + CMSettings.System.NOTIFICATION_LIGHT_MULTIPLE_LEDS_ENABLE, + CMSettings.System.NOTIFICATION_LIGHT_SCREEN_ON, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_COLOR, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_ON, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CALL_LED_OFF, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_ON, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_VMAIL_LED_OFF, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE, + CMSettings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES, + CMSettings.System.STATUS_BAR_QUICK_QS_PULLDOWN, + CMSettings.System.VOLUME_ADJUST_SOUNDS_ENABLED, + CMSettings.System.SYSTEM_PROFILES_ENABLED, + CMSettings.System.INCREASING_RING, + CMSettings.System.INCREASING_RING_START_VOLUME, + CMSettings.System.INCREASING_RING_RAMP_UP_TIME, + CMSettings.System.STATUS_BAR_CLOCK, + CMSettings.System.STATUS_BAR_AM_PM, + CMSettings.System.STATUS_BAR_BATTERY_STYLE, + CMSettings.System.STATUS_BAR_SHOW_BATTERY_PERCENT, + CMSettings.System.VOLUME_KEYS_CONTROL_RING_STREAM, + CMSettings.System.NAVIGATION_BAR_MENU_ARROW_KEYS, + }; + + /** + * @hide + */ + public static boolean isLegacySetting(String key) { + return Arrays.asList(LEGACY_SYSTEM_SETTINGS).contains(key); + } + } + + /** + * Secure settings, containing miscellaneous CM secure preferences. This + * table holds simple name/value pairs. There are convenience + * functions for accessing individual settings entries. + */ + public static final class Secure { + + // region Secure Settings + + /** + * Whether to enable "advanced mode" for the current user. + * Boolean setting. 0 = no, 1 = yes. + * @hide + */ + public static final String ADVANCED_MODE = "advanced_mode"; + + /** + * The time in ms to keep the button backlight on after pressing a button. + * A value of 0 will keep the buttons on for as long as the screen is on. + * @hide + */ + public static final String BUTTON_BACKLIGHT_TIMEOUT = "button_backlight_timeout"; + + /** + * The button brightness to be used while the screen is on or after a button press, + * depending on the value of {@link BUTTON_BACKLIGHT_TIMEOUT}. + * Valid value range is between 0 and {@link PowerManager#getMaximumButtonBrightness()} + * @hide + */ + public static final String BUTTON_BRIGHTNESS = "button_brightness"; + + /** + * A '|' delimited list of theme components to apply from the default theme on first boot. + * Components can be one or more of the "mods_XXXXXXX" found in + * {@link ThemesContract$ThemesColumns}. Leaving this field blank assumes all components + * will be applied. + * + * ex: mods_icons|mods_overlays|mods_homescreen + * + * @hide + */ + public static final String DEFAULT_THEME_COMPONENTS = "default_theme_components"; + + /** + * Default theme to use. If empty, use holo. + * @hide + */ + public static final String DEFAULT_THEME_PACKAGE = "default_theme_package"; + + /** + * Developer options - Navigation Bar show switch + * @hide + */ + public static final String DEV_FORCE_SHOW_NAVBAR = "dev_force_show_navbar"; + + /** + * The keyboard brightness to be used while the screen is on. + * Valid value range is between 0 and {@link PowerManager#getMaximumKeyboardBrightness()} + * @hide + */ + public static final String KEYBOARD_BRIGHTNESS = "keyboard_brightness"; + + /** + * Default theme config name + */ + public static final String NAME_THEME_CONFIG = "name_theme_config"; + + /** + * Custom navring actions + * @hide + */ + public static final String[] NAVIGATION_RING_TARGETS = new String[] { + "navigation_ring_targets_0", + "navigation_ring_targets_1", + "navigation_ring_targets_2", + }; + + /** + * String to contain power menu actions + * @hide + */ + public static final String POWER_MENU_ACTIONS = "power_menu_actions"; + + /** + * Whether to show the brightness slider in quick settings panel. + * @hide + */ + public static final String QS_SHOW_BRIGHTNESS_SLIDER = "qs_show_brightness_slider"; + + /** + * List of QS tile names + * @hide + */ + public static final String QS_TILES = "sysui_qs_tiles"; + + /** + * Use "main" tiles on the first row of the quick settings panel + * 0 = no, 1 = yes + * @hide + */ + public static final String QS_USE_MAIN_TILES = "sysui_qs_main_tiles"; + + /** + * Global stats collection + * @hide + */ + public static final String STATS_COLLECTION = "stats_collection"; + + /** + * Boolean value whether to link ringtone and notification volume + * + * @hide + */ + public static final String VOLUME_LINK_NOTIFICATION = "volume_link_notification"; + + /** + * Whether newly installed apps should run with privacy guard by default + * @hide + */ + public static final String PRIVACY_GUARD_DEFAULT = "privacy_guard_default"; + + /** + * The global recents long press activity chosen by the user. + * This setting is stored as a flattened component name as + * per {@link ComponentName#flattenToString()}. + * + * @hide + */ + public static final String RECENTS_LONG_PRESS_ACTIVITY = "recents_long_press_activity"; + + /** + * What happens when the user presses the Home button when the + * phone is ringing.
+ * Values:
+ * 1 - Nothing happens. (Default behavior)
+ * 2 - The Home button answer the current call.
+ * + * @hide + */ + public static final String RING_HOME_BUTTON_BEHAVIOR = "ring_home_button_behavior"; + + /** + * RING_HOME_BUTTON_BEHAVIOR value for "do nothing". + * @hide + */ + public static final int RING_HOME_BUTTON_BEHAVIOR_DO_NOTHING = 0x1; + + /** + * RING_HOME_BUTTON_BEHAVIOR value for "answer". + * @hide + */ + public static final int RING_HOME_BUTTON_BEHAVIOR_ANSWER = 0x2; + + /** + * RING_HOME_BUTTON_BEHAVIOR default value. + * @hide + */ + public static final int RING_HOME_BUTTON_BEHAVIOR_DEFAULT = + RING_HOME_BUTTON_BEHAVIOR_DO_NOTHING; + + /** + * When the user has enable the option to have a "bug report" command + * in the power menu. + * @deprecated Use {@link android.provider.Settings.Global#BUGREPORT_IN_POWER_MENU} instead + * @hide + */ + @Deprecated + public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu"; + + /** + * Performance profile + * @hide + */ + public static final String PERFORMANCE_PROFILE = "performance_profile"; + + /** + * App-based performance profile selection + * @hide + */ + public static final String APP_PERFORMANCE_PROFILES_ENABLED = "app_perf_profiles_enabled"; + + /** + * Launch actions for left/right lockscreen targets + * @hide + */ + public static final String LOCKSCREEN_TARGETS = "lockscreen_target_actions"; + + /** + * Whether to display a menu containing 'Wipe data', 'Force close' and other options + * in the notification area and in the recent app list + * @hide + */ + public static final String DEVELOPMENT_SHORTCUT = "development_shortcut"; + + /** + * What happens when the user presses the Power button while in-call + * and the screen is on.
+ * Values:
+ * 1 - The Power button turns off the screen and locks the device. (Default behavior)
+ * 2 - The Power button hangs up the current call.
+ * + * @hide + */ + public static final String INCALL_POWER_BUTTON_BEHAVIOR = "incall_power_button_behavior"; + + /** + * INCALL_POWER_BUTTON_BEHAVIOR value for "turn off screen". + * @hide + */ + public static final int INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF = 0x1; + + /** + * INCALL_POWER_BUTTON_BEHAVIOR value for "hang up". + * @hide + */ + public static final int INCALL_POWER_BUTTON_BEHAVIOR_HANGUP = 0x2; + + /** + * INCALL_POWER_BUTTON_BEHAVIOR default value. + * @hide + */ + public static final int INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT = + INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF; + + /** + * Whether to display the ADB notification. + * @hide + */ + public static final String ADB_NOTIFY = "adb_notify"; + + /** + * The TCP/IP port to run ADB on, or -1 for USB + * @hide + */ + public static final String ADB_PORT = "adb_port"; + + /** + * The hostname for this device + * @hide + */ + public static final String DEVICE_HOSTNAME = "device_hostname"; + + /** + * Whether to allow killing of the foreground app by long-pressing the Back button + * @hide + */ + public static final String KILL_APP_LONGPRESS_BACK = "kill_app_longpress_back"; + + /** Protected Components + * @hide + */ + public static final String PROTECTED_COMPONENTS = "protected_components"; + + /** + * Stored color matrix for LiveDisplay. This is used to allow co-existence with + * display tuning done by DisplayAdjustmentUtils when hardware support isn't + * available. + * @hide + */ + public static final String LIVE_DISPLAY_COLOR_MATRIX = "live_display_color_matrix"; + + /** + * Whether to include options in power menu for rebooting into recovery or bootloader + * @hide + */ + public static final String ADVANCED_REBOOT = "advanced_reboot"; + + /** + * This will be set to the system's current theme API version when ThemeService starts. + * It is useful for when an upgrade from one version of CM to another occurs. + * For example, after a user upgrades from CM11 to CM12, the value of this field + * might be 19. ThemeService would then change the value to 21. This is useful + * when an API change breaks a theme. Themeservice can identify old themes and + * unapply them from the system. + * @hide + */ + public static final String THEME_PREV_BOOT_API_LEVEL = "theme_prev_boot_api_level"; + // endregion + + /** + * @hide + */ + public static final String[] LEGACY_SECURE_SETTINGS = new String[]{ + CMSettings.Secure.ADVANCED_MODE, + CMSettings.Secure.BUTTON_BACKLIGHT_TIMEOUT, + CMSettings.Secure.BUTTON_BRIGHTNESS, + CMSettings.Secure.DEFAULT_THEME_COMPONENTS, + CMSettings.Secure.DEFAULT_THEME_PACKAGE, + CMSettings.Secure.DEV_FORCE_SHOW_NAVBAR, + CMSettings.Secure.KEYBOARD_BRIGHTNESS, + CMSettings.Secure.POWER_MENU_ACTIONS, + CMSettings.Secure.STATS_COLLECTION, + CMSettings.Secure.QS_SHOW_BRIGHTNESS_SLIDER, + CMSettings.Secure.QS_TILES, + CMSettings.Secure.QS_USE_MAIN_TILES, + CMSettings.Secure.VOLUME_LINK_NOTIFICATION, + CMSettings.Secure.NAVIGATION_RING_TARGETS[0], + CMSettings.Secure.NAVIGATION_RING_TARGETS[1], + CMSettings.Secure.NAVIGATION_RING_TARGETS[2], + CMSettings.Secure.RECENTS_LONG_PRESS_ACTIVITY, + CMSettings.Secure.ADB_NOTIFY, + CMSettings.Secure.ADB_PORT, + CMSettings.Secure.DEVICE_HOSTNAME, + CMSettings.Secure.KILL_APP_LONGPRESS_BACK, + CMSettings.Secure.PROTECTED_COMPONENTS, + CMSettings.Secure.LIVE_DISPLAY_COLOR_MATRIX, + CMSettings.Secure.ADVANCED_REBOOT, + CMSettings.Secure.THEME_PREV_BOOT_API_LEVEL, + CMSettings.Secure.LOCKSCREEN_TARGETS, + CMSettings.Secure.RING_HOME_BUTTON_BEHAVIOR, + CMSettings.Secure.PRIVACY_GUARD_DEFAULT, + CMSettings.Secure.DEVELOPMENT_SHORTCUT, + CMSettings.Secure.PERFORMANCE_PROFILE, + CMSettings.Secure.APP_PERFORMANCE_PROFILES_ENABLED}; + + /** + * @hide + */ + public static boolean isLegacySetting(String key) { + return Arrays.asList(LEGACY_SECURE_SETTINGS).contains(key); + } + } + + /** + * Global settings, containing miscellaneous CM global preferences. This + * table holds simple name/value pairs. There are convenience + * functions for accessing individual settings entries. + */ + public static final class Global { + // region Global Settings + /** + * Whether to wake the display when plugging or unplugging the charger + * + * @hide + */ + public static final String WAKE_WHEN_PLUGGED_OR_UNPLUGGED = + "wake_when_plugged_or_unplugged"; + + /** {@hide} */ + public static final String + BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX = "bluetooth_a2dp_src_priority_"; + + /** + * Whether to sound when charger power is connected/disconnected + * @hide + */ + public static final String POWER_NOTIFICATIONS_ENABLED = "power_notifications_enabled"; + + /** + * Whether to vibrate when charger power is connected/disconnected + * @hide + */ + public static final String POWER_NOTIFICATIONS_VIBRATE = "power_notifications_vibrate"; + + /** + * URI for power notification sounds + * @hide + */ + public static final String POWER_NOTIFICATIONS_RINGTONE = "power_notifications_ringtone"; + + /** + * @hide + */ + public static final String ZEN_DISABLE_DUCKING_DURING_MEDIA_PLAYBACK = + "zen_disable_ducking_during_media_playback"; + + /** + * Whether the system auto-configure the priority of the wifi ap's or use + * the manual settings established by the user. + * <> 0 to autoconfigure, 0 to manual settings. Default is <> 0. + * @hide + */ + public static final String WIFI_AUTO_PRIORITIES_CONFIGURATION = "wifi_auto_priority"; + // endregion + + /** + * @hide + */ + public static final String[] LEGACY_GLOBAL_SETTINGS = new String[]{ + CMSettings.Global.WAKE_WHEN_PLUGGED_OR_UNPLUGGED, + CMSettings.Global.POWER_NOTIFICATIONS_ENABLED, + CMSettings.Global.POWER_NOTIFICATIONS_VIBRATE, + CMSettings.Global.POWER_NOTIFICATIONS_RINGTONE, + CMSettings.Global.ZEN_DISABLE_DUCKING_DURING_MEDIA_PLAYBACK, + CMSettings.Global.WIFI_AUTO_PRIORITIES_CONFIGURATION}; + + /** + * @hide + */ + public static boolean isLegacySetting(String key) { + return Arrays.asList(LEGACY_GLOBAL_SETTINGS).contains(key); + } + } +} diff --git a/host/migration/src/Command.java b/host/migration/src/Command.java new file mode 100644 index 0000000..4fe29a9 --- /dev/null +++ b/host/migration/src/Command.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Created by adnan on 11/13/15. + */ +public class Command implements Runnable { + private String authority; + + /** + * Override for execution + */ + @Override + public void run() { + } + + /** + * Copies from one stream to another. + */ + protected static void copy(InputStream in, OutputStream out) { + byte[] buffer = new byte[1024]; + int read; + try { + while ((read = in.read(buffer)) > -1) { + out.write(buffer, 0, read); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected static boolean filter(String uri, Setting setting) { + switch (uri) { + case SettingsConstants.SYSTEM: + if (!CMSettings.System.isLegacySetting(setting.getKey())) { + return true; + } + break; + case SettingsConstants.SECURE: + if (SettingsConstants.Ignorables.SECURE_SETTINGS.contains(setting.getKey())) { + return true; + } + if (!CMSettings.Secure.isLegacySetting(setting.getKey())) { + return true; + } + break; + case SettingsConstants.GLOBAL: + if (!CMSettings.Global.isLegacySetting(setting.getKey())) { + return true; + } + break; + } + return false; + } + + public void prepend(String authority) { + this.authority = authority; + } + + public String getAuthority() { + return authority; + } +} diff --git a/host/migration/src/CommandExecutor.java b/host/migration/src/CommandExecutor.java new file mode 100644 index 0000000..57188ad --- /dev/null +++ b/host/migration/src/CommandExecutor.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Created by adnan on 11/16/15. + */ +public interface CommandExecutor { + public void execute(); +} diff --git a/host/migration/src/FastbootCommand.java b/host/migration/src/FastbootCommand.java new file mode 100644 index 0000000..1132315 --- /dev/null +++ b/host/migration/src/FastbootCommand.java @@ -0,0 +1,157 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by adnan on 11/17/15. + */ +public class FastbootCommand extends Command { + private static final int MAX_RETRIES = 20; + private static final String[] ADB_REBOOT_BOOTLOADER = new String[] { + "adb", "reboot", "bootloader" + }; + private static final String[] ADB_CHECK_BOOT_COMPLETE = new String[] { + "adb", "shell", "getprop", "sys.boot_completed" + }; + private static final String FASTBOOT_COMMAND = "fastboot"; + private static final String REBOOT = "reboot"; + private static final String DEVICES = "devices"; + private static final String FLASH = "flash"; + + private String[] baseCommand; + private String baseArg; + private String image; + private String targetImage; + + public FastbootCommand(int command, String[] args) { + switch (command) { + case Types.ADB_REBOOT_BOOTLOADER: + baseCommand = ADB_REBOOT_BOOTLOADER; + break; + case Types.FASTBOOT_FLASH: + baseCommand = new String[] { FASTBOOT_COMMAND }; + baseArg = FLASH; + image = args[0]; + targetImage = args[1]; + break; + case Types.FASTBOOT_DEVICES: + baseCommand = new String[] { FASTBOOT_COMMAND }; + baseArg = DEVICES; + break; + case Types.FASTBOOT_REBOOT: + baseCommand = new String[] { FASTBOOT_COMMAND }; + baseArg = REBOOT; + break; + default: + throw new UnsupportedOperationException("Unsupported operation " + command); + } + } + + @Override + public void run() { + List commandList = new ArrayList( + baseCommand.length + 1); + commandList.addAll(Arrays.asList(baseCommand)); + if (baseArg != null && baseArg.length() > 0) { + commandList.add(baseArg); + } + if (image != null &&image.length() > 0) { + commandList.add(image); + } + if (targetImage != null &&targetImage.length() > 0) { + commandList.add(targetImage); + } + String[] commands = commandList.toArray(new String[commandList.size()]); + + if (MigrationTest.DEBUG) { + System.out.println("Using commands: " + Arrays.toString(commands)); + } + try { + final Process process = Runtime.getRuntime().exec(commands); + final InputStream err = process.getErrorStream(); + + // Send error output to stderr. + Thread errThread = new Thread() { + @Override + public void run() { + copy(err, System.err); + } + }; + errThread.setDaemon(true); + errThread.start(); + + BufferedReader in = new BufferedReader( + new InputStreamReader(process.getInputStream())); + String rx = in.readLine(); + if (rx != null) { + if (MigrationTest.DEBUG) { + System.out.println("Received response " + rx); + } + } + + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + in.close(); + err.close(); + //Gross + if (baseArg != null && baseArg.equals(REBOOT)) { + List secondCommandList = new ArrayList( + ADB_CHECK_BOOT_COMPLETE.length + 1); + secondCommandList.addAll(Arrays.asList(ADB_CHECK_BOOT_COMPLETE)); + String[] secondCommands = secondCommandList.toArray( + new String[secondCommandList.size()]); + if (MigrationTest.DEBUG) { + System.out.println("Using commands: " + Arrays.toString(secondCommands)); + } + Process process2; + BufferedReader in2; + String line2; + for (int i = 1; i < MAX_RETRIES; i++) { + process2 = Runtime.getRuntime().exec(secondCommands); + in2 = new BufferedReader( + new InputStreamReader(process2.getInputStream())); + if ((line2 = in2.readLine()) != null) { + if (line2.equals("1")) { + in2.close(); + process2.destroy(); + try { + System.out.println("Device up detected..."); + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + break; + } + } + try { + System.out.println("Waiting for device to come up..."); + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + in2.close(); + process2.destroy(); + } + } + process.destroy(); + } catch (IOException e) { + System.err.println("Error "); + e.printStackTrace(); + } + } + + public final class Types { + public static final int ADB_REBOOT_BOOTLOADER = -1; + public static final int FASTBOOT_FLASH = 0; + public static final int FASTBOOT_DEVICES = 1; + public static final int FASTBOOT_REBOOT = 2; + } +} diff --git a/host/migration/src/GenerateExampleSettings.java b/host/migration/src/GenerateExampleSettings.java new file mode 100644 index 0000000..56e5fa5 --- /dev/null +++ b/host/migration/src/GenerateExampleSettings.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.File; +import java.io.IOException; +import java.io.BufferedWriter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.ArrayList; + +/** + * This is to be run on a live CM 12.1 device. + */ +public class GenerateExampleSettings { + + private static ArrayList androidSystemSettingList = new ArrayList(); + private static ArrayList androidSecureSettingList = new ArrayList(); + private static ArrayList androidGlobalSettingList = new ArrayList(); + private static ArrayList defaultSettings = new ArrayList(); + + public static void main(String[] args) throws IOException, ClassNotFoundException { + if (args.length != 1) { + System.err.println("Usage: GenerateExampleSettings [target file]"); + System.exit(-1); + } + + String rootFile = args[0]; + SettingImageCommands androidSettingImage = + new SettingImageCommands(SettingsConstants.SETTINGS_AUTHORITY); + androidSettingImage.addQuery(SettingsConstants.SYSTEM, androidSystemSettingList); + androidSettingImage.addQuery(SettingsConstants.SECURE, androidSecureSettingList); + androidSettingImage.addQuery(SettingsConstants.GLOBAL, androidGlobalSettingList); + androidSettingImage.execute(); + + for (Setting system : androidSystemSettingList) { + if (CMSettings.System.isLegacySetting(system.getKey())) { + defaultSettings.add(system); + } + } + + for (Setting secure : androidSecureSettingList) { + if (CMSettings.Secure.isLegacySetting(secure.getKey())) { + defaultSettings.add(secure); + } + } + + for (Setting global : androidGlobalSettingList) { + if (CMSettings.Global.isLegacySetting(global.getKey())) { + defaultSettings.add(global); + } + } + + Writer out = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(rootFile), + Charset.forName("US-ASCII"))); + + out.write("# Settings which are to be moved to CMSettings\n"); + out.write("# Automatically generated by " + + "vendor/cmsdk/host/migration/src/GenerateExampleSettings" + + GenerateExampleSettings.class.getSimpleName() + ".java.\n"); + // Write settings to file for output. + for (int i = 0; i < defaultSettings.size(); i++) { + Setting defaultSetting = defaultSettings.get(i); + // This is the same format as what is spit out by system/bin/content + out.write("Row: " + i + " name=" + defaultSetting.getKey() + + ", type=" + defaultSetting.getKeyType() + + ", value=" + defaultSetting.getValue() + + ", type=" + defaultSetting.getValueType() + "\n"); + } + out.close(); + + System.out.println("Settings written: " + rootFile.toString()); + } +} diff --git a/host/migration/src/InsertCommand.java b/host/migration/src/InsertCommand.java new file mode 100644 index 0000000..0e43557 --- /dev/null +++ b/host/migration/src/InsertCommand.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +/** + * Essentially: + * adb shell content insert --uri content://settings/secure + * --bind name:s:new_setting --bind value:s:new_value + */ +public class InsertCommand extends Command { + private static final String[] INSERT_SETTINGS = { + "adb", "shell", "content", "insert", "--uri" }; + + private String targetUri; + private Setting targetSetting; + + public InsertCommand(String targetUri, Setting targetSetting) { + this.targetUri = targetUri; + this.targetSetting = targetSetting; + } + + @Override + public void run() { + System.out.println("\nWriting setting " + targetSetting.getKey() + " for authority " + + getAuthority() + " for target uri " + targetUri + "..."); + insert(targetUri, targetSetting); + synchronized (this) { + notifyAll(); + } + } + + private void insert(String uri, Setting setting) { + String[] commands = INSERT_SETTINGS; + List commandList = new ArrayList( + INSERT_SETTINGS.length + 1); + commandList.addAll(Arrays.asList(commands)); + commandList.add(SettingsConstants.CONTENT_URI + getAuthority() + uri); + commandList.add("--bind name:" + setting.getKeyType() + ":" + setting.getKey()); + commandList.add("--bind value:" + setting.getValueType() + ":" + + "\"" + setting.getValue() + "\""); + commands = commandList.toArray(new String[commandList.size()]); + if (MigrationTest.DEBUG) { + System.out.println("Using commands: " + Arrays.toString(commands)); + } + try { + final Process process = Runtime.getRuntime().exec(commands); + final InputStream err = process.getErrorStream(); + + // Send error output to stderr. + Thread errThread = new Thread() { + @Override + public void run() { + copy(err, System.err); + } + }; + errThread.setDaemon(true); + errThread.start(); + + BufferedReader in = new BufferedReader( + new InputStreamReader(process.getInputStream())); + String rx = in.readLine(); + if (rx != null) { + if (MigrationTest.DEBUG) { + System.out.println("Received response " + rx); + } + } + in.close(); + err.close(); + process.destroy(); + } catch (IOException e) { + System.err.println("Error "); + e.printStackTrace(); + } + } +} diff --git a/host/migration/src/MigrationTest.java b/host/migration/src/MigrationTest.java new file mode 100644 index 0000000..0949d09 --- /dev/null +++ b/host/migration/src/MigrationTest.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; + +/** + * A verbose settings migration test + */ +class MigrationTest { + private static final String ARGUMENT_SETTINGS = "--settings"; + private static final String ARGUMENT_BOOT_IMG = "--bootimg"; + private static final String ARGUMENT_SYSTEM_IMG = "--systemimg"; + private static final String ARGUMENT_PREFIX = "--"; + + public static final boolean DEBUG = true; + + private static ArrayList cmSystemSettingList = new ArrayList(); + private static ArrayList cmSecureSettingList = new ArrayList(); + private static ArrayList cmGlobalSettingList = new ArrayList(); + + private static ArrayList legacySystemSettings = new ArrayList(); + private static ArrayList legacySecureSettings = new ArrayList(); + private static ArrayList legacyGlobalSettings = new ArrayList(); + + private static Tokenizer tokenizer; + + public static void main(String[] args) throws IOException { + if (args.length < 1) { + showUsage(); + System.exit(-1); + } + tokenizer = new Tokenizer(args); + + String settingFileName = null; + String bootImage = null; + String systemImage = null; + for (String argument; (argument = tokenizer.nextArg())!= null;) { + if (ARGUMENT_SETTINGS.equals(argument)) { + settingFileName = argumentValueRequired(argument); + } else if (ARGUMENT_BOOT_IMG.equals(argument)) { + bootImage = argumentValueRequired(argument); + } else if (ARGUMENT_SYSTEM_IMG.equals(argument)) { + systemImage = argumentValueRequired(argument); + } + } + + if (!new File(settingFileName).exists()) { + System.err.print("Invalid file provided " + settingFileName); + System.exit(-1); + } + + SettingImageCommands legacySettings = + new SettingImageCommands(SettingsConstants.SETTINGS_AUTHORITY); + legacySettings.addRead(settingFileName, SettingsConstants.SYSTEM, legacySystemSettings); + legacySettings.addRead(settingFileName, SettingsConstants.SECURE, legacySecureSettings); + legacySettings.addRead(settingFileName, SettingsConstants.GLOBAL, legacyGlobalSettings); + + //Read settings + legacySettings.execute(); + + SettingImageCommands legacyToCMSettings = + new SettingImageCommands(SettingsConstants.SETTINGS_AUTHORITY); + //For each example setting in the table, add inserts + for (Setting setting : legacySystemSettings) { + legacyToCMSettings.addInsert(SettingsConstants.SYSTEM, setting); + } + for (Setting setting : legacySecureSettings) { + legacyToCMSettings.addInsert(SettingsConstants.SECURE, setting); + } + for (Setting setting : legacyGlobalSettings) { + legacyToCMSettings.addInsert(SettingsConstants.GLOBAL, setting); + } + //Write them to the database for verification later + legacyToCMSettings.execute(); + + //Force update + SettingImageCommands updateRom = new SettingImageCommands(null); + updateRom.addFastboot(FastbootCommand.Types.ADB_REBOOT_BOOTLOADER, null); + updateRom.addFastboot(FastbootCommand.Types.FASTBOOT_DEVICES, null); + updateRom.addFastboot(FastbootCommand.Types.FASTBOOT_FLASH, + new String[]{"boot", bootImage}); + updateRom.addFastboot(FastbootCommand.Types.FASTBOOT_FLASH, + new String[]{"system", systemImage}); + updateRom.addFastboot(FastbootCommand.Types.FASTBOOT_REBOOT, null); + updateRom.execute(); + + //Requery + SettingImageCommands cmSettingImage = + new SettingImageCommands(SettingsConstants.CMSETTINGS_AUTHORITY); + cmSettingImage.addQuery(SettingsConstants.SYSTEM, cmSystemSettingList); + cmSettingImage.addQuery(SettingsConstants.SECURE, cmSecureSettingList); + cmSettingImage.addQuery(SettingsConstants.GLOBAL, cmGlobalSettingList); + cmSettingImage.execute(); + + //Validate + System.out.println("\n\nValidating " + SettingsConstants.SYSTEM + "..."); + validate(legacySystemSettings, cmSystemSettingList); + System.out.println("\n\nValidating " + SettingsConstants.SECURE + "..."); + validate(legacySecureSettings, cmSecureSettingList); + System.out.println("\n\nValidating " + SettingsConstants.GLOBAL + "..."); + validate(legacyGlobalSettings, cmGlobalSettingList); + System.exit(0); + } + + private static void showUsage() { + System.err.println("Usage: MigrationTest --settings [example setting file] " + + "--bootimg [image]" + + "--systemimg [image]"); + } + + private static class Tokenizer { + private final String[] mArgs; + private int mNextArg; + + public Tokenizer(String[] args) { + mArgs = args; + } + + private String nextArg() { + if (mNextArg < mArgs.length) { + return mArgs[mNextArg++]; + } else { + return null; + } + } + } + + private static String argumentValueRequired(String argument) { + String value = tokenizer.nextArg(); + if (value == null || value.length() == 0 || value.startsWith(ARGUMENT_PREFIX)) { + throw new IllegalArgumentException("No value for argument: " + argument); + } + return value; + } + + private static void validate(ArrayList legacySettings, ArrayList cmSettings) { + Collections.sort(legacySettings); + Collections.sort(cmSettings); + + if (legacySettings.size() != cmSettings.size()) { + System.err.println("Warning: Size mismatch: " + " legacy " + + legacySettings.size() + " cm " + cmSettings.size()); + } + + for (int i = 0; i < legacySettings.size(); i++) { + Setting legacySetting = legacySettings.get(i); + Setting cmSetting = cmSettings.get(i); + int error = 0; + + System.out.println("Comparing: legacy " + legacySetting.getKey() + " and cmsetting " + + cmSetting.getKey()); + + if (!legacySetting.getKey().equals(cmSetting.getKey())) { + System.err.println(" Key mismatch: " + legacySetting.getKey() + " and " + + cmSetting.getKey()); + error = 1; + } + if (!legacySetting.getKeyType().equals(cmSetting.getKeyType())) { + System.err.println(" Key type mismatch: " + legacySetting.getKeyType() + " and " + + cmSetting.getKeyType()); + error = 1; + } + if (legacySetting.getValue().length() > 0) { + if (!legacySetting.getValue().equals(cmSetting.getValue())) { + System.err.println(" Value mismatch: " + legacySetting.getValue() + " and " + + cmSetting.getValue()); + error = 1; + } + } + if (!legacySetting.getValueType().equals(cmSetting.getValueType())) { + System.err.println(" Value type mismatch: " + legacySetting.getValueType() + + " and " + cmSetting.getValueType()); + error = 1; + } + + if (error > 0) { + System.exit(-1); + } else { + System.out.println("...OK"); + } + } + } +} \ No newline at end of file diff --git a/host/migration/src/QueryCommand.java b/host/migration/src/QueryCommand.java new file mode 100644 index 0000000..c25779a --- /dev/null +++ b/host/migration/src/QueryCommand.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Essentially: + * adb shell content query --uri content://settings/secure --projection name:value + * --where \"name=\'new_setting\'\" --sort \"name ASC\"\n" + */ +public class QueryCommand extends Command { + private static final String[] QUERY_SETTINGS = { + "adb", "shell", "content", "query", "--uri" }; + private static final String PROJECTION = "name:value"; + + private ArrayList targetList; + private String targetUri; + + protected QueryCommand(String targetUri, + ArrayList targetList) { + this.targetUri = targetUri; + this.targetList = targetList; + } + + @Override + public void run() { + System.out.println("\nQuerying settings for authority " + + getAuthority() + " for target uri " + targetUri + "..."); + query(targetUri, targetList); + synchronized (this) { + notifyAll(); + } + } + + private void query(String uri, ArrayList arrayList) { + String[] commands = QUERY_SETTINGS; + List commandList = new ArrayList( + QUERY_SETTINGS.length + 1); + commandList.addAll(Arrays.asList(commands)); + commandList.add(SettingsConstants.CONTENT_URI + getAuthority() + uri); + commandList.add("--projection"); + commandList.add(PROJECTION); + commandList.add("--show-type"); //this is totally awesomely cm specific + commandList.add("true"); + commands = commandList.toArray(new String[commandList.size()]); + if (MigrationTest.DEBUG) { + System.out.println("Using commands: " + Arrays.toString(commands)); + } + + try { + final Process process = Runtime.getRuntime().exec(commands); + final InputStream err = process.getErrorStream(); + + // Send error output to stderr. + Thread errThread = new Thread() { + @Override + public void run() { + copy(err, System.err); + } + }; + errThread.setDaemon(true); + errThread.start(); + + BufferedReader in = new BufferedReader( + new InputStreamReader(process.getInputStream())); + + String line; + while ((line = in.readLine()) != null) { + if (!line.startsWith("Row: ")) { + throw new IOException("Unable to read settings"); + } + if (MigrationTest.DEBUG) { + System.out.println("LINE: " + line); + } + Setting setting = RowParser.parseAndPopulate(true, line); + if (filter(uri, setting)) { + continue; + } + arrayList.add(setting); + } + in.close(); + err.close(); + process.destroy(); + } catch (IOException e) { + System.err.println("Error "); + e.printStackTrace(); + } + } +} diff --git a/host/migration/src/ReadCommand.java b/host/migration/src/ReadCommand.java new file mode 100644 index 0000000..631abdd --- /dev/null +++ b/host/migration/src/ReadCommand.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; + +/** + * Created by adnan on 11/17/15. + */ +public class ReadCommand extends Command { + private String targetFile; + private ArrayList targetList; + private String targetUri; + + protected ReadCommand(String targetFile, String targetUri, ArrayList targetList) { + this.targetFile = targetFile; + this.targetUri = targetUri; + this.targetList = targetList; + } + + @Override + public void run() { + System.out.println("\nReading settings for authority " + + getAuthority() + " for target uri " + targetUri + " from file " + + targetFile +"..."); + read(targetFile, targetUri, targetList); + synchronized (this) { + notifyAll(); + } + } + + private void read(String fileName, String uri, ArrayList arrayList) { + try { + BufferedReader in = new BufferedReader( + new FileReader(fileName)); + String line; + //Skip first two lines of header + for (int i = 0; i < 2; i++) { + in.readLine(); + } + while ((line = in.readLine()) != null) { + if (!line.startsWith("Row: ")) { + throw new IOException("Unable to read settings"); + } + if (MigrationTest.DEBUG) { + System.out.println("LINE: " + line); + } + Setting setting = RowParser.parseAndPopulate(false, line); + //Sanitize + if (filter(uri, setting)) { + continue; + } + arrayList.add(setting); + } + in.close(); + } catch (IOException e) { + System.err.println("Error "); + e.printStackTrace(); + } + } +} diff --git a/host/migration/src/RowParser.java b/host/migration/src/RowParser.java new file mode 100644 index 0000000..e1c0de7 --- /dev/null +++ b/host/migration/src/RowParser.java @@ -0,0 +1,50 @@ +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by adnan on 11/17/15. + */ +public class RowParser { + private static final String REGEX = "=(.+)"; + private static Pattern p = Pattern.compile(REGEX); + + public static Setting parseAndPopulate(boolean fromCursor, String line) { + Setting setting = new Setting(); + String[] splitStrings = line.split(","); + for (int i = 0; i < 4; i++) { + Matcher matcher = p.matcher(splitStrings[i]); + while (matcher.find()) { + String value = matcher.group(0).replace("=", "").trim(); + switch (i) { + case 0: + setting.setKey(value); + break; + case 1: + //Seriously? + if (fromCursor) { + setting.setKeyType( + Setting.SettingType.mapNumericToType( + Integer.parseInt(value))); + } else { + setting.setKeyType(value); + } + break; + case 2: + setting.setValue(value); + break; + case 3: + //Who the fuck decided to do this? + if (fromCursor) { + setting.setValueType( + Setting.SettingType.mapNumericToType( + Integer.parseInt(value))); + } else { + setting.setValueType(value); + } + break; + } + } + } + return setting; + } +} diff --git a/host/migration/src/Setting.java b/host/migration/src/Setting.java new file mode 100644 index 0000000..d326738 --- /dev/null +++ b/host/migration/src/Setting.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.Serializable; + +/** + * A simple concept of a "setting" within the provider + */ +public class Setting implements Serializable, Comparable { + private static final long serialVersionUID = 0; + + private String key; + private String value; + private String keyType; + private String valueType; + + public Setting() { + this.keyType = SettingType.TYPE_NULL; + this.valueType = SettingType.TYPE_NULL; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getKeyType() { + return keyType; + } + + public void setKeyType(String type) { + this.keyType = type; + } + + public String getValueType() { + return valueType; + } + + public void setValueType(String valueType) { + this.valueType = valueType; + } + + /** s - string, i - integer, f - float */ + public static class SettingType { + private static final String TYPE_NULL = "NULL"; + private static final String TYPE_STRING = "s"; + private static final String TYPE_INTEGER = "i"; + private static final String TYPE_FLOAT = "f"; + private static final String TYPE_BLOB = "d"; + + //THIS IS FROM CURSOR.JAVA, DO NOT MODIFY + /** Value returned by {@link #getType(int)} if the specified column is null */ + static final int FIELD_TYPE_NULL = 0; + /** Value returned by {@link #getType(int)} if the specified column type is integer */ + static final int FIELD_TYPE_INTEGER = 1; + /** Value returned by {@link #getType(int)} if the specified column type is float */ + static final int FIELD_TYPE_FLOAT = 2; + /** Value returned by {@link #getType(int)} if the specified column type is string */ + static final int FIELD_TYPE_STRING = 3; + /** Value returned by {@link #getType(int)} if the specified column type is blob */ + static final int FIELD_TYPE_BLOB = 4; + + + public static String mapNumericToType(int numeric) { + switch (numeric) { + case FIELD_TYPE_NULL: + return TYPE_NULL; + case FIELD_TYPE_STRING: + return TYPE_STRING; + case FIELD_TYPE_INTEGER: + return TYPE_INTEGER; + case FIELD_TYPE_FLOAT: + return TYPE_FLOAT; + case FIELD_TYPE_BLOB: + return TYPE_BLOB; + default: + return TYPE_NULL; + } + } + } + + @Override + public int compareTo(Setting o) { + return this.key.compareTo(o.getKey()); + } +} diff --git a/host/migration/src/SettingImageCommands.java b/host/migration/src/SettingImageCommands.java new file mode 100644 index 0000000..0598e83 --- /dev/null +++ b/host/migration/src/SettingImageCommands.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.ArrayList; + +/** + * Created by adnan on 11/16/15. + */ +public class SettingImageCommands implements CommandExecutor { + private ArrayList commandHistory = new ArrayList(); + private String authority; + + public SettingImageCommands(String authority) { + this.authority = authority; + } + + @Override + public void execute() { + for (Command commandWithTimeout : commandHistory) { + commandWithTimeout.run(); + } + } + + private void addCommand(Command commandWithTimeout) { + commandWithTimeout.prepend(authority); + commandHistory.add(commandWithTimeout); + } + + public void addQuery(String uri, ArrayList settings) { + QueryCommand queryCommand = new QueryCommand(uri, settings); + addCommand(queryCommand); + } + + public void addInsert(String uri, Setting setting) { + InsertCommand insertCommand = new InsertCommand(uri, setting); + addCommand(insertCommand); + } + + public void addRead(String fileName, String uri, ArrayList settings) { + ReadCommand readCommand = new ReadCommand(fileName, uri, settings); + addCommand(readCommand); + } + + public void addFastboot(int command, String[] arguments) { + FastbootCommand fastbootCommand = new FastbootCommand(command, arguments); + addCommand(fastbootCommand); + } +} diff --git a/host/migration/src/SettingsConstants.java b/host/migration/src/SettingsConstants.java new file mode 100644 index 0000000..3868467 --- /dev/null +++ b/host/migration/src/SettingsConstants.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.ArrayList; + +/** + * Created by adnan on 11/16/15. + */ +public class SettingsConstants { + public static final String CMSETTINGS_AUTHORITY = "cmsettings"; + public static final String SETTINGS_AUTHORITY = "settings"; + public static final String CONTENT_URI = "content://"; + public static final String SYSTEM = "/system"; + public static final String SECURE = "/secure"; + public static final String GLOBAL = "/global"; + + public static class Ignorables { + public static ArrayList SECURE_SETTINGS = new ArrayList(); + + static { + SECURE_SETTINGS.add(CMSettings.Secure.ADB_PORT); + } + } +}