diff options
Diffstat (limited to 'services/java/com')
9 files changed, 137 insertions, 61 deletions
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java index e0f415b..16d2468 100644 --- a/services/java/com/android/server/NsdService.java +++ b/services/java/com/android/server/NsdService.java @@ -483,10 +483,14 @@ public class NsdService extends INsdManager.Stub { clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4])); stopResolveService(id); - if (!getAddrInfo(id, cooked[3])) { + removeRequestMap(clientId, id, clientInfo); + + int id2 = getUniqueId(); + if (getAddrInfo(id2, cooked[3])) { + storeRequestMap(clientId, id2, clientInfo); + } else { clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED, NsdManager.FAILURE_INTERNAL_ERROR, clientId); - removeRequestMap(clientId, id, clientInfo); clientInfo.mResolvedService = null; } break; diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java index c1a60ee..e25470c 100644 --- a/services/java/com/android/server/WallpaperManagerService.java +++ b/services/java/com/android/server/WallpaperManagerService.java @@ -40,6 +40,7 @@ import android.content.pm.ServiceInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.content.res.Resources; +import android.graphics.Point; import android.os.Binder; import android.os.Bundle; import android.os.Environment; @@ -637,6 +638,16 @@ class WallpaperManagerService extends IWallpaperManager.Stub { return false; } + private Point getDefaultDisplaySize() { + Point p = new Point(); + try { + mIWindowManager.getInitialDisplaySize(Display.DEFAULT_DISPLAY, p); + } catch (RemoteException e) { + // not remote + } + return p; + } + public void setDimensionHints(int width, int height) throws RemoteException { checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS); synchronized (mLock) { @@ -648,10 +659,10 @@ class WallpaperManagerService extends IWallpaperManager.Stub { if (width <= 0 || height <= 0) { throw new IllegalArgumentException("width and height must be > 0"); } - // Make sure it is at least as large as the display's maximum size. - int maxSizeDimension = getMaximumSizeDimension(); - width = Math.max(width, maxSizeDimension); - height = Math.max(height, maxSizeDimension); + // Make sure it is at least as large as the display. + Point displaySize = getDefaultDisplaySize(); + width = Math.max(width, displaySize.x); + height = Math.max(height, displaySize.y); if (width != wallpaper.width || height != wallpaper.height) { wallpaper.width = width; diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 569440d..fd791f9 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -1717,7 +1717,7 @@ final class ActivityStack { mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, - r.userId); + r.userId, r.info.configChanges); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } @@ -1778,7 +1778,8 @@ final class ActivityStack { r.updateOptionsLocked(options); mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, - (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId); + (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId, + r.info.configChanges); boolean doShow = true; if (newTask) { // Even though this activity is starting fresh, we still need @@ -1821,7 +1822,8 @@ final class ActivityStack { // because there is nothing for it to animate on top of. mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, - (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId); + (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId, + r.info.configChanges); ActivityOptions.abort(options); } if (VALIDATE_TOKENS) { diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java index 99f8ebb..11558a3 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/java/com/android/server/display/WifiDisplayAdapter.java @@ -400,8 +400,6 @@ final class WifiDisplayAdapter extends DisplayAdapter { mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height, refreshRate, deviceFlags, address, surface); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED); - - scheduleUpdateNotificationLocked(); } private void removeDisplayDeviceLocked() { @@ -409,8 +407,6 @@ final class WifiDisplayAdapter extends DisplayAdapter { mDisplayDevice.destroyLocked(); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED); mDisplayDevice = null; - - scheduleUpdateNotificationLocked(); } } @@ -457,21 +453,24 @@ final class WifiDisplayAdapter extends DisplayAdapter { // Runs on the handler. private void handleUpdateNotification() { - final boolean isConnected; + final int state; + final WifiDisplay display; synchronized (getSyncRoot()) { if (!mPendingNotificationUpdate) { return; } mPendingNotificationUpdate = false; - isConnected = (mDisplayDevice != null); + state = mActiveDisplayState; + display = mActiveDisplay; } // Cancel the old notification if there is one. mNotificationManager.cancelAsUser(null, - R.string.wifi_display_notification_title, UserHandle.ALL); + R.string.wifi_display_notification_disconnect, UserHandle.ALL); - if (isConnected) { + if (state == WifiDisplayStatus.DISPLAY_STATE_CONNECTING + || state == WifiDisplayStatus.DISPLAY_STATE_CONNECTED) { Context context = getContext(); // Initialize pending intents for the notification outside of the lock because @@ -493,20 +492,38 @@ final class WifiDisplayAdapter extends DisplayAdapter { // Post the notification. Resources r = context.getResources(); - Notification notification = new Notification.Builder(context) - .setContentTitle(r.getString( - R.string.wifi_display_notification_title)) - .setContentText(r.getString( - R.string.wifi_display_notification_message)) - .setContentIntent(mSettingsPendingIntent) - .setSmallIcon(R.drawable.ic_media_route_on_holo_dark) - .setOngoing(true) - .addAction(android.R.drawable.ic_menu_close_clear_cancel, - r.getString(R.string.wifi_display_notification_disconnect), - mDisconnectPendingIntent) - .build(); + Notification notification; + if (state == WifiDisplayStatus.DISPLAY_STATE_CONNECTING) { + notification = new Notification.Builder(context) + .setContentTitle(r.getString( + R.string.wifi_display_notification_connecting_title)) + .setContentText(r.getString( + R.string.wifi_display_notification_connecting_message, + display.getFriendlyDisplayName())) + .setContentIntent(mSettingsPendingIntent) + .setSmallIcon(R.drawable.ic_notification_cast_connecting) + .setOngoing(true) + .addAction(android.R.drawable.ic_menu_close_clear_cancel, + r.getString(R.string.wifi_display_notification_disconnect), + mDisconnectPendingIntent) + .build(); + } else { + notification = new Notification.Builder(context) + .setContentTitle(r.getString( + R.string.wifi_display_notification_connected_title)) + .setContentText(r.getString( + R.string.wifi_display_notification_connected_message, + display.getFriendlyDisplayName())) + .setContentIntent(mSettingsPendingIntent) + .setSmallIcon(R.drawable.ic_notification_cast_on) + .setOngoing(true) + .addAction(android.R.drawable.ic_menu_close_clear_cancel, + r.getString(R.string.wifi_display_notification_disconnect), + mDisconnectPendingIntent) + .build(); + } mNotificationManager.notifyAsUser(null, - R.string.wifi_display_notification_title, + R.string.wifi_display_notification_disconnect, notification, UserHandle.ALL); } } @@ -578,6 +595,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_CONNECTING; mActiveDisplay = display; scheduleStatusChangedBroadcastLocked(); + scheduleUpdateNotificationLocked(); } } } @@ -590,6 +608,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED; mActiveDisplay = null; scheduleStatusChangedBroadcastLocked(); + scheduleUpdateNotificationLocked(); } } } @@ -607,6 +626,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_CONNECTED; mActiveDisplay = display; scheduleStatusChangedBroadcastLocked(); + scheduleUpdateNotificationLocked(); } } } @@ -629,6 +649,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { mActiveDisplay = display; renameDisplayDeviceLocked(display.getFriendlyDisplayName()); scheduleStatusChangedBroadcastLocked(); + scheduleUpdateNotificationLocked(); } } } @@ -644,6 +665,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED; mActiveDisplay = null; scheduleStatusChangedBroadcastLocked(); + scheduleUpdateNotificationLocked(); } } } diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java index 9a4cfb7..b2939fe 100644 --- a/services/java/com/android/server/display/WifiDisplayController.java +++ b/services/java/com/android/server/display/WifiDisplayController.java @@ -76,7 +76,7 @@ final class WifiDisplayController implements DumpUtils.Dump { private static final int DEFAULT_CONTROL_PORT = 7236; private static final int MAX_THROUGHPUT = 50; private static final int CONNECTION_TIMEOUT_SECONDS = 60; - private static final int RTSP_TIMEOUT_SECONDS = 15; + private static final int RTSP_TIMEOUT_SECONDS = 30; private static final int RTSP_TIMEOUT_SECONDS_CERT_MODE = 120; private static final int DISCOVER_PEERS_MAX_RETRIES = 10; diff --git a/services/java/com/android/server/media/RemoteDisplayProviderWatcher.java b/services/java/com/android/server/media/RemoteDisplayProviderWatcher.java index f3a3c2f..6a5f563 100644 --- a/services/java/com/android/server/media/RemoteDisplayProviderWatcher.java +++ b/services/java/com/android/server/media/RemoteDisplayProviderWatcher.java @@ -16,6 +16,7 @@ package com.android.server.media; +import android.Manifest; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -116,7 +117,7 @@ public final class RemoteDisplayProviderWatcher { for (ResolveInfo resolveInfo : mPackageManager.queryIntentServicesAsUser( intent, 0, mUserId)) { ServiceInfo serviceInfo = resolveInfo.serviceInfo; - if (serviceInfo != null) { + if (serviceInfo != null && verifyServiceTrusted(serviceInfo)) { int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name); if (sourceIndex < 0) { RemoteDisplayProviderProxy provider = @@ -146,6 +147,43 @@ public final class RemoteDisplayProviderWatcher { } } + private boolean verifyServiceTrusted(ServiceInfo serviceInfo) { + if (serviceInfo.permission == null || !serviceInfo.permission.equals( + Manifest.permission.BIND_REMOTE_DISPLAY)) { + // If the service does not require this permission then any app could + // potentially bind to it and cause the remote display service to + // misbehave. So we only want to trust providers that require the + // correct permissions. + Slog.w(TAG, "Ignoring remote display provider service because it did not " + + "require the BIND_REMOTE_DISPLAY permission in its manifest: " + + serviceInfo.packageName + "/" + serviceInfo.name); + return false; + } + if (!hasCaptureVideoPermission(serviceInfo.packageName)) { + // If the service does not have permission to capture video then it + // isn't going to be terribly useful as a remote display, is it? + // Kind of makes you wonder what it's doing there in the first place. + Slog.w(TAG, "Ignoring remote display provider service because it does not " + + "have the CAPTURE_VIDEO_OUTPUT or CAPTURE_SECURE_VIDEO_OUTPUT " + + "permission: " + serviceInfo.packageName + "/" + serviceInfo.name); + return false; + } + // Looks good. + return true; + } + + private boolean hasCaptureVideoPermission(String packageName) { + if (mPackageManager.checkPermission(Manifest.permission.CAPTURE_VIDEO_OUTPUT, + packageName) == PackageManager.PERMISSION_GRANTED) { + return true; + } + if (mPackageManager.checkPermission(Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT, + packageName) == PackageManager.PERMISSION_GRANTED) { + return true; + } + return false; + } + private int findProvider(String packageName, String className) { int count = mProviders.size(); for (int i = 0; i < count; i++) { diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 7291dd4..7ae9251 100755 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -10011,11 +10011,11 @@ public class PackageManagerService extends IPackageManager.Stub { } if (filter.countDataAuthorities() != 0 || filter.countDataPaths() != 0 - || filter.countDataSchemes() != 0 + || filter.countDataSchemes() > 1 || filter.countDataTypes() != 0) { throw new IllegalArgumentException( "replacePreferredActivity expects filter to have no data authorities, " + - "paths, schemes or types."); + "paths, or types; and at most one scheme."); } synchronized (mPackages) { if (mContext.checkCallingOrSelfPermission( @@ -10032,33 +10032,27 @@ public class PackageManagerService extends IPackageManager.Stub { } final int callingUserId = UserHandle.getCallingUserId(); - ArrayList<PreferredActivity> removed = null; PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId); if (pir != null) { - Iterator<PreferredActivity> it = pir.filterIterator(); - String action = filter.getAction(0); - String category = filter.getCategory(0); - while (it.hasNext()) { - PreferredActivity pa = it.next(); - if ((pa.countActions() == 0) || (pa.countCategories() == 0) - || (pa.getAction(0).equals(action) - && pa.getCategory(0).equals(category))) { - if (removed == null) { - removed = new ArrayList<PreferredActivity>(); - } - removed.add(pa); - if (DEBUG_PREFERRED) { - Slog.i(TAG, "Removing preferred activity " - + pa.mPref.mComponent + ":"); - filter.dump(new LogPrinter(Log.INFO, TAG), " "); - } - } - } - if (removed != null) { - for (int i=0; i<removed.size(); i++) { - PreferredActivity pa = removed.get(i); - pir.removeFilter(pa); + Intent intent = new Intent(filter.getAction(0)).addCategory(filter.getCategory(0)); + if (filter.countDataSchemes() == 1) { + Uri.Builder builder = new Uri.Builder(); + builder.scheme(filter.getDataScheme(0)); + intent.setData(builder.build()); + } + List<PreferredActivity> matches = pir.queryIntent( + intent, null, true, callingUserId); + if (DEBUG_PREFERRED) { + Slog.i(TAG, matches.size() + " preferred matches for " + intent); + } + for (int i = 0; i < matches.size(); i++) { + PreferredActivity pa = matches.get(i); + if (DEBUG_PREFERRED) { + Slog.i(TAG, "Removing preferred activity " + + pa.mPref.mComponent + ":"); + filter.dump(new LogPrinter(Log.INFO, TAG), " "); } + pir.removeFilter(pa); } } addPreferredActivityInternal(filter, match, set, activity, true, callingUserId); diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java index 8cc1d02..b1d67de 100644 --- a/services/java/com/android/server/wm/AppWindowToken.java +++ b/services/java/com/android/server/wm/AppWindowToken.java @@ -53,6 +53,7 @@ class AppWindowToken extends WindowToken { int groupId = -1; boolean appFullscreen; int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; + int configChanges; boolean showWhenLocked; // The input dispatching timeout for this application token in nanoseconds. diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index de307a3..1395eda 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -3406,7 +3406,8 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId, - int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId) { + int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId, + int configChanges) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "addAppToken()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); @@ -3438,6 +3439,7 @@ public class WindowManagerService extends IWindowManager.Stub atoken.appFullscreen = fullscreen; atoken.showWhenLocked = showWhenLocked; atoken.requestedOrientation = requestedOrientation; + atoken.configChanges = configChanges; if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken + " to stack=" + stackId + " task=" + taskId + " at " + addPos); @@ -8267,8 +8269,10 @@ public class WindowManagerService extends IWindowManager.Stub // windows, since that means "perform layout as normal, // just don't display"). if (!gone || !win.mHaveFrame || win.mLayoutNeeded - || win.mAttrs.type == TYPE_KEYGUARD && win.isConfigChanged() - || mOpeningApps.contains(win.mAppToken) + || win.isConfigChanged() && (win.mAttrs.type == TYPE_KEYGUARD || + (win.mAppToken != null && (win.mAppToken.configChanges & + (ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) + != 0)) || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) { if (!win.mLayoutAttached) { if (initial) { |