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
AppMetaMimeCreator(Database * database,DatabaseLocker * databaseLocker,int32 force)35 AppMetaMimeCreator::AppMetaMimeCreator(Database* database,
36 DatabaseLocker* databaseLocker, int32 force)
37 :
38 MimeEntryProcessor(database, databaseLocker, force)
39 {
40 }
41
42
~AppMetaMimeCreator()43 AppMetaMimeCreator::~AppMetaMimeCreator()
44 {
45 }
46
47
48 status_t
Do(const entry_ref & entry,bool * _entryIsDir)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