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