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 30 namespace BPrivate { 31 namespace Storage { 32 namespace Mime { 33 34 35 AppMetaMimeCreator::AppMetaMimeCreator(Database* database, 36 DatabaseLocker* databaseLocker, int32 force) 37 : 38 MimeEntryProcessor(database, databaseLocker, force) 39 { 40 } 41 42 43 AppMetaMimeCreator::~AppMetaMimeCreator() 44 { 45 } 46 47 48 status_t 49 AppMetaMimeCreator::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