Merge "Remove debug logging for b/106899184." into klp-dev
diff --git a/api/current.txt b/api/current.txt
index 973a9fdc..9a90a58 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18327,7 +18327,7 @@
ctor public ParcelFileDescriptor(android.os.ParcelFileDescriptor);
method public static android.os.ParcelFileDescriptor adoptFd(int);
method public boolean canDetectErrors();
- method public void checkError(boolean) throws java.io.IOException;
+ method public void checkError() throws java.io.IOException;
method public void close() throws java.io.IOException;
method public void closeWithError(java.lang.String) throws java.io.IOException;
method public static android.os.ParcelFileDescriptor[] createPipe() throws java.io.IOException;
@@ -18366,8 +18366,12 @@
ctor public ParcelFileDescriptor.AutoCloseOutputStream(android.os.ParcelFileDescriptor);
}
+ public static class ParcelFileDescriptor.FileDescriptorDetachedException extends java.io.IOException {
+ ctor public ParcelFileDescriptor.FileDescriptorDetachedException();
+ }
+
public static abstract interface ParcelFileDescriptor.OnCloseListener {
- method public abstract void onClose(java.io.IOException, boolean);
+ method public abstract void onClose(java.io.IOException);
}
public class ParcelFormatException extends java.lang.RuntimeException {
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 5a49b98..e436241 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -80,7 +80,7 @@
private byte[] mStatusBuf;
/**
- * Status read by {@link #checkError(boolean)}, or null if not read yet.
+ * Status read by {@link #checkError()}, or null if not read yet.
*/
private Status mStatus;
@@ -371,7 +371,7 @@
* <p>
* The write end has the ability to deliver an error message through
* {@link #closeWithError(String)} which can be handled by the read end
- * calling {@link #checkError(boolean)}, usually after detecting an EOF.
+ * calling {@link #checkError()}, usually after detecting an EOF.
* This can also be used to detect remote crashes.
*/
public static ParcelFileDescriptor[] createReliablePipe() throws IOException {
@@ -409,7 +409,7 @@
* <p>
* Both ends have the ability to deliver an error message through
* {@link #closeWithError(String)} which can be detected by the other end
- * calling {@link #checkError(boolean)}, usually after detecting an EOF.
+ * calling {@link #checkError()}, usually after detecting an EOF.
* This can also be used to detect remote crashes.
*/
public static ParcelFileDescriptor[] createReliableSocketPair() throws IOException {
@@ -698,7 +698,7 @@
* Indicates if this ParcelFileDescriptor can communicate and detect remote
* errors/crashes.
*
- * @see #checkError(boolean)
+ * @see #checkError()
*/
public boolean canDetectErrors() {
if (mWrapped != null) {
@@ -716,17 +716,16 @@
* If this ParcelFileDescriptor is unable to detect remote errors, it will
* return silently.
*
- * @param throwIfDetached requests that an exception be thrown if the remote
- * side called {@link #detachFd()}. Once detached, the remote
+ * @throws IOException for normal errors.
+ * @throws FileDescriptorDetachedException
+ * if the remote side called {@link #detachFd()}. Once detached, the remote
* side is unable to communicate any errors through
- * {@link #closeWithError(String)}. An application may pass true
- * if it needs a stronger guarantee that the stream was closed
- * normally and was not merely detached.
+ * {@link #closeWithError(String)}.
* @see #canDetectErrors()
*/
- public void checkError(boolean throwIfDetached) throws IOException {
+ public void checkError() throws IOException {
if (mWrapped != null) {
- mWrapped.checkError(throwIfDetached);
+ mWrapped.checkError();
} else {
if (mStatus == null) {
if (mCommFd == null) {
@@ -739,8 +738,7 @@
mStatus = readCommStatus(mCommFd, getOrCreateStatusBuffer());
}
- if (mStatus == null || mStatus.status == Status.OK
- || (mStatus.status == Status.DETACHED && !throwIfDetached)) {
+ if (mStatus == null || mStatus.status == Status.OK) {
// No status yet, or everything is peachy!
return;
} else {
@@ -885,13 +883,26 @@
* attached has been closed.
*
* @param e error state, or {@code null} if closed cleanly.
- * @param fromDetach indicates if close event was result of
- * {@link ParcelFileDescriptor#detachFd()}. After detach the
- * remote side may continue reading/writing to the underlying
- * {@link FileDescriptor}, but they can no longer deliver
- * reliable close/error events.
+ * If the close event was the result of
+ * {@link ParcelFileDescriptor#detachFd()}, this will be a
+ * {@link FileDescriptorDetachedException}. After detach the
+ * remote side may continue reading/writing to the underlying
+ * {@link FileDescriptor}, but they can no longer deliver
+ * reliable close/error events.
*/
- public void onClose(IOException e, boolean fromDetach);
+ public void onClose(IOException e);
+ }
+
+ /**
+ * Exception that indicates that the file descriptor was detached.
+ */
+ public static class FileDescriptorDetachedException extends IOException {
+
+ private static final long serialVersionUID = 0xDe7ac4edFdL;
+
+ public FileDescriptorDetachedException() {
+ super("Remote side is detached");
+ }
}
/**
@@ -934,7 +945,7 @@
case ERROR:
return new IOException("Remote error: " + msg);
case DETACHED:
- return new IOException("Remote side is detached");
+ return new FileDescriptorDetachedException();
case LEAKED:
return new IOException("Remote side was leaked");
default:
@@ -959,13 +970,7 @@
@Override
public void handleMessage(Message msg) {
final Status s = (Status) msg.obj;
- if (s.status == Status.DETACHED) {
- listener.onClose(null, true);
- } else if (s.status == Status.OK) {
- listener.onClose(null, false);
- } else {
- listener.onClose(s.asIOException(), false);
- }
+ listener.onClose(s != null ? s.asIOException() : null);
}
};
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index e4956dd..c0fde2e 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1099,13 +1099,18 @@
}
@Override
- public int computeVerticalScrollOffset() {
+ protected int computeVerticalScrollOffset() {
return mCurrentScrollOffset;
}
@Override
- public int computeVerticalScrollRange() {
- return mSelectorIndices.length * mSelectorElementHeight;
+ protected int computeVerticalScrollRange() {
+ return (mMaxValue - mMinValue + 1) * mSelectorElementHeight;
+ }
+
+ @Override
+ protected int computeVerticalScrollExtent() {
+ return getHeight();
}
@Override
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index c72c770..91056f1 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -24,10 +24,10 @@
boolean getBoolean(in String key, in boolean defaultValue, in int userId);
long getLong(in String key, in long defaultValue, in int userId);
String getString(in String key, in String defaultValue, in int userId);
- void setLockPattern(in byte[] hash, int userId);
- boolean checkPattern(in byte[] hash, int userId);
- void setLockPassword(in byte[] hash, int userId);
- boolean checkPassword(in byte[] hash, int userId);
+ void setLockPattern(in String pattern, int userId);
+ boolean checkPattern(in String pattern, int userId);
+ void setLockPassword(in String password, int userId);
+ boolean checkPassword(in String password, int userId);
boolean havePattern(int userId);
boolean havePassword(int userId);
void removeUser(int userId);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 1f2ab93..8adc7b6 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -32,7 +32,6 @@
import android.os.UserHandle;
import android.os.storage.IMountService;
import android.provider.Settings;
-import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -292,11 +291,7 @@
public boolean checkPattern(List<LockPatternView.Cell> pattern) {
final int userId = getCurrentOrCallingUserId();
try {
- final boolean matched = getLockSettings().checkPattern(patternToHash(pattern), userId);
- if (matched && (userId == UserHandle.USER_OWNER)) {
- KeyStore.getInstance().password(patternToString(pattern));
- }
- return matched;
+ return getLockSettings().checkPattern(patternToString(pattern), userId);
} catch (RemoteException re) {
return true;
}
@@ -311,12 +306,7 @@
public boolean checkPassword(String password) {
final int userId = getCurrentOrCallingUserId();
try {
- final boolean matched = getLockSettings().checkPassword(passwordToHash(password),
- userId);
- if (matched && (userId == UserHandle.USER_OWNER)) {
- KeyStore.getInstance().password(password);
- }
- return matched;
+ return getLockSettings().checkPassword(password, userId);
} catch (RemoteException re) {
return true;
}
@@ -505,14 +495,10 @@
* @param isFallback Specifies if this is a fallback to biometric weak
*/
public void saveLockPattern(List<LockPatternView.Cell> pattern, boolean isFallback) {
- // Compute the hash
- final byte[] hash = LockPatternUtils.patternToHash(pattern);
try {
- getLockSettings().setLockPattern(hash, getCurrentOrCallingUserId());
+ getLockSettings().setLockPattern(patternToString(pattern), getCurrentOrCallingUserId());
DevicePolicyManager dpm = getDevicePolicyManager();
- KeyStore keyStore = KeyStore.getInstance();
if (pattern != null) {
- keyStore.password(patternToString(pattern));
setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
if (!isFallback) {
deleteGallery();
@@ -528,9 +514,6 @@
0, 0, 0, 0, 0, 0, 0, getCurrentOrCallingUserId());
}
} else {
- if (keyStore.isEmpty()) {
- keyStore.reset();
- }
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0,
0, 0, 0, 0, 0, getCurrentOrCallingUserId());
}
@@ -637,19 +620,13 @@
* @param userHandle The userId of the user to change the password for
*/
public void saveLockPassword(String password, int quality, boolean isFallback, int userHandle) {
- // Compute the hash
- final byte[] hash = passwordToHash(password);
try {
- getLockSettings().setLockPassword(hash, userHandle);
+ getLockSettings().setLockPassword(password, userHandle);
DevicePolicyManager dpm = getDevicePolicyManager();
- KeyStore keyStore = KeyStore.getInstance();
if (password != null) {
if (userHandle == UserHandle.USER_OWNER) {
// Update the encryption password.
updateEncryptionPassword(password);
-
- // Update the keystore password
- keyStore.password(password);
}
int computedQuality = computePasswordQuality(password);
@@ -709,6 +686,7 @@
if (passwordHistoryLength == 0) {
passwordHistory = "";
} else {
+ byte[] hash = passwordToHash(password);
passwordHistory = new String(hash) + "," + passwordHistory;
// Cut it to contain passwordHistoryLength hashes
// and passwordHistoryLength -1 commas.
@@ -718,11 +696,6 @@
}
setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
} else {
- // Conditionally reset the keystore if empty. If
- // non-empty, we are just switching key guard type
- if (keyStore.isEmpty()) {
- keyStore.reset();
- }
dpm.setActivePasswordState(
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0,
userHandle);
@@ -803,7 +776,7 @@
* @param pattern the gesture pattern.
* @return the hash of the pattern in a byte array.
*/
- private static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
+ public static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
if (pattern == null) {
return null;
}
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 2846e61..0d9a386 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -138,7 +138,8 @@
DroidSansHebrew-Regular.ttf \
DroidSansHebrew-Bold.ttf \
DroidSansArmenian.ttf \
- DroidSansGeorgian.ttf
+ DroidSansGeorgian.ttf \
+ AndroidEmoji.ttf
endif # !MINIMAL_FONT
diff --git a/data/fonts/AndroidEmoji.ttf b/data/fonts/AndroidEmoji.ttf
new file mode 100644
index 0000000..98f72e7
--- /dev/null
+++ b/data/fonts/AndroidEmoji.ttf
Binary files differ
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 69db6aa..ede7ef4 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -186,6 +186,11 @@
</family>
<family>
<fileset>
+ <file>AndroidEmoji.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
<file>NotoColorEmoji.ttf</file>
</fileset>
</family>
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index a677c4f..05cca13e 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -43,6 +43,7 @@
DroidSansMono.ttf \
DroidSansArmenian.ttf \
DroidSansGeorgian.ttf \
+ AndroidEmoji.ttf \
Clockopia.ttf \
AndroidClock.ttf \
AndroidClock_Highlight.ttf \
diff --git a/docs/html/about/index.jd b/docs/html/about/index.jd
index 1573cc3..215fc3c 100644
--- a/docs/html/about/index.jd
+++ b/docs/html/about/index.jd
@@ -53,7 +53,7 @@
multitude of device form-factors, chipset architectures, and price points. From
multicore processing and high-performance graphics to state-of-the-art sensors,
vibrant touchscreens, and emerging mobile technologies such as Near Field
-Communication (NFC), Wi-Fi Direct, and face tracking.</p> -->
+Communication (NFC), Wi-Fi P2P, and face tracking.</p> -->
<h3>Powerful development framework</h3>
diff --git a/docs/html/about/versions/android-4.0-highlights.jd b/docs/html/about/versions/android-4.0-highlights.jd
index 9fdb02c..f2b35ac 100644
--- a/docs/html/about/versions/android-4.0-highlights.jd
+++ b/docs/html/about/versions/android-4.0-highlights.jd
@@ -610,14 +610,17 @@
unlock, or use a backup PIN or pattern. </p>
-<p style="margin-top:1em;margin-bottom:.75em;"><strong>Wi-Fi Direct and Bluetooth HDP</strong></p>
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Wi-Fi P2P and Bluetooth HDP</strong></p>
-<p>Support for <strong>Wi-Fi Direct</strong> lets users connect directly to
-nearby peer devices over Wi-Fi, for more reliable, higher-speed communication.
-No internet connection or tethering is needed. Through third-party apps, users
-can connect to compatible devices to take advantage of new features such as
-instant sharing of files, photos, or other media; streaming video or audio from
-another device; or connecting to compatible printers or other devices.</p>
+<p>Support for <strong>Wi-Fi peer-to-peer (P2P)</strong> lets users connect directly to nearby peer
+devices over Wi-Fi, for more reliable, higher-speed communication (in compliance with the Wi-Fi
+Alliance's <a href="http://www.wi-fi.org/discover-and-learn/wi-fi-direct"
+ class="external-link">Wi-Fi Direct™</a>
+certification program). No internet connection or tethering is needed. Through third-party apps,
+users can connect to compatible devices to take advantage of new features such as instant sharing
+of files, photos, or other media; streaming video or audio from another device; or connecting to
+compatible printers or other devices.</p>
+
<p>Android 4.0 also introduces built-in support for connecting to <strong>Bluetooth Health Device Profile (HDP)</strong> devices. With support from third-party apps, users can connect to wireless medical devices and sensors in hospitals, fitness centers, homes, and elsewhere.</p>
@@ -868,16 +871,19 @@
<h3 id="connectivity-dev">New types of connectivity</h3>
-<p style="margin-top:1em;margin-bottom:.75em;"><strong>Wi-Fi Direct</strong></p>
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Wi-Fi P2P</strong></p>
-<p>Developers can use a framework API to discover and connect directly to nearby
-devices over a high-performance, secure Wi-Fi Direct connection. No internet
-connection or hotspot is needed.</p>
+<p>Developers can use a framework API to discover and connect directly to nearby devices over a
+high-performance, secure Wi-Fi peer-to-peer (P2P) connection. No internet connection or hotspot is
+needed. Android's Wi-Fi P2P framework complies with the Wi-Fi Alliance's <a href=
+"http://www.wi-fi.org/discover-and-learn/wi-fi-direct" class="external-link">Wi-Fi Direct™</a>
+certification program.</p>
-<p>Wi-Fi Direct opens new opportunities for developers to add innovative
-features to their applications. Applications can use Wi-Fi Direct to share
+
+<p>Wi-Fi peer-to-peer (P2P) opens new opportunities for developers to add innovative
+features to their applications. Applications can use Wi-Fi P2P to share
files, photos, or other media between devices or between a desktop computer and
-an Android-powered device. Applications could also use Wi-Fi Direct to stream
+an Android-powered device. Applications could also use Wi-Fi P2P to stream
media content from a peer device such as a digital television or audio player,
connect a group of users for gaming, print files, and more.</p>
diff --git a/docs/html/about/versions/android-4.0.jd b/docs/html/about/versions/android-4.0.jd
index c026534..6c4ccb4 100644
--- a/docs/html/about/versions/android-4.0.jd
+++ b/docs/html/about/versions/android-4.0.jd
@@ -619,12 +619,14 @@
<h3 id="WiFiDirect">Wi-Fi P2P</h3>
-<p>Android now supports Wi-Fi peer-to-peer (P2P) connections between Android-powered
-devices and other device types (in compliance with the Wi-Fi
-Alliance's Wi-Fi Direct™ certification program) without a hotspot or Internet connection. The Android framework
-provides a set of Wi-Fi P2P APIs that allow you to discover and connect to other devices when each
-device supports Wi-Fi P2P, then communicate over a speedy connection across distances much longer
-than a Bluetooth connection.</p>
+<p>Android now supports Wi-Fi peer-to-peer (P2P) connections between Android-powered devices and
+other device types (in compliance with the Wi-Fi Alliance's <a href=
+"http://www.wi-fi.org/discover-and-learn/wi-fi-direct" class="external-link">Wi-Fi Direct™</a>
+certification program) without a hotspot or Internet connection. The Android framework provides a
+set of Wi-Fi P2P APIs that allow you to discover and connect to other devices when each device
+supports Wi-Fi P2P, then communicate over a speedy connection across distances much longer than a
+Bluetooth connection.</p>
+
<p>A new package, {@link android.net.wifi.p2p}, contains all the APIs for performing peer-to-peer
connections with Wi-Fi. The primary class you need to work with is {@link
diff --git a/docs/html/about/versions/jelly-bean.jd b/docs/html/about/versions/jelly-bean.jd
index 5deb190..c7d1941 100644
--- a/docs/html/about/versions/jelly-bean.jd
+++ b/docs/html/about/versions/jelly-bean.jd
@@ -860,13 +860,13 @@
<h3 id="42-wireless-display">Wireless display</h3>
-<p>Starting in Android 4.2, users on supported devices can connect to an
-external display over Wi-Fi, using <a
-href="http://www.wi-fi.org/wi-fi-certified-miracast%E2%84%A2">Miracast</a>, a
-peer-to-peer wireless display standard created by the <a
-href="http://www.wi-fi.org/">Wi-Fi Alliance</a>. When a wireless display is
-connected, users can stream any type of content to the big screen, including
-photos, games, maps, and more.</p>
+<p>Starting in Android 4.2, users on supported devices can connect to an external display over
+Wi-Fi, using Wi-Fi Display (a peer-to-peer wireless display solution that complies with the
+<a href="http://www.wi-fi.org/wi-fi-certified-miracast%E2%84%A2"
+ class="external-link">Miracast™</a> certification
+program). When a wireless display is connected, users can stream any type of content to the big
+screen, including photos, games, maps, and more.</p>
+
<p>Apps can take advantage of <strong>wireless displays</strong> in the same way as they do other
external displays and no extra work is needed. The system manages the network
@@ -1455,15 +1455,22 @@
<p>You can take advantage of this API to build new features into your apps. For example, you could let users connect to a webcam, a printer, or an app on another mobile device that supports Wi-Fi peer-to-peer connections. </p>
-<h3>Wi-Fi Direct Service Discovery</h3>
+<h3>Wi-Fi P2P Service Discovery</h3>
-<p>Ice Cream Sandwich introduced support for Wi-Fi Direct, a technology that lets apps <strong>discover and pair directly</strong>, over a high-bandwidth peer-to-peer connection. Wi-Fi Direct is an ideal way to share media, photos, files and other types of data and sessions, even where there is no cell network or Wi-Fi available.</p>
+<p><a href="{@docRoot}about/versions/android-4.0-highlights.html">Ice Cream Sandwich</a> introduced
+support for Wi-Fi Peer-to-Peer (P2P), a technology that lets apps <strong>discover and pair
+directly</strong>, over a high-bandwidth peer-to-peer connection (in compliance with the Wi-Fi
+Alliance's <a href="http://www.wi-fi.org/discover-and-learn/wi-fi-direct"
+ class="external-link">Wi-Fi Direct™</a>
+certification program). Wi-Fi P2P is an ideal way to share media, photos, files and other types of
+data and sessions, even where there is no cell network or Wi-Fi available.</p>
-<p>Android 4.1 takes Wi-Fi Direct further, adding API support for <strong>pre-associated service discovery</strong>. Pre-associated service discovery lets your apps get more useful information from nearby devices about the services they support, before they attempt to connect. Apps can initiate discovery for a specific service and filter the list of discovered devices to those that actually support the target service or application.</p>
-<p>For example, this means that your app could discover only devices that are “printers” or that have a specific game available, instead of discovering all nearby Wi-Fi Direct devices. On the other hand, your app can advertise the service it provides to other devices, which can discover it and then negotiate a connection. This greatly simplifies discovery and pairing for users and lets apps take advantage of Wi-Fi Direct more effectively.</p>
+<p>Android 4.1 takes Wi-Fi P2P further, adding API support for <strong>pre-associated service discovery</strong>. Pre-associated service discovery lets your apps get more useful information from nearby devices about the services they support, before they attempt to connect. Apps can initiate discovery for a specific service and filter the list of discovered devices to those that actually support the target service or application.</p>
-<p>With Wi-Fi Direct service discovery, you can create apps and <strong>multiplayer games</strong> that can share photos, videos, gameplay, scores, or almost anything else — all without requiring any Internet or mobile network. Your users can connect using only a direct p2p connection, which avoids using mobile bandwidth.</p>
+<p>For example, this means that your app could discover only devices that are “printers” or that have a specific game available, instead of discovering all nearby Wi-Fi P2P devices. On the other hand, your app can advertise the service it provides to other devices, which can discover it and then negotiate a connection. This greatly simplifies discovery and pairing for users and lets apps take advantage of Wi-Fi P2P more effectively.</p>
+
+<p>With Wi-Fi P2P service discovery, you can create apps and <strong>multiplayer games</strong> that can share photos, videos, gameplay, scores, or almost anything else — all without requiring any Internet or mobile network. Your users can connect using only a direct p2p connection, which avoids using mobile bandwidth.</p>
<h3>Network Bandwidth Management</h3>
diff --git a/docs/html/guide/topics/connectivity/index.jd b/docs/html/guide/topics/connectivity/index.jd
index 322518e..385cf08 100644
--- a/docs/html/guide/topics/connectivity/index.jd
+++ b/docs/html/guide/topics/connectivity/index.jd
@@ -1,6 +1,6 @@
page.title=Connectivity
page.landing=true
-page.landing.intro=Android provides rich APIs to let your app connect and interact with other devices over Bluetooth, NFC, Wi-Fi Direct, USB, and SIP, in addition to standard network connections.
+page.landing.intro=Android provides rich APIs to let your app connect and interact with other devices over Bluetooth, NFC, Wi-Fi P2P, USB, and SIP, in addition to standard network connections.
page.landing.image=images/develop/connectivity.png
@jd:body
diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd
index 14a1682..c62510b 100644
--- a/docs/html/guide/topics/renderscript/compute.jd
+++ b/docs/html/guide/topics/renderscript/compute.jd
@@ -10,7 +10,7 @@
<ol>
<li><a href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a></li>
- <li><a href="#access-rs-apis">Accessing RenderScript Java APIs</a>
+ <li><a href="#access-rs-apis">Accessing RenderScript APIs</a>
<ol>
<li><a href="#ide-setup">Setting Up Your Development Environment</a></li>
</ol>
@@ -150,19 +150,24 @@
precision (such as SIMD CPU instructions).</p>
-<h2 id="access-rs-apis">Accessing RenderScript Java APIs</h2>
+<h2 id="access-rs-apis">Accessing RenderScript APIs</h2>
-<p>When developing an Android application that uses RenderScript, you can access its Java API in
- one of two ways. The APIs are available in the {@link android.renderscript} package
- on devices running Android 3.0 (API level 11) and higher. These are the original APIs for
- RenderScript. The APIs are also available as a Support Library in the
- {@link android.support.v8.renderscript} package, which allow you to use them on devices running
- Android 2.2 (API level 8) and higher.</p>
+<p>When developing an Android application that uses RenderScript, you can access its API in
+ one of two ways:</p>
+
+<ul>
+ <li><strong>{@link android.renderscript}</strong> - The APIs in this class package are
+ available on devices running Android 3.0 (API level 11) and higher. These are the original APIs
+ for RenderScript and are not currently being updated.</li>
+ <li><strong>{@link android.support.v8.renderscript}</strong> - The APIs in this package are
+ available through a <a href="{@docRoot}tools/support-library/features.html#v8">Support
+ Library</a>, which allows you to use them on devices running Android 2.2 (API level 8) and
+ higher.</li>
+</ul>
<p>We strongly recommend using the Support Library APIs for accessing RenderScript because they
include the latest improvements to the RenderScript compute framework and provide a wider range
- of device compatibility. Using the RenderScript APIs in the Support Library requires specific
- setup procedures for your development environment, which is described in the next section.</p>
+ of device compatibility.</p>
<h3 id="ide-setup">Using the RenderScript Support Library APIs</h3>
@@ -218,9 +223,9 @@
back to a compatible version if the device it is running on does not support the target version.
</li>
<li>{@code sdk.buildtools} - The version of the Android SDK build tools to use. This value
- should be set to 18.1.0 or higher. If this option is not specified, the highest installed build
- tools version is used. You should always set this value to ensure the consistency of builds
- across development machines with different configurations.</li>
+ should be set to {@code 18.1.0} or higher. If this option is not specified, the highest
+ installed build tools version is used. You should always set this value to ensure the
+ consistency of builds across development machines with different configurations.</li>
</ul>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 0581435..118958d 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -5,43 +5,43 @@
page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
-sdk.linux32_bundle_download=adt-bundle-linux-x86-20130911.zip
-sdk.linux32_bundle_bytes=474916528
-sdk.linux32_bundle_checksum=7eacc7124299ea99a8fa15c59123540f
+sdk.linux32_bundle_download=adt-bundle-linux-x86-20130917.zip
+sdk.linux32_bundle_bytes=474924071
+sdk.linux32_bundle_checksum=912b2dac6e0a4fa4ae1417271bf42863
-sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20130911.zip
-sdk.linux64_bundle_bytes=475207785
-sdk.linux64_bundle_checksum=daa5794a27be7c7fa708c3d28833b0d3
+sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20130917.zip
+sdk.linux64_bundle_bytes=475215747
+sdk.linux64_bundle_checksum=2f7523d4eba9a8302c3c4a3955785e18
-sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20130911.zip
-sdk.mac64_bundle_bytes=448575446
-sdk.mac64_bundle_checksum=a1e0cbcc820ae734cfdf439c40811b4c
+sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20130917.zip
+sdk.mac64_bundle_bytes=448581372
+sdk.mac64_bundle_checksum=4e2d599486ecc935d24eeef5eb641364
-sdk.win32_bundle_download=adt-bundle-windows-x86-20130911.zip
-sdk.win32_bundle_bytes=481794820
-sdk.win32_bundle_checksum=88a2f4f242aac44f4b1c53e6eccc8710
+sdk.win32_bundle_download=adt-bundle-windows-x86-20130917.zip
+sdk.win32_bundle_bytes=481803289
+sdk.win32_bundle_checksum=5d6c79a47c8b47170cff3d231dcf7ad3
-sdk.win64_bundle_download=adt-bundle-windows-x86_64-20130911.zip
-sdk.win64_bundle_bytes=481927327
-sdk.win64_bundle_checksum=e3fa9b7e38af9ed9ac0e99fce3c7026c
+sdk.win64_bundle_download=adt-bundle-windows-x86_64-20130917.zip
+sdk.win64_bundle_bytes=481934982
+sdk.win64_bundle_checksum=918f80aad61ec21509d86a2fbd87fd44
-sdk.linux_download=android-sdk_r22.2-linux.tgz
-sdk.linux_bytes=100909403
-sdk.linux_checksum=2a3776839e823ba9acb7a87a3fe26e02
+sdk.linux_download=android-sdk_r22.2.1-linux.tgz
+sdk.linux_bytes=100918342
+sdk.linux_checksum=05911d3052a1cbf678561104d35a1bc0
-sdk.mac_download=android-sdk_r22.2-macosx.zip
-sdk.mac_bytes=74857114
-sdk.mac_checksum=9dfef6404e2f842c433073796aed8b7d
+sdk.mac_download=android-sdk_r22.2.1-macosx.zip
+sdk.mac_bytes=74859877
+sdk.mac_checksum=727a51affa2af733eca1aa307c73c3bd
-sdk.win_download=android-sdk_r22.2-windows.zip
-sdk.win_bytes=108790714
-sdk.win_checksum=1ac4c104378cd53049daa6c4458ec544
+sdk.win_download=android-sdk_r22.2.1-windows.zip
+sdk.win_bytes=108676651
+sdk.win_checksum=3b3f63ae00cf946d1174fa08b37d8542
-sdk.win_installer=installer_r22.2-windows.exe
-sdk.win_installer_bytes=88788974
-sdk.win_installer_checksum=e5503fa059297d2b18475c086ac6e80c
+sdk.win_installer=installer_r22.2.1-windows.exe
+sdk.win_installer_bytes=88795776
+sdk.win_installer_checksum=07e6e47de6c4549bea6986453119b37c
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index e038d20..66b1c43 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -1,8 +1,8 @@
page.title=Installing the Eclipse Plugin
-adt.zip.version=22.2.0
-adt.zip.download=ADT-22.2.0.zip
-adt.zip.bytes=14474195
-adt.zip.checksum=52892c9e3b1ad2d1e6edd50e48b2a127
+adt.zip.version=22.2.1
+adt.zip.download=ADT-22.2.1.zip
+adt.zip.bytes=14476845
+adt.zip.checksum=97176754a1e86adf2e5e05f44dc7229e
@jd:body
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index 151707a..cfdf8cc 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -57,6 +57,40 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>ADT 22.2.1</a> <em>(September 2013)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+<dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Java 1.6 or higher is required.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r22.2.1</a>.
+ If you haven't already installed SDK Tools r22.2.1 into your SDK, use the
+ Android SDK Manager to do so.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed problem with templates that causes the new project wizard to hang.
+ (<a href="http://b.android.com/60149">Issue 60149</a>)</li>
+ </ul>
+ </dd>
+
+</dl>
+</div>
+</div>
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>ADT 22.2</a> <em>(September 2013)</em>
</p>
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index e8c4717..25c409e 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -30,6 +30,40 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>SDK Tools, Revision 22.2.1</a> <em>(September 2013)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+
+ <dl>
+ <dt>Dependencies:</dt>
+ <dd>
+ <ul>
+ <li>Android SDK Platform-tools revision 16 or later.</li>
+ <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
+ designed for use with ADT 22.2.1 and later. If you haven't already, update your
+ <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 22.2.1.</li>
+ <li>If you are developing outside Eclipse, you must have
+ <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed problem with templates that causes the new project wizard to hang.
+ (<a href="http://b.android.com/60149">Issue 60149</a>)</li>
+ <li>Fixed crash when using the lint command line tool because of mis-matched library
+ dependency. (<a href="http://b.android.com/60190">Issue 60190</a>)</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+</div>
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>SDK Tools, Revision 22.2</a> <em>(September 2013)</em>
</p>
diff --git a/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd b/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd
index 8dc5fd9..5c1321e 100644
--- a/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd
+++ b/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd
@@ -1,7 +1,4 @@
page.title=Using Wi-Fi P2P for Service Discovery
-parent.title=Connecting Devices Wirelessly
-parent.link=index.html
-
trainingnavtop=true
@jd:body
diff --git a/docs/html/training/connect-devices-wirelessly/nsd.jd b/docs/html/training/connect-devices-wirelessly/nsd.jd
index 30f5c49..e07e2af 100644
--- a/docs/html/training/connect-devices-wirelessly/nsd.jd
+++ b/docs/html/training/connect-devices-wirelessly/nsd.jd
@@ -1,10 +1,6 @@
page.title=Using Network Service Discovery
-parent.title=Connecting Devices Wirelessly
-parent.link=index.html
trainingnavtop=true
-next.title=Connecting with Wi-Fi Direct
-next.link=wifi-direct.html
@jd:body
diff --git a/docs/html/training/connect-devices-wirelessly/wifi-direct.jd b/docs/html/training/connect-devices-wirelessly/wifi-direct.jd
index 98435c6..d67ed23 100644
--- a/docs/html/training/connect-devices-wirelessly/wifi-direct.jd
+++ b/docs/html/training/connect-devices-wirelessly/wifi-direct.jd
@@ -23,8 +23,10 @@
</div>
<p>The Wi-Fi peer-to-peer (P2P) APIs allow applications to connect to nearby devices without
-needing to connect to a network or hotspot (Android's Wi-Fi P2P framework complies with the Wi-Fi
-Alliance's Wi-Fi Direct™ certification program). Wi-Fi P2P allows your application to quickly
+needing to connect to a network or hotspot (Android's Wi-Fi P2P framework complies with the
+<a href="http://www.wi-fi.org/discover-and-learn/wi-fi-direct"
+ class="external-link">Wi-Fi Direct™</a> certification program).
+ Wi-Fi P2P allows your application to quickly
find and interact with nearby devices, at a range beyond the capabilities of Bluetooth.
</p>
<p>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 0c4f9df..8c2752e 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -418,7 +418,7 @@
</a>
</li>
<li><a href="<?cs var:toroot ?>training/connect-devices-wirelessly/nsd-wifi-direct.html">
- Using Wi-Fi Direct for Service Discovery
+ Using Wi-Fi P2P for Service Discovery
</a>
</li>
</ul>
diff --git a/packages/DocumentsUI/res/animator/dir_down.xml b/packages/DocumentsUI/res/animator/dir_down.xml
new file mode 100644
index 0000000..7f547f1
--- /dev/null
+++ b/packages/DocumentsUI/res/animator/dir_down.xml
@@ -0,0 +1,22 @@
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:propertyName="position"
+ android:valueType="floatType"
+ android:duration="@android:integer/config_mediumAnimTime"
+ android:interpolator="@android:interpolator/decelerate_quad" />
diff --git a/packages/DocumentsUI/res/animator/dir_frozen.xml b/packages/DocumentsUI/res/animator/dir_frozen.xml
new file mode 100644
index 0000000..b541d13
--- /dev/null
+++ b/packages/DocumentsUI/res/animator/dir_frozen.xml
@@ -0,0 +1,21 @@
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:propertyName="position"
+ android:valueType="floatType"
+ android:duration="@android:integer/config_mediumAnimTime" />
diff --git a/packages/DocumentsUI/res/animator/dir_up.xml b/packages/DocumentsUI/res/animator/dir_up.xml
new file mode 100644
index 0000000..fda0faf
--- /dev/null
+++ b/packages/DocumentsUI/res/animator/dir_up.xml
@@ -0,0 +1,22 @@
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:propertyName="position"
+ android:valueType="floatType"
+ android:duration="@android:integer/config_mediumAnimTime"
+ android:interpolator="@android:interpolator/accelerate_quad" />
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_album.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_album.png
new file mode 100644
index 0000000..a1e2b7f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_album.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_generic.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_generic.png
new file mode 100644
index 0000000..68d973f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_generic.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png
index c86b92d..7e2bef1 100644
--- a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_grid_folder.png b/packages/DocumentsUI/res/drawable-hdpi/ic_grid_folder.png
new file mode 100644
index 0000000..7c9aee3
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_grid_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png
index 06adf31..490d7ca 100644
--- a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_overflow.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_overflow.png
new file mode 100644
index 0000000..d49b58f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_overflow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_popout.png b/packages/DocumentsUI/res/drawable-hdpi/ic_popout.png
new file mode 100644
index 0000000..f89f813
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_popout.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_album.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_album.png
new file mode 100644
index 0000000..adf23f4
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_album.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_generic.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_generic.png
new file mode 100644
index 0000000..f73ab71
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_generic.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png
index ff51096..4fca711 100644
--- a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_grid_folder.png b/packages/DocumentsUI/res/drawable-mdpi/ic_grid_folder.png
new file mode 100644
index 0000000..7cf9178
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_grid_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_overflow.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_overflow.png
new file mode 100644
index 0000000..795a28d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_overflow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_popout.png b/packages/DocumentsUI/res/drawable-mdpi/ic_popout.png
new file mode 100644
index 0000000..98a853f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_popout.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_dialog_alert.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_dialog_alert.png
index d824bb0..7d1468a 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_dialog_alert.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_dialog_alert.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_dir_shadow.9.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_dir_shadow.9.png
new file mode 100644
index 0000000..0240874
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_dir_shadow.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_album.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_album.png
new file mode 100644
index 0000000..29e009e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_album.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_generic.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_generic.png
new file mode 100644
index 0000000..82cf876
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_generic.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png
index 518e591..3e94790 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_folder.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_folder.png
new file mode 100644
index 0000000..3344980
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_copy.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_copy.png
index 946e450..614b1e3 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_copy.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_copy.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png
index 4af42d4..f94d3f6 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_overflow.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_overflow.png
new file mode 100644
index 0000000..0603bbf
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_overflow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share.png
index bdd8e20..1cf6dca 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_undo.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_undo.png
index 34a0e33..0cadd92 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_undo.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_undo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png
index c955fc3..8ec013c 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png
index a23c73a..45dd72f 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_popout.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_popout.png
new file mode 100644
index 0000000..3a33bce
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_popout.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png
index f66739d..6f64d8c 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png
index 7e24377..000a521 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_sdcard.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_sdcard.png
index 0ce9f9f..223cff1 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_sdcard.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_sdcard.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png
index dde7586..d77023b 100644
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_dialog_alert.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_dialog_alert.png
index 887b1b5..865f3a5 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_dialog_alert.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_dialog_alert.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_album.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_album.png
new file mode 100644
index 0000000..7515993
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_album.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_generic.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_generic.png
new file mode 100644
index 0000000..c459556
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_generic.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png
index dd94dda..cd46f79 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_folder.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_folder.png
new file mode 100644
index 0000000..86a74cd
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_copy.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_copy.png
index 2a0cfc2..1f72cce 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_copy.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_copy.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png
index fb40707..038a597 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_overflow.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_overflow.png
new file mode 100644
index 0000000..58f1381
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_overflow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share.png
index 0a3ac2e..9084717 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_undo.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_undo.png
index fd0a194..eec1b95 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_undo.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_undo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png
index 11ec8da..175a76c 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png
index ed3b0c5..07c7c02 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_popout.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_popout.png
new file mode 100644
index 0000000..5f5a86f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_popout.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png
index f22a94a..d68f9c5 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png
index 09cac0e..d95ebb5 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_sdcard.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_sdcard.png
index 5349252..cc27107 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_sdcard.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_sdcard.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png
index 6deafc7..1562609 100644
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/DocumentsUI/res/layout/activity.xml b/packages/DocumentsUI/res/layout/activity.xml
index ff28e41..9937c39 100644
--- a/packages/DocumentsUI/res/layout/activity.xml
+++ b/packages/DocumentsUI/res/layout/activity.xml
@@ -24,7 +24,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <FrameLayout
+ <com.android.documentsui.DirectoryContainerView
android:id="@+id/container_directory"
android:layout_width="match_parent"
android:layout_height="0dip"
diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml
index b4138a5..07bf127 100644
--- a/packages/DocumentsUI/res/layout/fragment_directory.xml
+++ b/packages/DocumentsUI/res/layout/fragment_directory.xml
@@ -14,9 +14,10 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.DirectoryView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:background="@drawable/ic_dir_shadow">
<TextView
android:id="@android:id/empty"
@@ -40,4 +41,4 @@
android:listSelector="@android:color/transparent"
android:visibility="gone" />
-</FrameLayout>
+</com.android.documentsui.DirectoryView>
diff --git a/packages/DocumentsUI/res/values-sw720dp/styles.xml b/packages/DocumentsUI/res/values-sw720dp/styles.xml
index 4ff1c60..a581e08 100644
--- a/packages/DocumentsUI/res/values-sw720dp/styles.xml
+++ b/packages/DocumentsUI/res/values-sw720dp/styles.xml
@@ -16,6 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Theme" parent="@android:style/Theme.Holo.Light">
+ <item name="android:actionOverflowButtonStyle">@style/DarkerOverflow</item>
<item name="android:windowBackground">@*android:drawable/dialog_full_holo_light</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index 945e7ae..0c8f712 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -29,5 +29,12 @@
<!-- Normally just a redirection, but this is used to make ourselves a
dialog on large tablets -->
- <style name="Theme" parent="@android:style/Theme.Holo.Light" />
+ <style name="Theme" parent="@android:style/Theme.Holo.Light">
+ <item name="android:actionOverflowButtonStyle">@style/DarkerOverflow</item>
+ </style>
+
+ <style name="DarkerOverflow" parent="@android:style/Widget.Holo.Light.ActionButton.Overflow">
+ <item name="android:src">@drawable/ic_menu_overflow</item>
+ </style>
+
</resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryContainerView.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryContainerView.java
new file mode 100644
index 0000000..77595b6
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryContainerView.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import java.util.ArrayList;
+
+public class DirectoryContainerView extends FrameLayout {
+ private boolean mDisappearingFirst = false;
+
+ public DirectoryContainerView(Context context) {
+ super(context);
+ setClipChildren(false);
+ }
+
+ public DirectoryContainerView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setClipChildren(false);
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ final ArrayList<View> disappearing = mDisappearingChildren;
+ if (mDisappearingFirst && disappearing != null) {
+ for (int i = 0; i < disappearing.size(); i++) {
+ super.drawChild(canvas, disappearing.get(i), getDrawingTime());
+ }
+ }
+ super.dispatchDraw(canvas);
+ }
+
+ @Override
+ protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+ if (mDisappearingFirst && mDisappearingChildren != null
+ && mDisappearingChildren.contains(child)) {
+ return false;
+ }
+ return super.drawChild(canvas, child, drawingTime);
+ }
+
+ public void setDrawDisappearingFirst(boolean disappearingFirst) {
+ mDisappearingFirst = disappearingFirst;
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 198927c..4c2c99c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -43,12 +43,14 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.text.format.DateUtils;
import android.text.format.Formatter;
import android.text.format.Time;
import android.util.Log;
+import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
@@ -96,7 +98,13 @@
public static final int TYPE_SEARCH = 2;
public static final int TYPE_RECENT_OPEN = 3;
+ public static final int ANIM_NONE = 1;
+ public static final int ANIM_SIDE = 2;
+ public static final int ANIM_DOWN = 3;
+ public static final int ANIM_UP = 4;
+
private int mType = TYPE_NORMAL;
+ private String mStateKey;
private int mLastMode = MODE_UNKNOWN;
private int mLastSortOrder = SORT_ORDER_UNKNOWN;
@@ -113,39 +121,61 @@
private static final String EXTRA_ROOT = "root";
private static final String EXTRA_DOC = "doc";
private static final String EXTRA_QUERY = "query";
+ private static final String EXTRA_IGNORE_STATE = "ignoreState";
private static AtomicInteger sLoaderId = new AtomicInteger(4000);
private final int mLoaderId = sLoaderId.incrementAndGet();
- public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc) {
- show(fm, TYPE_NORMAL, root, doc, null);
+ public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
+ show(fm, TYPE_NORMAL, root, doc, null, anim);
}
- public static void showSearch(FragmentManager fm, RootInfo root, String query) {
- show(fm, TYPE_SEARCH, root, null, query);
+ public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) {
+ show(fm, TYPE_SEARCH, root, null, query, anim);
}
- public static void showRecentsOpen(FragmentManager fm) {
- show(fm, TYPE_RECENT_OPEN, null, null, null);
+ public static void showRecentsOpen(FragmentManager fm, int anim) {
+ show(fm, TYPE_RECENT_OPEN, null, null, null, anim);
}
- private static void show(
- FragmentManager fm, int type, RootInfo root, DocumentInfo doc, String query) {
+ private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc,
+ String query, int anim) {
final Bundle args = new Bundle();
args.putInt(EXTRA_TYPE, type);
args.putParcelable(EXTRA_ROOT, root);
args.putParcelable(EXTRA_DOC, doc);
args.putString(EXTRA_QUERY, query);
+ final FragmentTransaction ft = fm.beginTransaction();
+ switch (anim) {
+ case ANIM_SIDE:
+ args.putBoolean(EXTRA_IGNORE_STATE, true);
+ break;
+ case ANIM_DOWN:
+ args.putBoolean(EXTRA_IGNORE_STATE, true);
+ ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen);
+ break;
+ case ANIM_UP:
+ ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up);
+ break;
+ }
+
final DirectoryFragment fragment = new DirectoryFragment();
fragment.setArguments(args);
- final FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container_directory, fragment);
ft.commitAllowingStateLoss();
}
+ private static String buildStateKey(RootInfo root, DocumentInfo doc) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(root != null ? root.authority : "null").append(';');
+ builder.append(root != null ? root.rootId : "null").append(';');
+ builder.append(doc != null ? doc.documentId : "null");
+ return builder.toString();
+ }
+
public static DirectoryFragment get(FragmentManager fm) {
// TODO: deal with multiple directories shown at once
return (DirectoryFragment) fm.findFragmentById(R.id.container_directory);
@@ -184,6 +214,7 @@
mAdapter = new DocumentsAdapter();
mType = getArguments().getInt(EXTRA_TYPE);
+ mStateKey = buildStateKey(root, doc);
if (mType == TYPE_RECENT_OPEN) {
// Hide titles when showing recents for picking images/videos
@@ -241,11 +272,16 @@
updateDisplayState();
- if (mLastSortOrder != state.derivedSortOrder) {
- mLastSortOrder = state.derivedSortOrder;
+ // Restore any previous instance state
+ final SparseArray<Parcelable> container = state.dirState.remove(mStateKey);
+ if (container != null && !getArguments().getBoolean(EXTRA_IGNORE_STATE, false)) {
+ getView().restoreHierarchyState(container);
+ } else if (mLastSortOrder != state.derivedSortOrder) {
mListView.smoothScrollToPosition(0);
mGridView.smoothScrollToPosition(0);
}
+
+ mLastSortOrder = state.derivedSortOrder;
}
@Override
@@ -261,6 +297,17 @@
}
@Override
+ public void onStop() {
+ super.onStop();
+
+ // Remember last scroll location
+ final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
+ getView().saveHierarchyState(container);
+ final State state = getDisplayState(this);
+ state.dirState.put(mStateKey, container);
+ }
+
+ @Override
public void onResume() {
super.onResume();
updateDisplayState();
@@ -734,7 +781,8 @@
iconMime.setImageDrawable(
IconUtils.loadPackageIcon(context, docAuthority, docIcon));
} else {
- iconMime.setImageDrawable(IconUtils.loadMimeIcon(context, docMimeType));
+ iconMime.setImageDrawable(IconUtils.loadMimeIcon(
+ context, docMimeType, docAuthority, docId, state.derivedMode));
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryView.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryView.java
new file mode 100644
index 0000000..34cb14fd
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryView.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+public class DirectoryView extends FrameLayout {
+ private float mPosition = 0f;
+
+ private int mWidth;
+
+ public DirectoryView(Context context) {
+ super(context);
+ }
+
+ public DirectoryView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void setBackground(Drawable background) {
+ final Rect rect = new Rect();
+ background.getPadding(rect);
+ final InsetDrawable inset = new InsetDrawable(background, -rect.left, 0, 0, 0);
+ super.setBackground(inset);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ mWidth = w;
+ setPosition(mPosition);
+ }
+
+ public float getPosition() {
+ return mPosition;
+ }
+
+ public void setPosition(float position) {
+ mPosition = position;
+ setX((mWidth > 0) ? (mPosition * mWidth) : 0);
+ setAlpha(1f - position);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index f6cb481..3b71f60 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -16,6 +16,10 @@
package com.android.documentsui;
+import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
+import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
+import static com.android.documentsui.DirectoryFragment.ANIM_SIDE;
+import static com.android.documentsui.DirectoryFragment.ANIM_UP;
import static com.android.documentsui.DocumentsActivity.State.ACTION_CREATE;
import static com.android.documentsui.DocumentsActivity.State.ACTION_GET_CONTENT;
import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE;
@@ -44,6 +48,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
+import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
import android.support.v4.app.ActionBarDrawerToggle;
@@ -51,6 +56,7 @@
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.util.Log;
+import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -73,12 +79,14 @@
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
+import com.google.common.collect.Maps;
import libcore.io.IoUtils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
public class DocumentsActivity extends Activity {
@@ -94,6 +102,8 @@
private ActionBarDrawerToggle mDrawerToggle;
private View mRootsContainer;
+ private DirectoryContainerView mDirectoryContainer;
+
private boolean mIgnoreNextNavigation;
private boolean mIgnoreNextClose;
private boolean mIgnoreNextCollapse;
@@ -165,6 +175,8 @@
mRootsContainer = findViewById(R.id.container_roots);
}
+ mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
+
if (icicle != null) {
mState = icicle.getParcelable(EXTRA_STATE);
} else {
@@ -195,7 +207,7 @@
RootsFragment.show(getFragmentManager(), null);
}
- onCurrentDirectoryChanged();
+ onCurrentDirectoryChanged(ANIM_NONE);
}
private void buildDefaultState() {
@@ -397,7 +409,7 @@
public boolean onQueryTextSubmit(String query) {
mState.currentSearch = query;
mSearchView.clearFocus();
- onCurrentDirectoryChanged();
+ onCurrentDirectoryChanged(ANIM_NONE);
return true;
}
@@ -421,7 +433,7 @@
}
mState.currentSearch = null;
- onCurrentDirectoryChanged();
+ onCurrentDirectoryChanged(ANIM_NONE);
return true;
}
});
@@ -435,7 +447,7 @@
}
mState.currentSearch = null;
- onCurrentDirectoryChanged();
+ onCurrentDirectoryChanged(ANIM_NONE);
return false;
}
});
@@ -595,7 +607,7 @@
final int size = mState.stack.size();
if (size > 1) {
mState.stack.pop();
- onCurrentDirectoryChanged();
+ onCurrentDirectoryChanged(ANIM_UP);
} else if (size == 1 && !isRootsDrawerOpen()) {
// TODO: open root drawer once we can capture back key
super.onBackPressed();
@@ -690,7 +702,7 @@
mState.stackTouched = true;
mState.stack.pop();
}
- onCurrentDirectoryChanged();
+ onCurrentDirectoryChanged(ANIM_UP);
return true;
}
};
@@ -711,17 +723,19 @@
return mState;
}
- private void onCurrentDirectoryChanged() {
+ private void onCurrentDirectoryChanged(int anim) {
final FragmentManager fm = getFragmentManager();
final RootInfo root = getCurrentRoot();
final DocumentInfo cwd = getCurrentDirectory();
+ mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_DOWN);
+
if (cwd == null) {
// No directory means recents
if (mState.action == ACTION_CREATE) {
RecentsCreateFragment.show(fm);
} else {
- DirectoryFragment.showRecentsOpen(fm);
+ DirectoryFragment.showRecentsOpen(fm, anim);
// Start recents in relevant mode
final boolean acceptImages = MimePredicate.mimeMatches(
@@ -732,10 +746,10 @@
} else {
if (mState.currentSearch != null) {
// Ongoing search
- DirectoryFragment.showSearch(fm, root, mState.currentSearch);
+ DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
} else {
// Normal boring directory
- DirectoryFragment.showNormal(fm, root, cwd);
+ DirectoryFragment.showNormal(fm, root, cwd, anim);
}
}
@@ -760,7 +774,7 @@
public void onStackPicked(DocumentStack stack) {
mState.stack = stack;
mState.stackTouched = true;
- onCurrentDirectoryChanged();
+ onCurrentDirectoryChanged(ANIM_SIDE);
}
public void onRootPicked(RootInfo root, boolean closeDrawer) {
@@ -772,11 +786,14 @@
if (!mRoots.isRecentsRoot(root)) {
try {
final Uri uri = DocumentsContract.buildDocumentUri(root.authority, root.documentId);
- onDocumentPicked(DocumentInfo.fromUri(getContentResolver(), uri));
+ final DocumentInfo doc = DocumentInfo.fromUri(getContentResolver(), uri);
+ mState.stack.push(doc);
+ mState.stackTouched = true;
+ onCurrentDirectoryChanged(ANIM_SIDE);
} catch (FileNotFoundException e) {
}
} else {
- onCurrentDirectoryChanged();
+ onCurrentDirectoryChanged(ANIM_SIDE);
}
if (closeDrawer) {
@@ -798,7 +815,7 @@
if (doc.isDirectory()) {
mState.stack.push(doc);
mState.stackTouched = true;
- onCurrentDirectoryChanged();
+ onCurrentDirectoryChanged(ANIM_DOWN);
} else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
// Explicit file picked, return
onFinished(doc.derivedUri);
@@ -924,6 +941,9 @@
/** Currently active search, overriding any stack. */
public String currentSearch;
+ /** Instance state for every shown directory */
+ public HashMap<String, SparseArray<Parcelable>> dirState = Maps.newHashMap();
+
public static final int ACTION_OPEN = 1;
public static final int ACTION_CREATE = 2;
public static final int ACTION_GET_CONTENT = 3;
@@ -956,6 +976,7 @@
out.writeInt(stackTouched ? 1 : 0);
DurableUtils.writeToParcel(out, stack);
out.writeString(currentSearch);
+ out.writeMap(dirState);
}
public static final Creator<State> CREATOR = new Creator<State>() {
@@ -973,6 +994,7 @@
state.stackTouched = in.readInt() != 0;
DurableUtils.readFromParcel(in, state.stack);
state.currentSearch = in.readString();
+ in.readMap(state.dirState, null);
return state;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
index 5caf9ba..1f7386c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
@@ -22,6 +22,7 @@
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.provider.DocumentsContract.Document;
+import android.util.Log;
import com.google.android.collect.Maps;
@@ -206,6 +207,27 @@
return null;
}
+ public static Drawable loadMimeIcon(
+ Context context, String mimeType, String authority, String docId, int mode) {
+ final Resources res = context.getResources();
+
+ if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+ // TODO: eventually move these hacky assets into that package
+ if ("com.android.providers.media.documents".equals(authority)
+ && docId.startsWith("album")) {
+ return res.getDrawable(R.drawable.ic_doc_album);
+ }
+
+ if (mode == DocumentsActivity.State.MODE_GRID) {
+ return res.getDrawable(R.drawable.ic_grid_folder);
+ } else {
+ return res.getDrawable(R.drawable.ic_root_folder);
+ }
+ }
+
+ return loadMimeIcon(context, mimeType);
+ }
+
public static Drawable loadMimeIcon(Context context, String mimeType) {
final Resources res = context.getResources();
@@ -236,8 +258,7 @@
} else if ("video".equals(typeOnly)) {
return res.getDrawable(R.drawable.ic_doc_video);
} else {
- // TODO: generic icon?
- return null;
+ return res.getDrawable(R.drawable.ic_doc_generic);
}
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
index 2d96876..9df55a0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
@@ -80,10 +80,10 @@
}
public static boolean mimeMatches(String filter, String test) {
- if (filter == null || "*/*".equals(filter)) {
- return true;
- } else if (test == null) {
+ if (test == null) {
return false;
+ } else if (filter == null || "*/*".equals(filter)) {
+ return true;
} else if (filter.equals(test)) {
return true;
} else if (filter.endsWith("/*")) {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 8ab4645..34e87cc 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -139,7 +139,7 @@
private static final int MIN_COPIES = 1;
private static final String MIN_COPIES_STRING = String.valueOf(MIN_COPIES);
- private static final Pattern PATTERN_DIGITS = Pattern.compile("\\d");
+ private static final Pattern PATTERN_DIGITS = Pattern.compile("[\\d]+");
private static final Pattern PATTERN_ESCAPE_SPECIAL_CHARS = Pattern.compile(
"(?=[]\\[+&|!(){}^\"~*?:\\\\])");
@@ -1484,7 +1484,8 @@
fromIndex = toIndex = Integer.parseInt(range) - 1;
}
- PageRange pageRange = new PageRange(fromIndex, toIndex);
+ PageRange pageRange = new PageRange(Math.min(fromIndex, toIndex),
+ Math.max(fromIndex, toIndex));
pageRanges.add(pageRange);
}
@@ -2166,6 +2167,11 @@
return false;
}
+ if (ourPageRanges.length == 1
+ && PageRange.ALL_PAGES.equals(ourPageRanges[0])) {
+ return true;
+ }
+
otherPageRanges = normalize(otherPageRanges);
int otherPageIdx = 0;
@@ -2197,28 +2203,28 @@
if (pageRanges == null) {
return null;
}
- final int oldPageCount = pageRanges.length;
- if (oldPageCount <= 1) {
+ final int oldRangeCount = pageRanges.length;
+ if (oldRangeCount <= 1) {
return pageRanges;
}
Arrays.sort(pageRanges, sComparator);
- int newRangeCount = 0;
- for (int i = 0; i < oldPageCount - 1; i++) {
+ int newRangeCount = 1;
+ for (int i = 0; i < oldRangeCount - 1; i++) {
newRangeCount++;
PageRange currentRange = pageRanges[i];
PageRange nextRange = pageRanges[i + 1];
- if (currentRange.getEnd() >= nextRange.getStart()) {
+ if (currentRange.getEnd() + 1 >= nextRange.getStart()) {
newRangeCount--;
pageRanges[i] = null;
pageRanges[i + 1] = new PageRange(currentRange.getStart(),
- nextRange.getEnd());
+ Math.max(currentRange.getEnd(), nextRange.getEnd()));
}
}
- if (newRangeCount == oldPageCount) {
+ if (newRangeCount == oldRangeCount) {
return pageRanges;
}
- return Arrays.copyOfRange(pageRanges, oldPageCount - newRangeCount,
- oldPageCount - 1);
+ return Arrays.copyOfRange(pageRanges, oldRangeCount - newRangeCount,
+ oldRangeCount);
}
public static void offsetStart(PageRange[] pageRanges, int offset) {
diff --git a/services/java/com/android/server/LockSettingsService.java b/services/java/com/android/server/LockSettingsService.java
index c5555c8..cd746cf 100644
--- a/services/java/com/android/server/LockSettingsService.java
+++ b/services/java/com/android/server/LockSettingsService.java
@@ -40,6 +40,7 @@
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.provider.Settings.SettingNotFoundException;
+import android.security.KeyStore;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -80,11 +81,14 @@
private static final String LOCK_PASSWORD_FILE = "password.key";
private final Context mContext;
+ private LockPatternUtils mLockPatternUtils;
public LockSettingsService(Context context) {
mContext = context;
// Open the database
mOpenHelper = new DatabaseHelper(mContext);
+
+ mLockPatternUtils = new LockPatternUtils(context);
}
public void systemReady() {
@@ -255,15 +259,42 @@
return new File(getLockPatternFilename(userId)).length() > 0;
}
+ private void maybeUpdateKeystore(String password, int userId) {
+ if (userId == UserHandle.USER_OWNER) {
+ final KeyStore keyStore = KeyStore.getInstance();
+ // Conditionally reset the keystore if empty. If non-empty, we are just
+ // switching key guard type
+ if (TextUtils.isEmpty(password) && keyStore.isEmpty()) {
+ keyStore.reset();
+ } else {
+ // Update the keystore password
+ keyStore.password(password);
+ }
+ }
+ }
+
@Override
- public void setLockPattern(byte[] hash, int userId) throws RemoteException {
+ public void setLockPattern(String pattern, int userId) throws RemoteException {
checkWritePermission(userId);
+ maybeUpdateKeystore(pattern, userId);
+
+ final byte[] hash = LockPatternUtils.patternToHash(
+ LockPatternUtils.stringToPattern(pattern));
writeFile(getLockPatternFilename(userId), hash);
}
@Override
- public boolean checkPattern(byte[] hash, int userId) throws RemoteException {
+ public void setLockPassword(String password, int userId) throws RemoteException {
+ checkWritePermission(userId);
+
+ maybeUpdateKeystore(password, userId);
+
+ writeFile(getLockPasswordFilename(userId), mLockPatternUtils.passwordToHash(password));
+ }
+
+ @Override
+ public boolean checkPattern(String pattern, int userId) throws RemoteException {
checkPasswordReadPermission(userId);
try {
// Read all the bytes from the file
@@ -275,25 +306,23 @@
return true;
}
// Compare the hash from the file with the entered pattern's hash
- return Arrays.equals(stored, hash);
+ final byte[] hash = LockPatternUtils.patternToHash(
+ LockPatternUtils.stringToPattern(pattern));
+ final boolean matched = Arrays.equals(stored, hash);
+ if (matched && !TextUtils.isEmpty(pattern)) {
+ maybeUpdateKeystore(pattern, userId);
+ }
+ return matched;
} catch (FileNotFoundException fnfe) {
Slog.e(TAG, "Cannot read file " + fnfe);
- return true;
} catch (IOException ioe) {
Slog.e(TAG, "Cannot read file " + ioe);
- return true;
}
+ return true;
}
@Override
- public void setLockPassword(byte[] hash, int userId) throws RemoteException {
- checkWritePermission(userId);
-
- writeFile(getLockPasswordFilename(userId), hash);
- }
-
- @Override
- public boolean checkPassword(byte[] hash, int userId) throws RemoteException {
+ public boolean checkPassword(String password, int userId) throws RemoteException {
checkPasswordReadPermission(userId);
try {
@@ -306,14 +335,18 @@
return true;
}
// Compare the hash from the file with the entered password's hash
- return Arrays.equals(stored, hash);
+ final byte[] hash = mLockPatternUtils.passwordToHash(password);
+ final boolean matched = Arrays.equals(stored, hash);
+ if (matched && !TextUtils.isEmpty(password)) {
+ maybeUpdateKeystore(password, userId);
+ }
+ return matched;
} catch (FileNotFoundException fnfe) {
Slog.e(TAG, "Cannot read file " + fnfe);
- return true;
} catch (IOException ioe) {
Slog.e(TAG, "Cannot read file " + ioe);
- return true;
}
+ return true;
}
@Override
@@ -445,13 +478,12 @@
private void maybeEnableWidgetSettingForUsers(SQLiteDatabase db) {
final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
final ContentResolver cr = mContext.getContentResolver();
- final LockPatternUtils utils = new LockPatternUtils(mContext);
final List<UserInfo> users = um.getUsers();
for (int i = 0; i < users.size(); i++) {
final int userId = users.get(i).id;
- final boolean enabled = utils.hasWidgetsEnabledInKeyguard(userId);
+ final boolean enabled = mLockPatternUtils.hasWidgetsEnabledInKeyguard(userId);
Log.v(TAG, "Widget upgrade uid=" + userId + ", enabled="
- + enabled + ", w[]=" + utils.getAppWidgets());
+ + enabled + ", w[]=" + mLockPatternUtils.getAppWidgets());
loadSetting(db, LockPatternUtils.LOCKSCREEN_WIDGETS_ENABLED, userId, enabled);
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 676b330..f08b5b9 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -21,12 +21,12 @@
import static com.android.internal.util.XmlUtils.writeIntAttribute;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
+
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
import android.app.AppOpsManager;
import android.appwidget.AppWidgetManager;
import android.util.ArrayMap;
-
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
@@ -52,7 +52,6 @@
import com.android.server.wm.AppTransition;
import com.android.server.wm.StackBox;
import com.android.server.wm.WindowManagerService;
-
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
@@ -155,7 +154,6 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.text.format.Time;
-import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.EventLog;
import android.util.Log;
@@ -519,7 +517,7 @@
* This is the process holding what we currently consider to be
* the "home" activity.
*/
- ArraySet<ProcessRecord> mHomeProcess = new ArraySet<ProcessRecord>();
+ ProcessRecord mHomeProcess;
/**
* This is the process holding the activity the user last visited that
@@ -9122,8 +9120,8 @@
// with a home activity running in the process to prevent a repeatedly crashing app
// from blocking the user to manually clear the list.
final ArrayList<ActivityRecord> activities = app.activities;
- if (mHomeProcess.contains(app) && activities.size() > 0
- && (app.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ if (app == mHomeProcess && activities.size() > 0
+ && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
if (r.isHomeActivity()) {
@@ -10400,20 +10398,13 @@
pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
}
}
- if (!mHomeProcess.isEmpty()) {
- final int size = mHomeProcess.size();
- ProcessRecord[] processes = new ProcessRecord[size];
- mHomeProcess.toArray(processes);
- for (int processNdx = 0; processNdx < size; ++processNdx) {
- final ProcessRecord app = processes[processNdx];
- if (dumpPackage == null || app.pkgList.containsKey(dumpPackage)) {
- if (needSep) {
- pw.println();
- needSep = false;
- }
- pw.println(" mHomeProcess[" + processNdx + "]: " + app);
- }
+ if (mHomeProcess != null && (dumpPackage == null
+ || mHomeProcess.pkgList.containsKey(dumpPackage))) {
+ if (needSep) {
+ pw.println();
+ needSep = false;
}
+ pw.println(" mHomeProcess: " + mHomeProcess);
}
if (mPreviousProcess != null && (dumpPackage == null
|| mPreviousProcess.pkgList.containsKey(dumpPackage))) {
@@ -11943,8 +11934,6 @@
}
mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
- mHomeProcess.remove(app);
-
// If the caller is restarting this app, then leave it in its
// current lists and let the caller take care of it.
if (restarting) {
@@ -11974,8 +11963,8 @@
"Clean-up removing on hold: " + app);
mProcessesOnHold.remove(app);
- if (mHomeProcess.contains(app)) {
- mHomeProcess.remove(app);
+ if (app == mHomeProcess) {
+ mHomeProcess = null;
}
if (app == mPreviousProcess) {
mPreviousProcess = null;
@@ -13904,7 +13893,7 @@
}
}
- if (mHomeProcess.contains(app)) {
+ if (app == mHomeProcess) {
if (adj > ProcessList.HOME_APP_ADJ) {
// This process is hosting what we currently consider to be the
// home app, so we don't want to let it go into the background.
@@ -13971,7 +13960,7 @@
if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
procState = ActivityManager.PROCESS_STATE_SERVICE;
}
- if (app.hasShownUi && !mHomeProcess.contains(app)) {
+ if (app.hasShownUi && app != mHomeProcess) {
// If this process has shown some UI, let it immediately
// go to the LRU list because it may be pretty heavy with
// UI stuff. We'll tag it with a label just to help
@@ -14034,7 +14023,7 @@
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
// Not doing bind OOM management, so treat
// this guy more like a started service.
- if (app.hasShownUi && !mHomeProcess.contains(app)) {
+ if (app.hasShownUi && app != mHomeProcess) {
// If this process has shown some UI, let it immediately
// go to the LRU list because it may be pretty heavy with
// UI stuff. We'll tag it with a label just to help
@@ -14089,7 +14078,7 @@
// about letting this process get into the LRU
// list to be killed and restarted if needed for
// memory.
- if (app.hasShownUi && !mHomeProcess.contains(app)
+ if (app.hasShownUi && app != mHomeProcess
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
adjType = "cch-bound-ui-services";
} else {
@@ -14203,7 +14192,7 @@
clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
}
if (adj > clientAdj) {
- if (app.hasShownUi && !mHomeProcess.contains(app)
+ if (app.hasShownUi && app != mHomeProcess
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
app.adjType = "cch-ui-provider";
} else {
@@ -15065,7 +15054,7 @@
// to be good enough at this point that destroying
// activities causes more harm than good.
if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
- && !mHomeProcess.contains(app) && app != mPreviousProcess) {
+ && app != mHomeProcess && app != mPreviousProcess) {
// Need to do this on its own message because the stack may not
// be in a consistent state at this point.
// For these apps we will also finish their activities
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index c31c213..1482440 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2254,7 +2254,7 @@
if (r.state == ActivityState.RESUMED
|| r.state == ActivityState.PAUSING
|| r.state == ActivityState.PAUSED) {
- if (!r.isHomeActivity() || !mService.mHomeProcess.contains(r.app)) {
+ if (!r.isHomeActivity() || mService.mHomeProcess != r.app) {
Slog.w(TAG, " Force finishing activity "
+ r.intent.getComponent().flattenToShortString());
finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 8ad29f3..219cb85 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -906,7 +906,8 @@
r.task.taskId, r.shortComponentName);
}
if (r.isHomeActivity() && r.isNotResolverActivity()) {
- mService.mHomeProcess.add(app);
+ // Home process is the root process of the task.
+ mService.mHomeProcess = r.task.mActivities.get(0).app;
}
mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
r.sleeping = false;
@@ -1949,7 +1950,7 @@
// makes sense to.
if (r.app != null && fgApp != null && r.app != fgApp
&& r.lastVisibleTime > mService.mPreviousProcessVisibleTime
- && !mService.mHomeProcess.contains(r.app)) {
+ && r.app != mService.mHomeProcess) {
mService.mPreviousProcess = r.app;
mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
}
diff --git a/services/java/com/android/server/connectivity/PacManager.java b/services/java/com/android/server/connectivity/PacManager.java
index 772921a..53e1dc2 100644
--- a/services/java/com/android/server/connectivity/PacManager.java
+++ b/services/java/com/android/server/connectivity/PacManager.java
@@ -252,7 +252,7 @@
Intent intent = new Intent();
intent.setClassName(PAC_PACKAGE, PAC_SERVICE);
// Already bound no need to bind again.
- if (mProxyConnection != null) {
+ if ((mProxyConnection != null) && (mConnection != null)) {
if (mLastPort != -1) {
sendPacBroadcast(new ProxyProperties(mPacUrl, mLastPort));
} else {
@@ -332,10 +332,15 @@
}
private void unbind() {
- mContext.unbindService(mConnection);
- mContext.unbindService(mProxyConnection);
- mConnection = null;
- mProxyConnection = null;
+ if (mConnection != null) {
+ mContext.unbindService(mConnection);
+ mConnection = null;
+ }
+ if (mProxyConnection != null) {
+ mContext.unbindService(mProxyConnection);
+ mProxyConnection = null;
+ }
+ mProxyService = null;
}
private void sendPacBroadcast(ProxyProperties proxy) {