system/corennnnn
Revision | a3bf41eb069a63c3d087f45f6f945db2535528c8 (tree) |
---|---|
Time | 2016-12-09 16:22:10 |
Author | Ma Jian <majian@jide...> |
Commiter | Chih-Wei Huang |
Support use local time for RTC
When default timezone isn't UTC, there will no persist.sys.timezone
under /data/property/, so init won't get the default timezone for
setting time from rtc.
This change adds a fallback to read the property when the persist file
does not exists.
Notice, the default property of persist.sys.timezone should be set in
/default.prop instead of /system/build.prop
NO_REF_TASK
Tested: set default timezone with Asia/Shanghai, make sure bios time
is correct in local time, reboot to android, the local time should
be correct.
Change-Id: Ifbd20cb3710f833ab65852b4e5d51e38cc7c2d79
@@ -785,13 +785,96 @@ static int do_rmdir(const std::vector<std::string>& args) { | ||
785 | 785 | return rmdir(args[1].c_str()); |
786 | 786 | } |
787 | 787 | |
788 | +// read persist property from /data/property directly, because it maybe has not loaded | |
789 | +// if the file not found, try to call property_get, the default value could be saved | |
790 | +// into /default.prop | |
791 | +static std::string persist_property_get(const char *name) | |
792 | +{ | |
793 | + const char *filename_template = "/data/property/%s"; | |
794 | + size_t max_file_name_len = strlen(filename_template) + PROP_NAME_MAX; | |
795 | + char filename[max_file_name_len]; | |
796 | + snprintf(filename, max_file_name_len, filename_template, name); | |
797 | + | |
798 | + if (access(filename, 0) == 0) { | |
799 | + char *line = NULL; | |
800 | + size_t len; | |
801 | + FILE *fp = fopen(filename, "r+"); | |
802 | + if (fp == NULL) { | |
803 | + ERROR("failed to read file for property:%s\n", filename); | |
804 | + return 0; | |
805 | + } | |
806 | + | |
807 | + std::string result; | |
808 | + if (getline(&line, &len, fp) == -1) { | |
809 | + len = 0; | |
810 | + } else { | |
811 | + for (len = 0; *(line+len) != '\n' && *(line+len) != 0; len++); | |
812 | + *(line + len) = '\0'; | |
813 | + result = line; | |
814 | + free(line); | |
815 | + } | |
816 | + fclose(fp); | |
817 | + return result; | |
818 | + } | |
819 | + | |
820 | + return property_get(name); | |
821 | +} | |
822 | + | |
788 | 823 | static int do_sysclktz(const std::vector<std::string>& args) { |
789 | 824 | struct timezone tz; |
825 | + struct timeval tv; | |
826 | + struct tm tm; | |
827 | + time_t t; | |
790 | 828 | |
791 | 829 | memset(&tz, 0, sizeof(tz)); |
792 | - tz.tz_minuteswest = std::stoi(args[1]); | |
793 | - if (settimeofday(NULL, &tz)) | |
830 | + memset(&tv, 0, sizeof(tv)); | |
831 | + memset(&tm, 0, sizeof(tm)); | |
832 | + | |
833 | + INFO("sysclktz: the arg %s is ignored, only persist.rtc_local_time matters\n", args[1].c_str()); | |
834 | + | |
835 | + if (gettimeofday(&tv, NULL)) { | |
836 | + ERROR("sysclktz: failed to call gettimeofday"); | |
794 | 837 | return -1; |
838 | + } | |
839 | + | |
840 | + if (persist_property_get("persist.rtc_local_time") == "1") { | |
841 | + /* Notify kernel that hwtime use local time */ | |
842 | + write_file("/sys/class/misc/alarm/rtc_local_time", "1"); | |
843 | + /* | |
844 | + * If ro.hwtime.mode is local, set system time | |
845 | + * and saved system zone in case of network not | |
846 | + * available and auto syncing time not available. | |
847 | + */ | |
848 | + | |
849 | + std::string time_zone = persist_property_get("persist.sys.timezone"); | |
850 | + if (time_zone.empty()) { | |
851 | + INFO("sysclktz: persist.sys.timezone not found\n"); | |
852 | + tz.tz_minuteswest = 0; | |
853 | + } else { | |
854 | + const char *timezone_prop = time_zone.c_str(); | |
855 | + INFO("sysclktz: persist.sys.timezone: %s\n", timezone_prop); | |
856 | + // localtime_r need the property, we need to set it | |
857 | + property_set("persist.sys.timezone", timezone_prop); | |
858 | + t = tv.tv_sec; | |
859 | + localtime_r(&t, &tm); | |
860 | + tz.tz_minuteswest = -(tm.tm_gmtoff / 60); | |
861 | + INFO("sysclktz: tz.tz_minuteswest: %d\n", tz.tz_minuteswest); | |
862 | + } | |
863 | + | |
864 | + /* | |
865 | + * At this moment, system time should be local | |
866 | + * time too, set it back to utc which linux required. | |
867 | + */ | |
868 | + tv.tv_sec += tz.tz_minuteswest * 60; | |
869 | + if (settimeofday(&tv, &tz)) { | |
870 | + ERROR("sysclktz: failed to call settimeofdays\n"); | |
871 | + return -1; | |
872 | + } | |
873 | + } else { | |
874 | + tz.tz_minuteswest = std::stoi(args[1]); | |
875 | + return settimeofday(NULL, &tz); | |
876 | + } | |
877 | + | |
795 | 878 | return 0; |
796 | 879 | } |
797 | 880 |