Merge "Add listener for changes to touch exploration state" into klp-dev
diff --git a/api/current.txt b/api/current.txt
index 9d73f5f..c1cc278 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5759,6 +5759,7 @@
method public static java.util.List<android.content.SyncInfo> getCurrentSyncs();
method public static int getIsSyncable(android.accounts.Account, java.lang.String);
method public static boolean getMasterSyncAutomatically();
+ method public java.util.List<android.content.UriPermission> getOutgoingPersistedUriPermissions();
method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.accounts.Account, java.lang.String);
method public java.util.List<android.content.UriPermission> getPersistedUriPermissions();
method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String);
@@ -28397,6 +28398,7 @@
field public static final int SYSTEM_UI_FLAG_FULLSCREEN = 4; // 0x4
field public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2; // 0x2
field public static final int SYSTEM_UI_FLAG_IMMERSIVE = 2048; // 0x800
+ field public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 4096; // 0x1000
field public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024; // 0x400
field public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512; // 0x200
field public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 256; // 0x100
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 961ee57..74266cc 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1160,7 +1160,10 @@
case GET_PERSISTED_URI_PERMISSIONS_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
- final ParceledListSlice<UriPermission> perms = getPersistedUriPermissions();
+ final String packageName = data.readString();
+ final boolean incoming = data.readInt() != 0;
+ final ParceledListSlice<UriPermission> perms = getPersistedUriPermissions(
+ packageName, incoming);
reply.writeNoException();
perms.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
return true;
@@ -3500,10 +3503,13 @@
}
@Override
- public ParceledListSlice<UriPermission> getPersistedUriPermissions() throws RemoteException {
+ public ParceledListSlice<UriPermission> getPersistedUriPermissions(
+ String packageName, boolean incoming) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeString(packageName);
+ data.writeInt(incoming ? 1 : 0);
mRemote.transact(GET_PERSISTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
reply.readException();
final ParceledListSlice<UriPermission> perms = ParceledListSlice.CREATOR.createFromParcel(
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e07b50f..df63ab3 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -95,6 +95,7 @@
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.Objects;
import com.android.org.conscrypt.OpenSSLSocketImpl;
+import com.google.android.collect.Lists;
import java.io.File;
import java.io.FileDescriptor;
@@ -1277,6 +1278,11 @@
}
}
}
+
+ @Override
+ public void scheduleInstallProvider(ProviderInfo provider) {
+ queueOrSendMessage(H.INSTALL_PROVIDER, provider);
+ }
}
private class H extends Handler {
@@ -1325,6 +1331,7 @@
public static final int UNSTABLE_PROVIDER_DIED = 142;
public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
+ public static final int INSTALL_PROVIDER = 145;
String codeToString(int code) {
if (DEBUG_MESSAGES) {
switch (code) {
@@ -1373,6 +1380,7 @@
case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
+ case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
}
}
return Integer.toString(code);
@@ -1590,6 +1598,9 @@
case TRANSLUCENT_CONVERSION_COMPLETE:
handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
break;
+ case INSTALL_PROVIDER:
+ handleInstallProvider((ProviderInfo) msg.obj);
+ break;
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}
@@ -2330,6 +2341,10 @@
}
}
+ public void handleInstallProvider(ProviderInfo info) {
+ installContentProviders(mInitialApplication, Lists.newArrayList(info));
+ }
+
private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
/**
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index e40a04b..347d43f 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -618,6 +618,15 @@
reply.writeNoException();
return true;
}
+
+ case SCHEDULE_INSTALL_PROVIDER_TRANSACTION:
+ {
+ data.enforceInterface(IApplicationThread.descriptor);
+ ProviderInfo provider = ProviderInfo.CREATOR.createFromParcel(data);
+ scheduleInstallProvider(provider);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -1248,4 +1257,13 @@
mRemote.transact(SET_PROCESS_STATE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
data.recycle();
}
+
+ @Override
+ public void scheduleInstallProvider(ProviderInfo provider) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(IApplicationThread.descriptor);
+ provider.writeToParcel(data, 0);
+ mRemote.transact(SCHEDULE_INSTALL_PROVIDER_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+ data.recycle();
+ }
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index dfea736..77c2ea0 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -215,7 +215,8 @@
int mode) throws RemoteException;
public void takePersistableUriPermission(Uri uri, int modeFlags) throws RemoteException;
public void releasePersistableUriPermission(Uri uri, int modeFlags) throws RemoteException;
- public ParceledListSlice<UriPermission> getPersistedUriPermissions() throws RemoteException;
+ public ParceledListSlice<UriPermission> getPersistedUriPermissions(
+ String packageName, boolean incoming) throws RemoteException;
public void showWaitingForDebugger(IApplicationThread who, boolean waiting)
throws RemoteException;
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 43a5fbd..d0cc1bb 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -137,6 +137,7 @@
void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
throws RemoteException;
void setProcessState(int state) throws RemoteException;
+ void scheduleInstallProvider(ProviderInfo provider) throws RemoteException;
String descriptor = "android.app.IApplicationThread";
@@ -189,4 +190,5 @@
int REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
int SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
int SET_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
+ int SCHEDULE_INSTALL_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+50;
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 916a6cd..49dfdb5 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1659,8 +1659,9 @@
}
/**
- * Return list of all Uri permission grants that have been persisted for the
- * calling app. Only persistable grants taken with
+ * Return list of all Uri permission grants that have been persisted by the
+ * calling app. That is, the returned permissions have been granted
+ * <em>to</em> the calling app. Only persistable grants taken with
* {@link #takePersistableUriPermission(Uri, int)} are returned.
*
* @see #takePersistableUriPermission(Uri, int)
@@ -1668,7 +1669,23 @@
*/
public List<UriPermission> getPersistedUriPermissions() {
try {
- return ActivityManagerNative.getDefault().getPersistedUriPermissions().getList();
+ return ActivityManagerNative.getDefault()
+ .getPersistedUriPermissions(mPackageName, true).getList();
+ } catch (RemoteException e) {
+ throw new RuntimeException("Activity manager has died", e);
+ }
+ }
+
+ /**
+ * Return list of all persisted Uri permission grants that are hosted by the
+ * calling app. That is, the returned permissions have been granted
+ * <em>from</em> the calling app. Only grants taken with
+ * {@link #takePersistableUriPermission(Uri, int)} are returned.
+ */
+ public List<UriPermission> getOutgoingPersistedUriPermissions() {
+ try {
+ return ActivityManagerNative.getDefault()
+ .getPersistedUriPermissions(mPackageName, false).getList();
} catch (RemoteException e) {
throw new RuntimeException("Activity manager has died", e);
}
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index f30bcc5..898f123 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -82,6 +82,7 @@
private CaptureRequest(CaptureRequest source) {
mSettings = new CameraMetadataNative(source.mSettings);
mSurfaceSet = (HashSet<Surface>) source.mSurfaceSet.clone();
+ mUserTag = source.mUserTag;
}
/**
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 9319d4a..1b7d9ea 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -687,6 +687,8 @@
mThemeAttrs = obtainStyledAttributes(android.R.styleable.InputMethodService);
mRootView = mInflater.inflate(
com.android.internal.R.layout.input_method, null);
+ mRootView.setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
mWindow.setContentView(mRootView);
mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);
if (Settings.Global.getInt(getContentResolver(),
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 1c14c38..c5e4f21 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -23,8 +23,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Bitmap;
@@ -69,16 +68,15 @@
private DocumentsContract() {
}
- /** {@hide} */
- @Deprecated
- public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER";
-
/**
* Intent action used to identify {@link DocumentsProvider} instances.
*/
public static final String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
/** {@hide} */
+ public static final String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";
+
+ /** {@hide} */
public static final String ACTION_MANAGE_ROOT = "android.provider.action.MANAGE_ROOT";
/** {@hide} */
public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
@@ -565,11 +563,13 @@
return false;
}
- final ProviderInfo info = context.getPackageManager()
- .resolveContentProvider(uri.getAuthority(), PackageManager.GET_META_DATA);
- if (info != null && info.metaData != null && info.metaData.containsKey(
- DocumentsContract.META_DATA_DOCUMENT_PROVIDER)) {
- return true;
+ final Intent intent = new Intent(PROVIDER_INTERFACE);
+ final List<ResolveInfo> infos = context.getPackageManager()
+ .queryIntentContentProviders(intent, 0);
+ for (ResolveInfo info : infos) {
+ if (uri.getAuthority().equals(info.providerInfo.authority)) {
+ return true;
+ }
}
return false;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c45307b..01da6b3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2423,6 +2423,16 @@
/**
* Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
+ * hiding the navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. If this flag is
+ * not set, {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any
+ * user interaction.
+ * <p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only
+ * has an effect when used in combination with that flag.</p>
+ */
+ public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;
+
+ /**
+ * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
* hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation
* bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. Use this flag to create an immersive
* experience while also hiding the system bars. If this flag is not set,
@@ -2437,7 +2447,7 @@
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
* with one or both of those flags.</p>
*/
- public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;
+ public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000;
/**
* @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
@@ -8885,10 +8895,10 @@
*/
mPrivateFlags |= PFLAG_DRAWN;
- if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE) && hasFocus()) {
+ if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE)) {
// root view becoming invisible shouldn't clear focus and accessibility focus
if (getRootView() != this) {
- clearFocus();
+ if (hasFocus()) clearFocus();
clearAccessibilityFocus();
}
}
@@ -16934,7 +16944,8 @@
* @param visibility Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
* {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
- * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, and {@link #SYSTEM_UI_FLAG_IMMERSIVE}.
+ * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
+ * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
*/
public void setSystemUiVisibility(int visibility) {
if (visibility != mSystemUiVisibility) {
@@ -16950,7 +16961,8 @@
* @return Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
* {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
- * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, and {@link #SYSTEM_UI_FLAG_IMMERSIVE}.
+ * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
+ * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
*/
public int getSystemUiVisibility() {
return mSystemUiVisibility;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index 6bef78e..7dd1e8a 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -86,7 +86,9 @@
refreshCachedNode(event.getSourceNodeId());
} break;
case AccessibilityEvent.TYPE_VIEW_SCROLLED: {
- clearSubTreeLocked(event.getSourceNodeId());
+ synchronized (mLock) {
+ clearSubTreeLocked(event.getSourceNodeId());
+ }
} break;
case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: {
synchronized (mLock) {
diff --git a/core/java/com/android/internal/inputmethod/InputMethodRoot.java b/core/java/com/android/internal/inputmethod/InputMethodRoot.java
new file mode 100644
index 0000000..f070a58
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputMethodRoot.java
@@ -0,0 +1,61 @@
+/*
+ * 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.internal.inputmethod;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+public class InputMethodRoot extends LinearLayout {
+ private final Rect mGuardRect = new Rect();
+ private final Paint mGuardPaint = new Paint();
+
+ public InputMethodRoot(Context context) {
+ this(context, null);
+ }
+
+ public InputMethodRoot(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public InputMethodRoot(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs);
+ setWillNotDraw(false);
+ mGuardPaint.setColor(context.getResources()
+ .getColor(com.android.internal.R.color.input_method_navigation_guard));
+ }
+
+ @Override
+ protected boolean fitSystemWindows(Rect insets) {
+ setPadding(0, 0, 0, insets.bottom);
+ return true;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ // draw navigation bar guard
+ final int w = getMeasuredWidth();
+ final int h = getMeasuredHeight();
+ mGuardRect.set(0, h - getPaddingBottom(), w, h);
+ canvas.drawRect(mGuardRect, mGuardPaint);
+ }
+}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 04351da..73d34c3 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -322,6 +322,9 @@
// Restore default.
runtime.setTargetHeapUtilization(defaultUtilization);
+ // Fill in dex caches with classes, fields, and methods brought in by preloading.
+ runtime.preloadDexCaches();
+
Debug.stopAllocCounting();
// Bring back root. We'll need it later.
diff --git a/core/res/res/layout/input_method.xml b/core/res/res/layout/input_method.xml
index f80d628..23d7189 100644
--- a/core/res/res/layout/input_method.xml
+++ b/core/res/res/layout/input_method.xml
@@ -18,7 +18,7 @@
*/
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.internal.inputmethod.InputMethodRoot xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parentPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -52,4 +52,4 @@
android:layout_height="wrap_content"
android:visibility="gone">
</FrameLayout>
-</LinearLayout>
+</com.android.internal.inputmethod.InputMethodRoot>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 81ee3af..28e7af7 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -78,6 +78,7 @@
<drawable name="input_method_fullscreen_background">#fff9f9f9</drawable>
<drawable name="input_method_fullscreen_background_holo">@drawable/screen_background_holo_dark</drawable>
+ <color name="input_method_navigation_guard">#ff000000</color>
<!-- For date picker widget -->
<drawable name="selected_day_background">#ff0092f4</drawable>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ad9144c..edfdcc2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1441,6 +1441,7 @@
<java-symbol type="bool" name="config_wimaxEnabled" />
<java-symbol type="bool" name="show_ongoing_ime_switcher" />
<java-symbol type="color" name="config_defaultNotificationColor" />
+ <java-symbol type="color" name="input_method_navigation_guard" />
<java-symbol type="drawable" name="ic_notification_ime_default" />
<java-symbol type="drawable" name="ic_notify_wifidisplay" />
<java-symbol type="drawable" name="ic_menu_refresh" />
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 32e85d9..7865ec8 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -36,6 +36,8 @@
import android.util.Log;
import android.view.KeyEvent;
+import java.lang.ref.WeakReference;
+
/**
* The RemoteController class is used to control media playback, display and update media metadata
* and playback status, published by applications using the {@link RemoteControlClient} class.
@@ -122,7 +124,7 @@
}
mOnClientUpdateListener = updateListener;
mContext = context;
- mRcd = new RcDisplay();
+ mRcd = new RcDisplay(this);
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if (ActivityManager.isLowRamDeviceStatic()) {
@@ -505,34 +507,51 @@
//==================================================
// Implementation of IRemoteControlDisplay interface
- private class RcDisplay extends IRemoteControlDisplay.Stub {
+ private static class RcDisplay extends IRemoteControlDisplay.Stub {
+ private final WeakReference<RemoteController> mController;
+
+ RcDisplay(RemoteController rc) {
+ mController = new WeakReference<RemoteController>(rc);
+ }
public void setCurrentClientId(int genId, PendingIntent clientMediaIntent,
boolean clearing) {
+ final RemoteController rc = mController.get();
+ if (rc == null) {
+ return;
+ }
boolean isNew = false;
synchronized(mGenLock) {
- if (mClientGenerationIdCurrent != genId) {
- mClientGenerationIdCurrent = genId;
+ if (rc.mClientGenerationIdCurrent != genId) {
+ rc.mClientGenerationIdCurrent = genId;
isNew = true;
}
}
if (clientMediaIntent != null) {
- sendMsg(mEventHandler, MSG_NEW_PENDING_INTENT, SENDMSG_REPLACE,
+ sendMsg(rc.mEventHandler, MSG_NEW_PENDING_INTENT, SENDMSG_REPLACE,
genId /*arg1*/, 0, clientMediaIntent /*obj*/, 0 /*delay*/);
}
if (isNew || clearing) {
- sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+ sendMsg(rc.mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
genId /*arg1*/, clearing ? 1 : 0, null /*obj*/, 0 /*delay*/);
}
}
public void setEnabled(boolean enabled) {
- sendMsg(mEventHandler, MSG_DISPLAY_ENABLE, SENDMSG_REPLACE,
+ final RemoteController rc = mController.get();
+ if (rc == null) {
+ return;
+ }
+ sendMsg(rc.mEventHandler, MSG_DISPLAY_ENABLE, SENDMSG_REPLACE,
enabled ? 1 : 0 /*arg1*/, 0, null /*obj*/, 0 /*delay*/);
}
public void setPlaybackState(int genId, int state,
long stateChangeTimeMs, long currentPosMs, float speed) {
+ final RemoteController rc = mController.get();
+ if (rc == null) {
+ return;
+ }
if (DEBUG) {
Log.d(TAG, "> new playback state: genId="+genId
+ " state="+ state
@@ -542,65 +561,81 @@
}
synchronized(mGenLock) {
- if (mClientGenerationIdCurrent != genId) {
+ if (rc.mClientGenerationIdCurrent != genId) {
return;
}
}
final PlaybackInfo playbackInfo =
new PlaybackInfo(state, stateChangeTimeMs, currentPosMs, speed);
- sendMsg(mEventHandler, MSG_NEW_PLAYBACK_INFO, SENDMSG_REPLACE,
+ sendMsg(rc.mEventHandler, MSG_NEW_PLAYBACK_INFO, SENDMSG_REPLACE,
genId /*arg1*/, 0, playbackInfo /*obj*/, 0 /*delay*/);
}
public void setTransportControlInfo(int genId, int transportControlFlags,
int posCapabilities) {
+ final RemoteController rc = mController.get();
+ if (rc == null) {
+ return;
+ }
synchronized(mGenLock) {
- if (mClientGenerationIdCurrent != genId) {
+ if (rc.mClientGenerationIdCurrent != genId) {
return;
}
}
- sendMsg(mEventHandler, MSG_NEW_TRANSPORT_INFO, SENDMSG_REPLACE,
+ sendMsg(rc.mEventHandler, MSG_NEW_TRANSPORT_INFO, SENDMSG_REPLACE,
genId /*arg1*/, transportControlFlags /*arg2*/,
null /*obj*/, 0 /*delay*/);
}
public void setMetadata(int genId, Bundle metadata) {
+ final RemoteController rc = mController.get();
+ if (rc == null) {
+ return;
+ }
if (DEBUG) { Log.e(TAG, "setMetadata("+genId+")"); }
if (metadata == null) {
return;
}
synchronized(mGenLock) {
- if (mClientGenerationIdCurrent != genId) {
+ if (rc.mClientGenerationIdCurrent != genId) {
return;
}
}
- sendMsg(mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
+ sendMsg(rc.mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
genId /*arg1*/, 0 /*arg2*/,
metadata /*obj*/, 0 /*delay*/);
}
public void setArtwork(int genId, Bitmap artwork) {
+ final RemoteController rc = mController.get();
+ if (rc == null) {
+ return;
+ }
if (DEBUG) { Log.v(TAG, "setArtwork("+genId+")"); }
synchronized(mGenLock) {
- if (mClientGenerationIdCurrent != genId) {
+ if (rc.mClientGenerationIdCurrent != genId) {
return;
}
}
Bundle metadata = new Bundle(1);
metadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK), artwork);
- sendMsg(mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
+ sendMsg(rc.mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
genId /*arg1*/, 0 /*arg2*/,
metadata /*obj*/, 0 /*delay*/);
}
public void setAllMetadata(int genId, Bundle metadata, Bitmap artwork) {
+ final RemoteController rc = mController.get();
+ if (rc == null) {
+ return;
+ }
if (DEBUG) { Log.e(TAG, "setAllMetadata("+genId+")"); }
if ((metadata == null) && (artwork == null)) {
return;
}
synchronized(mGenLock) {
- if (mClientGenerationIdCurrent != genId) {
+ if (rc.mClientGenerationIdCurrent != genId) {
return;
}
}
@@ -611,7 +646,7 @@
metadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
artwork);
}
- sendMsg(mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
+ sendMsg(rc.mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
genId /*arg1*/, 0 /*arg2*/,
metadata /*obj*/, 0 /*delay*/);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index 22dd6e4..90be197 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -73,7 +73,7 @@
final DocumentsActivity activity = (DocumentsActivity) getActivity();
final DocumentInfo cwd = activity.getCurrentDirectory();
- new CreateDirectoryTask(displayName).executeOnExecutor(
+ new CreateDirectoryTask(activity, cwd, displayName).executeOnExecutor(
ProviderExecutor.forAuthority(cwd.authority));
}
});
@@ -83,25 +83,26 @@
}
private class CreateDirectoryTask extends AsyncTask<Void, Void, DocumentInfo> {
+ private final DocumentsActivity mActivity;
+ private final DocumentInfo mCwd;
private final String mDisplayName;
- public CreateDirectoryTask(String displayName) {
+ public CreateDirectoryTask(
+ DocumentsActivity activity, DocumentInfo cwd, String displayName) {
+ mActivity = activity;
+ mCwd = cwd;
mDisplayName = displayName;
}
@Override
protected DocumentInfo doInBackground(Void... params) {
- final DocumentsActivity activity = (DocumentsActivity) getActivity();
- final ContentResolver resolver = activity.getContentResolver();
-
- final DocumentInfo cwd = activity.getCurrentDirectory();
-
+ final ContentResolver resolver = mActivity.getContentResolver();
ContentProviderClient client = null;
try {
client = DocumentsApplication.acquireUnstableProviderOrThrow(
- resolver, cwd.derivedUri.getAuthority());
+ resolver, mCwd.derivedUri.getAuthority());
final Uri childUri = DocumentsContract.createDocument(
- client, cwd.derivedUri, Document.MIME_TYPE_DIR, mDisplayName);
+ client, mCwd.derivedUri, Document.MIME_TYPE_DIR, mDisplayName);
return DocumentInfo.fromUri(resolver, childUri);
} catch (Exception e) {
Log.w(TAG, "Failed to create directory", e);
@@ -113,12 +114,11 @@
@Override
protected void onPostExecute(DocumentInfo result) {
- final DocumentsActivity activity = (DocumentsActivity) getActivity();
if (result != null) {
// Navigate into newly created child
- activity.onDocumentPicked(result);
+ mActivity.onDocumentPicked(result);
} else {
- Toast.makeText(activity, R.string.create_error, Toast.LENGTH_SHORT).show();
+ Toast.makeText(mActivity, R.string.create_error, Toast.LENGTH_SHORT).show();
}
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 7660779..d675e8d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -292,7 +292,7 @@
@Override
protected Void doInBackground(Void... params) {
// Restore last stack for calling package
- final String packageName = getCallingPackage();
+ final String packageName = getCallingPackageMaybeExtra();
final Cursor cursor = getContentResolver()
.query(RecentsProvider.buildResume(packageName), null, null, null, null);
try {
@@ -783,6 +783,11 @@
return mState.stack.peek();
}
+ private String getCallingPackageMaybeExtra() {
+ final String extra = getIntent().getStringExtra(DocumentsContract.EXTRA_PACKAGE_NAME);
+ return (extra != null) ? extra : getCallingPackage();
+ }
+
public Executor getCurrentExecutor() {
final DocumentInfo cwd = getCurrentDirectory();
if (cwd != null && cwd.authority != null) {
@@ -921,7 +926,7 @@
if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) {
// Remember that we last picked via external app
- final String packageName = getCallingPackage();
+ final String packageName = getCallingPackageMaybeExtra();
final ContentValues values = new ContentValues();
values.put(ResumeColumns.EXTERNAL, 1);
getContentResolver().insert(RecentsProvider.buildResume(packageName), values);
@@ -1002,7 +1007,7 @@
}
// Remember location for next app launch
- final String packageName = getCallingPackage();
+ final String packageName = getCallingPackageMaybeExtra();
values.clear();
values.put(ResumeColumns.STACK, rawStack);
values.put(ResumeColumns.EXTERNAL, 0);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index eb56765..b98e1ee 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -194,16 +194,6 @@
handleDocumentsProvider(info.providerInfo);
}
- // Pick up legacy providers
- final List<ProviderInfo> legacyProviders = pm.queryContentProviders(
- null, -1, PackageManager.GET_META_DATA);
- for (ProviderInfo info : legacyProviders) {
- if (info.metaData != null && info.metaData.containsKey(
- DocumentsContract.META_DATA_DOCUMENT_PROVIDER)) {
- handleDocumentsProvider(info);
- }
- }
-
final long delta = SystemClock.elapsedRealtime() - start;
Log.d(TAG, "Update found " + mTaskRoots.size() + " roots in " + delta + "ms");
synchronized (mLock) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index 6584180..58ca0b0 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -420,6 +420,7 @@
public synchronized void onScreenTurnedOn(final IKeyguardShowCallback callback) {
if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
mScreenOn = true;
+ final IBinder token = mKeyguardHost == null ? null : mKeyguardHost.getWindowToken();
if (mKeyguardView != null) {
mKeyguardView.onScreenTurnedOn();
@@ -432,10 +433,6 @@
mKeyguardHost.post(new Runnable() {
@Override
public void run() {
- IBinder token = null;
- if (mKeyguardHost.getVisibility() == View.VISIBLE) {
- token = mKeyguardHost.getWindowToken();
- }
try {
callback.onShown(token);
} catch (RemoteException e) {
@@ -445,7 +442,7 @@
});
} else {
try {
- callback.onShown(null);
+ callback.onShown(token);
} catch (RemoteException e) {
Slog.w(TAG, "Exception calling onShown():", e);
}
@@ -453,7 +450,7 @@
}
} else if (callback != null) {
try {
- callback.onShown(null);
+ callback.onShown(token);
} catch (RemoteException e) {
Slog.w(TAG, "Exception calling onShown():", e);
}
diff --git a/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png b/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png
index e8cfc0f..d1948d6 100644
--- a/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png
+++ b/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png b/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png
index 89cd10e..a540efb1 100644
--- a/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png
+++ b/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png b/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png
index 7d7868d..ba25f65 100644
--- a/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png
+++ b/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png b/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png
index f93da09..53d85de 100644
--- a/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png
+++ b/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png b/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png
index bbcea9e..0b012b4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png
+++ b/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png b/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png
index 56b63d0..d4526c0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png
+++ b/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index c02a99b..04ca4d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1923,10 +1923,8 @@
}
private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
- final boolean imeVisible = (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0;
- final int finalMode = imeVisible ? MODE_OPAQUE : mode;
final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN;
- transitions.transitionTo(finalMode, anim);
+ transitions.transitionTo(mode, anim);
}
private final Runnable mCheckBarModes = new Runnable() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index adbada7..e9e3b27 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2991,8 +2991,10 @@
pf.left = df.left = of.left = cf.left = vf.left = mDockLeft;
pf.top = df.top = of.top = cf.top = vf.top = mDockTop;
pf.right = df.right = of.right = cf.right = vf.right = mDockRight;
- // IM dock windows always go above the nav bar.
- pf.bottom = df.bottom = of.bottom = cf.bottom = vf.bottom = mStableBottom;
+ // IM dock windows layout below the nav bar...
+ pf.bottom = df.bottom = of.bottom = mRestrictedScreenTop + mRestrictedScreenHeight;
+ // ...with content insets above the nav bar
+ cf.bottom = vf.bottom = mStableBottom;
// IM dock windows always go to the bottom of the screen.
attrs.gravity = Gravity.BOTTOM;
mDockLayer = win.getSurfaceLayer();
@@ -4282,12 +4284,14 @@
})) {
return;
}
+ Slog.i(TAG, "No lock screen! waitForWindowDrawn false");
+
} catch (RemoteException ex) {
// Can't happen in system process.
}
}
- Slog.i(TAG, "No lock screen!");
+ Slog.i(TAG, "No lock screen! windowToken=" + windowToken);
finishScreenTurningOn(screenOnListener);
}
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 59b559e..5695ee5 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -4247,6 +4247,9 @@
addrTried ++) {
// Choose the address at random but make sure its type is supported
+ // TODO: This doesn't work 100% of the time, because we may end up
+ // trying the same invalid address more than once and ignoring one
+ // of the valid addresses.
InetAddress hostAddr = addresses[rand.nextInt(addresses.length)];
if (((hostAddr instanceof Inet4Address) && linkHasIpv4)
|| ((hostAddr instanceof Inet6Address) && linkHasIpv6)) {
@@ -4271,10 +4274,8 @@
}
// Rewrite the url to have numeric address to use the specific route.
- // I also set the "Connection" to "Close" as by default "Keep-Alive"
- // is used which is useless in this case.
- URL newUrl = new URL(orgUri.getScheme() + "://"
- + hostAddr.getHostAddress() + orgUri.getPath());
+ URL newUrl = new URL(orgUri.getScheme(),
+ hostAddr.getHostAddress(), orgUri.getPath());
log("isMobileOk: newUrl=" + newUrl);
HttpURLConnection urlConn = null;
@@ -4287,6 +4288,8 @@
urlConn.setReadTimeout(SOCKET_TIMEOUT_MS);
urlConn.setUseCaches(false);
urlConn.setAllowUserInteraction(false);
+ // Set the "Connection" to "Close" as by default "Keep-Alive"
+ // is used which is useless in this case.
urlConn.setRequestProperty("Connection", "close");
int responseCode = urlConn.getResponseCode();
diff --git a/services/java/com/android/server/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java
index dd9ae4c..cc43a9c 100644
--- a/services/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/java/com/android/server/accounts/AccountManagerService.java
@@ -293,17 +293,16 @@
return mUserManager;
}
- private UserAccounts initUser(int userId) {
- synchronized (mUsers) {
- UserAccounts accounts = mUsers.get(userId);
- if (accounts == null) {
- accounts = new UserAccounts(mContext, userId);
- mUsers.append(userId, accounts);
- purgeOldGrants(accounts);
- validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
- }
- return accounts;
+ /* Caller should lock mUsers */
+ private UserAccounts initUserLocked(int userId) {
+ UserAccounts accounts = mUsers.get(userId);
+ if (accounts == null) {
+ accounts = new UserAccounts(mContext, userId);
+ mUsers.append(userId, accounts);
+ purgeOldGrants(accounts);
+ validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
}
+ return accounts;
}
private void purgeOldGrantsAll() {
@@ -427,7 +426,7 @@
synchronized (mUsers) {
UserAccounts accounts = mUsers.get(userId);
if (accounts == null) {
- accounts = initUser(userId);
+ accounts = initUserLocked(userId);
mUsers.append(userId, accounts);
}
return accounts;
@@ -1798,16 +1797,14 @@
private AccountAndUser[] getAccounts(int[] userIds) {
final ArrayList<AccountAndUser> runningAccounts = Lists.newArrayList();
- synchronized (mUsers) {
- for (int userId : userIds) {
- UserAccounts userAccounts = getUserAccounts(userId);
- if (userAccounts == null) continue;
- synchronized (userAccounts.cacheLock) {
- Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
- Binder.getCallingUid(), null);
- for (int a = 0; a < accounts.length; a++) {
- runningAccounts.add(new AccountAndUser(accounts[a], userId));
- }
+ for (int userId : userIds) {
+ UserAccounts userAccounts = getUserAccounts(userId);
+ if (userAccounts == null) continue;
+ synchronized (userAccounts.cacheLock) {
+ Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
+ Binder.getCallingUid(), null);
+ for (int a = 0; a < accounts.length; a++) {
+ runningAccounts.add(new AccountAndUser(accounts[a], userId));
}
}
}
@@ -2858,7 +2855,8 @@
|| callingUid == Process.myUid()) {
return unfiltered;
}
- if (mUserManager.getUserInfo(userAccounts.userId).isRestricted()) {
+ UserInfo user = mUserManager.getUserInfo(userAccounts.userId);
+ if (user != null && user.isRestricted()) {
String[] packages = mPackageManager.getPackagesForUid(callingUid);
// If any of the packages is a white listed package, return the full set,
// otherwise return non-shared accounts only.
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1987d04..6c6cc98 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6489,26 +6489,53 @@
}
@Override
- public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions() {
+ public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
+ String packageName, boolean incoming) {
enforceNotIsolatedCaller("getPersistedUriPermissions");
+ Preconditions.checkNotNull(packageName, "packageName");
+ final int callingUid = Binder.getCallingUid();
+ final IPackageManager pm = AppGlobals.getPackageManager();
+ try {
+ final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
+ if (packageUid != callingUid) {
+ throw new SecurityException(
+ "Package " + packageName + " does not belong to calling UID " + callingUid);
+ }
+ } catch (RemoteException e) {
+ throw new SecurityException("Failed to verify package name ownership");
+ }
+
+ final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
synchronized (this) {
- final int callingUid = Binder.getCallingUid();
- final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
- final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
- if (perms == null) {
- Slog.w(TAG, "No permission grants found for UID " + callingUid);
+ if (incoming) {
+ final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
+ if (perms == null) {
+ Slog.w(TAG, "No permission grants found for " + packageName);
+ } else {
+ final int size = perms.size();
+ for (int i = 0; i < size; i++) {
+ final UriPermission perm = perms.valueAt(i);
+ if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
+ result.add(perm.buildPersistedPublicApiObject());
+ }
+ }
+ }
} else {
- final int size = perms.size();
+ final int size = mGrantedUriPermissions.size();
for (int i = 0; i < size; i++) {
- final UriPermission perm = perms.valueAt(i);
- if (perm.persistedModeFlags != 0) {
- result.add(perm.buildPersistedPublicApiObject());
+ final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
+ final int permsSize = perms.size();
+ for (int j = 0; j < permsSize; j++) {
+ final UriPermission perm = perms.valueAt(j);
+ if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
+ result.add(perm.buildPersistedPublicApiObject());
+ }
}
}
}
- return new ParceledListSlice<android.content.UriPermission>(result);
}
+ return new ParceledListSlice<android.content.UriPermission>(result);
}
@Override
@@ -6755,7 +6782,6 @@
private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
tr.disposeThumbnail();
mRecentTasks.remove(tr);
- mStackSupervisor.removeTask(tr);
final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
Intent baseIntent = new Intent(
tr.intent != null ? tr.intent : tr.affinityIntent);
@@ -7526,16 +7552,30 @@
+ cpr.appInfo.packageName + ": " + e);
}
- ProcessRecord proc = startProcessLocked(cpi.processName,
- cpr.appInfo, false, 0, "content provider",
- new ComponentName(cpi.applicationInfo.packageName,
- cpi.name), false, false, false);
- if (proc == null) {
- Slog.w(TAG, "Unable to launch app "
- + cpi.applicationInfo.packageName + "/"
- + cpi.applicationInfo.uid + " for provider "
- + name + ": process is bad");
- return null;
+ // Use existing process if already started
+ ProcessRecord proc = getProcessRecordLocked(
+ cpi.processName, cpr.appInfo.uid, false);
+ if (proc != null) {
+ if (DEBUG_PROVIDER) {
+ Slog.d(TAG, "Installing in existing process " + proc);
+ }
+ proc.pubProviders.put(cpi.name, cpr);
+ try {
+ proc.thread.scheduleInstallProvider(cpi);
+ } catch (RemoteException e) {
+ }
+ } else {
+ proc = startProcessLocked(cpi.processName,
+ cpr.appInfo, false, 0, "content provider",
+ new ComponentName(cpi.applicationInfo.packageName,
+ cpi.name), false, false, false);
+ if (proc == null) {
+ Slog.w(TAG, "Unable to launch app "
+ + cpi.applicationInfo.packageName + "/"
+ + cpi.applicationInfo.uid + " for provider "
+ + name + ": process is bad");
+ return null;
+ }
}
cpr.launchingApp = proc;
mLaunchingProviders.add(cpr);
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index dbc05fa..a6375e1 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -566,6 +566,15 @@
return;
}
+ long ident = Binder.clearCallingIdentity();
+ try {
+ dumpInner(fd, pw, args);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private void dumpInner(FileDescriptor fd, PrintWriter pw, String[] args) {
final long now = SystemClock.uptimeMillis();
boolean isCheckin = false;
diff --git a/services/java/com/android/server/am/UriPermission.java b/services/java/com/android/server/am/UriPermission.java
index 5868c08..684f247 100644
--- a/services/java/com/android/server/am/UriPermission.java
+++ b/services/java/com/android/server/am/UriPermission.java
@@ -20,7 +20,6 @@
import android.net.Uri;
import android.os.UserHandle;
import android.util.Log;
-import android.util.Slog;
import com.android.internal.util.Preconditions;
import com.google.android.collect.Sets;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index e089ca6..0fc10f9 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -9473,9 +9473,8 @@
//Slog.i(TAG, "Waiting for drawn " + win + ": removed="
// + win.mRemoved + " visible=" + win.isVisibleLw()
// + " shown=" + win.mSurfaceShown);
- if (win.mRemoved || !win.isVisibleLw()) {
- // Window has been removed or made invisible; no draw
- // will now happen, so stop waiting.
+ if (win.mRemoved) {
+ // Window has been removed; no draw will now happen, so stop waiting.
Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
try {
pair.second.sendResult(null);
@@ -9510,6 +9509,7 @@
checkDrawnWindowsLocked();
return true;
}
+ Slog.i(TAG, "waitForWindowDrawn: win null");
}
}
return false;
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 6978551..e3c664b 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -20,6 +20,7 @@
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
+import android.location.Country;
import android.location.CountryDetector;
import android.net.Uri;
import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -561,17 +562,23 @@
* is in.
*/
private static String getCurrentCountryIso(Context context, Locale locale) {
- String countryIso;
- CountryDetector detector = (CountryDetector) context.getSystemService(
- Context.COUNTRY_DETECTOR);
- if (detector != null) {
- countryIso = detector.detectCountry().getCountryIso();
- } else {
- countryIso = locale.getCountry();
- Rlog.w(TAG, "No CountryDetector; falling back to countryIso based on locale: "
- + countryIso);
- }
- return countryIso;
+ String countryIso = null;
+ CountryDetector detector = (CountryDetector) context.getSystemService(
+ Context.COUNTRY_DETECTOR);
+ if (detector != null) {
+ Country country = detector.detectCountry();
+ if (country != null) {
+ countryIso = country.getCountryIso();
+ } else {
+ Rlog.e(TAG, "CountryDetector.detectCountry() returned null.");
+ }
+ }
+ if (countryIso == null) {
+ countryIso = locale.getCountry();
+ Rlog.w(TAG, "No CountryDetector; falling back to countryIso based on locale: "
+ + countryIso);
+ }
+ return countryIso;
}
/**