Merge "Gracefuly return on detecting wrong AAC format from corrupted files"
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 173da8d..91def67 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1811,6 +1811,14 @@
}
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ fout.println("Permission Denial: can't dump AccountsManager from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " without permission " + android.Manifest.permission.DUMP);
+ return;
+ }
+
synchronized (mCacheLock) {
final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 66373fe..be87946 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -79,6 +79,16 @@
void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable);
/**
+ * Disable IPv6 on an interface
+ */
+ void disableIpv6(String iface);
+
+ /**
+ * Enable IPv6 on an interface
+ */
+ void enableIpv6(String iface);
+
+ /**
* Retrieves the network routes currently configured on the specified
* interface
*/
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index e849b71..237a892 100755
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1574,22 +1574,6 @@
public static final String SENT_TIME = "sent_time";
}
- public static final class ScrapSpace {
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI = Uri.parse("content://mms/scrapSpace");
-
- /**
- * This is the scrap file we use to store the media attachment when the user
- * chooses to capture a photo to be attached . We pass {#link@Uri} to the Camera app,
- * which streams the captured image to the uri. Internally we write the media content
- * to this file. It's named '.temp.jpg' so Gallery won't pick it up.
- */
- public static final String SCRAP_FILE_PATH =
- Environment.getExternalStorageDirectory().getPath() + "/mms/scrapSpace/.temp.jpg";
- }
-
public static final class Intents {
private Intents() {
// Non-instantiatable.
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index 0433ec4..af524ee 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -73,10 +73,6 @@
}
};
- public void forceUpdate() {
- mCurrentDirty = true;
- }
-
public void setCharSequence(CharSequence incoming) {
// When incoming is different object, move listeners to new sequence
// and mark as dirty so we reload contents.
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index e9eec10..ac9535a 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -185,18 +185,16 @@
if (!isInDictionary && looksLikeTypo) {
String[] suggestions = getSuggestions(suggestionsInfo);
- if (suggestions.length > 0) {
- SuggestionSpan suggestionSpan = new SuggestionSpan(
- mTextView.getContext(), suggestions,
- SuggestionSpan.FLAG_EASY_CORRECT |
- SuggestionSpan.FLAG_MISSPELLED);
- final int start = editable.getSpanStart(spellCheckSpan);
- final int end = editable.getSpanEnd(spellCheckSpan);
- editable.setSpan(suggestionSpan, start, end,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- // TODO limit to the word rectangle region
- mTextView.invalidate();
- }
+ SuggestionSpan suggestionSpan = new SuggestionSpan(
+ mTextView.getContext(), suggestions,
+ SuggestionSpan.FLAG_EASY_CORRECT |
+ SuggestionSpan.FLAG_MISSPELLED);
+ final int start = editable.getSpanStart(spellCheckSpan);
+ final int end = editable.getSpanEnd(spellCheckSpan);
+ editable.setSpan(suggestionSpan, start, end,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ // TODO limit to the word rectangle region
+ mTextView.invalidate();
}
editable.removeSpan(spellCheckSpan);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b74f9b6..5cd7902 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7609,9 +7609,6 @@
sendOnTextChanged(buffer, start, before, after);
onTextChanged(buffer, start, before, after);
- // The WordIterator text change listener may be called after this one.
- // Make sure this changed text is rescanned before the iterator is used on it.
- getWordIterator().forceUpdate();
updateSpellCheckSpans(start, start + after);
// Hide the controllers if the amount of content changed
@@ -7745,21 +7742,22 @@
private void updateSpellCheckSpans(int start, int end) {
if (!isTextEditable() || !isSuggestionsEnabled() || !getSpellChecker().isSessionActive())
return;
-
Editable text = (Editable) mText;
- WordIterator wordIterator = getWordIterator();
- wordIterator.setCharSequence(text);
+
+ final int shift = prepareWordIterator(start, end);
+ final int shiftedStart = start - shift;
+ final int shiftedEnd = end - shift;
// Move back to the beginning of the current word, if any
- int wordStart = wordIterator.preceding(start);
+ int wordStart = mWordIterator.preceding(shiftedStart);
int wordEnd;
if (wordStart == BreakIterator.DONE) {
- wordEnd = wordIterator.following(start);
+ wordEnd = mWordIterator.following(shiftedStart);
if (wordEnd != BreakIterator.DONE) {
- wordStart = wordIterator.getBeginning(wordEnd);
+ wordStart = mWordIterator.getBeginning(wordEnd);
}
} else {
- wordEnd = wordIterator.getEnd(wordStart);
+ wordEnd = mWordIterator.getEnd(wordStart);
}
if (wordEnd == BreakIterator.DONE) {
return;
@@ -7772,22 +7770,22 @@
final int numberOfSpellCheckSpans = spellCheckSpans.length;
// Iterate over the newly added text and schedule new SpellCheckSpans
- while (wordStart <= end) {
- if (wordEnd >= start) {
+ while (wordStart <= shiftedEnd) {
+ if (wordEnd >= shiftedStart) {
// A new word has been created across the interval boundaries. Remove previous spans
- if (wordStart < start && wordEnd > start) {
+ if (wordStart < shiftedStart && wordEnd > shiftedStart) {
removeSpansAt(start, spellCheckSpans, text);
removeSpansAt(start, suggestionSpans, text);
}
- if (wordStart < end && wordEnd > end) {
+ if (wordStart < shiftedEnd && wordEnd > shiftedEnd) {
removeSpansAt(end, spellCheckSpans, text);
removeSpansAt(end, suggestionSpans, text);
}
// Do not create new boundary spans if they already exist
boolean createSpellCheckSpan = true;
- if (wordEnd == start) {
+ if (wordEnd == shiftedStart) {
for (int i = 0; i < numberOfSpellCheckSpans; i++) {
final int spanEnd = text.getSpanEnd(spellCheckSpans[i]);
if (spanEnd == start) {
@@ -7797,9 +7795,9 @@
}
}
- if (wordStart == end) {
+ if (wordStart == shiftedEnd) {
for (int i = 0; i < numberOfSpellCheckSpans; i++) {
- final int spanStart = text.getSpanEnd(spellCheckSpans[i]);
+ final int spanStart = text.getSpanStart(spellCheckSpans[i]);
if (spanStart == end) {
createSpellCheckSpan = false;
break;
@@ -7808,16 +7806,16 @@
}
if (createSpellCheckSpan) {
- mSpellChecker.addSpellCheckSpan(wordStart, wordEnd);
+ mSpellChecker.addSpellCheckSpan(wordStart + shift, wordEnd + shift);
}
}
// iterate word by word
- wordEnd = wordIterator.following(wordEnd);
+ wordEnd = mWordIterator.following(wordEnd);
if (wordEnd == BreakIterator.DONE) break;
- wordStart = wordIterator.getBeginning(wordEnd);
+ wordStart = mWordIterator.getBeginning(wordEnd);
if (wordStart == BreakIterator.DONE) {
- Log.e(LOG_TAG, "Unable to find word beginning from " + wordEnd + "in " + mText);
+ Log.e(LOG_TAG, "No word beginning from " + (wordEnd + shift) + "in " + mText);
break;
}
}
@@ -8941,26 +8939,32 @@
selectionStart = ((Spanned) mText).getSpanStart(url);
selectionEnd = ((Spanned) mText).getSpanEnd(url);
} else {
- WordIterator wordIterator = getWordIterator();
- // WordIterator handles text changes, this is a no-op if text in unchanged.
- wordIterator.setCharSequence(mText);
+ final int shift = prepareWordIterator(minOffset, maxOffset);
- selectionStart = wordIterator.getBeginning(minOffset);
+ selectionStart = mWordIterator.getBeginning(minOffset - shift);
if (selectionStart == BreakIterator.DONE) return false;
+ selectionStart += shift;
- selectionEnd = wordIterator.getEnd(maxOffset);
+ selectionEnd = mWordIterator.getEnd(maxOffset - shift);
if (selectionEnd == BreakIterator.DONE) return false;
+ selectionEnd += shift;
}
Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
return true;
}
- WordIterator getWordIterator() {
+ int prepareWordIterator(int start, int end) {
if (mWordIterator == null) {
mWordIterator = new WordIterator();
}
- return mWordIterator;
+
+ final int TEXT_WINDOW_WIDTH = 50; // Should be larger than the longest word's length
+ final int windowStart = Math.max(0, start - TEXT_WINDOW_WIDTH);
+ final int windowEnd = Math.min(mText.length(), end + TEXT_WINDOW_WIDTH);
+ mWordIterator.setCharSequence(mText.subSequence(windowStart, windowEnd));
+
+ return windowStart;
}
private SpellChecker getSpellChecker() {
@@ -9188,19 +9192,23 @@
return true;
case ID_CUT:
- setPrimaryClip(ClipData.newPlainText(null, mTransformed.subSequence(min, max)));
+ setPrimaryClip(ClipData.newPlainText(null, getTransformedText(min, max)));
((Editable) mText).delete(min, max);
stopSelectionActionMode();
return true;
case ID_COPY:
- setPrimaryClip(ClipData.newPlainText(null, mTransformed.subSequence(min, max)));
+ setPrimaryClip(ClipData.newPlainText(null, getTransformedText(min, max)));
stopSelectionActionMode();
return true;
}
return false;
}
+ private CharSequence getTransformedText(int start, int end) {
+ return removeSuggestionSpans(mTransformed.subSequence(start, end));
+ }
+
/**
* Prepare text so that there are not zero or two spaces at beginning and end of region defined
* by [min, max] when replacing this region by paste.
@@ -9317,7 +9325,7 @@
// Start a drag
final int start = getSelectionStart();
final int end = getSelectionEnd();
- CharSequence selectedText = mTransformed.subSequence(start, end);
+ CharSequence selectedText = getTransformedText(start, end);
ClipData data = ClipData.newPlainText(null, selectedText);
DragLocalState localState = new DragLocalState(this, start, end);
startDrag(data, getTextThumbnailBuilder(selectedText), localState, 0);
@@ -9900,6 +9908,8 @@
suggestionInfo.suggestionIndex = ADD_TO_DICTIONARY;
suggestionInfo.text.replace(0, suggestionInfo.text.length(),
getContext().getString(com.android.internal.R.string.addToDictionary));
+ suggestionInfo.text.setSpan(suggestionInfo.highlightSpan, 0, 0,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mNumberOfSuggestions++;
}
@@ -9911,6 +9921,8 @@
suggestionInfo.suggestionIndex = DELETE_TEXT;
suggestionInfo.text.replace(0, suggestionInfo.text.length(),
getContext().getString(com.android.internal.R.string.deleteText));
+ suggestionInfo.text.setSpan(suggestionInfo.highlightSpan, 0, 0,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mNumberOfSuggestions++;
if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
@@ -9939,8 +9951,7 @@
suggestionInfo.suggestionStart = spanStart - unionStart;
suggestionInfo.suggestionEnd = suggestionInfo.suggestionStart
+ suggestionInfo.text.length();
-
- suggestionInfo.text.clearSpans();
+
suggestionInfo.text.setSpan(suggestionInfo.highlightSpan, 0,
suggestionInfo.text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 81e7c34..3795a7c 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -23,6 +23,7 @@
import android.app.admin.DevicePolicyManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
import android.os.FileObserver;
import android.os.IBinder;
import android.os.RemoteException;
@@ -125,6 +126,8 @@
private static FileObserver sPasswordObserver;
+ private static boolean mLastAttemptWasBiometric = false;
+
private static class PasswordFileObserver extends FileObserver {
public PasswordFileObserver(String path, int mask) {
super(path, mask);
@@ -371,7 +374,8 @@
/**
* Clear any lock pattern or password.
*/
- public void clearLock() {
+ public void clearLock(boolean isFallback) {
+ if(!isFallback) deleteGallery();
saveLockPassword(null, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
setLockPatternEnabled(false);
saveLockPattern(null);
@@ -390,6 +394,13 @@
}
/**
+ * Sets whether the last lockscreen setup attempt was biometric
+ */
+ public static void setLastAttemptWasBiometric(boolean val) {
+ mLastAttemptWasBiometric = val;
+ }
+
+ /**
* Determine if LockScreen can be disabled. This is used, for example, to tell if we should
* show LockScreen or go straight to the home screen.
*
@@ -408,6 +419,41 @@
}
/**
+ * Calls back SetupFaceLock to save the temporary gallery file if this is the backup lock.
+ * This doesn't have to verify that biometric is enabled because it's only called in that case
+ */
+ void moveTempGallery() {
+ Intent intent = new Intent().setClassName("com.android.facelock",
+ "com.android.facelock.SetupFaceLock");
+ intent.putExtra("moveTempGallery", true);
+ mContext.startActivity(intent);
+ }
+
+ /**
+ * Calls back SetupFaceLock to delete the temporary gallery file if this is the backup lock.
+ */
+ public void deleteTempGallery() {
+ //if(mLastAttemptWasBiometric) {
+ Intent intent = new Intent().setClassName("com.android.facelock",
+ "com.android.facelock.SetupFaceLock");
+ intent.putExtra("deleteTempGallery", true);
+ mContext.startActivity(intent);
+ //}
+ }
+
+ /**
+ * Calls back SetupFaceLock to delete the gallery file when the lock type is changed
+ */
+ void deleteGallery() {
+ if(isBiometricEnabled()) {
+ Intent intent = new Intent().setClassName("com.android.facelock",
+ "com.android.facelock.SetupFaceLock");
+ intent.putExtra("deleteGallery", true);
+ mContext.startActivity(intent);
+ }
+ }
+
+ /**
* Save a lock pattern.
* @param pattern The new pattern to save.
* @param isFallback Specifies if this is a fallback to biometric weak
@@ -431,11 +477,13 @@
keyStore.password(patternToString(pattern));
setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
if (!isFallback) {
+ deleteGallery();
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
} else {
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
setLong(PASSWORD_TYPE_ALTERNATE_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+ moveTempGallery();
}
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern
.size(), 0, 0, 0, 0, 0, 0);
@@ -547,10 +595,12 @@
int computedQuality = computePasswordQuality(password);
if (!isFallback) {
+ deleteGallery();
setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality));
} else {
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
setLong(PASSWORD_TYPE_ALTERNATE_KEY, Math.max(quality, computedQuality));
+ moveTempGallery();
}
if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
int letters = 0;
diff --git a/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java
index 4d2d535..c4be513 100644
--- a/core/java/com/google/android/mms/pdu/PduPersister.java
+++ b/core/java/com/google/android/mms/pdu/PduPersister.java
@@ -667,6 +667,13 @@
String contentType = null;
if (part.getContentType() != null) {
contentType = toIsoString(part.getContentType());
+
+ // There is no "image/jpg" in Android (and it's an invalid mimetype).
+ // Change it to "image/jpeg"
+ if (ContentType.IMAGE_JPG.equals(contentType)) {
+ contentType = ContentType.IMAGE_JPEG;
+ }
+
values.put(Part.CONTENT_TYPE, contentType);
// To ensure the SMIL part is always the first part.
if (ContentType.APP_SMIL.equals(contentType)) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
index 8737595..91100ae 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
@@ -20,6 +20,7 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
/**
* Unit test class to test the set of valid and invalid states that
@@ -27,6 +28,8 @@
*/
public class MediaRecorderStopStateUnitTest extends AndroidTestCase implements MediaRecorderMethodUnderTest {
private MediaRecorderStateUnitTestTemplate mTestTemplate = new MediaRecorderStateUnitTestTemplate();
+ private static final String TAG = "MediaRecorderStopStateUnitTest";
+ private static final int SLEEP_TIME_BEFORE_STOP = 1000;
/**
* 1. It is valid to call stop() in the following states:
@@ -51,6 +54,15 @@
}
public void invokeMethodUnderTest(MediaRecorder recorder) {
+ // Wait for some time before stopping the media recorder.
+ // This will fix the assertion caused by stopping it immediatedly
+ // after it is started
+ try {
+ Thread.sleep(SLEEP_TIME_BEFORE_STOP);
+ } catch(Exception e) {
+ Log.v(TAG, "sleep was interrupted and terminated prematurely");
+ }
+
recorder.stop();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index c83c470..a98d519 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -786,6 +786,7 @@
mWifiActivityIconId = R.drawable.stat_sys_wifi_inout;
break;
case WifiManager.DATA_ACTIVITY_NONE:
+ mWifiActivityIconId = 0;
break;
}
}
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 6fcf399..aacaa6a 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -508,6 +508,28 @@
}
}
+ public void enableIpv6(String iface) throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+ try {
+ mConnector.doCommand(String.format("interface ipv6 %s enable", iface));
+ } catch (NativeDaemonConnectorException e) {
+ throw new IllegalStateException(
+ "Unable to communicate to native daemon for enabling ipv6");
+ }
+ }
+
+ public void disableIpv6(String iface) throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+ try {
+ mConnector.doCommand(String.format("interface ipv6 %s disable", iface));
+ } catch (NativeDaemonConnectorException e) {
+ throw new IllegalStateException(
+ "Unable to communicate to native daemon for disabling ipv6");
+ }
+ }
+
public void addRoute(String interfaceName, RouteInfo route) {
modifyRoute(interfaceName, ADD, route);
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2942c28..d038d76 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1318,6 +1318,14 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump meminfo from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " without permission " + android.Manifest.permission.DUMP);
+ return;
+ }
+
mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
}
}
@@ -1330,6 +1338,14 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump gfxinfo from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " without permission " + android.Manifest.permission.DUMP);
+ return;
+ }
+
mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
}
}
@@ -1342,6 +1358,14 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump cpuinfo from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " without permission " + android.Manifest.permission.DUMP);
+ return;
+ }
+
synchronized (mActivityManagerService.mProcessStatsThread) {
pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
pw.print(mActivityManagerService.mProcessStats.printCurrentState(
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 226723f..b44dc8a2 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -21,6 +21,7 @@
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
@@ -457,6 +458,14 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump BatteryStats from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " without permission " + android.Manifest.permission.DUMP);
+ return;
+ }
+
boolean isCheckin = false;
boolean noOutput = false;
if (args != null) {
diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java
index 0d36d69..e810e3c 100644
--- a/services/java/com/android/server/am/UsageStatsService.java
+++ b/services/java/com/android/server/am/UsageStatsService.java
@@ -19,6 +19,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.FileUtils;
@@ -1034,6 +1035,14 @@
* The data persisted to file is parsed and the stats are computed.
*/
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump UsageStats from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " without permission " + android.Manifest.permission.DUMP);
+ return;
+ }
+
final boolean isCheckinRequest = scanArgs(args, "--checkin");
final boolean isCompactOutput = isCheckinRequest || scanArgs(args, "-c");
final boolean deleteAfterPrint = isCheckinRequest || scanArgs(args, "-d");
diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
index 9732530..8868c65 100644
--- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
@@ -47,14 +47,14 @@
@LayoutlibDelegate
/** @hide special for when we are faking the screen size. */
- /*package*/ static int getRawWidth(Display theDisplay) {
+ /*package*/ static int getRawWidthNative(Display theDisplay) {
// same as real since we're not faking compatibility mode.
return RenderAction.getCurrentContext().getIWindowManager().getMetrics().widthPixels;
}
@LayoutlibDelegate
/** @hide special for when we are faking the screen size. */
- /*package*/ static int getRawHeight(Display theDisplay) {
+ /*package*/ static int getRawHeightNative(Display theDisplay) {
// same as real since we're not faking compatibility mode.
return RenderAction.getCurrentContext().getIWindowManager().getMetrics().heightPixels;
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 41fc55d..d1522fb 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1560,8 +1560,9 @@
try {
mNwService.clearInterfaceAddresses(mInterfaceName);
+ mNwService.disableIpv6(mInterfaceName);
} catch (Exception e) {
- Log.e(TAG, "Failed to clear IP addresses on disconnect" + e);
+ Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
}
/* Reset data structures */
@@ -1841,6 +1842,21 @@
mWifiP2pManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE);
mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
+ /* IPv6 is disabled at boot time and is controlled by framework
+ * to be enabled only as long as we are connected to an access point
+ *
+ * This fixes issues, a few being:
+ * - IPv6 addresses and routes stick around after disconnection
+ * - When connected, the kernel is unaware and can fail to start IPv6 negotiation
+ * - The kernel sometimes starts autoconfiguration when 802.1x is not complete
+ */
+ try {
+ mNwService.disableIpv6(mInterfaceName);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Failed to disable IPv6: " + re);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Failed to disable IPv6: " + e);
+ }
}
}
@@ -2734,7 +2750,15 @@
if (DBG) Log.d(TAG, getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
- if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+ try {
+ mNwService.enableIpv6(mInterfaceName);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Failed to enable IPv6: " + re);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Failed to enable IPv6: " + e);
+ }
+
+ if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
//start DHCP
mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
mContext, WifiStateMachine.this, mInterfaceName);
@@ -2758,7 +2782,7 @@
sendMessage(CMD_STATIC_IP_FAILURE);
}
}
- }
+ }
@Override
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");