Home
last modified time | relevance | path

Searched refs:LOG (Results 1 – 25 of 48) sorted by relevance

12

/bootable/recovery/update_verifier/
Dupdate_verifier.cpp101 LOG(ERROR) << "No dm block device found."; in FindDmPartitions()
175 LOG(INFO) << "Finished reading " << block_count << " blocks on " << dm_block_device; in ReadBlocks()
186 LOG(INFO) << "Finished reading blocks on " << dm_block_device << " with " << thread_num in ReadBlocks()
194 LOG(ERROR) << "No dm-enabled block device is found."; in VerifyPartitions()
200 LOG(ERROR) << "Failed to find dm block device for " << partition_name; in VerifyPartitions()
217 LOG(ERROR) << care_map_name << " doesn't exist"; in ParseCareMap()
237 LOG(WARNING) << "Unexpected empty care map"; in ParseCareMap()
243 LOG(WARNING) << "Failed to parse " << care_map_name << " in protobuf format."; in ParseCareMap()
249 LOG(WARNING) << "Unexpected empty partition name."; in ParseCareMap()
253 LOG(WARNING) << "Unexpected block ranges for partition " << partition.name(); in ParseCareMap()
[all …]
/bootable/recovery/install/
Dverifier.cpp129 LOG(ERROR) << "not big enough to contain footer"; in verify_file()
135 LOG(ERROR) << "Failed to read footer"; in verify_file()
140 LOG(ERROR) << "footer is wrong"; in verify_file()
146 LOG(INFO) << "comment is " << comment_size << " bytes; signature is " << signature_start in verify_file()
150 LOG(ERROR) << "signature start: " << signature_start in verify_file()
156 LOG(ERROR) << "Signature start is in the footer"; in verify_file()
166 LOG(ERROR) << "not big enough to contain EOCD"; in verify_file()
177 LOG(ERROR) << "Failed to read EOCD of " << eocd_size << " bytes"; in verify_file()
183 LOG(ERROR) << "signature length doesn't match EOCD marker"; in verify_file()
192 LOG(ERROR) << "EOCD marker occurs after start of EOCD"; in verify_file()
[all …]
Dwipe_device.cpp45 LOG(ERROR) << "Failed to get ZipArchiveHandle"; in GetWipePartitionList()
56 LOG(ERROR) << "Failed to extract " << RECOVERY_WIPE_ENTRY_NAME in GetWipePartitionList()
64 LOG(ERROR) << "Failed to extract " << RECOVERY_WIPE_ENTRY_NAME << ": " in GetWipePartitionList()
69 LOG(INFO) << "Failed to find " << RECOVERY_WIPE_ENTRY_NAME in GetWipePartitionList()
107 LOG(INFO) << "Secure-wiping \"" << partition << "\" from " << range[0] << " to " << range[1]; in SecureWipePartition()
109 LOG(INFO) << " Trying BLKSECDISCARD..."; in SecureWipePartition()
116 LOG(INFO) << " Trying BLKDISCARD..."; in SecureWipePartition()
122 LOG(INFO) << " Trying BLKZEROOUT..."; in SecureWipePartition()
130 LOG(INFO) << " Done"; in SecureWipePartition()
136 LOG(ERROR) << "wipe_package_size is zero"; in ReadWipePackage()
[all …]
Dinstall.cpp83 LOG(ERROR) << "Failed to find " << METADATA_PATH; in ReadMetadataFromPackage()
92 LOG(ERROR) << "Failed to extract " << METADATA_PATH << ": " << ErrorCodeString(err); in ReadMetadataFromPackage()
151 LOG(ERROR) << "Package is for source build " << pkg_pre_build << " but expected " in CheckAbSpecificMetadata()
160 LOG(ERROR) << "Package is for source build " << pkg_pre_build_fingerprint << " but expected " in CheckAbSpecificMetadata()
176 LOG(ERROR) << "Update package is older than the current build, expected a build " in CheckAbSpecificMetadata()
183 LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed."; in CheckAbSpecificMetadata()
195 LOG(INFO) << "Skip package metadata check for ota type " << expected_ota_type; in CheckPackageMetadata()
200 LOG(ERROR) << "Unexpected ota package type, expects " << expected_ota_type << ", actual " in CheckPackageMetadata()
209 LOG(ERROR) << "Package is for product " << pkg_device << " but expected " << device; in CheckPackageMetadata()
226 LOG(ERROR) << "Package is for serial " << pkg_serial_no; in CheckPackageMetadata()
[all …]
Dspl_check.cpp23 LOG(WARNING) << "Failed to get device's current security patch level. Target SPL is " in ViolatesSPLDowngrade()
33 LOG(ERROR) << "Current SPL: " << current_spl << " Target SPL: " << post_spl in ViolatesSPLDowngrade()
36 LOG(WARNING) in ViolatesSPLDowngrade()
44 LOG(INFO) << "old spl: " << current_spl << " new spl: " << post_spl << " CHECK passes"; in ViolatesSPLDowngrade()
53 LOG(WARNING) << "Failed to find " << OTA_OTA_METADATA in ViolatesSPLDowngrade()
60 LOG(ERROR) << "Failed to extract " << OTA_OTA_METADATA in ViolatesSPLDowngrade()
68 LOG(ERROR) << "Failed to extract " << OTA_OTA_METADATA << ": " << ErrorCodeString(err); in ViolatesSPLDowngrade()
74 LOG(ERROR) << "Failed to parse ota_medata"; in ViolatesSPLDowngrade()
Dadb_install.cpp65 LOG(ERROR) << "Failed to parse command in message " << message; in ParseMinadbdCommand()
72 LOG(ERROR) << "Unsupported command code: " << cmd_code; in ParseMinadbdCommand()
170 LOG(ERROR) << "Unsupported command: " in HandleMessageFromMinadbd()
179 LOG(INFO) << "Command " << static_cast<uint32_t>(command_type) << " finished with " << result; in HandleMessageFromMinadbd()
226 LOG(ERROR) << "Timeout waiting for messages from minadbd"; in ListenAndExecuteMinadbdCommands()
233 LOG(INFO) << "Socket has been closed"; in ListenAndExecuteMinadbdCommands()
315 LOG(ERROR) << "Failed to set usb config to sideload"; in CreateMinadbdServiceAndExecuteCommands()
329 LOG(ERROR) << "\nYou need adb 1.0.32 or newer to sideload\nto this device.\n"; in CreateMinadbdServiceAndExecuteCommands()
331 LOG(ERROR) << "\n(adbd status " << WEXITSTATUS(status) << ")"; in CreateMinadbdServiceAndExecuteCommands()
343 LOG(ERROR) << "Failed to clear USB config"; in ApplyFromAdb()
[all …]
/bootable/recovery/applypatch/
Dapplypatch.cpp74 LOG(ERROR) << "Failed to parse target hash \"" << partition.hash << "\""; in ReadPartitionToBuffer()
96 LOG(ERROR) << "Partition contents don't have the expected checksum"; in ReadPartitionToBuffer()
105 LOG(ERROR) << "Both of partition contents and backup don't have the expected checksum"; in ReadPartitionToBuffer()
179 LOG(INFO) << " caches dropped"; in WriteBufferToPartition()
203 LOG(ERROR) << "Verification failed starting at " << p; in WriteBufferToPartition()
210 LOG(INFO) << "Verification read succeeded (attempt " << attempt + 1 << ")"; in WriteBufferToPartition()
222 LOG(ERROR) << "Failed to verify after all attempts"; in WriteBufferToPartition()
270 LOG(INFO) << "Patching " << target.name; in PatchPartition()
277 LOG(INFO) << " already " << target.hash.substr(0, 8); in PatchPartition()
286 LOG(ERROR) << "Failed to find any match"; in PatchPartition()
[all …]
Dimgdiff.cpp232 LOG(INFO) << "Removing block " << used_ranges.ToString() << " from " << *start << " - " in RemoveUsedBlocks()
244 LOG(WARNING) << "Failed to remove the overlapped block ranges; skip the source"; in RemoveUsedBlocks()
289 LOG(INFO) << "chunk: " << index << ", type: " << type_ << ", start: " << start_ in Dump()
351 LOG(ERROR) << "bsdiff() failed: " << r; in MakePatch()
382 LOG(ERROR) << "Attempted to reconstruct non-deflate chunk"; in ReconstructDeflateChunk()
412 LOG(ERROR) << "Failed to initialize deflate: " << ret; in TryReconstruction()
423 LOG(ERROR) << "Failed to deflate: " << ret; in TryReconstruction()
503 LOG(INFO) << android::base::StringPrintf("chunk %zu: normal (%10zu, %10zu) %10zu", index, in WriteHeaderToFd()
510 LOG(INFO) << android::base::StringPrintf("chunk %zu: deflate (%10zu, %10zu) %10zu", index, in WriteHeaderToFd()
524 LOG(INFO) << android::base::StringPrintf("chunk %zu: raw (%10zu, %10zu)", index, in WriteHeaderToFd()
[all …]
Dfreecache.cpp71 LOG(INFO) << link << " is open by " << de->d_name; in EliminateOpenFiles()
111 LOG(INFO) << files.size() << " regular files in deletable directory"; in FindExpendableFiles()
147 LOG(ERROR) << "Invalid block size or overflow (sf.f_bsize " << sf.f_bsize << ", sf.f_bavail " in FreeSpaceForFile()
157 LOG(WARNING) << "Skipped making (" << bytes in CheckAndFreeSpaceOnCache()
177 LOG(ERROR) << "Invalid arg of bytes_needed: " << bytes_needed; in RemoveFilesInDirectory()
187 LOG(ERROR) << dirname << " is not a directory"; in RemoveFilesInDirectory()
193 LOG(ERROR) << "Failed to check free space for " << dirname; in RemoveFilesInDirectory()
196 LOG(INFO) << free_now << " bytes free on " << dirname << " (" << bytes_needed << " needed)"; in RemoveFilesInDirectory()
237 LOG(ERROR) << "Failed to check free space for " << dirname; in RemoveFilesInDirectory()
240 LOG(INFO) << "Deleted " << file << "; now " << free_now << " bytes free"; in RemoveFilesInDirectory()
Dimgpatch.cpp72 LOG(ERROR) << "Failed to init uncompressed data deflation: " << ret; in ApplyBSDiffPatchAndStreamOutput()
96 LOG(ERROR) << "Failed to deflate stream: " << ret; in ApplyBSDiffPatchAndStreamOutput()
104 LOG(ERROR) << "Failed to write " << have << " compressed bytes to output."; in ApplyBSDiffPatchAndStreamOutput()
121 LOG(ERROR) << "ret is expected to be Z_STREAM_END, but it's " << ret; in ApplyBSDiffPatchAndStreamOutput()
126 LOG(ERROR) << "target length is expected to be " << expected_target_length << ", but it's " in ApplyBSDiffPatchAndStreamOutput()
130 LOG(DEBUG) << "bspatch wrote " << total_written << " bytes in total to streaming output."; in ApplyBSDiffPatchAndStreamOutput()
189 LOG(DEBUG) << "Processed chunk type normal"; in ApplyImagePatch()
210 LOG(DEBUG) << "Processed chunk type raw"; in ApplyImagePatch()
281 LOG(ERROR) << "Fail to apply streaming bspatch."; in ApplyImagePatch()
285 LOG(DEBUG) << "Processed chunk type deflate"; in ApplyImagePatch()
Dapplypatch_modes.cpp42 LOG(ERROR) << "Failed to parse target \"" << target_emmc << "\": " << err; in CheckMode()
52 LOG(ERROR) << "Failed to parse target \"" << target_emmc << "\": " << err; in FlashMode()
63 LOG(ERROR) << "Failed to parse target \"" << target_emmc << "\": " << err; in PatchMode()
69 LOG(ERROR) << "Failed to parse source \"" << source_emmc << "\": " << err; in PatchMode()
165 LOG(ERROR) << "Invalid argument"; in applypatch_modes()
176 LOG(ERROR) << "bonus file not supported in flash mode"; in applypatch_modes()
/bootable/recovery/updater/
Dupdater_runtime_dynamic_partitions.cpp64 LOG(ERROR) << "Unknown device mapper state: " in UnmapPartitionWithSuffixOnDeviceMapper()
91 LOG(ERROR) << "Unknown device mapper state: " in MapPartitionOnDeviceMapper()
110 LOG(ERROR) << "Op " << op() << " expects " << size << " args, got " << actual; in ExpectArgSize()
127 LOG(ERROR) << "Op " << op() << " expects uint64 for argument " << name << ", got " << str; in uint_arg()
145 LOG(ERROR) << "Failed to find partition " << partition_name_suffix in PerformOpResize()
150 LOG(ERROR) << "Cannot unmap " << partition_name_suffix << " before resizing."; in PerformOpResize()
154 LOG(ERROR) << "Failed to resize partition " << partition_name_suffix << " to size " << *size in PerformOpResize()
166 LOG(ERROR) << "Cannot unmap " << partition_name_suffix << " before removing."; in PerformOpRemove()
180 LOG(ERROR) << "Failed to add partition " << partition_name_suffix << " to group " in PerformOpAdd()
194 LOG(ERROR) << "Cannot move partition " << partition_name_suffix << " to group " in PerformOpMove()
[all …]
Dupdater.cpp39 LOG(ERROR) << "Failed to open the command pipe"; in Init()
46 LOG(ERROR) << "failed to map package " << package_filename; in Init()
52 LOG(ERROR) << "failed to open package " << package_filename << ": " in Init()
73 LOG(ERROR) << error_count << " parse errors"; in RunUpdate()
89 LOG(WARNING) << "Skipped executing function " << func; in RunUpdate()
118 LOG(INFO) << message; in UiPrint()
128 LOG(ERROR) << "script aborted (no error message)"; in ParseAndReportErrorCode()
131 LOG(ERROR) << "script aborted: " << state->errmsg; in ParseAndReportErrorCode()
138 LOG(ERROR) << "Failed to parse error code: [" << line << "]"; in ParseAndReportErrorCode()
155 LOG(INFO) << "Patch application failed, retry update."; in ParseAndReportErrorCode()
[all …]
Dblockimg.cpp102 LOG(INFO) << last_command_file << " doesn't exist."; in ParseLastCommandFile()
109 LOG(ERROR) << "Failed to read: " << last_command_file; in ParseLastCommandFile()
115 LOG(ERROR) << "Unexpected line counts in last command file: " << content; in ParseLastCommandFile()
120 LOG(ERROR) << "Failed to parse integer in: " << lines[0]; in ParseLastCommandFile()
191 LOG(INFO) << "Wrote updated marker to " << marker; in SetUpdatedMarker()
255 LOG(ERROR) << "range sink write overrun; can't write " << size << " bytes"; in Write()
382 LOG(ERROR) << "Failed to write " << write_now << " bytes."; in receive_new_data()
423 LOG(ERROR) << "No space left in output range"; in receive_brotli_new_data()
436 LOG(ERROR) << "Decompression failed with " in receive_brotli_new_data()
441 LOG(DEBUG) << "bytes to write: " << buffer_size - available_out << ", bytes consumed " in receive_brotli_new_data()
[all …]
Dtarget_files.cpp43 LOG(ERROR) << "Failed to import the sparse image."; in SimgToImg()
57 LOG(INFO) << "Start parsing build property\n"; in ParsePropertyFile()
65 LOG(INFO) << key << ": " << value; in ParsePropertyFile()
73 LOG(INFO) << "parsing fstab\n"; in ParseFstab()
82 LOG(ERROR) << "Unexpected token size: " << tokens.size() << std::endl in ParseFstab()
91 LOG(WARNING) << "mount point '" << mount_point << "' does not start with '/'"; in ParseFstab()
97 LOG(WARNING) << "Unsupported fs_type in " << line; in ParseFstab()
131 LOG(ERROR) << "failed to find " << name << " in the package: " << ErrorCodeString(find_err); in ReadEntryToString()
141 LOG(ERROR) << "Failed to extract " << name in ReadEntryToString()
151 LOG(ERROR) << "failed to read " << name << " from package: " << ErrorCodeString(extract_err); in ReadEntryToString()
[all …]
Dsimulator_runtime.cpp48 LOG(ERROR) << mount_point << " has been mounted at " << mounted_location->second; in Mount()
75 LOG(INFO) << "Running program with args " << android::base::Join(args, " "); in RunProgram()
80 LOG(INFO) << "Running Tune2Fs with args " << android::base::Join(args, " "); in Tune2Fs()
85 LOG(INFO) << "SKip wiping block device " << filename; in WipeBlockDevice()
95 LOG(INFO) << "SKip reading filename " << filename; in ReadFileToString()
101 LOG(INFO) << "SKip writing " << content.size() << " bytes to file " << filename; in WriteStringToFile()
112 LOG(INFO) << "Skip unmapping " << partition_name; in UnmapPartitionOnDeviceMapper()
127 LOG(ERROR) << "Unknown operation in op_list: " << line; in UpdateDynamicPartitions()
135 LOG(INFO) << "Skip adding slot suffix to " << arg; in AddSlotSuffix()
Dupdater_main.cpp62 LOG(ERROR) << "Failed to run the boringssl self tests"; in main()
67 LOG(ERROR) << "unexpected number of arguments: " << argc; in main()
74 LOG(ERROR) << "wrong updater binary API; expected 1, 2, or 3; got " << argv[1]; in main()
80 LOG(ERROR) << "Failed to parse fd in " << argv[2]; in main()
91 LOG(ERROR) << "unexpected argument: " << argv[4]; in main()
Dbuild_info.cpp49 LOG(WARNING) << "Failed to find the image entry in the target file: " << entry_name; in ParseTargetFile()
56 LOG(ERROR) << "Failed to set up source image files."; in ParseTargetFile()
71 LOG(INFO) << "Mounted " << fstab_info.mount_point << "\nMapping: " << fstab_info.blockdev_name in ParseTargetFile()
106 LOG(WARNING) << "Failed to find property: " << key; in GetProperty()
124 LOG(WARNING) << "Failed to find property: " << key; in GetProperty()
134 LOG(WARNING) << "Failed to find path to block device " << name; in FindBlockDeviceName()
Dupdate_simulator_main.cpp41 LOG(INFO) << "Usage: " << name << "[--oem_settings <oem_property_file>]" in Usage()
49 LOG(INFO) << "Skip function " << name << " in host simulation"; in SimulatorPlaceHolderFn()
78 LOG(ERROR) << "Invalid command argument"; in main()
146 LOG(ERROR) << "Failed to parse the target file " << source_target_file; in main()
164 LOG(INFO) << "\nscript succeeded, result: " << updater.GetResult(); in main()
/bootable/recovery/otautil/
Dsysutil.cpp47 LOG(ERROR) << "Block map file is too short: " << lines.size(); in ParseBlockMapFile()
56 LOG(ERROR) << "Failed to parse file size and block size: " << lines[1]; in ParseBlockMapFile()
61 LOG(ERROR) << "Invalid size in block map file: size " << file_size << ", blksize " << blksize; in ParseBlockMapFile()
67 LOG(ERROR) << "Failed to parse block map header: " << lines[2]; in ParseBlockMapFile()
74 LOG(ERROR) << "Invalid data in block map file: size " << file_size << ", blksize " << blksize in ParseBlockMapFile()
85 LOG(ERROR) << "failed to parse range " << i << ": " << line; in ParseBlockMapFile()
90 LOG(ERROR) << "Invalid range: " << start << " " << end; in ParseBlockMapFile()
98 LOG(ERROR) << "Invalid ranges: remaining blocks " << remaining_blocks; in ParseBlockMapFile()
133 LOG(ERROR) << "File size is too large for mmap " << block_map_data.file_size(); in MapBlockFile()
172 LOG(ERROR) << "Invalid ranges: remaining_size " << remaining_size; in MapBlockFile()
[all …]
Drangeset.cpp35 LOG(ERROR) << "Invalid number of tokens"; in RangeSet()
50 LOG(ERROR) << "Invalid range text: " << range_text; in Parse()
56 LOG(ERROR) << "Failed to parse the number of tokens: " << range_text; in Parse()
60 LOG(ERROR) << "Invalid number of tokens: " << range_text; in Parse()
64 LOG(ERROR) << "Number of tokens must be even: " << range_text; in Parse()
68 LOG(ERROR) << "Mismatching number of tokens: " << range_text; in Parse()
87 LOG(ERROR) << "Empty or negative range: " << range.first << ", " << range.second; in PushBack()
92 LOG(ERROR) << "RangeSet size overflow"; in PushBack()
190 LOG(ERROR) << "Failed to get the sub ranges for start_index " << start_index in GetSubRanges()
197 LOG(WARNING) << "num_of_blocks is zero when calling GetSubRanges()"; in GetSubRanges()
[all …]
/bootable/recovery/uncrypt/
Duncrypt.cpp239 LOG(ERROR) << "fibmap of " << head_block << " always returns 0"; in RetryFibmap()
247 LOG(ERROR) << "failed to remove the existing map file " << map_file << ": " << err; in ProductBlockMap()
259 LOG(ERROR) << "failed to write to socket " << socket; in ProductBlockMap()
269 LOG(INFO) << " block size: " << sb.st_blksize << " bytes"; in ProductBlockMap()
272 LOG(INFO) << " file size: " << sb.st_size << " bytes, " << blocks << " blocks"; in ProductBlockMap()
351 LOG(ERROR) << "failed to find block " << head_block << ", retrying"; in ProductBlockMap()
396 LOG(ERROR) << "failed to find block " << head_block << ", retrying"; in ProductBlockMap()
470 LOG(INFO) << "update package is \"" << input_path << "\""; in Uncrypt()
485 LOG(ERROR) << "Failed to find block device for " << path; in Uncrypt()
491 LOG(INFO) << "encryptable: " << (encryptable ? "yes" : "no"); in Uncrypt()
[all …]
/bootable/recovery/recovery_utils/
Droots.cpp53 LOG(ERROR) << "Failed to read default fstab"; in load_volume_table()
105 LOG(ERROR) << args[0] << " failed with status " << WEXITSTATUS(status); in exec_cmd()
136 LOG(ERROR) << "unknown volume \"" << volume << "\""; in format_volume()
140 LOG(ERROR) << "can't format_volume \"" << volume << "\""; in format_volume()
144 LOG(ERROR) << "can't give path \"" << volume << "\" to format_volume"; in format_volume()
148 LOG(ERROR) << "format_volume: Failed to unmount \"" << v->mount_point << "\""; in format_volume()
152 LOG(ERROR) << "format_volume: fs_type \"" << v->fs_type << "\" unsupported"; in format_volume()
167 LOG(INFO) << "Wiping " << v->key_loc; in format_volume()
188 LOG(ERROR) << "get_file_size: invalid size " << length << " for " << v->blk_device; in format_volume()
295 LOG(ERROR) << "can't set up install mounts: no fstab loaded"; in setup_install_mounts()
[all …]
/bootable/recovery/
Drecovery_main.cpp98 LOG(ERROR) << err; in get_args()
113 LOG(INFO) << "Boot command: " << boot_command; in get_args()
118 LOG(INFO) << "Boot status: " << boot_status; in get_args()
133 LOG(INFO) << "Got " << args.size() << " arguments from boot message"; in get_args()
135 LOG(ERROR) << "Bad boot message: \"" << boot_recovery << "\""; in get_args()
151 LOG(INFO) << "Got " << args.size() << " arguments from " << COMMAND_FILE; in get_args()
160 LOG(ERROR) << "Failed to set BCB message: " << err; in get_args()
176 LOG(ERROR) << "Can't mount " << LOCALE_FILE; in load_locale_from_cache()
226 LOG(ERROR) << "Unrecognized char from socket " << msg; in ListenRecoverySocket()
454 LOG(INFO) << "Starting recovery (pid " << getpid() << ") on " << ctime(&start); in main()
[all …]
/bootable/recovery/recovery_ui/
Dui.cpp138 LOG(WARNING) << "Failed to parse max brightness: " << content; in InitScreensaver()
150 LOG(INFO) << "Brightness: " << brightness_normal_value_ << " (" << brightness_normal_ << "%)"; in InitScreensaver()
179 LOG(INFO) << "Screensaver disabled"; in Init()
205 LOG(DEBUG) << "Ignored " << dx << " " << dy << " (low: " << touch_low_threshold_ in OnTouchDetected()
216 LOG(DEBUG) << "Swipe direction=" << direction; in OnTouchDetected()
428 LOG(INFO) << "Brightness: " << brightness_normal_value_ << " (" << brightness_normal_ in SetScreensaverState()
431 LOG(WARNING) << "Unable to set brightness to normal"; in SetScreensaverState()
437 LOG(INFO) << "Brightness: " << brightness_dimmed_value_ << " (" << brightness_dimmed_ in SetScreensaverState()
441 LOG(WARNING) << "Unable to set brightness to dim"; in SetScreensaverState()
446 LOG(INFO) << "Brightness: 0 (off)"; in SetScreensaverState()
[all …]

12