Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
halo
packages_providers_DownloadProvider
Commits
cf79a11f
Commit
cf79a11f
authored
15 years ago
by
Jean-Baptiste Queru
Browse files
Options
Download
Email Patches
Plain Diff
eclair snapshot
parent
89d4bc91
Changes
32
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
570 additions
and
478 deletions
+570
-478
res/values-zh-rTW/strings.xml
res/values-zh-rTW/strings.xml
+2
-2
res/values/strings.xml
res/values/strings.xml
+3
-3
src/com/android/providers/downloads/Constants.java
src/com/android/providers/downloads/Constants.java
+6
-3
src/com/android/providers/downloads/DownloadFileInfo.java
src/com/android/providers/downloads/DownloadFileInfo.java
+8
-8
src/com/android/providers/downloads/DownloadInfo.java
src/com/android/providers/downloads/DownloadInfo.java
+79
-76
src/com/android/providers/downloads/DownloadNotification.java
...com/android/providers/downloads/DownloadNotification.java
+58
-49
src/com/android/providers/downloads/DownloadProvider.java
src/com/android/providers/downloads/DownloadProvider.java
+76
-76
src/com/android/providers/downloads/DownloadReceiver.java
src/com/android/providers/downloads/DownloadReceiver.java
+29
-14
src/com/android/providers/downloads/DownloadService.java
src/com/android/providers/downloads/DownloadService.java
+153
-144
src/com/android/providers/downloads/DownloadThread.java
src/com/android/providers/downloads/DownloadThread.java
+147
-93
src/com/android/providers/downloads/Helpers.java
src/com/android/providers/downloads/Helpers.java
+8
-9
tests/permission/src/com/android/providers/downloads/permission/tests/DownloadProviderPermissionsTest.java
...ads/permission/tests/DownloadProviderPermissionsTest.java
+1
-1
No files found.
res/values-zh-rTW/strings.xml
View file @
cf79a11f
...
...
@@ -19,14 +19,14 @@
<string
name=
"permlab_downloadManager"
msgid=
"7779544811202855500"
>
"存取下載管理員。"
</string>
<string
name=
"permdesc_downloadManager"
msgid=
"4240298564918160337"
>
"允許應用程式存取下載管理員,並使用它下載檔案。請注意:惡意程式可能使用此功能,影響下載並存取個人資料。"
</string>
<string
name=
"permlab_downloadManagerAdvanced"
msgid=
"7103642833308809655"
>
"下載管理員進階功能。"
</string>
<string
name=
"permdesc_downloadManagerAdvanced"
msgid=
"
8761177317775872287
"
>
"允許應用程式存取下載管理員的進階功能
。"\n" 請注意:
惡意應用程式可能
使
用此功能讓下載發生錯誤並存取私人資訊。"
\n
</string>
<string
name=
"permdesc_downloadManagerAdvanced"
msgid=
"
6985743912436565114
"
>
"允許應用程式存取下載管理員的進階功能
(
惡意應用程式可能
會利
用此功能讓下載發生錯誤並存取私人資訊
)
。"
</string>
<string
name=
"permlab_cacheFilesystem"
msgid=
"6987994626343144212"
>
"使用系統快取。"
</string>
<string
name=
"permdesc_cacheFilesystem"
msgid=
"7301787168569544726"
>
"允許應用程式直接存取、修改與刪除系統快取。請注意:惡意程式可能使用此功能,嚴重影響下載與其他應用程式,並存取個人資料。"
</string>
<string
name=
"permlab_downloadCompletedIntent"
msgid=
"945913803765675685"
>
"傳送下載通知。"
</string>
<string
name=
"permdesc_downloadCompletedIntent"
msgid=
"8672701687104399228"
>
"下載完成時,允許應用程式送出通知。請注意:惡意程式可能使用此功能干擾其他下載檔案的應用程式。"
</string>
<string
name=
"download_unknown_title"
msgid=
"7015124071247271585"
>
"
<
未命名
>
"
</string>
<string
name=
"notification_filename_separator"
msgid=
"7147189522857807618"
>
", "
</string>
<string
name=
"notification_filename_extras"
msgid=
"
4790181201453108165"
>
" 還有 %d 項下載
"
</string>
<string
name=
"notification_filename_extras"
msgid=
"
5549729917695688191"
>
" 以及其他
<xliff:g
id=
"NUMBER"
>
%d
</xliff:g>
個
"
</string>
<string
name=
"notification_download_complete"
msgid=
"840713937779273632"
>
"完成下載"
</string>
<string
name=
"notification_download_failed"
msgid=
"5343637375905111462"
>
"下載失敗"
</string>
</resources>
This diff is collapsed.
Click to expand it.
res/values/strings.xml
View file @
cf79a11f
...
...
@@ -14,7 +14,7 @@
limitations under the License.
-->
<resources>
<resources
xmlns:xliff=
"urn:oasis:names:tc:xliff:document:1.2"
>
<!-- This is the name of the Download Manager application. -->
<string
name=
"app_label"
>
Download Manager
</string>
...
...
@@ -51,7 +51,7 @@
system applications but aren't necessary for regular applications
that just initiate plain downloads. -->
<string
name=
"permdesc_downloadManagerAdvanced"
>
Allows the application to
access the download manager's advanced functions.
access the download manager
\
's advanced functions.
Malicious applications can use this to disrupt downloads and access
private information.
</string>
...
...
@@ -102,7 +102,7 @@
downloads beyond the first two, i.e. "[title], [title] and [n] more".
This is the " and [n] more" part, including the leading space, and it's
used regardless of the number of additional downloads. -->
<string
name=
"notification_filename_extras"
>
" and
%d
more"
</string>
<string
name=
"notification_filename_extras"
>
" and
<xliff:g
id=
"number"
example=
"27"
>
%d
</xliff:g>
more"
</string>
<!-- When a download completes, a notification is displayed, and this
string is used to indicate that the download successfully completed.
...
...
This diff is collapsed.
Click to expand it.
src/com/android/providers/downloads/Constants.java
View file @
cf79a11f
...
...
@@ -29,7 +29,7 @@ public class Constants {
public
static
final
String
TAG
=
"DownloadManager"
;
/** The column that used to be used for the HTTP method of the request */
public
static
final
String
RETRY_AFTER_
_
_REDIRECT_COUNT
=
"method"
;
public
static
final
String
RETRY_AFTER_
X
_REDIRECT_COUNT
=
"method"
;
/** The column that used to be used for the magic OTA update filename */
public
static
final
String
OTA_UPDATE
=
"otaupdate"
;
...
...
@@ -140,12 +140,15 @@ public class Constants {
*/
public
static
final
int
RETRY_FIRST_DELAY
=
30
;
/** Enable separate connectivity logging */
static
final
boolean
LOGX
=
false
;
/** Enable verbose logging - use with "setprop log.tag.DownloadManager VERBOSE" */
private
static
final
boolean
LOCAL_LOGV
=
tru
e
;
private
static
final
boolean
LOCAL_LOGV
=
fals
e
;
public
static
final
boolean
LOGV
=
Config
.
LOGV
||
(
Config
.
LOGD
&&
LOCAL_LOGV
&&
Log
.
isLoggable
(
TAG
,
Log
.
VERBOSE
));
/** Enable super-verbose logging */
private
static
final
boolean
LOCAL_LOGVV
=
tru
e
;
private
static
final
boolean
LOCAL_LOGVV
=
fals
e
;
public
static
final
boolean
LOGVV
=
LOCAL_LOGVV
&&
LOGV
;
}
This diff is collapsed.
Click to expand it.
src/com/android/providers/downloads/DownloadFileInfo.java
View file @
cf79a11f
...
...
@@ -22,13 +22,13 @@ import java.io.FileOutputStream;
* Stores information about the file in which a download gets saved.
*/
public
class
DownloadFileInfo
{
public
DownloadFileInfo
(
String
filename
,
FileOutputStream
stream
,
int
status
)
{
this
.
filename
=
filename
;
this
.
stream
=
stream
;
this
.
status
=
status
;
}
String
mFileName
;
FileOutputStream
mStream
;
int
mStatus
;
String
filename
;
FileOutputStream
stream
;
int
status
;
public
DownloadFileInfo
(
String
fileName
,
FileOutputStream
stream
,
int
status
)
{
mFileName
=
fileName
;
mStream
=
stream
;
mStatus
=
status
;
}
}
This diff is collapsed.
Click to expand it.
src/com/android/providers/downloads/DownloadInfo.java
View file @
cf79a11f
...
...
@@ -16,81 +16,84 @@
package
com.android.providers.downloads
;
import
android.net.Uri
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.net.Uri
;
import
android.provider.Downloads
;
/**
* Stores information about an individual download.
*/
public
class
DownloadInfo
{
public
int
id
;
public
String
uri
;
public
boolean
noIntegrity
;
public
String
hint
;
public
String
filename
;
public
String
mimetype
;
public
int
destination
;
public
int
visibility
;
public
int
control
;
public
int
status
;
public
int
numFailed
;
public
int
retryAfter
;
public
int
redirectCount
;
public
long
lastMod
;
public
String
pckg
;
public
String
clazz
;
public
String
extras
;
public
String
cookies
;
public
String
userAgent
;
public
String
referer
;
public
int
totalBytes
;
public
int
currentBytes
;
public
String
etag
;
public
boolean
mediaScanned
;
public
int
mId
;
public
String
mUri
;
public
boolean
mNoIntegrity
;
public
String
mHint
;
public
String
mFileName
;
public
String
mMimeType
;
public
int
mDestination
;
public
int
mVisibility
;
public
int
mControl
;
public
int
mStatus
;
public
int
mNumFailed
;
public
int
mRetryAfter
;
public
int
mRedirectCount
;
public
long
mLastMod
;
public
String
mPackage
;
public
String
mClass
;
public
String
mExtras
;
public
String
mCookies
;
public
String
mUserAgent
;
public
String
mReferer
;
public
int
mTotalBytes
;
public
int
mCurrentBytes
;
public
String
mETag
;
public
boolean
mMediaScanned
;
public
int
mFuzz
;
public
volatile
boolean
h
asActiveThread
;
public
volatile
boolean
mH
asActiveThread
;
public
DownloadInfo
(
int
id
,
String
uri
,
boolean
noIntegrity
,
String
hint
,
String
file
n
ame
,
String
mime
t
ype
,
int
destination
,
int
visibility
,
int
control
,
String
hint
,
String
file
N
ame
,
String
mime
T
ype
,
int
destination
,
int
visibility
,
int
control
,
int
status
,
int
numFailed
,
int
retryAfter
,
int
redirectCount
,
long
lastMod
,
String
pckg
,
String
clazz
,
String
extras
,
String
cookies
,
String
userAgent
,
String
referer
,
int
totalBytes
,
int
currentBytes
,
String
e
t
ag
,
String
userAgent
,
String
referer
,
int
totalBytes
,
int
currentBytes
,
String
e
T
ag
,
boolean
mediaScanned
)
{
this
.
id
=
id
;
this
.
uri
=
uri
;
this
.
noIntegrity
=
noIntegrity
;
this
.
hint
=
hint
;
this
.
filename
=
filename
;
this
.
mimetype
=
mimetype
;
this
.
destination
=
destination
;
this
.
visibility
=
visibility
;
this
.
control
=
control
;
this
.
status
=
status
;
this
.
numFailed
=
numFailed
;
this
.
retryAfter
=
retryAfter
;
this
.
redirectCount
=
redirectCount
;
this
.
lastMod
=
lastMod
;
this
.
pckg
=
pckg
;
this
.
clazz
=
clazz
;
this
.
extras
=
extras
;
this
.
cookies
=
cookies
;
this
.
userAgent
=
userAgent
;
this
.
referer
=
referer
;
this
.
totalBytes
=
totalBytes
;
this
.
currentBytes
=
currentBytes
;
this
.
etag
=
etag
;
this
.
mediaScanned
=
mediaScanned
;
mId
=
id
;
mUri
=
uri
;
mNoIntegrity
=
noIntegrity
;
mHint
=
hint
;
mFileName
=
fileName
;
mMimeType
=
mimeType
;
mDestination
=
destination
;
mVisibility
=
visibility
;
mControl
=
control
;
mStatus
=
status
;
mNumFailed
=
numFailed
;
mRetryAfter
=
retryAfter
;
mRedirectCount
=
redirectCount
;
mLastMod
=
lastMod
;
mPackage
=
pckg
;
mClass
=
clazz
;
mExtras
=
extras
;
mCookies
=
cookies
;
mUserAgent
=
userAgent
;
mReferer
=
referer
;
mTotalBytes
=
totalBytes
;
mCurrentBytes
=
currentBytes
;
mETag
=
eTag
;
mMediaScanned
=
mediaScanned
;
mFuzz
=
Helpers
.
sRandom
.
nextInt
(
1001
);
}
public
void
sendIntentIfRequested
(
Uri
contentUri
,
Context
context
)
{
if
(
pckg
!=
null
&&
clazz
!=
null
)
{
Intent
intent
=
new
Intent
(
Downloads
.
DOWNLOAD_COMPLETED
_ACTION
);
intent
.
setClassName
(
pckg
,
clazz
);
if
(
e
xtras
!=
null
)
{
intent
.
putExtra
(
Downloads
.
NOTIFICATION_EXTRAS
,
e
xtras
);
if
(
mPackage
!=
null
&&
mClass
!=
null
)
{
Intent
intent
=
new
Intent
(
Downloads
.
ACTION_
DOWNLOAD_COMPLETED
);
intent
.
setClassName
(
mPackage
,
mClass
);
if
(
mE
xtras
!=
null
)
{
intent
.
putExtra
(
Downloads
.
COLUMN_
NOTIFICATION_EXTRAS
,
mE
xtras
);
}
// We only send the content: URI, for security reasons. Otherwise, malicious
// applications would have an easier time spoofing download results by
...
...
@@ -105,12 +108,12 @@ public class DownloadInfo {
* be called when numFailed > 0.
*/
public
long
restartTime
()
{
if
(
r
etryAfter
>
0
)
{
return
l
astMod
+
r
etryAfter
;
if
(
mR
etryAfter
>
0
)
{
return
mL
astMod
+
mR
etryAfter
;
}
return
l
astMod
+
return
mL
astMod
+
Constants
.
RETRY_FIRST_DELAY
*
(
1000
+
Helpers
.
rnd
.
nextInt
(
1001
)
)
*
(
1
<<
(
n
umFailed
-
1
));
(
1000
+
mFuzz
)
*
(
1
<<
(
mN
umFailed
-
1
));
}
/**
...
...
@@ -118,25 +121,25 @@ public class DownloadInfo {
* should be started.
*/
public
boolean
isReadyToStart
(
long
now
)
{
if
(
c
ontrol
==
Downloads
.
CONTROL_PAUSED
)
{
if
(
mC
ontrol
==
Downloads
.
CONTROL_PAUSED
)
{
// the download is paused, so it's not going to start
return
false
;
}
if
(
s
tatus
==
0
)
{
if
(
mS
tatus
==
0
)
{
// status hasn't been initialized yet, this is a new download
return
true
;
}
if
(
s
tatus
==
Downloads
.
STATUS_PENDING
)
{
if
(
mS
tatus
==
Downloads
.
STATUS_PENDING
)
{
// download is explicit marked as ready to start
return
true
;
}
if
(
s
tatus
==
Downloads
.
STATUS_RUNNING
)
{
if
(
mS
tatus
==
Downloads
.
STATUS_RUNNING
)
{
// download was interrupted (process killed, loss of power) while it was running,
// without a chance to update the database
return
true
;
}
if
(
s
tatus
==
Downloads
.
STATUS_RUNNING_PAUSED
)
{
if
(
n
umFailed
==
0
)
{
if
(
mS
tatus
==
Downloads
.
STATUS_RUNNING_PAUSED
)
{
if
(
mN
umFailed
==
0
)
{
// download is waiting for network connectivity to return before it can resume
return
true
;
}
...
...
@@ -157,20 +160,20 @@ public class DownloadInfo {
* by checking the status.
*/
public
boolean
isReadyToRestart
(
long
now
)
{
if
(
c
ontrol
==
Downloads
.
CONTROL_PAUSED
)
{
if
(
mC
ontrol
==
Downloads
.
CONTROL_PAUSED
)
{
// the download is paused, so it's not going to restart
return
false
;
}
if
(
s
tatus
==
0
)
{
if
(
mS
tatus
==
0
)
{
// download hadn't been initialized yet
return
true
;
}
if
(
s
tatus
==
Downloads
.
STATUS_PENDING
)
{
if
(
mS
tatus
==
Downloads
.
STATUS_PENDING
)
{
// download is explicit marked as ready to start
return
true
;
}
if
(
s
tatus
==
Downloads
.
STATUS_RUNNING_PAUSED
)
{
if
(
n
umFailed
==
0
)
{
if
(
mS
tatus
==
Downloads
.
STATUS_RUNNING_PAUSED
)
{
if
(
mN
umFailed
==
0
)
{
// download is waiting for network connectivity to return before it can resume
return
true
;
}
...
...
@@ -187,10 +190,10 @@ public class DownloadInfo {
* completion.
*/
public
boolean
hasCompletionNotification
()
{
if
(!
Downloads
.
isStatusCompleted
(
s
tatus
))
{
if
(!
Downloads
.
isStatusCompleted
(
mS
tatus
))
{
return
false
;
}
if
(
v
isibility
==
Downloads
.
VISIBILITY_VISIBLE_NOTIFY_COMPLETED
)
{
if
(
mV
isibility
==
Downloads
.
VISIBILITY_VISIBLE_NOTIFY_COMPLETED
)
{
return
true
;
}
return
false
;
...
...
@@ -203,7 +206,7 @@ public class DownloadInfo {
if
(!
available
)
{
return
false
;
}
if
(
d
estination
==
Downloads
.
DESTINATION_CACHE_PARTITION_NOROAMING
)
{
if
(
mD
estination
==
Downloads
.
DESTINATION_CACHE_PARTITION_NOROAMING
)
{
return
!
roaming
;
}
else
{
return
true
;
...
...
This diff is collapsed.
Click to expand it.
src/com/android/providers/downloads/DownloadNotification.java
View file @
cf79a11f
...
...
@@ -43,14 +43,15 @@ class DownloadNotification {
static
final
String
LOGTAG
=
"DownloadNotification"
;
static
final
String
WHERE_RUNNING
=
"("
+
Downloads
.
STATUS
+
" >= '100') AND ("
+
Downloads
.
STATUS
+
" <= '199') AND ("
+
Downloads
.
VISIBILITY
+
" IS NULL OR "
+
Downloads
.
VISIBILITY
+
" == '"
+
Downloads
.
VISIBILITY_VISIBLE
+
"' OR "
+
Downloads
.
VISIBILITY
+
" == '"
+
Downloads
.
VISIBILITY_VISIBLE_NOTIFY_COMPLETED
+
"')"
;
"("
+
Downloads
.
COLUMN_STATUS
+
" >= '100') AND ("
+
Downloads
.
COLUMN_STATUS
+
" <= '199') AND ("
+
Downloads
.
COLUMN_VISIBILITY
+
" IS NULL OR "
+
Downloads
.
COLUMN_VISIBILITY
+
" == '"
+
Downloads
.
VISIBILITY_VISIBLE
+
"' OR "
+
Downloads
.
COLUMN_VISIBILITY
+
" == '"
+
Downloads
.
VISIBILITY_VISIBLE_NOTIFY_COMPLETED
+
"')"
;
static
final
String
WHERE_COMPLETED
=
Downloads
.
STATUS
+
" >= '200' AND "
+
Downloads
.
VISIBILITY
+
" == '"
+
Downloads
.
VISIBILITY_VISIBLE_NOTIFY_COMPLETED
+
"'"
;
Downloads
.
COLUMN_
STATUS
+
" >= '200' AND "
+
Downloads
.
COLUMN_
VISIBILITY
+
" == '"
+
Downloads
.
VISIBILITY_VISIBLE_NOTIFY_COMPLETED
+
"'"
;
/**
...
...
@@ -60,28 +61,28 @@ class DownloadNotification {
*
*/
static
class
NotificationItem
{
int
i
d
;
// This first db _id for the download for the app
int
t
otalCurrent
=
0
;
int
t
otalTotal
=
0
;
int
t
itleCount
=
0
;
String
p
ackageName
;
// App package name
String
d
escription
;
String
[]
t
itles
=
new
String
[
2
];
// download titles.
int
mI
d
;
// This first db _id for the download for the app
int
mT
otalCurrent
=
0
;
int
mT
otalTotal
=
0
;
int
mT
itleCount
=
0
;
String
mP
ackageName
;
// App package name
String
mD
escription
;
String
[]
mT
itles
=
new
String
[
2
];
// download titles.
/*
* Add a second download to this notification item.
*/
void
addItem
(
String
title
,
int
currentBytes
,
int
totalBytes
)
{
t
otalCurrent
+=
currentBytes
;
if
(
totalBytes
<=
0
||
t
otalTotal
==
-
1
)
{
t
otalTotal
=
-
1
;
mT
otalCurrent
+=
currentBytes
;
if
(
totalBytes
<=
0
||
mT
otalTotal
==
-
1
)
{
mT
otalTotal
=
-
1
;
}
else
{
t
otalTotal
+=
totalBytes
;
mT
otalTotal
+=
totalBytes
;
}
if
(
t
itleCount
<
2
)
{
t
itles
[
t
itleCount
]
=
title
;
if
(
mT
itleCount
<
2
)
{
mT
itles
[
mT
itleCount
]
=
title
;
}
t
itleCount
++;
mT
itleCount
++;
}
}
...
...
@@ -110,11 +111,14 @@ class DownloadNotification {
// Active downloads
Cursor
c
=
mContext
.
getContentResolver
().
query
(
Downloads
.
CONTENT_URI
,
new
String
[]
{
Downloads
.
_ID
,
Downloads
.
TITLE
,
Downloads
.
DESCRIPTION
,
Downloads
.
NOTIFICATION_PACKAGE
,
Downloads
.
NOTIFICATION_CLASS
,
Downloads
.
CURRENT_BYTES
,
Downloads
.
TOTAL_BYTES
,
Downloads
.
STATUS
,
Downloads
.
_DATA
Downloads
.
_ID
,
Downloads
.
COLUMN_TITLE
,
Downloads
.
COLUMN_DESCRIPTION
,
Downloads
.
COLUMN_NOTIFICATION_PACKAGE
,
Downloads
.
COLUMN_NOTIFICATION_CLASS
,
Downloads
.
COLUMN_CURRENT_BYTES
,
Downloads
.
COLUMN_TOTAL_BYTES
,
Downloads
.
COLUMN_STATUS
,
Downloads
.
_DATA
},
WHERE_RUNNING
,
null
,
Downloads
.
_ID
);
...
...
@@ -148,9 +152,9 @@ class DownloadNotification {
mNotifications
.
get
(
packageName
).
addItem
(
title
,
progress
,
max
);
}
else
{
NotificationItem
item
=
new
NotificationItem
();
item
.
i
d
=
c
.
getInt
(
idColumn
);
item
.
p
ackageName
=
packageName
;
item
.
d
escription
=
c
.
getString
(
descColumn
);
item
.
mI
d
=
c
.
getInt
(
idColumn
);
item
.
mP
ackageName
=
packageName
;
item
.
mD
escription
=
c
.
getString
(
descColumn
);
String
className
=
c
.
getString
(
classOwnerColumn
);
item
.
addItem
(
title
,
progress
,
max
);
mNotifications
.
put
(
packageName
,
item
);
...
...
@@ -171,26 +175,26 @@ class DownloadNotification {
RemoteViews
expandedView
=
new
RemoteViews
(
"com.android.providers.downloads"
,
R
.
layout
.
status_bar_ongoing_event_progress_bar
);
StringBuilder
title
=
new
StringBuilder
(
item
.
t
itles
[
0
]);
if
(
item
.
t
itleCount
>
1
)
{
StringBuilder
title
=
new
StringBuilder
(
item
.
mT
itles
[
0
]);
if
(
item
.
mT
itleCount
>
1
)
{
title
.
append
(
mContext
.
getString
(
R
.
string
.
notification_filename_separator
));
title
.
append
(
item
.
t
itles
[
1
]);
n
.
number
=
item
.
t
itleCount
;
if
(
item
.
t
itleCount
>
2
)
{
title
.
append
(
item
.
mT
itles
[
1
]);
n
.
number
=
item
.
mT
itleCount
;
if
(
item
.
mT
itleCount
>
2
)
{
title
.
append
(
mContext
.
getString
(
R
.
string
.
notification_filename_extras
,
new
Object
[]
{
Integer
.
valueOf
(
item
.
t
itleCount
-
2
)
}));
new
Object
[]
{
Integer
.
valueOf
(
item
.
mT
itleCount
-
2
)
}));
}
}
else
{
expandedView
.
setTextViewText
(
R
.
id
.
description
,
item
.
d
escription
);
item
.
mD
escription
);
}
expandedView
.
setTextViewText
(
R
.
id
.
title
,
title
);
expandedView
.
setProgressBar
(
R
.
id
.
progress_bar
,
item
.
t
otalTotal
,
item
.
t
otalCurrent
,
item
.
t
otalTotal
==
-
1
);
item
.
mT
otalTotal
,
item
.
mT
otalCurrent
,
item
.
mT
otalTotal
==
-
1
);
expandedView
.
setTextViewText
(
R
.
id
.
progress_text
,
getDownloadingText
(
item
.
t
otalTotal
,
item
.
t
otalCurrent
));
getDownloadingText
(
item
.
mT
otalTotal
,
item
.
mT
otalCurrent
));
expandedView
.
setImageViewResource
(
R
.
id
.
appIcon
,
android
.
R
.
drawable
.
stat_sys_download
);
n
.
contentView
=
expandedView
;
...
...
@@ -198,12 +202,12 @@ class DownloadNotification {
Intent
intent
=
new
Intent
(
Constants
.
ACTION_LIST
);
intent
.
setClassName
(
"com.android.providers.downloads"
,
DownloadReceiver
.
class
.
getName
());
intent
.
setData
(
Uri
.
parse
(
Downloads
.
CONTENT_URI
+
"/"
+
item
.
i
d
));
intent
.
putExtra
(
"multiple"
,
item
.
t
itleCount
>
1
);
intent
.
setData
(
Uri
.
parse
(
Downloads
.
CONTENT_URI
+
"/"
+
item
.
mI
d
));
intent
.
putExtra
(
"multiple"
,
item
.
mT
itleCount
>
1
);
n
.
contentIntent
=
PendingIntent
.
getBroadcast
(
mContext
,
0
,
intent
,
0
);
mNotificationMgr
.
notify
(
item
.
i
d
,
n
);
mNotificationMgr
.
notify
(
item
.
mI
d
,
n
);
}
}
...
...
@@ -212,12 +216,17 @@ class DownloadNotification {
// Completed downloads
Cursor
c
=
mContext
.
getContentResolver
().
query
(
Downloads
.
CONTENT_URI
,
new
String
[]
{
Downloads
.
_ID
,
Downloads
.
TITLE
,
Downloads
.
DESCRIPTION
,
Downloads
.
NOTIFICATION_PACKAGE
,
Downloads
.
NOTIFICATION_CLASS
,
Downloads
.
CURRENT_BYTES
,
Downloads
.
TOTAL_BYTES
,
Downloads
.
STATUS
,
Downloads
.
_DATA
,
Downloads
.
LAST_MODIFICATION
,
Downloads
.
DESTINATION
Downloads
.
_ID
,
Downloads
.
COLUMN_TITLE
,
Downloads
.
COLUMN_DESCRIPTION
,
Downloads
.
COLUMN_NOTIFICATION_PACKAGE
,
Downloads
.
COLUMN_NOTIFICATION_CLASS
,
Downloads
.
COLUMN_CURRENT_BYTES
,
Downloads
.
COLUMN_TOTAL_BYTES
,
Downloads
.
COLUMN_STATUS
,
Downloads
.
_DATA
,
Downloads
.
COLUMN_LAST_MODIFICATION
,
Downloads
.
COLUMN_DESTINATION
},
WHERE_COMPLETED
,
null
,
Downloads
.
_ID
);
...
...
This diff is collapsed.
Click to expand it.
src/com/android/providers/downloads/DownloadProvider.java
View file @
cf79a11f
...
...
@@ -26,10 +26,10 @@ import android.database.CrossProcessCursor;
import
android.database.Cursor
;
import
android.database.CursorWindow
;
import
android.database.CursorWrapper
;
import
android.database.SQLException
;
import
android.database.sqlite.SQLiteDatabase
;
import
android.database.sqlite.SQLiteOpenHelper
;
import
android.database.sqlite.SQLiteQueryBuilder
;
import
android.database.SQLException
;
import
android.net.Uri
;
import
android.os.Binder
;
import
android.os.ParcelFileDescriptor
;
...
...
@@ -40,7 +40,6 @@ import android.util.Log;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.util.HashSet
;
...
...
@@ -78,20 +77,20 @@ public final class DownloadProvider extends ContentProvider {
private
static
final
String
[]
sAppReadableColumnsArray
=
new
String
[]
{
Downloads
.
_ID
,
Downloads
.
APP_DATA
,
Downloads
.
COLUMN_
APP_DATA
,
Downloads
.
_DATA
,
Downloads
.
MIMETYPE
,
Downloads
.
VISIBILITY
,
Downloads
.
DESTINATION
,
Downloads
.
CONTROL
,
Downloads
.
STATUS
,
Downloads
.
LAST_MODIFICATION
,
Downloads
.
NOTIFICATION_PACKAGE
,
Downloads
.
NOTIFICATION_CLASS
,
Downloads
.
TOTAL_BYTES
,
Downloads
.
CURRENT_BYTES
,
Downloads
.
TITLE
,
Downloads
.
DESCRIPTION
Downloads
.
COLUMN_
MIME
_
TYPE
,
Downloads
.
COLUMN_
VISIBILITY
,
Downloads
.
COLUMN_
DESTINATION
,
Downloads
.
COLUMN_
CONTROL
,
Downloads
.
COLUMN_
STATUS
,
Downloads
.
COLUMN_
LAST_MODIFICATION
,
Downloads
.
COLUMN_
NOTIFICATION_PACKAGE
,
Downloads
.
COLUMN_
NOTIFICATION_CLASS
,
Downloads
.
COLUMN_
TOTAL_BYTES
,
Downloads
.
COLUMN_
CURRENT_BYTES
,
Downloads
.
COLUMN_
TITLE
,
Downloads
.
COLUMN_
DESCRIPTION
};
private
static
HashSet
<
String
>
sAppReadableColumnsSet
;
...
...
@@ -201,34 +200,34 @@ public final class DownloadProvider extends ContentProvider {
try
{
db
.
execSQL
(
"CREATE TABLE "
+
DB_TABLE
+
"("
+
Downloads
.
_ID
+
" INTEGER PRIMARY KEY AUTOINCREMENT,"
+
Downloads
.
URI
+
" TEXT, "
+
Constants
.
RETRY_AFTER_
_
_REDIRECT_COUNT
+
" INTEGER, "
+
Downloads
.
APP_DATA
+
" TEXT, "
+
Downloads
.
NO_INTEGRITY
+
" BOOLEAN, "
+
Downloads
.
FILENAME_HINT
+
" TEXT, "
+
Downloads
.
COLUMN_
URI
+
" TEXT, "
+
Constants
.
RETRY_AFTER_
X
_REDIRECT_COUNT
+
" INTEGER, "
+
Downloads
.
COLUMN_
APP_DATA
+
" TEXT, "
+
Downloads
.
COLUMN_
NO_INTEGRITY
+
" BOOLEAN, "
+
Downloads
.
COLUMN_
FILE
_
NAME_HINT
+
" TEXT, "
+
Constants
.
OTA_UPDATE
+
" BOOLEAN, "
+
Downloads
.
_DATA
+
" TEXT, "
+
Downloads
.
MIMETYPE
+
" TEXT, "
+
Downloads
.
DESTINATION
+
" INTEGER, "
+
Downloads
.
COLUMN_
MIME
_
TYPE
+
" TEXT, "
+
Downloads
.
COLUMN_
DESTINATION
+
" INTEGER, "
+
Constants
.
NO_SYSTEM_FILES
+
" BOOLEAN, "
+
Downloads
.
VISIBILITY
+
" INTEGER, "
+
Downloads
.
CONTROL
+
" INTEGER, "
+
Downloads
.
STATUS
+
" INTEGER, "
+
Downloads
.
COLUMN_
VISIBILITY
+
" INTEGER, "
+
Downloads
.
COLUMN_
CONTROL
+
" INTEGER, "
+
Downloads
.
COLUMN_
STATUS
+
" INTEGER, "
+
Constants
.
FAILED_CONNECTIONS
+
" INTEGER, "
+
Downloads
.
LAST_MODIFICATION
+
" BIGINT, "
+
Downloads
.
NOTIFICATION_PACKAGE
+
" TEXT, "
+
Downloads
.
NOTIFICATION_CLASS
+
" TEXT, "
+
Downloads
.
NOTIFICATION_EXTRAS
+
" TEXT, "
+
Downloads
.
COOKIE_DATA
+
" TEXT, "
+
Downloads
.
USER_AGENT
+
" TEXT, "
+
Downloads
.
REFERER
+
" TEXT, "
+
Downloads
.
TOTAL_BYTES
+
" INTEGER, "
+
Downloads
.
CURRENT_BYTES
+
" INTEGER, "
+
Downloads
.
COLUMN_
LAST_MODIFICATION
+
" BIGINT, "
+
Downloads
.
COLUMN_
NOTIFICATION_PACKAGE
+
" TEXT, "
+
Downloads
.
COLUMN_
NOTIFICATION_CLASS
+
" TEXT, "
+
Downloads
.
COLUMN_
NOTIFICATION_EXTRAS
+
" TEXT, "
+
Downloads
.
COLUMN_
COOKIE_DATA
+
" TEXT, "
+
Downloads
.
COLUMN_
USER_AGENT
+
" TEXT, "
+
Downloads
.
COLUMN_
REFERER
+
" TEXT, "
+
Downloads
.
COLUMN_
TOTAL_BYTES
+
" INTEGER, "
+
Downloads
.
COLUMN_
CURRENT_BYTES
+
" INTEGER, "
+
Constants
.
ETAG
+
" TEXT, "
+
Constants
.
UID
+
" INTEGER, "
+
Downloads
.
OTHER_UID
+
" INTEGER, "
+
Downloads
.
TITLE
+
" TEXT, "
+
Downloads
.
DESCRIPTION
+
" TEXT, "
+
Downloads
.
COLUMN_
OTHER_UID
+
" INTEGER, "
+
Downloads
.
COLUMN_
TITLE
+
" TEXT, "
+
Downloads
.
COLUMN_
DESCRIPTION
+
" TEXT, "
+
Constants
.
MEDIA_SCANNED
+
" BOOLEAN);"
);
}
catch
(
SQLException
ex
)
{
Log
.
e
(
Constants
.
TAG
,
"couldn't create table in downloads database"
);
...
...
@@ -264,12 +263,12 @@ public final class DownloadProvider extends ContentProvider {
ContentValues
filteredValues
=
new
ContentValues
();
copyString
(
Downloads
.
URI
,
values
,
filteredValues
);
copyString
(
Downloads
.
APP_DATA
,
values
,
filteredValues
);
copyBoolean
(
Downloads
.
NO_INTEGRITY
,
values
,
filteredValues
);
copyString
(
Downloads
.
FILENAME_HINT
,
values
,
filteredValues
);
copyString
(
Downloads
.
MIMETYPE
,
values
,
filteredValues
);
Integer
dest
=
values
.
getAsInteger
(
Downloads
.
DESTINATION
);
copyString
(
Downloads
.
COLUMN_
URI
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
APP_DATA
,
values
,
filteredValues
);
copyBoolean
(
Downloads
.
COLUMN_
NO_INTEGRITY
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
FILE
_
NAME_HINT
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
MIME
_
TYPE
,
values
,
filteredValues
);
Integer
dest
=
values
.
getAsInteger
(
Downloads
.
COLUMN_
DESTINATION
);
if
(
dest
!=
null
)
{
if
(
getContext
().
checkCallingPermission
(
Downloads
.
PERMISSION_ACCESS_ADVANCED
)
!=
PackageManager
.
PERMISSION_GRANTED
...
...
@@ -277,57 +276,57 @@ public final class DownloadProvider extends ContentProvider {
&&
dest
!=
Downloads
.
DESTINATION_CACHE_PARTITION_PURGEABLE
)
{
throw
new
SecurityException
(
"unauthorized destination code"
);
}
filteredValues
.
put
(
Downloads
.
DESTINATION
,
dest
);
filteredValues
.
put
(
Downloads
.
COLUMN_
DESTINATION
,
dest
);
}
Integer
vis
=
values
.
getAsInteger
(
Downloads
.
VISIBILITY
);
Integer
vis
=
values
.
getAsInteger
(
Downloads
.
COLUMN_
VISIBILITY
);
if
(
vis
==
null
)
{
if
(
dest
==
Downloads
.
DESTINATION_EXTERNAL
)
{
filteredValues
.
put
(
Downloads
.
VISIBILITY
,
filteredValues
.
put
(
Downloads
.
COLUMN_
VISIBILITY
,
Downloads
.
VISIBILITY_VISIBLE_NOTIFY_COMPLETED
);
}
else
{
filteredValues
.
put
(
Downloads
.
VISIBILITY
,
Downloads
.
VISIBILITY_HIDDEN
);
filteredValues
.
put
(
Downloads
.
COLUMN_
VISIBILITY
,
Downloads
.
VISIBILITY_HIDDEN
);
}
}
else
{
filteredValues
.
put
(
Downloads
.
VISIBILITY
,
vis
);
filteredValues
.
put
(
Downloads
.
COLUMN_
VISIBILITY
,
vis
);
}
copyInteger
(
Downloads
.
CONTROL
,
values
,
filteredValues
);
filteredValues
.
put
(
Downloads
.
STATUS
,
Downloads
.
STATUS_PENDING
);
filteredValues
.
put
(
Downloads
.
LAST_MODIFICATION
,
System
.
currentTimeMillis
());
String
pckg
=
values
.
getAsString
(
Downloads
.
NOTIFICATION_PACKAGE
);
String
clazz
=
values
.
getAsString
(
Downloads
.
NOTIFICATION_CLASS
);
copyInteger
(
Downloads
.
COLUMN_
CONTROL
,
values
,
filteredValues
);
filteredValues
.
put
(
Downloads
.
COLUMN_
STATUS
,
Downloads
.
STATUS_PENDING
);
filteredValues
.
put
(
Downloads
.
COLUMN_
LAST_MODIFICATION
,
System
.
currentTimeMillis
());
String
pckg
=
values
.
getAsString
(
Downloads
.
COLUMN_
NOTIFICATION_PACKAGE
);
String
clazz
=
values
.
getAsString
(
Downloads
.
COLUMN_
NOTIFICATION_CLASS
);
if
(
pckg
!=
null
&&
clazz
!=
null
)
{
int
uid
=
Binder
.
getCallingUid
();
try
{
if
(
uid
==
0
||
getContext
().
getPackageManager
().
getApplicationInfo
(
pckg
,
0
).
uid
==
uid
)
{
filteredValues
.
put
(
Downloads
.
NOTIFICATION_PACKAGE
,
pckg
);
filteredValues
.
put
(
Downloads
.
NOTIFICATION_CLASS
,
clazz
);
filteredValues
.
put
(
Downloads
.
COLUMN_
NOTIFICATION_PACKAGE
,
pckg
);
filteredValues
.
put
(
Downloads
.
COLUMN_
NOTIFICATION_CLASS
,
clazz
);
}
}
catch
(
PackageManager
.
NameNotFoundException
ex
)
{
/* ignored for now */
}
}
copyString
(
Downloads
.
NOTIFICATION_EXTRAS
,
values
,
filteredValues
);
copyString
(
Downloads
.
COOKIE_DATA
,
values
,
filteredValues
);
copyString
(
Downloads
.
USER_AGENT
,
values
,
filteredValues
);
copyString
(
Downloads
.
REFERER
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
NOTIFICATION_EXTRAS
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
COOKIE_DATA
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
USER_AGENT
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
REFERER
,
values
,
filteredValues
);
if
(
getContext
().
checkCallingPermission
(
Downloads
.
PERMISSION_ACCESS_ADVANCED
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
copyInteger
(
Downloads
.
OTHER_UID
,
values
,
filteredValues
);
copyInteger
(
Downloads
.
COLUMN_
OTHER_UID
,
values
,
filteredValues
);
}
filteredValues
.
put
(
Constants
.
UID
,
Binder
.
getCallingUid
());
if
(
Binder
.
getCallingUid
()
==
0
)
{
copyInteger
(
Constants
.
UID
,
values
,
filteredValues
);
}
copyString
(
Downloads
.
TITLE
,
values
,
filteredValues
);
copyString
(
Downloads
.
DESCRIPTION
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
TITLE
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
DESCRIPTION
,
values
,
filteredValues
);
if
(
Constants
.
LOGVV
)
{
Log
.
v
(
Constants
.
TAG
,
"initiating download with UID "
+
filteredValues
.
getAsInteger
(
Constants
.
UID
));
if
(
filteredValues
.
containsKey
(
Downloads
.
OTHER_UID
))
{
if
(
filteredValues
.
containsKey
(
Downloads
.
COLUMN_
OTHER_UID
))
{
Log
.
v
(
Constants
.
TAG
,
"other UID "
+
filteredValues
.
getAsInteger
(
Downloads
.
OTHER_UID
));
filteredValues
.
getAsInteger
(
Downloads
.
COLUMN_
OTHER_UID
));
}
}
...
...
@@ -387,12 +386,13 @@ public final class DownloadProvider extends ContentProvider {
}
}
if
(
Binder
.
getCallingPid
()
!=
Process
.
myPid
()
&&
Binder
.
getCallingUid
()
!=
0
)
{
if
(
Binder
.
getCallingPid
()
!=
Process
.
myPid
()
&&
Binder
.
getCallingUid
()
!=
0
&&
Process
.
supportsProcesses
())
{
if
(!
emptyWhere
)
{
qb
.
appendWhere
(
" AND "
);
}
qb
.
appendWhere
(
"( "
+
Constants
.
UID
+
"="
+
Binder
.
getCallingUid
()
+
" OR "
+
Downloads
.
OTHER_UID
+
"="
+
Binder
.
getCallingUid
()
+
" )"
);
+
Downloads
.
COLUMN_
OTHER_UID
+
"="
+
Binder
.
getCallingUid
()
+
" )"
);
emptyWhere
=
false
;
if
(
projection
==
null
)
{
...
...
@@ -489,16 +489,16 @@ public final class DownloadProvider extends ContentProvider {
ContentValues
filteredValues
;
if
(
Binder
.
getCallingPid
()
!=
Process
.
myPid
())
{
filteredValues
=
new
ContentValues
();
copyString
(
Downloads
.
APP_DATA
,
values
,
filteredValues
);
copyInteger
(
Downloads
.
VISIBILITY
,
values
,
filteredValues
);
Integer
i
=
values
.
getAsInteger
(
Downloads
.
CONTROL
);
copyString
(
Downloads
.
COLUMN_
APP_DATA
,
values
,
filteredValues
);
copyInteger
(
Downloads
.
COLUMN_
VISIBILITY
,
values
,
filteredValues
);
Integer
i
=
values
.
getAsInteger
(
Downloads
.
COLUMN_
CONTROL
);
if
(
i
!=
null
)
{
filteredValues
.
put
(
Downloads
.
CONTROL
,
i
);
filteredValues
.
put
(
Downloads
.
COLUMN_
CONTROL
,
i
);
startService
=
true
;
}
copyInteger
(
Downloads
.
CONTROL
,
values
,
filteredValues
);
copyString
(
Downloads
.
TITLE
,
values
,
filteredValues
);
copyString
(
Downloads
.
DESCRIPTION
,
values
,
filteredValues
);
copyInteger
(
Downloads
.
COLUMN_
CONTROL
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
TITLE
,
values
,
filteredValues
);
copyString
(
Downloads
.
COLUMN_
DESCRIPTION
,
values
,
filteredValues
);
}
else
{
filteredValues
=
values
;
}
...
...
@@ -523,7 +523,7 @@ public final class DownloadProvider extends ContentProvider {
}
if
(
Binder
.
getCallingPid
()
!=
Process
.
myPid
()
&&
Binder
.
getCallingUid
()
!=
0
)
{
myWhere
+=
" AND ( "
+
Constants
.
UID
+
"="
+
Binder
.
getCallingUid
()
+
" OR "
+
Downloads
.
OTHER_UID
+
"="
+
Binder
.
getCallingUid
()
+
" )"
;
+
Downloads
.
COLUMN_
OTHER_UID
+
"="
+
Binder
.
getCallingUid
()
+
" )"
;
}
if
(
filteredValues
.
size
()
>
0
)
{
count
=
db
.
update
(
DB_TABLE
,
filteredValues
,
myWhere
,
whereArgs
);
...
...
@@ -579,7 +579,7 @@ public final class DownloadProvider extends ContentProvider {
}
if
(
Binder
.
getCallingPid
()
!=
Process
.
myPid
()
&&
Binder
.
getCallingUid
()
!=
0
)
{
myWhere
+=
" AND ( "
+
Constants
.
UID
+
"="
+
Binder
.
getCallingUid
()
+
" OR "
+
Downloads
.
OTHER_UID
+
"="
+
Binder
.
getCallingUid
()
+
" )"
;
+
Downloads
.
COLUMN_
OTHER_UID
+
"="
+
Binder
.
getCallingUid
()
+
" )"
;
}
count
=
db
.
delete
(
DB_TABLE
,
myWhere
,
whereArgs
);
break
;
...
...
@@ -673,7 +673,7 @@ public final class DownloadProvider extends ContentProvider {
throw
new
FileNotFoundException
(
"couldn't open file"
);
}
else
{
ContentValues
values
=
new
ContentValues
();
values
.
put
(
Downloads
.
LAST_MODIFICATION
,
System
.
currentTimeMillis
());
values
.
put
(
Downloads
.
COLUMN_
LAST_MODIFICATION
,
System
.
currentTimeMillis
());
update
(
uri
,
values
,
null
,
null
);
}
return
ret
;
...
...
This diff is collapsed.
Click to expand it.
src/com/android/providers/downloads/DownloadReceiver.java
View file @
cf79a11f
...
...
@@ -23,18 +23,15 @@ import android.content.ContentUris;
import
android.content.ContentValues
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.content.pm.ResolveInfo
;
import
android.database.Cursor
;
import
android.provider.Downloads
;
import
android.net.ConnectivityManager
;
import
android.net.NetworkInfo
;
import
android.net.Uri
;
import
android.provider.Downloads
;
import
android.util.Config
;
import
android.util.Log
;
import
java.io.File
;
import
java.util.List
;
/**
* Receives system broadcasts (boot, network connectivity)
...
...
@@ -54,7 +51,22 @@ public class DownloadReceiver extends BroadcastReceiver {
NetworkInfo
info
=
(
NetworkInfo
)
intent
.
getParcelableExtra
(
ConnectivityManager
.
EXTRA_NETWORK_INFO
);
if
(
info
!=
null
&&
info
.
isConnected
())
{
if
(
Constants
.
LOGX
)
{
if
(
Helpers
.
isNetworkAvailable
(
context
))
{
Log
.
i
(
Constants
.
TAG
,
"Broadcast: Network Up"
);
}
else
{
Log
.
i
(
Constants
.
TAG
,
"Broadcast: Network Up, Actually Down"
);
}
}
context
.
startService
(
new
Intent
(
context
,
DownloadService
.
class
));
}
else
{
if
(
Constants
.
LOGX
)
{
if
(
Helpers
.
isNetworkAvailable
(
context
))
{
Log
.
i
(
Constants
.
TAG
,
"Broadcast: Network Down, Actually Up"
);
}
else
{
Log
.
i
(
Constants
.
TAG
,
"Broadcast: Network Down"
);
}
}
}
}
else
if
(
intent
.
getAction
().
equals
(
Constants
.
ACTION_RETRY
))
{
if
(
Constants
.
LOGVV
)
{
...
...
@@ -74,20 +86,22 @@ public class DownloadReceiver extends BroadcastReceiver {
intent
.
getData
(),
null
,
null
,
null
,
null
);
if
(
cursor
!=
null
)
{
if
(
cursor
.
moveToFirst
())
{
int
statusColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
STATUS
);
int
statusColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
COLUMN_
STATUS
);
int
status
=
cursor
.
getInt
(
statusColumn
);
int
visibilityColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
VISIBILITY
);
int
visibilityColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
COLUMN_VISIBILITY
);
int
visibility
=
cursor
.
getInt
(
visibilityColumn
);
if
(
Downloads
.
isStatusCompleted
(
status
)
&&
visibility
==
Downloads
.
VISIBILITY_VISIBLE_NOTIFY_COMPLETED
)
{
ContentValues
values
=
new
ContentValues
();
values
.
put
(
Downloads
.
VISIBILITY
,
Downloads
.
VISIBILITY_VISIBLE
);
values
.
put
(
Downloads
.
COLUMN_
VISIBILITY
,
Downloads
.
VISIBILITY_VISIBLE
);
context
.
getContentResolver
().
update
(
intent
.
getData
(),
values
,
null
,
null
);
}
if
(
intent
.
getAction
().
equals
(
Constants
.
ACTION_OPEN
))
{
int
filenameColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
_DATA
);
int
mimetypeColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
MIMETYPE
);
int
mimetypeColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
COLUMN_MIME_TYPE
);
String
filename
=
cursor
.
getString
(
filenameColumn
);
String
mimetype
=
cursor
.
getString
(
mimetypeColumn
);
Uri
path
=
Uri
.
parse
(
filename
);
...
...
@@ -109,13 +123,13 @@ public class DownloadReceiver extends BroadcastReceiver {
}
}
else
{
int
packageColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
NOTIFICATION_PACKAGE
);
cursor
.
getColumnIndexOrThrow
(
Downloads
.
COLUMN_
NOTIFICATION_PACKAGE
);
int
classColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
NOTIFICATION_CLASS
);
cursor
.
getColumnIndexOrThrow
(
Downloads
.
COLUMN_
NOTIFICATION_CLASS
);
String
pckg
=
cursor
.
getString
(
packageColumn
);
String
clazz
=
cursor
.
getString
(
classColumn
);
if
(
pckg
!=
null
&&
clazz
!=
null
)
{
Intent
appIntent
=
new
Intent
(
Downloads
.
NOTIFICATION_CLICKED
_ACTION
);
Intent
appIntent
=
new
Intent
(
Downloads
.
ACTION_
NOTIFICATION_CLICKED
);
appIntent
.
setClassName
(
pckg
,
clazz
);
if
(
intent
.
getBooleanExtra
(
"multiple"
,
true
))
{
appIntent
.
setData
(
Downloads
.
CONTENT_URI
);
...
...
@@ -141,14 +155,15 @@ public class DownloadReceiver extends BroadcastReceiver {
intent
.
getData
(),
null
,
null
,
null
,
null
);
if
(
cursor
!=
null
)
{
if
(
cursor
.
moveToFirst
())
{
int
statusColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
STATUS
);
int
statusColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
COLUMN_
STATUS
);
int
status
=
cursor
.
getInt
(
statusColumn
);
int
visibilityColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
VISIBILITY
);
int
visibilityColumn
=
cursor
.
getColumnIndexOrThrow
(
Downloads
.
COLUMN_VISIBILITY
);
int
visibility
=
cursor
.
getInt
(
visibilityColumn
);
if
(
Downloads
.
isStatusCompleted
(
status
)
&&
visibility
==
Downloads
.
VISIBILITY_VISIBLE_NOTIFY_COMPLETED
)
{
ContentValues
values
=
new
ContentValues
();
values
.
put
(
Downloads
.
VISIBILITY
,
Downloads
.
VISIBILITY_VISIBLE
);
values
.
put
(
Downloads
.
COLUMN_
VISIBILITY
,
Downloads
.
VISIBILITY_VISIBLE
);
context
.
getContentResolver
().
update
(
intent
.
getData
(),
values
,
null
,
null
);
}
}
...
...
This diff is collapsed.
Click to expand it.
src/com/android/providers/downloads/DownloadService.java
View file @
cf79a11f
This diff is collapsed.
Click to expand it.
src/com/android/providers/downloads/DownloadThread.java
View file @
cf79a11f
This diff is collapsed.
Click to expand it.
src/com/android/providers/downloads/Helpers.java
View file @
cf79a11f
...
...
@@ -38,18 +38,17 @@ import android.webkit.MimeTypeMap;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileOutputStream
;
import
java.util.List
;
import
java.util.Random
;
import
java.util.Set
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
java.util.Set
;
/**
* Some helper functions for the download manager
*/
public
class
Helpers
{
public
static
Random
rnd
=
new
Random
(
SystemClock
.
uptimeMillis
());
public
static
Random
sRandom
=
new
Random
(
SystemClock
.
uptimeMillis
());
/** Regex used to parse content-disposition headers */
private
static
final
Pattern
CONTENT_DISPOSITION_PATTERN
=
...
...
@@ -411,7 +410,7 @@ public class Helpers {
if
(
Constants
.
LOGVV
)
{
Log
.
v
(
Constants
.
TAG
,
"file with sequence number "
+
sequence
+
" exists"
);
}
sequence
+=
rnd
.
nextInt
(
magnitude
)
+
1
;
sequence
+=
sRandom
.
nextInt
(
magnitude
)
+
1
;
}
}
return
null
;
...
...
@@ -427,11 +426,11 @@ public class Helpers {
Downloads
.
CONTENT_URI
,
null
,
"( "
+
Downloads
.
STATUS
+
" = '"
+
Downloads
.
STATUS_SUCCESS
+
"' AND "
+
Downloads
.
DESTINATION
+
" = '"
+
Downloads
.
DESTINATION_CACHE_PARTITION_PURGEABLE
+
"' )"
,
Downloads
.
COLUMN_
STATUS
+
" = '"
+
Downloads
.
STATUS_SUCCESS
+
"' AND "
+
Downloads
.
COLUMN_
DESTINATION
+
" = '"
+
Downloads
.
DESTINATION_CACHE_PARTITION_PURGEABLE
+
"' )"
,
null
,
Downloads
.
LAST_MODIFICATION
);
Downloads
.
COLUMN_
LAST_MODIFICATION
);
if
(
cursor
==
null
)
{
return
false
;
}
...
...
@@ -755,7 +754,7 @@ public class Helpers {
// quoted strings
if
(
chars
[
mOffset
]
==
'\''
)
{
++
mOffset
;
while
(
mOffset
<
chars
.
length
)
{
while
(
mOffset
<
chars
.
length
)
{
if
(
chars
[
mOffset
]
==
'\''
)
{
if
(
mOffset
+
1
<
chars
.
length
&&
chars
[
mOffset
+
1
]
==
'\''
)
{
++
mOffset
;
...
...
This diff is collapsed.
Click to expand it.
tests/permission/src/com/android/providers/downloads/permission/tests/DownloadProviderPermissionsTest.java
View file @
cf79a11f
...
...
@@ -88,7 +88,7 @@ public class DownloadProviderPermissionsTest extends AndroidTestCase {
public
void
testWriteDownloadProvider
()
throws
IOException
{
try
{
ContentValues
values
=
new
ContentValues
();
values
.
put
(
Downloads
.
DESTINATION
,
"foo"
);
values
.
put
(
Downloads
.
COLUMN_URI
,
"foo"
);
mContentResolver
.
insert
(
Downloads
.
CONTENT_URI
,
values
);
fail
(
"write to provider did not throw SecurityException as expected."
);
}
catch
(
SecurityException
e
)
{
...
...
This diff is collapsed.
Click to expand it.
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment