system/corennnnn
Revision | ab3b02614d73d00e5d9af0fdc294a3158fee398d (tree) |
---|---|
Zeit | 2016-11-09 00:56:25 |
Autor | 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
@@ -737,13 +737,96 @@ static int do_rmdir(const std::vector<std::string>& args) { | ||
737 | 737 | return rmdir(args[1].c_str()); |
738 | 738 | } |
739 | 739 | |
740 | +// read persist property from /data/property directly, because it maybe has not loaded | |
741 | +// if the file not found, try to call property_get, the default value could be saved | |
742 | +// into /default.prop | |
743 | +static std::string persist_property_get(const char *name) | |
744 | +{ | |
745 | + const char *filename_template = "/data/property/%s"; | |
746 | + size_t max_file_name_len = strlen(filename_template) + PROP_NAME_MAX; | |
747 | + char filename[max_file_name_len]; | |
748 | + snprintf(filename, max_file_name_len, filename_template, name); | |
749 | + | |
750 | + if (access(filename, 0) == 0) { | |
751 | + char *line = NULL; | |
752 | + size_t len; | |
753 | + FILE *fp = fopen(filename, "r+"); | |
754 | + if (fp == NULL) { | |
755 | + ERROR("failed to read file for property:%s\n", filename); | |
756 | + return 0; | |
757 | + } | |
758 | + | |
759 | + std::string result; | |
760 | + if (getline(&line, &len, fp) == -1) { | |
761 | + len = 0; | |
762 | + } else { | |
763 | + for (len = 0; *(line+len) != '\n' && *(line+len) != 0; len++); | |
764 | + *(line + len) = '\0'; | |
765 | + result = line; | |
766 | + free(line); | |
767 | + } | |
768 | + fclose(fp); | |
769 | + return result; | |
770 | + } | |
771 | + | |
772 | + return property_get(name); | |
773 | +} | |
774 | + | |
740 | 775 | static int do_sysclktz(const std::vector<std::string>& args) { |
741 | 776 | struct timezone tz; |
777 | + struct timeval tv; | |
778 | + struct tm tm; | |
779 | + time_t t; | |
742 | 780 | |
743 | 781 | memset(&tz, 0, sizeof(tz)); |
744 | - tz.tz_minuteswest = std::stoi(args[1]); | |
745 | - if (settimeofday(NULL, &tz)) | |
782 | + memset(&tv, 0, sizeof(tv)); | |
783 | + memset(&tm, 0, sizeof(tm)); | |
784 | + | |
785 | + INFO("sysclktz: the arg %s is ignored, only persist.rtc_local_time matters\n", args[1].c_str()); | |
786 | + | |
787 | + if (gettimeofday(&tv, NULL)) { | |
788 | + ERROR("sysclktz: failed to call gettimeofday"); | |
746 | 789 | return -1; |
790 | + } | |
791 | + | |
792 | + if (persist_property_get("persist.rtc_local_time") == "1") { | |
793 | + /* Notify kernel that hwtime use local time */ | |
794 | + write_file("/sys/class/misc/alarm/rtc_local_time", "1"); | |
795 | + /* | |
796 | + * If ro.hwtime.mode is local, set system time | |
797 | + * and saved system zone in case of network not | |
798 | + * available and auto syncing time not available. | |
799 | + */ | |
800 | + | |
801 | + std::string time_zone = persist_property_get("persist.sys.timezone"); | |
802 | + if (time_zone.empty()) { | |
803 | + INFO("sysclktz: persist.sys.timezone not found\n"); | |
804 | + tz.tz_minuteswest = 0; | |
805 | + } else { | |
806 | + const char *timezone_prop = time_zone.c_str(); | |
807 | + INFO("sysclktz: persist.sys.timezone: %s\n", timezone_prop); | |
808 | + // localtime_r need the property, we need to set it | |
809 | + property_set("persist.sys.timezone", timezone_prop); | |
810 | + t = tv.tv_sec; | |
811 | + localtime_r(&t, &tm); | |
812 | + tz.tz_minuteswest = -(tm.tm_gmtoff / 60); | |
813 | + INFO("sysclktz: tz.tz_minuteswest: %d\n", tz.tz_minuteswest); | |
814 | + } | |
815 | + | |
816 | + /* | |
817 | + * At this moment, system time should be local | |
818 | + * time too, set it back to utc which linux required. | |
819 | + */ | |
820 | + tv.tv_sec += tz.tz_minuteswest * 60; | |
821 | + if (settimeofday(&tv, &tz)) { | |
822 | + ERROR("sysclktz: failed to call settimeofdays\n"); | |
823 | + return -1; | |
824 | + } | |
825 | + } else { | |
826 | + tz.tz_minuteswest = std::stoi(args[1]); | |
827 | + return settimeofday(NULL, &tz); | |
828 | + } | |
829 | + | |
747 | 830 | return 0; |
748 | 831 | } |
749 | 832 |