1/* 2 * Copyright 2002-2013, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Tyler Dauwalder 7 * Axel D��rfler, axeld@pinc-software.de 8 * Ingo Weinhold, ingo_weinhold@gmx.de 9 */ 10 11 12#include <mime/AppMetaMimeCreator.h> 13 14#include <stdlib.h> 15 16#include <AppFileInfo.h> 17#include <Bitmap.h> 18#include <File.h> 19#include <fs_attr.h> 20#include <Message.h> 21#include <MimeType.h> 22#include <String.h> 23 24#include <AutoLocker.h> 25#include <mime/Database.h> 26#include <mime/database_support.h> 27#include <mime/DatabaseLocation.h> 28 29 30namespace BPrivate { 31namespace Storage { 32namespace Mime { 33 34 35AppMetaMimeCreator::AppMetaMimeCreator(Database* database, 36 DatabaseLocker* databaseLocker, int32 force) 37 : 38 MimeEntryProcessor(database, databaseLocker, force) 39{ 40} 41 42 43AppMetaMimeCreator::~AppMetaMimeCreator() 44{ 45} 46 47 48status_t 49AppMetaMimeCreator::Do(const entry_ref& entry, bool* _entryIsDir) 50{ 51 BFile file; 52 status_t status = file.SetTo(&entry, B_READ_ONLY | O_NOTRAVERSE); 53 if (status < B_OK) 54 return status; 55 56 bool isDir = file.IsDirectory(); 57 if (_entryIsDir != NULL) 58 *_entryIsDir = isDir; 59 60 if (isDir || !file.IsFile()) 61 return B_OK; 62 63 BAppFileInfo appInfo(&file); 64 status = appInfo.InitCheck(); 65 if (status < B_OK) 66 return status; 67 68 // Read the app sig (which consequently keeps us from updating 69 // non-applications, since we get an error if the file has no 70 // app sig) 71 BString signature; 72 status = file.ReadAttrString("BEOS:APP_SIG", &signature); 73 if (status != B_OK) 74 return B_BAD_TYPE; 75 76 if (!BMimeType::IsValid(signature)) 77 return B_BAD_TYPE; 78 79 InstallNotificationDeferrer _(fDatabase, signature.String()); 80 81 if (!fDatabase->Location()->IsInstalled(signature)) { 82 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 83 fDatabase->Install(signature); 84 } 85 86 BNode typeNode; 87 status = fDatabase->Location()->OpenType(signature, typeNode); 88 if (status != B_OK) 89 return status; 90 91 // Preferred App 92 attr_info info; 93 if (status == B_OK 94 && (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK)) { 95 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 96 status = fDatabase->SetPreferredApp(signature, signature); 97 } 98 99 // Short Description (name of the application) 100 if (status == B_OK 101 && (fForce 102 || typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK)) { 103 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 104 status = fDatabase->SetShortDescription(signature, entry.name); 105 } 106 107 // App Hint 108 if (status == B_OK 109 && (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK)) { 110 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 111 status = fDatabase->SetAppHint(signature, &entry); 112 } 113 114 // Vector Icon 115 if (status == B_OK 116 && (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) { 117 uint8* data = NULL; 118 size_t size = 0; 119 if (appInfo.GetIcon(&data, &size) == B_OK) { 120 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 121 status = fDatabase->SetIcon(signature, data, size); 122 free(data); 123 } 124 } 125 // Mini Icon 126 BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8); 127 if (status == B_OK 128 && (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) { 129 if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK) { 130 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 131 status = fDatabase->SetIcon(signature, &miniIcon, B_MINI_ICON); 132 } 133 } 134 // Large Icon 135 BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8); 136 if (status == B_OK 137 && (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) { 138 if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK) { 139 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 140 status = fDatabase->SetIcon(signature, &largeIcon, B_LARGE_ICON); 141 } 142 } 143 144 // Supported Types 145 bool setSupportedTypes = false; 146 BMessage supportedTypes; 147 if (status == B_OK 148 && (fForce 149 || typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) { 150 if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK) 151 setSupportedTypes = true; 152 } 153 154 // defer notifications for supported types 155 const char* type; 156 for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) 157 fDatabase->DeferInstallNotification(type); 158 159 // set supported types 160 if (setSupportedTypes) { 161 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 162 status = fDatabase->SetSupportedTypes(signature, &supportedTypes, true); 163 } 164 165 // Icons for supported types 166 for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; 167 i++) { 168 // vector icon 169 uint8* data = NULL; 170 size_t size = 0; 171 if (status == B_OK 172 && appInfo.GetIconForType(type, &data, &size) == B_OK) { 173 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 174 status = fDatabase->SetIconForType(signature, type, data, size); 175 free(data); 176 } 177 // mini icon 178 if (status == B_OK 179 && appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK) { 180 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 181 status = fDatabase->SetIconForType(signature, type, &miniIcon, 182 B_MINI_ICON); 183 } 184 // large icon 185 if (status == B_OK 186 && appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK) { 187 AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker); 188 status = fDatabase->SetIconForType(signature, type, &largeIcon, 189 B_LARGE_ICON); 190 } 191 } 192 193 // undefer notifications for supported types 194 for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) 195 fDatabase->UndeferInstallNotification(type); 196 197 return status; 198} 199 200 201} // namespace Mime 202} // namespace Storage 203} // namespace BPrivate 204