diff options
180 files changed, 2786 insertions, 1418 deletions
diff --git a/api/current.txt b/api/current.txt index 3b868ad1f645..e299720ad582 100644 --- a/api/current.txt +++ b/api/current.txt @@ -22742,6 +22742,7 @@ package android.media { method public android.graphics.Bitmap getFrameAtTime(long, int); method public android.graphics.Bitmap getFrameAtTime(long); method public android.graphics.Bitmap getFrameAtTime(); + method public android.graphics.Bitmap getScaledFrameAtTime(long, int, int, int); method public void release(); method public void setDataSource(java.lang.String) throws java.lang.IllegalArgumentException; method public void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.lang.IllegalArgumentException; diff --git a/api/system-current.txt b/api/system-current.txt index fc1b6edc4ca9..1b292ccb5302 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -24686,6 +24686,7 @@ package android.media { method public android.graphics.Bitmap getFrameAtTime(long, int); method public android.graphics.Bitmap getFrameAtTime(long); method public android.graphics.Bitmap getFrameAtTime(); + method public android.graphics.Bitmap getScaledFrameAtTime(long, int, int, int); method public void release(); method public void setDataSource(java.lang.String) throws java.lang.IllegalArgumentException; method public void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.lang.IllegalArgumentException; diff --git a/api/test-current.txt b/api/test-current.txt index f50ef55a7e46..7aeb52e38154 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -22878,6 +22878,7 @@ package android.media { method public android.graphics.Bitmap getFrameAtTime(long, int); method public android.graphics.Bitmap getFrameAtTime(long); method public android.graphics.Bitmap getFrameAtTime(); + method public android.graphics.Bitmap getScaledFrameAtTime(long, int, int, int); method public void release(); method public void setDataSource(java.lang.String) throws java.lang.IllegalArgumentException; method public void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.lang.IllegalArgumentException; diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java index c6d83f51a40a..b69ef1c2fca5 100644 --- a/cmds/am/src/com/android/commands/am/Instrument.java +++ b/cmds/am/src/com/android/commands/am/Instrument.java @@ -152,7 +152,7 @@ public class Instrument { System.out.println(pretty); } else { if (results != null) { - for (String key : results.keySet()) { + for (String key : sorted(results.keySet())) { System.out.println( "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key)); } @@ -163,6 +163,10 @@ public class Instrument { @Override public void onError(String errorText, boolean commandError) { + if (mRawMode) { + System.out.println("onError: commandError=" + commandError + " message=" + + errorText); + } // The regular BaseCommand error printing will print the commandErrors. if (!commandError) { System.out.println(errorText); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 4a4bab55f054..43693e1983b7 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -5718,6 +5718,7 @@ public final class ActivityThread { // probably end up doing the same disk access. Application app; final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); + final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy(); try { // If the app is being launched for full backup or restore, bring it up in // a restricted environment with the base application class. @@ -5745,17 +5746,21 @@ public final class ActivityThread { "Exception thrown in onCreate() of " + data.instrumentationName + ": " + e.toString(), e); } + try { + mInstrumentation.callApplicationOnCreate(app); + } catch (Exception e) { + if (!mInstrumentation.onException(app, e)) { + throw new RuntimeException( + "Unable to create application " + app.getClass().getName() + + ": " + e.toString(), e); + } + } } finally { - StrictMode.setThreadPolicy(savedPolicy); - } - - try { - mInstrumentation.callApplicationOnCreate(app); - } catch (Exception e) { - if (!mInstrumentation.onException(app, e)) { - throw new RuntimeException( - "Unable to create application " + app.getClass().getName() - + ": " + e.toString(), e); + // If the app targets < O-MR1, or doesn't change the thread policy + // during startup, clobber the policy to maintain behavior of b/36951662 + if (data.appInfo.targetSdkVersion <= Build.VERSION_CODES.O + || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) { + StrictMode.setThreadPolicy(savedPolicy); } } diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 0e33934acf8e..49d58eb2c38d 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -144,15 +144,15 @@ interface IWallpaperManager { * or {@link WallpaperManager#FLAG_SYSTEM} * @return colors of chosen wallpaper */ - WallpaperColors getWallpaperColors(int which); + WallpaperColors getWallpaperColors(int which, int userId); /** * Register a callback to receive color updates */ - void registerWallpaperColorsCallback(IWallpaperManagerCallback cb); + void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId); /** * Unregister a callback that was receiving color updates */ - void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb); + void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId); } diff --git a/core/java/android/app/IWallpaperManagerCallback.aidl b/core/java/android/app/IWallpaperManagerCallback.aidl index 0cfbaef6d6eb..ea0ceab9a8df 100644 --- a/core/java/android/app/IWallpaperManagerCallback.aidl +++ b/core/java/android/app/IWallpaperManagerCallback.aidl @@ -34,6 +34,6 @@ oneway interface IWallpaperManagerCallback { /** * Called when wallpaper colors change */ - void onWallpaperColorsChanged(in WallpaperColors colors, int which); + void onWallpaperColorsChanged(in WallpaperColors colors, int which, int userId); } diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 885817231175..34343e9e106a 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -204,7 +204,12 @@ public class NotificationManager { public static final int IMPORTANCE_NONE = 0; /** - * Min notification importance: only shows in the shade, below the fold. + * Min notification importance: only shows in the shade, below the fold. This should + * not be used with {@link Service#startForeground(int, Notification) Service.startForeground} + * since a foreground service is supposed to be something the user cares about so it does + * not make semantic sense to mark its notification as minimum importance. If you do this + * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show + * a higher-priority notification about your app running in the background. */ public static final int IMPORTANCE_MIN = 1; diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java index d0791cf93469..2a8130f1bd5e 100644 --- a/core/java/android/app/WallpaperColors.java +++ b/core/java/android/app/WallpaperColors.java @@ -408,4 +408,13 @@ public final class WallpaperColors implements Parcelable { return new Size(newWidth, newHeight); } + + @Override + public String toString() { + final StringBuilder colors = new StringBuilder(); + for (int i = 0; i < mMainColors.size(); i++) { + colors.append(Integer.toHexString(mMainColors.get(i).toArgb())).append(" "); + } + return "[WallpaperColors: " + colors.toString() + "h: " + mColorHints + "]"; + } } diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 0398b47e8591..16d02149cc0d 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -307,13 +307,14 @@ public class WallpaperManager { * changes its colors. * @param callback Listener * @param handler Thread to call it from. Main thread if null. + * @param userId Owner of the wallpaper or UserHandle.USER_ALL */ public void addOnColorsChangedListener(@NonNull OnColorsChangedListener callback, - @Nullable Handler handler) { + @Nullable Handler handler, int userId) { synchronized (this) { if (!mColorCallbackRegistered) { try { - mService.registerWallpaperColorsCallback(this); + mService.registerWallpaperColorsCallback(this, userId); mColorCallbackRegistered = true; } catch (RemoteException e) { // Failed, service is gone @@ -328,15 +329,17 @@ public class WallpaperManager { * Stop listening to wallpaper color events. * * @param callback listener + * @param userId Owner of the wallpaper or UserHandle.USER_ALL */ - public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback) { + public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback, + int userId) { synchronized (this) { mColorListeners.removeIf(pair -> pair.first == callback); if (mColorListeners.size() == 0 && mColorCallbackRegistered) { mColorCallbackRegistered = false; try { - mService.unregisterWallpaperColorsCallback(this); + mService.unregisterWallpaperColorsCallback(this, userId); } catch (RemoteException e) { // Failed, service is gone Log.w(TAG, "Can't unregister color updates", e); @@ -346,7 +349,7 @@ public class WallpaperManager { } @Override - public void onWallpaperColorsChanged(WallpaperColors colors, int which) { + public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) { synchronized (this) { for (Pair<OnColorsChangedListener, Handler> listener : mColorListeners) { Handler handler = listener.second; @@ -361,21 +364,21 @@ public class WallpaperManager { stillExists = mColorListeners.contains(listener); } if (stillExists) { - listener.first.onColorsChanged(colors, which); + listener.first.onColorsChanged(colors, which, userId); } }); } } } - WallpaperColors getWallpaperColors(int which) { + WallpaperColors getWallpaperColors(int which, int userId) { if (which != FLAG_LOCK && which != FLAG_SYSTEM) { throw new IllegalArgumentException( "Must request colors for exactly one kind of wallpaper"); } try { - return mService.getWallpaperColors(which); + return mService.getWallpaperColors(which, userId); } catch (RemoteException e) { // Can't get colors, connection lost. } @@ -857,7 +860,7 @@ public class WallpaperManager { * @param listener A listener to register */ public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) { - sGlobals.addOnColorsChangedListener(listener, null); + addOnColorsChangedListener(listener, null); } /** @@ -868,25 +871,61 @@ public class WallpaperManager { */ public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener, @NonNull Handler handler) { - sGlobals.addOnColorsChangedListener(listener, handler); + addOnColorsChangedListener(listener, handler, mContext.getUserId()); + } + + /** + * Registers a listener to get notified when the wallpaper colors change + * @param listener A listener to register + * @param handler Where to call it from. Will be called from the main thread + * if null. + * @param userId Owner of the wallpaper or UserHandle.USER_ALL. + * @hide + */ + public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener, + @NonNull Handler handler, int userId) { + sGlobals.addOnColorsChangedListener(listener, handler, userId); } /** * Stop listening to color updates. - * @param callback A callback to unsubscribe + * @param callback A callback to unsubscribe. */ public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback) { - sGlobals.removeOnColorsChangedListener(callback); + removeOnColorsChangedListener(callback, mContext.getUserId()); + } + + /** + * Stop listening to color updates. + * @param callback A callback to unsubscribe. + * @param userId Owner of the wallpaper or UserHandle.USER_ALL. + * @hide + */ + public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback, + int userId) { + sGlobals.removeOnColorsChangedListener(callback, userId); } /** * Get the primary colors of a wallpaper * @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or * {@link #FLAG_LOCK} - * @return a list of colors ordered by priority + * @return {@link WallpaperColors} or null if colors are unknown. */ public @Nullable WallpaperColors getWallpaperColors(int which) { - return sGlobals.getWallpaperColors(which); + return getWallpaperColors(which, mContext.getUserId()); + } + + /** + * Get the primary colors of a wallpaper + * @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or + * {@link #FLAG_LOCK} + * @param userId Owner of the wallpaper. + * @return {@link WallpaperColors} or null if colors are unknown. + * @hide + */ + public @Nullable WallpaperColors getWallpaperColors(int which, int userId) { + return sGlobals.getWallpaperColors(which, userId); } /** @@ -1902,9 +1941,9 @@ public class WallpaperManager { } @Override - public void onWallpaperColorsChanged(WallpaperColors colors, int which) + public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) throws RemoteException { - sGlobals.onWallpaperColorsChanged(colors, which); + sGlobals.onWallpaperColorsChanged(colors, which, userId); } } @@ -1921,5 +1960,19 @@ public class WallpaperManager { * @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM} */ void onColorsChanged(WallpaperColors colors, int which); + + /** + * Called when colors change. + * A {@link android.app.WallpaperColors} object containing a simplified + * color histogram will be given. + * + * @param colors Wallpaper color info + * @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM} + * @param userId Owner of the wallpaper + * @hide + */ + default void onColorsChanged(WallpaperColors colors, int which, int userId) { + onColorsChanged(colors, which); + } } } diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java index f98746851678..36f5f9673236 100644 --- a/core/java/android/app/backup/WallpaperBackupHelper.java +++ b/core/java/android/app/backup/WallpaperBackupHelper.java @@ -18,20 +18,19 @@ package android.app.backup; import android.app.WallpaperManager; import android.content.Context; -import android.graphics.BitmapFactory; -import android.graphics.Point; import android.os.Environment; import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.util.Slog; -import android.view.Display; -import android.view.WindowManager; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; /** - * Helper for backing up / restoring wallpapers. Basically an AbsoluteFileBackupHelper, - * but with logic for deciding what to do with restored wallpaper images. + * We no longer back up wallpapers with this helper, but we do need to process restores + * of legacy backup payloads. We just take the restored image as-is and apply it as the + * system wallpaper using the public "set the wallpaper" API. * * @hide */ @@ -39,83 +38,34 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu private static final String TAG = "WallpaperBackupHelper"; private static final boolean DEBUG = false; - // If 'true', then apply an acceptable-size heuristic at restore time, dropping back - // to the factory default wallpaper if the restored one differs "too much" from the - // device's preferred wallpaper image dimensions. - private static final boolean REJECT_OUTSIZED_RESTORE = false; - - // When outsized restore rejection is enabled, this is the maximum ratio between the - // source and target image heights that will be permitted. The ratio is checked both - // ways (i.e. >= MAX, or <= 1/MAX) to validate restores from both largeer-than-target - // and smaller-than-target sources. - private static final double MAX_HEIGHT_RATIO = 1.35; - - // The height ratio check when applying larger images on smaller screens is separate; - // in current policy we accept any such restore regardless of the relative dimensions. - private static final double MIN_HEIGHT_RATIO = 0; - - // This path must match what the WallpaperManagerService uses - // TODO: Will need to change if backing up non-primary user's wallpaper - // http://b/22388012 - public static final String WALLPAPER_IMAGE = - new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM), - "wallpaper").getAbsolutePath(); - public static final String WALLPAPER_ORIG_IMAGE = - new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM), - "wallpaper_orig").getAbsolutePath(); - public static final String WALLPAPER_INFO = - new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM), - "wallpaper_info.xml").getAbsolutePath(); - // Use old keys to keep legacy data compatibility and avoid writing two wallpapers + // Key that legacy wallpaper imagery was stored under public static final String WALLPAPER_IMAGE_KEY = "/data/data/com.android.settings/files/wallpaper"; public static final String WALLPAPER_INFO_KEY = "/data/system/wallpaper_info.xml"; - // Stage file - should be adjacent to the WALLPAPER_IMAGE location. The wallpapers - // will be saved to this file from the restore stream, then renamed to the proper - // location if it's deemed suitable. - // TODO: Will need to change if backing up non-primary user's wallpaper - // http://b/22388012 + // Stage file that the restored imagery is stored to prior to being applied + // as the system wallpaper. private static final String STAGE_FILE = new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM), "wallpaper-tmp").getAbsolutePath(); - Context mContext; - String[] mFiles; - String[] mKeys; - double mDesiredMinWidth; - double mDesiredMinHeight; + private final String[] mKeys; + private final WallpaperManager mWpm; /** - * Construct a helper for backing up / restoring the files at the given absolute locations - * within the file system. + * Legacy wallpaper restores, from back when the imagery was stored under the + * "android" system package as file key/value entities. * * @param context * @param files */ - public WallpaperBackupHelper(Context context, String[] files, String[] keys) { + public WallpaperBackupHelper(Context context, String[] keys) { super(context); mContext = context; - mFiles = files; mKeys = keys; - final WindowManager wm = - (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - final WallpaperManager wpm = - (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE); - final Display d = wm.getDefaultDisplay(); - final Point size = new Point(); - d.getSize(size); - mDesiredMinWidth = Math.min(size.x, size.y); - mDesiredMinHeight = (double) wpm.getDesiredMinimumHeight(); - if (mDesiredMinHeight <= 0) { - mDesiredMinHeight = size.y; - } - - if (DEBUG) { - Slog.d(TAG, "dmW=" + mDesiredMinWidth + " dmH=" + mDesiredMinHeight); - } + mWpm = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE); } /** @@ -126,13 +76,12 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu @Override public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) { - performBackup_checked(oldState, data, newState, mFiles, mKeys); + // Intentionally no-op; we don't back up the wallpaper this way any more. } /** * Restore one absolute file entity from the restore stream. If we're restoring the - * magic wallpaper file, take specific action to determine whether it is suitable for - * the current device. + * magic wallpaper file, apply it as the system wallpaper. */ @Override public void restoreEntity(BackupDataInputStream data) { @@ -140,69 +89,21 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu if (isKeyInList(key, mKeys)) { if (key.equals(WALLPAPER_IMAGE_KEY)) { // restore the file to the stage for inspection - File f = new File(STAGE_FILE); - if (writeFile(f, data)) { - - // Preflight the restored image's dimensions without loading it - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeFile(STAGE_FILE, options); - - if (DEBUG) Slog.d(TAG, "Restoring wallpaper image w=" + options.outWidth - + " h=" + options.outHeight); - - if (REJECT_OUTSIZED_RESTORE) { - // We accept any wallpaper that is at least as wide as our preference - // (i.e. wide enough to fill the screen), and is within a comfortable - // factor of the target height, to avoid significant clipping/scaling/ - // letterboxing. At this point we know that mDesiredMinWidth is the - // smallest dimension, regardless of current orientation, so we can - // safely require that the candidate's width and height both exceed - // that hard minimum. - final double heightRatio = mDesiredMinHeight / options.outHeight; - if (options.outWidth < mDesiredMinWidth - || options.outHeight < mDesiredMinWidth - || heightRatio >= MAX_HEIGHT_RATIO - || heightRatio <= MIN_HEIGHT_RATIO) { - // Not wide enough for the screen, or too short/tall to be a good fit - // for the height of the screen, broken image file, or the system's - // desires for wallpaper size are in a bad state. Probably one of the - // first two. - Slog.i(TAG, "Restored image dimensions (w=" - + options.outWidth + ", h=" + options.outHeight - + ") too far off target (tw=" - + mDesiredMinWidth + ", th=" + mDesiredMinHeight - + "); falling back to default wallpaper."); - f.delete(); - return; + File stage = new File(STAGE_FILE); + try { + if (writeFile(stage, data)) { + try (FileInputStream in = new FileInputStream(stage)) { + mWpm.setStream(in); + } catch (IOException e) { + Slog.e(TAG, "Unable to set restored wallpaper: " + e.getMessage()); } + } else { + Slog.e(TAG, "Unable to save restored wallpaper"); } - - // We passed the acceptable-dimensions test (if any), so we're going to - // use the restored image. That comes last, when we are done restoring - // both the pixels and the metadata. + } finally { + stage.delete(); } - } else if (key.equals(WALLPAPER_INFO_KEY)) { - // XML file containing wallpaper info - File f = new File(WALLPAPER_INFO); - writeFile(f, data); } } } - - /** - * Hook for the agent to call this helper upon completion of the restore. We do this - * upon completion so that we know both the imagery and the wallpaper info have - * been emplaced without requiring either or relying on ordering. - */ - public void onRestoreFinished() { - final File f = new File(STAGE_FILE); - if (f.exists()) { - // TODO: spin a service to copy the restored image to sd/usb storage, - // since it does not exist anywhere other than the private wallpaper - // file. - Slog.d(TAG, "Applying restored wallpaper image."); - f.renameTo(new File(WALLPAPER_ORIG_IMAGE)); - } - } } diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index ea675fb4c3cd..c3ebf554ea8c 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1406,8 +1406,9 @@ public class PackageInstaller { // Icon may have been omitted for calls that return bulk session // lists, so try fetching the specific icon. try { - appIcon = AppGlobals.getPackageManager().getPackageInstaller() - .getSessionInfo(sessionId).appIcon; + final SessionInfo info = AppGlobals.getPackageManager().getPackageInstaller() + .getSessionInfo(sessionId); + appIcon = (info != null) ? info.appIcon : null; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index 63eedf539bfe..55343a2904f2 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -73,8 +73,10 @@ public abstract class CameraDevice implements AutoCloseable { * Create a request suitable for still image capture. Specifically, this * means prioritizing image quality over frame rate. These requests would * commonly be used with the {@link CameraCaptureSession#capture} method. - * This template is guaranteed to be supported on all camera devices. - * + * This template is guaranteed to be supported on all camera devices except + * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices + * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE + * BACKWARD_COMPATIBLE}. * @see #createCaptureRequest */ public static final int TEMPLATE_STILL_CAPTURE = 2; @@ -84,7 +86,10 @@ public abstract class CameraDevice implements AutoCloseable { * that a stable frame rate is used, and post-processing is set for * recording quality. These requests would commonly be used with the * {@link CameraCaptureSession#setRepeatingRequest} method. - * This template is guaranteed to be supported on all camera devices. + * This template is guaranteed to be supported on all camera devices except + * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices + * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE + * BACKWARD_COMPATIBLE}. * * @see #createCaptureRequest */ @@ -98,7 +103,10 @@ public abstract class CameraDevice implements AutoCloseable { * {@link #TEMPLATE_RECORD} is is in use with {@link CameraCaptureSession#setRepeatingRequest}. * This template is guaranteed to be supported on all camera devices except * legacy devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} - * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}) + * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}) and + * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices + * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE + * BACKWARD_COMPATIBLE}. * * @see #createCaptureRequest */ diff --git a/core/java/android/hardware/radio/ITunerCallback.aidl b/core/java/android/hardware/radio/ITunerCallback.aidl index c3bbaec85134..a09a6864ac6e 100644 --- a/core/java/android/hardware/radio/ITunerCallback.aidl +++ b/core/java/android/hardware/radio/ITunerCallback.aidl @@ -23,7 +23,7 @@ import android.hardware.radio.RadioMetadata; oneway interface ITunerCallback { void onError(int status); void onConfigurationChanged(in RadioManager.BandConfig config); - void onProgramInfoChanged(); + void onCurrentProgramInfoChanged(); void onTrafficAnnouncement(boolean active); void onEmergencyAnnouncement(boolean active); void onAntennaState(boolean connected); diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java index 00a36c8af1a5..02ca52ed84fc 100644 --- a/core/java/android/hardware/radio/TunerCallbackAdapter.java +++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java @@ -49,7 +49,7 @@ class TunerCallbackAdapter extends ITunerCallback.Stub { synchronized (mLock) { if (mTuner != null) throw new IllegalStateException(); mTuner = tuner; - if (mPendingProgramInfoChanged) onProgramInfoChanged(); + if (mPendingProgramInfoChanged) onCurrentProgramInfoChanged(); } } @@ -64,7 +64,7 @@ class TunerCallbackAdapter extends ITunerCallback.Stub { } @Override - public void onProgramInfoChanged() { + public void onCurrentProgramInfoChanged() { synchronized (mLock) { if (mTuner == null) { mPendingProgramInfoChanged = true; diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index ed223d1fd503..d2e3510ee3b1 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -16,10 +16,6 @@ package android.inputmethodservice; -import com.android.internal.os.HandlerCaller; -import com.android.internal.os.SomeArgs; -import com.android.internal.view.IInputMethodSession; - import android.content.Context; import android.graphics.Rect; import android.os.Bundle; @@ -34,9 +30,13 @@ import android.view.InputEventReceiver; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.inputmethod.CompletionInfo; +import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.InputMethodSession; -import android.view.inputmethod.CursorAnchorInfo; + +import com.android.internal.os.HandlerCaller; +import com.android.internal.os.SomeArgs; +import com.android.internal.view.IInputMethodSession; class IInputMethodSessionWrapper extends IInputMethodSession.Stub implements HandlerCaller.Callback { @@ -218,7 +218,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { if (mInputMethodSession == null) { // The session has been finished. finishInputEvent(event, false); diff --git a/core/java/android/net/NetworkRecommendationProvider.java b/core/java/android/net/NetworkRecommendationProvider.java index fdb4ba073893..a70c97bac10c 100644 --- a/core/java/android/net/NetworkRecommendationProvider.java +++ b/core/java/android/net/NetworkRecommendationProvider.java @@ -35,6 +35,7 @@ import java.util.concurrent.Executor; * A network recommendation provider is any application which: * <ul> * <li>Is granted the {@link permission#SCORE_NETWORKS} permission. + * <li>Is granted the {@link permission#ACCESS_COARSE_LOCATION} permission. * <li>Includes a Service for the {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} intent * which is protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE} permission. * </ul> diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java index 7e0c9ce33b82..060af0dd1ba1 100644 --- a/core/java/android/net/NetworkScoreManager.java +++ b/core/java/android/net/NetworkScoreManager.java @@ -38,7 +38,8 @@ import java.util.List; * * <p>A network scorer is any application which: * <ul> - * <li>Declares the {@link permission#SCORE_NETWORKS} permission. + * <li>Is granted the {@link permission#SCORE_NETWORKS} permission. + * <li>Is granted the {@link permission#ACCESS_COARSE_LOCATION} permission. * <li>Include a Service for the {@link #ACTION_RECOMMEND_NETWORKS} action * protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE} * permission. diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 54d5860048ad..cc6b5e1e3ce3 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -3544,6 +3544,7 @@ public abstract class BatteryStats implements Parcelable { if (name.indexOf(',') >= 0) { name = name.replace(',', '_'); } + name = name.replaceAll("[\\n|\\r]+", ""); dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString()); } } diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index f45efdab361e..0df6361d4224 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -441,6 +441,11 @@ public class Binder implements IBinder { * * <p>If you want to call this, call transact(). * + * <p>Implementations that are returning a result should generally use + * {@link Parcel#writeNoException() Parcel.writeNoException} and + * {@link Parcel#writeException(Exception) Parcel.writeException} to propagate + * exceptions back to the caller.</p> + * * @param code The action to perform. This should * be a number between {@link #FIRST_CALL_TRANSACTION} and * {@link #LAST_CALL_TRANSACTION}. diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 10331b9229e3..2efb0f5e419d 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -1782,6 +1782,7 @@ public final class Parcel { * <li>{@link IllegalStateException} * <li>{@link NullPointerException} * <li>{@link SecurityException} + * <li>{@link UnsupportedOperationException} * <li>{@link NetworkOnMainThreadException} * </ul> * diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java index 712bbaa101aa..459aeb087c2f 100644 --- a/core/java/android/os/SharedMemory.java +++ b/core/java/android/os/SharedMemory.java @@ -28,6 +28,7 @@ import java.io.Closeable; import java.io.FileDescriptor; import java.nio.ByteBuffer; import java.nio.DirectByteBuffer; +import java.nio.NioUtils; import sun.misc.Cleaner; @@ -191,11 +192,16 @@ public final class SharedMemory implements Parcelable, Closeable { } /** - * Creates an mmap of the SharedMemory with the specified prot, offset, and length. + * Creates an mmap of the SharedMemory with the specified prot, offset, and length. This will + * always produce a new ByteBuffer window to the backing shared memory region. Every call + * to map() may be paired with a call to {@link #unmap(ByteBuffer)} when the ByteBuffer + * returned by map() is no longer needed. * * @param prot A bitwise-or'd combination of PROT_READ, PROT_WRITE, PROT_EXEC, or PROT_NONE. - * @param offset The offset into the shared memory to begin mapping - * @param length The length of the region to map + * @param offset The offset into the shared memory to begin mapping. Must be >= 0 and less than + * getSize(). + * @param length The length of the region to map. Must be > 0 and offset + length must not + * exceed getSize(). * @return A ByteBuffer mapping. * @throws ErrnoException if the mmap call failed. */ @@ -203,7 +209,7 @@ public final class SharedMemory implements Parcelable, Closeable { checkOpen(); validateProt(prot); if (offset < 0) { - throw new IllegalArgumentException("Offset must be > 0"); + throw new IllegalArgumentException("Offset must be >= 0"); } if (length <= 0) { throw new IllegalArgumentException("Length must be > 0"); @@ -218,15 +224,16 @@ public final class SharedMemory implements Parcelable, Closeable { } /** - * Unmaps a buffer previously returned by {@link #map(int, int, int)} + * Unmaps a buffer previously returned by {@link #map(int, int, int)}. This will immediately + * release the backing memory of the ByteBuffer, invalidating all references to it. Only + * call this method if there are no duplicates of the ByteBuffer in use and don't + * access the ByteBuffer after calling this method. + * * @param buffer The buffer to unmap */ public static void unmap(@NonNull ByteBuffer buffer) { if (buffer instanceof DirectByteBuffer) { - Cleaner cleaner = ((DirectByteBuffer) buffer).cleaner(); - if (cleaner != null) { - cleaner.clean(); - } + NioUtils.freeDirectBuffer(buffer); } else { throw new IllegalArgumentException( "ByteBuffer wasn't created by #map(int, int, int); can't unmap"); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 53c82e6c5237..dc9a26e431b8 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -576,21 +576,6 @@ public final class Settings { "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS"; /** - * Activity Action: Show a dialog to select input method. - * <p> - * In some cases, a matching Activity may not exist, so ensure you - * safeguard against this. - * <p> - * Input: Nothing. - * <p> - * Output: Nothing. - * @hide - */ - @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_SHOW_INPUT_METHOD_PICKER = - "android.settings.SHOW_INPUT_METHOD_PICKER"; - - /** * Activity Action: Show settings to manage the user input dictionary. * <p> * Starting with {@link android.os.Build.VERSION_CODES#KITKAT}, diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl index eff52e6ca1b5..fb6f637fd927 100644 --- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl +++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl @@ -30,5 +30,6 @@ oneway interface IWallpaperEngine { void dispatchPointer(in MotionEvent event); void dispatchWallpaperCommand(String action, int x, int y, int z, in Bundle extras); + void requestWallpaperColors(); void destroy(); } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 424967f0e011..65d66dc863d5 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -105,6 +105,7 @@ public abstract class WallpaperService extends Service { private static final int MSG_WINDOW_RESIZED = 10030; private static final int MSG_WINDOW_MOVED = 10035; private static final int MSG_TOUCH_EVENT = 10040; + private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050; private final ArrayList<Engine> mActiveEngines = new ArrayList<Engine>(); @@ -268,7 +269,7 @@ public abstract class WallpaperService extends Service { } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { boolean handled = false; try { if (event instanceof MotionEvent @@ -626,8 +627,7 @@ public abstract class WallpaperService extends Service { } Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event); mCaller.sendMessage(msg); - } else { - event.recycle(); + } else {event.recycle(); } } @@ -1192,6 +1192,11 @@ public abstract class WallpaperService extends Service { } } + public void requestWallpaperColors() { + Message msg = mCaller.obtainMessage(MSG_REQUEST_WALLPAPER_COLORS); + mCaller.sendMessage(msg); + } + public void destroy() { Message msg = mCaller.obtainMessage(DO_DETACH); mCaller.sendMessage(msg); @@ -1210,7 +1215,6 @@ public abstract class WallpaperService extends Service { mEngine = engine; mActiveEngines.add(engine); engine.attach(this); - engine.notifyColorsChanged(); return; } case DO_DETACH: { @@ -1268,6 +1272,16 @@ public abstract class WallpaperService extends Service { } ev.recycle(); } break; + case MSG_REQUEST_WALLPAPER_COLORS: { + if (mConnection == null) { + break; + } + try { + mConnection.onWallpaperColorsChanged(mEngine.onComputeColors()); + } catch (RemoteException e) { + // Connection went away, nothing to do in here. + } + } break; default : Log.w(TAG, "Unknown message type " + message.what); } diff --git a/core/java/android/text/InputFilter.java b/core/java/android/text/InputFilter.java index d773158ed0cb..a507f2b373fc 100644 --- a/core/java/android/text/InputFilter.java +++ b/core/java/android/text/InputFilter.java @@ -16,7 +16,9 @@ package android.text; -import android.annotation.Nullable; +import android.annotation.NonNull; + +import com.android.internal.util.Preconditions; import java.util.Locale; @@ -64,7 +66,8 @@ public interface InputFilter * Constructs a locale-specific AllCaps filter, to make sure capitalization rules of that * locale are used for transforming the sequence. */ - public AllCaps(@Nullable Locale locale) { + public AllCaps(@NonNull Locale locale) { + Preconditions.checkNotNull(locale); mLocale = locale; } diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java index 48e5ca9a20f4..af26a88e877c 100644 --- a/core/java/android/view/FocusFinder.java +++ b/core/java/android/view/FocusFinder.java @@ -193,6 +193,8 @@ public class FocusFinder { private View findNextUserSpecifiedFocus(ViewGroup root, View focused, int direction) { // check for user specified next focus View userSetNextFocus = focused.findUserSetNextFocus(root, direction); + View cycleCheck = userSetNextFocus; + boolean cycleStep = true; // we want the first toggle to yield false while (userSetNextFocus != null) { if (userSetNextFocus.isFocusable() && userSetNextFocus.getVisibility() == View.VISIBLE @@ -201,6 +203,14 @@ public class FocusFinder { return userSetNextFocus; } userSetNextFocus = userSetNextFocus.findUserSetNextFocus(root, direction); + if (cycleStep = !cycleStep) { + cycleCheck = cycleCheck.findUserSetNextFocus(root, direction); + if (cycleCheck == userSetNextFocus) { + // found a cycle, user-specified focus forms a loop and none of the views + // are currently focusable. + break; + } + } } return null; } diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java index 20ab539f52d2..c566a653da42 100644 --- a/core/java/android/view/InputEventReceiver.java +++ b/core/java/android/view/InputEventReceiver.java @@ -111,9 +111,10 @@ public abstract class InputEventReceiver { * to indicate whether the event was handled. No new input events will be received * until {@link #finishInputEvent} is called. * + * @param displayId The display id on which input event triggered. * @param event The input event that was received. */ - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { finishInputEvent(event, false); } @@ -180,9 +181,9 @@ public abstract class InputEventReceiver { // Called from native code. @SuppressWarnings("unused") - private void dispatchInputEvent(int seq, InputEvent event) { + private void dispatchInputEvent(int seq, InputEvent event, int displayId) { mSeqMap.put(event.getSequenceNumber(), seq); - onInputEvent(event); + onInputEvent(event, displayId); } // Called from native code. diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 22329f4e772b..44c88e146879 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -272,6 +272,15 @@ public class SurfaceControl { public static final int POWER_MODE_DOZE_SUSPEND = 3; /** + * A value for windowType used to indicate that the window should be omitted from screenshots + * and display mirroring. A temporary workaround until we express such things with + * the hierarchy. + * TODO: b/64227542 + * @hide + */ + public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731; + + /** * Create a surface with a name. * <p> * The surface creation flags specify what kind of surface to create and diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 6af01f66ac6e..eea692aa952a 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -9711,6 +9711,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param hasTransientState true if this view has transient state */ public void setHasTransientState(boolean hasTransientState) { + final boolean oldHasTransientState = hasTransientState(); mTransientStateCount = hasTransientState ? mTransientStateCount + 1 : mTransientStateCount - 1; if (mTransientStateCount < 0) { @@ -9722,9 +9723,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // update flag if we've just incremented up from 0 or decremented down to 0 mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) | (hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0); - if (mParent != null) { + final boolean newHasTransientState = hasTransientState(); + if (mParent != null && newHasTransientState != oldHasTransientState) { try { - mParent.childHasTransientStateChanged(this, hasTransientState); + mParent.childHasTransientStateChanged(this, newHasTransientState); } catch (AbstractMethodError e) { Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() + " does not fully implement ViewParent", e); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 05f9da5e2867..6bf48450fc71 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -6752,7 +6752,7 @@ public final class ViewRootImpl implements ViewParent, } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { enqueueInputEvent(event, this, 0, true); } diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 4041bcf7e3cb..be763afddb88 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1413,11 +1413,12 @@ public interface WindowManager extends ViewManager { public static final int PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 0x00080000; /** - * Flag to indicate that this window should be ignored when determining what parts of the - * screen can be magnified. + * Indicates that this window is the rounded corners overlay present on some + * devices this means that it will be excluded from: screenshots, + * screen magnification, and mirroring. * @hide */ - public static final int PRIVATE_FLAG_NO_MAGNIFICATION_REGION_EFFECT = 0x00100000; + public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 0x00100000; /** * Control flags that are private to the platform. diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java index 4c9cf40beb8d..98f8dc8e3a6d 100644 --- a/core/java/android/view/WindowManagerInternal.java +++ b/core/java/android/view/WindowManagerInternal.java @@ -347,4 +347,11 @@ public abstract class WindowManagerInternal { * Requests the window manager to recompute the windows for accessibility. */ public abstract void computeWindowsForAccessibility(); + + /** + * Called after virtual display Id is updated by + * {@link com.android.server.vr.Vr2dDisplay} with a specific + * {@param vr2dDisplayId}. + */ + public abstract void setVr2dDisplayId(int vr2dDisplayId); } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 668d25e74276..49b7ed8bac0e 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -16,6 +16,7 @@ package android.view; +import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; @@ -616,7 +617,16 @@ public interface WindowManagerPolicy { * 2. motionEvent will be recycled after onPointerEvent returns so if it is needed later a * copy() must be made and the copy must be recycled. **/ - public void onPointerEvent(MotionEvent motionEvent); + void onPointerEvent(MotionEvent motionEvent); + + /** + * @see #onPointerEvent(MotionEvent) + **/ + default void onPointerEvent(MotionEvent motionEvent, int displayId) { + if (displayId == DEFAULT_DISPLAY) { + onPointerEvent(motionEvent); + } + } } /** Window has been added to the screen. */ diff --git a/core/java/android/view/textclassifier/LangId.java b/core/java/android/view/textclassifier/LangId.java deleted file mode 100644 index 23c7842780a9..000000000000 --- a/core/java/android/view/textclassifier/LangId.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 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 android.view.textclassifier; - -/** - * Java wrapper for LangId native library interface. - * This class is used to detect languages in text. - */ -final class LangId { - - static { - System.loadLibrary("textclassifier"); - } - - private final long mModelPtr; - - /** - * Creates a new instance of LangId predictor, using the provided model image. - */ - LangId(int fd) { - mModelPtr = nativeNew(fd); - } - - /** - * Detects the language for given text. - */ - public ClassificationResult[] findLanguages(String text) { - return nativeFindLanguages(mModelPtr, text); - } - - /** - * Frees up the allocated memory. - */ - public void close() { - nativeClose(mModelPtr); - } - - private static native long nativeNew(int fd); - - private static native ClassificationResult[] nativeFindLanguages( - long context, String text); - - private static native void nativeClose(long context); - - /** Classification result for findLanguage method. */ - static final class ClassificationResult { - final String mLanguage; - /** float range: 0 - 1 */ - final float mScore; - - ClassificationResult(String language, float score) { - mLanguage = language; - mScore = score; - } - } -} diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java index efc88e23fa67..d7b07761a653 100644 --- a/core/java/android/view/textclassifier/TextClassificationManager.java +++ b/core/java/android/view/textclassifier/TextClassificationManager.java @@ -16,37 +16,22 @@ package android.view.textclassifier; -import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; import android.content.Context; -import android.os.ParcelFileDescriptor; -import android.util.Log; import com.android.internal.util.Preconditions; -import java.io.File; -import java.io.FileNotFoundException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Locale; - /** * Interface to the text classification service. */ @SystemService(Context.TEXT_CLASSIFICATION_SERVICE) public final class TextClassificationManager { - private static final String LOG_TAG = "TextClassificationManager"; - private final Object mTextClassifierLock = new Object(); - private final Object mLangIdLock = new Object(); private final Context mContext; - private ParcelFileDescriptor mLangIdFd; private TextClassifier mTextClassifier; - private LangId mLangId; /** @hide */ public TextClassificationManager(Context context) { @@ -75,47 +60,4 @@ public final class TextClassificationManager { mTextClassifier = textClassifier; } } - - /** - * Returns information containing languages that were detected in the provided text. - * This is a blocking operation you should avoid calling it on the UI thread. - * - * @throws IllegalArgumentException if text is null - * @hide - */ - public List<TextLanguage> detectLanguages(@NonNull CharSequence text) { - Preconditions.checkArgument(text != null); - try { - if (text.length() > 0) { - final LangId.ClassificationResult[] results = - getLanguageDetector().findLanguages(text.toString()); - final TextLanguage.Builder tlBuilder = new TextLanguage.Builder(0, text.length()); - final int size = results.length; - for (int i = 0; i < size; i++) { - tlBuilder.setLanguage( - new Locale.Builder().setLanguageTag(results[i].mLanguage).build(), - results[i].mScore); - } - - return Collections.unmodifiableList(Arrays.asList(tlBuilder.build())); - } - } catch (Throwable t) { - // Avoid throwing from this method. Log the error. - Log.e(LOG_TAG, "Error detecting languages for text. Returning empty result.", t); - } - // Getting here means something went wrong. Return an empty result. - return Collections.emptyList(); - } - - private LangId getLanguageDetector() throws FileNotFoundException { - synchronized (mLangIdLock) { - if (mLangId == null) { - mLangIdFd = ParcelFileDescriptor.open( - new File("/etc/textclassifier/textclassifier.langid.model"), - ParcelFileDescriptor.MODE_READ_ONLY); - mLangId = new LangId(mLangIdFd.getFd()); - } - return mLangId; - } - } } diff --git a/core/java/android/view/textclassifier/TextLanguage.java b/core/java/android/view/textclassifier/TextLanguage.java deleted file mode 100644 index 209813a2beac..000000000000 --- a/core/java/android/view/textclassifier/TextLanguage.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2017 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 android.view.textclassifier; - -import android.annotation.FloatRange; -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.Nullable; - -import com.android.internal.util.Preconditions; - -import java.util.List; -import java.util.Locale; - -/** - * Specifies detected languages for a section of text indicated by a start and end index. - * @hide - */ -public final class TextLanguage { - - private final int mStartIndex; - private final int mEndIndex; - @NonNull private final EntityConfidence<Locale> mLanguageConfidence; - @NonNull private final List<Locale> mLanguages; - - private TextLanguage( - int startIndex, int endIndex, @NonNull EntityConfidence<Locale> languageConfidence) { - mStartIndex = startIndex; - mEndIndex = endIndex; - mLanguageConfidence = new EntityConfidence<>(languageConfidence); - mLanguages = mLanguageConfidence.getEntities(); - } - - /** - * Returns the start index of the detected languages in the text provided to generate this - * object. - */ - public int getStartIndex() { - return mStartIndex; - } - - /** - * Returns the end index of the detected languages in the text provided to generate this object. - */ - public int getEndIndex() { - return mEndIndex; - } - - /** - * Returns the number of languages found in the classified text. - */ - @IntRange(from = 0) - public int getLanguageCount() { - return mLanguages.size(); - } - - /** - * Returns the language locale at the specified index. - * Language locales are ordered from high confidence to low confidence. - * - * @throws IndexOutOfBoundsException if the specified index is out of range. - * @see #getLanguageCount() for the number of language locales available. - */ - @NonNull - public Locale getLanguage(int index) { - return mLanguages.get(index); - } - - /** - * Returns the confidence score for the specified language. The value ranges from - * 0 (low confidence) to 1 (high confidence). 0 indicates that the language was - * not found for the classified text. - */ - @FloatRange(from = 0.0, to = 1.0) - public float getConfidenceScore(@Nullable Locale language) { - return mLanguageConfidence.getConfidenceScore(language); - } - - @Override - public String toString() { - return String.format("TextLanguage {%d, %d, %s}", - mStartIndex, mEndIndex, mLanguageConfidence); - } - - /** - * Builder to build {@link TextLanguage} objects. - */ - public static final class Builder { - - private final int mStartIndex; - private final int mEndIndex; - @NonNull private final EntityConfidence<Locale> mLanguageConfidence = - new EntityConfidence<>(); - - /** - * Creates a builder to build {@link TextLanguage} objects. - * - * @param startIndex the start index of the detected languages in the text provided - * to generate the result - * @param endIndex the end index of the detected languages in the text provided - * to generate the result. Must be greater than startIndex - */ - public Builder(@IntRange(from = 0) int startIndex, @IntRange(from = 0) int endIndex) { - Preconditions.checkArgument(startIndex >= 0); - Preconditions.checkArgument(endIndex > startIndex); - mStartIndex = startIndex; - mEndIndex = endIndex; - } - - /** - * Sets a language locale with the associated confidence score. - */ - public Builder setLanguage( - @NonNull Locale locale, @FloatRange(from = 0.0, to = 1.0) float confidenceScore) { - mLanguageConfidence.setEntityType(locale, confidenceScore); - return this; - } - - /** - * Builds and returns a {@link TextLanguage}. - */ - public TextLanguage build() { - return new TextLanguage(mStartIndex, mEndIndex, mLanguageConfidence); - } - } -} diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java index 727412b03e28..ef98a5e9f787 100644 --- a/core/java/com/android/internal/colorextraction/ColorExtractor.java +++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java @@ -22,6 +22,7 @@ import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; import android.os.Trace; +import android.os.UserHandle; import android.util.Log; import android.util.SparseArray; @@ -44,6 +45,7 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener private static final int[] sGradientTypes = new int[]{TYPE_NORMAL, TYPE_DARK, TYPE_EXTRA_DARK}; private static final String TAG = "ColorExtractor"; + private static final boolean DEBUG = false; protected final SparseArray<GradientColors[]> mGradientColors; private final ArrayList<WeakReference<OnColorsChangedListener>> mOnColorsChangedListeners; @@ -147,6 +149,9 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener @Override public void onColorsChanged(WallpaperColors colors, int which) { + if (DEBUG) { + Log.d(TAG, "New wallpaper colors for " + which + ": " + colors); + } boolean changed = false; if ((which & WallpaperManager.FLAG_LOCK) != 0) { mLockColors = colors; diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 3599e64da4f1..e59cf8408963 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -3632,7 +3632,12 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteUidProcessStateLocked(int uid, int state) { - uid = mapUid(uid); + int parentUid = mapUid(uid); + if (uid != parentUid) { + // Isolated UIDs process state is already rolled up into parent, so no need to track + // Otherwise the parent's process state will get downgraded incorrectly + return; + } getUidStatsLocked(uid).updateUidProcessStateLocked(state); } diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java index 537565185d9b..a96b5dd3ed70 100644 --- a/core/java/com/android/server/backup/SystemBackupAgent.java +++ b/core/java/com/android/server/backup/SystemBackupAgent.java @@ -35,7 +35,8 @@ import java.io.File; import java.io.IOException; /** - * Backup agent for various system-managed data, currently just the system wallpaper + * Backup agent for various system-managed data. Wallpapers are now handled by a + * separate package, but we still process restores from legacy datasets here. */ public class SystemBackupAgent extends BackupAgentHelper { private static final String TAG = "SystemBackupAgent"; @@ -61,16 +62,19 @@ public class SystemBackupAgent extends BackupAgentHelper { // TODO: http://b/22388012 private static final String WALLPAPER_IMAGE_DIR = Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM).getAbsolutePath(); - private static final String WALLPAPER_IMAGE = WallpaperBackupHelper.WALLPAPER_IMAGE; + public static final String WALLPAPER_IMAGE = + new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM), + "wallpaper").getAbsolutePath(); // TODO: Will need to change if backing up non-primary user's wallpaper // TODO: http://b/22388012 private static final String WALLPAPER_INFO_DIR = Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM).getAbsolutePath(); - private static final String WALLPAPER_INFO = WallpaperBackupHelper.WALLPAPER_INFO; + public static final String WALLPAPER_INFO = + new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM), + "wallpaper_info.xml").getAbsolutePath(); // Use old keys to keep legacy data compatibility and avoid writing two wallpapers private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY; - private static final String WALLPAPER_INFO_KEY = WallpaperBackupHelper.WALLPAPER_INFO_KEY; private WallpaperBackupHelper mWallpaperHelper = null; @@ -98,13 +102,11 @@ public class SystemBackupAgent extends BackupAgentHelper { // Slot in a restore helper for the older wallpaper backup schema to support restore // from devices still generating data in that format. mWallpaperHelper = new WallpaperBackupHelper(this, - new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }, - new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY} ); + new String[] { WALLPAPER_IMAGE_KEY} ); addHelper(WALLPAPER_HELPER, mWallpaperHelper); // On restore, we also support a long-ago wallpaper data schema "system_files" addHelper("system_files", new WallpaperBackupHelper(this, - new String[] { WALLPAPER_IMAGE }, new String[] { WALLPAPER_IMAGE_KEY} )); addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this)); @@ -115,27 +117,12 @@ public class SystemBackupAgent extends BackupAgentHelper { addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper()); addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper()); - try { - super.onRestore(data, appVersionCode, newState); - - IWallpaperManager wallpaper = (IWallpaperManager) ServiceManager.getService( - Context.WALLPAPER_SERVICE); - if (wallpaper != null) { - try { - wallpaper.settingsRestored(); - } catch (RemoteException re) { - Slog.e(TAG, "Couldn't restore settings\n" + re); - } - } - } catch (IOException ex) { - // If there was a failure, delete everything for the wallpaper, this is too aggressive, - // but this is hopefully a rare failure. - Slog.d(TAG, "restore failed", ex); - (new File(WALLPAPER_IMAGE)).delete(); - (new File(WALLPAPER_INFO)).delete(); - } + super.onRestore(data, appVersionCode, newState); } + /** + * Support for 'adb restore' of legacy archives + */ @Override public void onRestoreFile(ParcelFileDescriptor data, long size, int type, String domain, String path, long mode, long mtime) @@ -183,12 +170,4 @@ public class SystemBackupAgent extends BackupAgentHelper { } } } - - @Override - public void onRestoreFinished() { - // helper will be null following 'adb restore' or other full-data operation - if (mWallpaperHelper != null) { - mWallpaperHelper.onRestoreFinished(); - } - } } diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index 31e954bf5b88..c457ab0cdb04 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -233,8 +233,9 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, for (;;) { uint32_t seq; InputEvent* inputEvent; + int32_t displayId; status_t status = mInputConsumer.consume(&mInputEventFactory, - consumeBatches, frameTime, &seq, &inputEvent); + consumeBatches, frameTime, &seq, &inputEvent, &displayId); if (status) { if (status == WOULD_BLOCK) { if (!skipCallbacks && !mBatchedInputEventPending @@ -311,7 +312,8 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName()); } env->CallVoidMethod(receiverObj.get(), - gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj); + gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj, + displayId); if (env->ExceptionCheck()) { ALOGE("Exception dispatching input event."); skipCallbacks = true; @@ -417,7 +419,7 @@ int register_android_view_InputEventReceiver(JNIEnv* env) { gInputEventReceiverClassInfo.dispatchInputEvent = GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, - "dispatchInputEvent", "(ILandroid/view/InputEvent;)V"); + "dispatchInputEvent", "(ILandroid/view/InputEvent;I)V"); gInputEventReceiverClassInfo.dispatchBatchedInputEventPending = GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "dispatchBatchedInputEventPending", "()V"); diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp index 420ff2a46814..58ccef183f96 100644 --- a/core/jni/android_view_InputEventSender.cpp +++ b/core/jni/android_view_InputEventSender.cpp @@ -39,6 +39,8 @@ namespace android { // Log debug messages about the dispatch cycle. static const bool kDebugDispatchCycle = false; +// Display id for default(primary) display. +static const int32_t kDefaultDisplayId = 0; static struct { jclass clazz; @@ -136,6 +138,7 @@ status_t NativeInputEventSender::sendMotionEvent(uint32_t seq, const MotionEvent publishedSeq = mNextPublishedSeq++; status_t status = mInputPublisher.publishMotionEvent(publishedSeq, event->getDeviceId(), event->getSource(), + kDefaultDisplayId /* TODO(multi-display): propagate display id */, event->getAction(), event->getActionButton(), event->getFlags(), event->getEdgeFlags(), event->getMetaState(), event->getButtonState(), event->getXOffset(), event->getYOffset(), diff --git a/core/res/res/drawable-hdpi/ic_corp_icon.png b/core/res/res/drawable-hdpi/ic_corp_icon.png Binary files differdeleted file mode 100644 index 06c51351e8f2..000000000000 --- a/core/res/res/drawable-hdpi/ic_corp_icon.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_corp_icon.png b/core/res/res/drawable-mdpi/ic_corp_icon.png Binary files differdeleted file mode 100644 index 79372b21035c..000000000000 --- a/core/res/res/drawable-mdpi/ic_corp_icon.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_corp_icon.png b/core/res/res/drawable-xhdpi/ic_corp_icon.png Binary files differdeleted file mode 100644 index 3626c7d03b81..000000000000 --- a/core/res/res/drawable-xhdpi/ic_corp_icon.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/ic_corp_icon.png b/core/res/res/drawable-xxhdpi/ic_corp_icon.png Binary files differdeleted file mode 100644 index d33319f3eda4..000000000000 --- a/core/res/res/drawable-xxhdpi/ic_corp_icon.png +++ /dev/null diff --git a/core/res/res/drawable-xxxhdpi/ic_corp_icon.png b/core/res/res/drawable-xxxhdpi/ic_corp_icon.png Binary files differdeleted file mode 100644 index 359e210ea81f..000000000000 --- a/core/res/res/drawable-xxxhdpi/ic_corp_icon.png +++ /dev/null diff --git a/core/res/res/drawable/ic_corp_badge.xml b/core/res/res/drawable/ic_corp_badge.xml new file mode 100644 index 000000000000..78cce586ac18 --- /dev/null +++ b/core/res/res/drawable/ic_corp_badge.xml @@ -0,0 +1,12 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="20dp" + android:height="20dp" + android:viewportWidth="20.0" + android:viewportHeight="20.0"> + <path + android:pathData="M10,10m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" + android:fillColor="#FF6D00"/> + <path + android:pathData="M14.67,6.5h-2.33V5.33c0,-0.65 -0.52,-1.17 -1.17,-1.17H8.83c-0.65,0 -1.17,0.52 -1.17,1.17V6.5H5.33c-0.65,0 -1.16,0.52 -1.16,1.17l-0.01,6.42c0,0.65 0.52,1.17 1.17,1.17h9.33c0.65,0 1.17,-0.52 1.17,-1.17V7.67C15.83,7.02 15.31,6.5 14.67,6.5zM10,11.75c-0.64,0 -1.17,-0.52 -1.17,-1.17c0,-0.64 0.52,-1.17 1.17,-1.17c0.64,0 1.17,0.52 1.17,1.17C11.17,11.22 10.64,11.75 10,11.75zM11.17,6.5H8.83V5.33h2.33V6.5z" + android:fillColor="#FFFFFF"/> +</vector> diff --git a/core/res/res/drawable/ic_corp_badge_case.xml b/core/res/res/drawable/ic_corp_badge_case.xml index 0b6028cc5d2a..2d11ee61eabb 100644 --- a/core/res/res/drawable/ic_corp_badge_case.xml +++ b/core/res/res/drawable/ic_corp_badge_case.xml @@ -1,30 +1,9 @@ -<!-- -Copyright (C) 2016 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. ---> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="20.0dp" - android:height="20.0dp" + android:width="20dp" + android:height="20dp" android:viewportWidth="20.0" android:viewportHeight="20.0"> <path - android:pathData="M15.2,6.2L4.8,6.2c-0.5,0.0 -0.9,0.4 -0.9,1.0L3.9,10.0c0.0,0.5 0.4,1.0 0.9,1.0l3.8,0.0l0.0,-1.0l2.9,0.0l0.0,1.0l3.8,0.0c0.5,0.0 1.0,-0.4 1.0,-1.0L16.3,7.1C16.2,6.6 15.8,6.2 15.2,6.2z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M8.6,12.9l0.0,-1.0L4.3,11.9l0.0,2.4c0.0,0.5 0.4,0.9 0.9,0.9l9.5,0.0c0.5,0.0 0.9,-0.4 0.9,-0.9l0.0,-2.4l-4.3,0.0l0.0,1.0L8.6,12.9z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M7.1,5.2l0.0,1.0 1.0,0.0 0.0,-1.0 3.799999,0.0 0.0,1.0 1.0,0.0 0.0,-1.0 -1.0,-0.9 -3.799999,0.0z" + android:pathData="M14.67,6.5h-2.33V5.33c0,-0.65 -0.52,-1.17 -1.17,-1.17H8.83c-0.65,0 -1.17,0.52 -1.17,1.17V6.5H5.33c-0.65,0 -1.16,0.52 -1.16,1.17l-0.01,6.42c0,0.65 0.52,1.17 1.17,1.17h9.33c0.65,0 1.17,-0.52 1.17,-1.17V7.67C15.83,7.02 15.31,6.5 14.67,6.5zM10,11.75c-0.64,0 -1.17,-0.52 -1.17,-1.17c0,-0.64 0.52,-1.17 1.17,-1.17c0.64,0 1.17,0.52 1.17,1.17C11.17,11.22 10.64,11.75 10,11.75zM11.17,6.5H8.83V5.33h2.33V6.5z" android:fillColor="#FFFFFF"/> </vector> diff --git a/core/res/res/drawable/ic_corp_badge_no_background.xml b/core/res/res/drawable/ic_corp_badge_no_background.xml index 78322a9920c8..8f7fb70d5b83 100644 --- a/core/res/res/drawable/ic_corp_badge_no_background.xml +++ b/core/res/res/drawable/ic_corp_badge_no_background.xml @@ -1,30 +1,9 @@ -<!-- -Copyright (C) 2016 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. ---> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> <path - android:pathData="M20.801,5.981L17.13,5.98l0.001,-1.471l-2.053,-2.055L8.969,2.453L6.915,4.506L6.914,5.977L3.203,5.976c-1.216,0.0 -2.189,0.983 -2.189,2.199L1.0,12.406c0.0,1.216 0.983,2.2 2.199,2.2L10.0,14.608l0.0,-1.644l0.291,0.0l3.351,0.0l0.291,0.0l0.0,1.645l6.863,0.002c1.216,0.0 2.2,-0.983 2.2,-2.199L23.0,8.181C23.0,6.965 22.017,5.981 20.801,5.981zM15.076,5.979L8.968,5.978l0.001,-1.471l6.108,0.001L15.076,5.979z" + android:pathData="M20,6h-4V4c0,-1.11 -0.89,-2 -2,-2h-4C8.89,2 8,2.89 8,4v2H4C2.89,6 2.01,6.89 2.01,8L2,19c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2V8C22,6.89 21.11,6 20,6zM12,15c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2s2,0.9 2,2S13.1,15 12,15zM14,6h-4V4h4V6z" android:fillColor="#FFFFFF"/> - <path - android:pathData="M13.911,16.646L9.978,16.646L9.978,15.48L1.673,15.48l0.0,4.105c0.0,1.216 0.959,2.2 2.175,2.2l16.13,0.004c1.216,0.0 2.203,-0.983 2.203,-2.199l0.0,-4.11l-8.27,0.0L13.910999,16.646z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M23.657,6.55 h4.72 v1.137 h-4.72z" - android:fillColor="#00000000"/> </vector> diff --git a/core/res/res/drawable/ic_corp_badge_off.xml b/core/res/res/drawable/ic_corp_badge_off.xml index 6799bf716d97..4774f318738a 100644 --- a/core/res/res/drawable/ic_corp_badge_off.xml +++ b/core/res/res/drawable/ic_corp_badge_off.xml @@ -1,56 +1,12 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright (C) 2015 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. ---> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="20dp" - android:height="20dp" - android:viewportWidth="20" - android:viewportHeight="20"> - + android:width="20dp" + android:height="20dp" + android:viewportWidth="20.0" + android:viewportHeight="20.0"> <path - android:fillColor="#607D8B" - android:pathData="M10,0 C15.5228,0,20,4.47715,20,10 C20,15.5228,15.5228,20,10,20 -C4.47715,20,0,15.5228,0,10 C0,4.47715,4.47715,0,10,0 Z" /> + android:pathData="M10,10m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" + android:fillColor="#607D8B"/> <path - android:pathData="M1.91667,1.91667 L18.0833,1.91667 L18.0833,18.0833 L1.91667,18.0833 -L1.91667,1.91667 Z" /> - <path - android:fillColor="#ffffff" - android:pathData="M11.9167,11.9167 L11.4167,11.9167 L11.4167,12.8333 L8.5,12.8333 L8.5,11.9167 -L4.16667,11.9167 L4.16667,14.3333 C4.16667,14.8333,4.58333,15.25,5.08333,15.25 -L14.75,15.25 C14.9167,15.25,15,15.25,15.1667,15.1667 L11.9167,11.9167 Z" /> - <path - android:fillColor="#ffffff" - android:pathData="M15.8333,13.75 L15.8333,11.9167 L14,11.9167 -C14.6667,12.6667,15.3333,13.3333,15.8333,13.75 Z" /> - <path - android:fillColor="#ffffff" - android:pathData="M6.16667,6.16667 L4.66667,6.16667 C4.16667,6.16667,3.75,6.58333,3.75,7.08333 -L3.75,10 C3.75,10.5,4.16667,10.9167,4.66667,10.9167 L8.5,10.9167 L8.5,10 L10,10 -L6.16667,6.16667 Z" /> - <path - android:fillColor="#ffffff" - android:pathData="M8.08333,6 L8.08333,5.16667 L11.9167,5.16667 L11.9167,6.08333 L8.16667,6.08333 -C9.66667,7.58333,11.4167,9.33333,12.9167,10.8333 L15.25,10.8333 -C15.75,10.8333,16.1667,10.4167,16.1667,9.91667 L16.1667,7.08333 -C16.1667,6.58333,15.75,6.16667,15.25,6.16667 L12.8333,6.16667 L12.8333,5.25 -L11.9167,4.33333 L8.08333,4.33333 L7.16667,5.16667 -C7.41667,5.41667,7.75,5.75,8.08333,6 Z" /> - <path - android:fillColor="#ffffff" - android:pathData="M15.6824,15.676 L14.6807,16.6777 L3.24921,5.24624 L4.25093,4.24452 -L15.6824,15.676 Z" /> -</vector>
\ No newline at end of file + android:pathData="M16.42,15.68l-0.85,-0.85L7.21,6.47L4.9,4.16L4.16,4.9l1.57,1.57H5.36c-0.65,0 -1.16,0.52 -1.16,1.17L4.2,14.05c0,0.65 0.52,1.17 1.17,1.17h9.12l1.2,1.2L16.42,15.68zM15.83,7.64c0.03,-0.65 -0.49,-1.17 -1.14,-1.14h-2.33V5.3c0,-0.65 -0.52,-1.17 -1.17,-1.14H8.86C8.22,4.14 7.7,4.66 7.7,5.3v0.19l8.14,8.17V7.64zM11.2,6.5H8.83V5.3h2.36V6.5z" + android:fillColor="#FFFFFF"/> +</vector> diff --git a/core/res/res/drawable/ic_corp_icon.xml b/core/res/res/drawable/ic_corp_icon.xml new file mode 100644 index 000000000000..a6b68f17409d --- /dev/null +++ b/core/res/res/drawable/ic_corp_icon.xml @@ -0,0 +1,12 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="48dp" + android:height="48dp" + android:viewportWidth="48.0" + android:viewportHeight="48.0"> + <path + android:pathData="M24,24m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0" + android:fillColor="#FF6D00"/> + <path + android:pathData="M35.2,15.6h-5.6v-2.8c0,-1.55 -1.25,-2.8 -2.8,-2.8h-5.6c-1.55,0 -2.8,1.25 -2.8,2.8v2.8h-5.6c-1.55,0 -2.79,1.25 -2.79,2.8L10,33.8c0,1.55 1.25,2.8 2.8,2.8h22.4c1.55,0 2.8,-1.25 2.8,-2.8V18.4C38,16.85 36.75,15.6 35.2,15.6zM24,28.2c-1.54,0 -2.8,-1.26 -2.8,-2.8s1.26,-2.8 2.8,-2.8c1.54,0 2.8,1.26 2.8,2.8S25.54,28.2 24,28.2zM26.8,15.6h-5.6v-2.8h5.6V15.6z" + android:fillColor="#FFFFFF"/> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/ic_corp_icon_badge_case.xml b/core/res/res/drawable/ic_corp_icon_badge_case.xml index d62eda4a12ba..dd653c6ff2d3 100644 --- a/core/res/res/drawable/ic_corp_icon_badge_case.xml +++ b/core/res/res/drawable/ic_corp_icon_badge_case.xml @@ -1,30 +1,9 @@ -<!-- -Copyright (C) 2016 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. ---> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64.0dp" - android:height="64.0dp" + android:width="64dp" + android:height="64dp" android:viewportWidth="64.0" android:viewportHeight="64.0"> <path - android:pathData="M56.4,43.5L41.8,43.5c-0.7,0.0 -1.3,0.6 -1.3,1.3l0.0,4.0c0.0,0.7 0.6,1.3 1.3,1.3L47.0,50.1l0.0,-1.3l4.0,0.0l0.0,1.4l5.4,0.0c0.7,0.0 1.3,-0.6 1.3,-1.3l0.0,-4.0C57.6,44.1 57.0,43.5 56.4,43.5z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M47.1,52.8l0.0,-1.3l-6.0,0.0l0.0,3.3c0.0,0.7 0.6,1.3 1.3,1.3l13.2,0.0c0.7,0.0 1.3,-0.6 1.3,-1.3l0.0,-3.3l-6.0,0.0l0.0,1.3L47.1,52.8z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M45.1,42.2l0.0,1.299999 1.300003,0.0 0.0,-1.299999 5.299999,0.0 0.0,1.299999 1.399998,0.0 0.0,-1.299999 -1.399998,-1.299999 -5.299999,0.0z" + android:pathData="M55.67,44h-3.33v-1.67c0,-0.92 -0.74,-1.67 -1.67,-1.67h-3.33c-0.92,0 -1.67,0.74 -1.67,1.67V44h-3.33c-0.92,0 -1.66,0.74 -1.66,1.67l-0.01,9.17c0,0.93 0.74,1.67 1.67,1.67h13.33c0.92,0 1.67,-0.74 1.67,-1.67v-9.17C57.33,44.74 56.59,44 55.67,44zM49,51.5c-0.92,0 -1.67,-0.75 -1.67,-1.67c0,-0.92 0.75,-1.67 1.67,-1.67s1.67,0.75 1.67,1.67C50.67,50.75 49.92,51.5 49,51.5zM50.67,44h-3.33v-1.67h3.33V44z" android:fillColor="#FFFFFF"/> </vector> diff --git a/core/res/res/drawable/ic_corp_statusbar_icon.xml b/core/res/res/drawable/ic_corp_statusbar_icon.xml index e742c0b9bff2..8f7fb70d5b83 100644 --- a/core/res/res/drawable/ic_corp_statusbar_icon.xml +++ b/core/res/res/drawable/ic_corp_statusbar_icon.xml @@ -1,30 +1,9 @@ -<!-- -Copyright (C) 2014 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. ---> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" + android:width="24dp" + android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> <path - android:pathData="M20.801,5.981L17.13,5.98l0.001,-1.471l-2.053,-2.055L8.969,2.453L6.915,4.506L6.914,5.977L3.203,5.976c-1.216,0.0 -2.189,0.983 -2.189,2.199L1.0,12.406c0.0,1.216 0.983,2.2 2.199,2.2L10.0,14.608l0.0,-1.644l0.291,0.0l3.351,0.0l0.291,0.0l0.0,1.645l6.863,0.002c1.216,0.0 2.2,-0.983 2.2,-2.199L23.0,8.181C23.0,6.965 22.017,5.981 20.801,5.981zM15.076,5.979L8.968,5.978l0.001,-1.471l6.108,0.001L15.076,5.979z" + android:pathData="M20,6h-4V4c0,-1.11 -0.89,-2 -2,-2h-4C8.89,2 8,2.89 8,4v2H4C2.89,6 2.01,6.89 2.01,8L2,19c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2V8C22,6.89 21.11,6 20,6zM12,15c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2s2,0.9 2,2S13.1,15 12,15zM14,6h-4V4h4V6z" android:fillColor="#FFFFFF"/> - <path - android:pathData="M13.911,16.646L9.978,16.646L9.978,15.48L1.673,15.48l0.0,4.105c0.0,1.216 0.959,2.2 2.175,2.2l16.13,0.004c1.216,0.0 2.203,-0.983 2.203,-2.199l0.0,-4.11l-8.27,0.0L13.910999,16.646z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M23.657,6.55 h4.72 v1.137 h-4.72z" - android:fillColor="#00000000"/> </vector> diff --git a/core/res/res/drawable/ic_corp_user_badge.xml b/core/res/res/drawable/ic_corp_user_badge.xml index 23809d5a3310..6a0d9025684d 100644 --- a/core/res/res/drawable/ic_corp_user_badge.xml +++ b/core/res/res/drawable/ic_corp_user_badge.xml @@ -1,24 +1,15 @@ -<!-- -Copyright (C) 2016 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. ---> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="36dp" android:height="36dp" android:viewportWidth="36.0" android:viewportHeight="36.0"> <path - android:fillColor="#FFFFFFFF" - android:pathData="M18,0C8.06,-0 0,8.06 0,18C0,27.94 8.06,36 18,36C27.94,36 36,27.94 36,18C36,8.06 27.94,0 18,0zM15.5,10.5L20.5,10.5L21.75,11.75L21.75,13L24.66,13C25.57,13 26.34,13.74 26.34,14.66L26.34,18C26.34,18.92 25.57,19.66 24.66,19.66L19.66,19.66L19.66,18.41L16.34,18.41L16.34,19.66L11.34,19.66C10.43,19.66 9.66,18.92 9.66,18L9.66,14.66C9.66,13.74 10.43,13 11.34,13L14.25,13L14.25,11.78L15.5,10.5zM15.5,11.75L15.5,13L20.5,13L20.5,11.75L15.5,11.75zM10.5,20.5L16.34,20.5L16.34,21.75L19.66,21.75L19.66,20.5L25.5,20.5L25.5,23.84C25.5,24.76 24.76,25.5 23.84,25.5L12.16,25.5C11.24,25.5 10.5,24.76 10.5,23.84L10.5,20.5z"/> + android:pathData="M16.3,11.3h3.4v1.7h-3.4z" + android:fillColor="#FFFFFF"/> + <path + android:pathData="M18,17.17c-0.92,0 -1.67,0.75 -1.67,1.67c0,0.92 0.75,1.67 1.67,1.67c0.92,0 1.67,-0.75 1.67,-1.67C19.67,17.92 18.92,17.17 18,17.17z" + android:fillColor="#FFFFFF"/> + <path + android:pathData="M18,0C8.06,0 0,8.06 0,18s8.06,18 18,18s18,-8.06 18,-18S27.94,0 18,0zM26.3,23.83c0,0.92 -0.71,1.67 -1.63,1.67H11.33c-0.93,0 -1.67,-0.74 -1.67,-1.67l0.01,-9.17c0,-0.92 0.73,-1.67 1.66,-1.67h3.37v-1.67c0,-0.93 0.71,-1.63 1.63,-1.63h3.33c0.93,0 1.63,0.71 1.63,1.63V13h3.37c0.93,0 1.63,0.74 1.63,1.67V23.83z" + android:fillColor="#FFFFFF"/> </vector> diff --git a/core/res/res/drawable/toast_frame.xml b/core/res/res/drawable/toast_frame.xml index 053b4f4fed5f..d57bd6a554e1 100644 --- a/core/res/res/drawable/toast_frame.xml +++ b/core/res/res/drawable/toast_frame.xml @@ -17,8 +17,8 @@ --> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - <!-- background is material_grey_300 with .9 alpha --> - <solid android:color="#E6E0E0E0" /> + <!-- background is material_grey_200 with .9 alpha --> + <solid android:color="#E6EEEEEE" /> <corners android:radius="22dp" /> </shape> diff --git a/core/res/res/layout/transient_notification.xml b/core/res/res/layout/transient_notification.xml index 2c08bf70491e..db586ec37cf1 100644 --- a/core/res/res/layout/transient_notification.xml +++ b/core/res/res/layout/transient_notification.xml @@ -34,8 +34,6 @@ android:layout_gravity="center_horizontal" android:textAppearance="@style/TextAppearance.Toast" android:textColor="@color/primary_text_default_material_light" - android:shadowColor="#BB000000" - android:shadowRadius="2.75" /> </LinearLayout> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 536906cde30c..fd7850009e59 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -167,7 +167,7 @@ <color name="user_icon_default_white">#ffffffff</color><!-- white --> <!-- Default profile badge colors --> - <color name="profile_badge_1">#ffff5722</color><!-- Orange --> + <color name="profile_badge_1">#ffff6d00</color><!-- Orange --> <color name="profile_badge_2">#ff000000</color><!-- Black --> <color name="profile_badge_3">#ff22f033</color><!-- Green --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 40380100121a..4b64e3fab7e5 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -525,6 +525,9 @@ <!-- Integers specifying the max packet Tx/Rx rates for full scan --> <integer translatable="false" name="config_wifi_framework_max_tx_rate_for_full_scan">8</integer> <integer translatable="false" name="config_wifi_framework_max_rx_rate_for_full_scan">16</integer> + <!-- Integers specifying the min packet Tx/Rx rates in packets per second for staying on the same network --> + <integer translatable="false" name="config_wifi_framework_min_tx_rate_for_staying_on_network">16</integer> + <integer translatable="false" name="config_wifi_framework_min_rx_rate_for_staying_on_network">16</integer> <!-- Integer parameters of the wifi to cellular handover feature wifi should not stick to bad networks --> <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-82</integer> @@ -1388,6 +1391,7 @@ <!-- The package name of the default network recommendation app. A network recommendation provider must: * Be granted the SCORE_NETWORKS permission. + * Be granted the ACCESS_COARSE_LOCATION permission. * Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action protected by the BIND_NETWORK_RECOMMENDATION_SERVICE permission. diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f392ea0e3833..e7a95c8b88b5 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -377,6 +377,8 @@ <java-symbol type="string" name="config_wifi_framework_sap_2G_channel_list" /> <java-symbol type="integer" name="config_wifi_framework_max_tx_rate_for_full_scan" /> <java-symbol type="integer" name="config_wifi_framework_max_rx_rate_for_full_scan" /> + <java-symbol type="integer" name="config_wifi_framework_min_tx_rate_for_staying_on_network" /> + <java-symbol type="integer" name="config_wifi_framework_min_rx_rate_for_staying_on_network" /> <java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" /> <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" /> diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index e127896a7091..ab9912a438d4 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -978,6 +978,13 @@ </intent-filter> </activity> + <activity android:name="android.view.ViewTransientState" android:label="View Transient State"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" /> + </intent-filter> + </activity> + <activity android:name="android.view.RemoteViewsActivity" android:label="RemoteViewsActicity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> diff --git a/core/tests/coretests/res/layout/view_transient_state.xml b/core/tests/coretests/res/layout/view_transient_state.xml new file mode 100644 index 000000000000..887301547ef1 --- /dev/null +++ b/core/tests/coretests/res/layout/view_transient_state.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2017, 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. +*/ +--> + +<!-- Demonstrates view transient state, See corresponding Java code. --> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <FrameLayout + android:id="@+id/p1" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + <FrameLayout + android:id="@+id/p2" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + <TextView + android:id="@+id/p3" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + </TextView> + + </FrameLayout> + + </FrameLayout> + +</FrameLayout> diff --git a/core/tests/coretests/src/android/view/ViewTransientState.java b/core/tests/coretests/src/android/view/ViewTransientState.java new file mode 100644 index 000000000000..206ff8166054 --- /dev/null +++ b/core/tests/coretests/src/android/view/ViewTransientState.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2007 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 android.view; + +import android.app.Activity; +import android.os.Bundle; + +import com.android.frameworks.coretests.R; + +/** + * Exercise set View's transient state + */ +public class ViewTransientState extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.view_transient_state); + } +} diff --git a/core/tests/coretests/src/android/view/ViewTransientStateTest.java b/core/tests/coretests/src/android/view/ViewTransientStateTest.java new file mode 100644 index 000000000000..36ea01deea22 --- /dev/null +++ b/core/tests/coretests/src/android/view/ViewTransientStateTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2017 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 android.view; + +import android.app.Activity; +import android.test.ActivityInstrumentationTestCase; +import android.test.UiThreadTest; +import android.test.suitebuilder.annotation.MediumTest; + +import com.android.frameworks.coretests.R; + +import static org.junit.Assert.assertFalse; + +/** + * Exercise set View's transient state + */ +public class ViewTransientStateTest extends ActivityInstrumentationTestCase<ViewTransientState> { + + View mP1; + View mP2; + View mP3; + + public ViewTransientStateTest() { + super("com.android.frameworks.coretests", ViewTransientState.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + + final Activity a = getActivity(); + mP1 = a.findViewById(R.id.p1); + mP2 = a.findViewById(R.id.p2); + mP3 = a.findViewById(R.id.p3); + } + + @UiThreadTest + @MediumTest + public void testSetTransientState1() throws Exception { + mP3.setHasTransientState(true); + mP2.setHasTransientState(true); + mP3.setHasTransientState(false); + mP2.setHasTransientState(false); + assertFalse(mP3.hasTransientState()); + assertFalse(mP2.hasTransientState()); + assertFalse(mP1.hasTransientState()); + } + + @UiThreadTest + @MediumTest + public void testSetTransientState2() throws Exception { + mP3.setHasTransientState(true); + mP2.setHasTransientState(true); + mP2.setHasTransientState(false); + mP3.setHasTransientState(false); + assertFalse(mP3.hasTransientState()); + assertFalse(mP2.hasTransientState()); + assertFalse(mP1.hasTransientState()); + } + + @UiThreadTest + @MediumTest + public void testSetTransientState3() throws Exception { + mP2.setHasTransientState(true); + mP3.setHasTransientState(true); + mP3.setHasTransientState(false); + mP2.setHasTransientState(false); + assertFalse(mP3.hasTransientState()); + assertFalse(mP2.hasTransientState()); + assertFalse(mP1.hasTransientState()); + } + + @UiThreadTest + @MediumTest + public void testSetTransientState4() throws Exception { + mP2.setHasTransientState(true); + mP3.setHasTransientState(true); + mP2.setHasTransientState(false); + mP3.setHasTransientState(false); + assertFalse(mP3.hasTransientState()); + assertFalse(mP2.hasTransientState()); + assertFalse(mP1.hasTransientState()); + } +} diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java index 29447edfddd2..2a6c22e21487 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java @@ -32,9 +32,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.List; -import java.util.Locale; - @SmallTest @RunWith(AndroidJUnit4.class) public class TextClassificationManagerTest { @@ -177,20 +174,6 @@ public class TextClassificationManagerTest { } @Test - public void testLanguageDetection() { - if (isTextClassifierDisabled()) return; - - String text = "This is a piece of English text"; - assertThat(mTcm.detectLanguages(text), isDetectedLanguage("en")); - - text = "Das ist ein deutscher Text"; - assertThat(mTcm.detectLanguages(text), isDetectedLanguage("de")); - - text = "これは日本語のテキストです"; - assertThat(mTcm.detectLanguages(text), isDetectedLanguage("ja")); - } - - @Test public void testSetTextClassifier() { TextClassifier classifier = mock(TextClassifier.class); mTcm.setTextClassifier(classifier); @@ -270,30 +253,4 @@ public class TextClassificationManagerTest { } }; } - - private static Matcher<List<TextLanguage>> isDetectedLanguage(final String language) { - return new BaseMatcher<List<TextLanguage>>() { - @Override - public boolean matches(Object o) { - if (o instanceof List) { - List languages = (List) o; - if (!languages.isEmpty()) { - Object o1 = languages.get(0); - if (o1 instanceof TextLanguage) { - TextLanguage lang = (TextLanguage) o1; - return lang.getLanguageCount() > 0 - && new Locale(language).getLanguage() - .equals(lang.getLanguage(0).getLanguage()); - } - } - } - return false; - } - - @Override - public void describeTo(Description description) { - description.appendValue(String.format("%s", language)); - } - }; - } } diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 55eeb7fa2073..61b3876cd095 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -241,7 +241,8 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { if (CC_LIKELY(layerType != LayerType::RenderLayer) || CC_UNLIKELY(!isRenderable()) || CC_UNLIKELY(properties().getWidth() == 0) - || CC_UNLIKELY(properties().getHeight() == 0)) { + || CC_UNLIKELY(properties().getHeight() == 0) + || CC_UNLIKELY(!properties().fitsOnLayer())) { if (CC_UNLIKELY(hasLayer())) { renderthread::CanvasContext::destroyLayer(this); } diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 6677178514e0..59597af55085 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -2101,9 +2101,7 @@ public class ExifInterface { private int getMimeType(BufferedInputStream in) throws IOException { in.mark(SIGNATURE_CHECK_SIZE); byte[] signatureCheckBytes = new byte[SIGNATURE_CHECK_SIZE]; - if (in.read(signatureCheckBytes) != SIGNATURE_CHECK_SIZE) { - throw new EOFException(); - } + in.read(signatureCheckBytes); in.reset(); if (isJpegFormat(signatureCheckBytes)) { return IMAGE_TYPE_JPEG; diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java index 7dd70d4d5527..666445685831 100644 --- a/media/java/android/media/MediaMetadataRetriever.java +++ b/media/java/android/media/MediaMetadataRetriever.java @@ -246,7 +246,7 @@ public class MediaMetadataRetriever * {@link #OPTION_CLOSEST} often has larger performance overhead compared * to the other options if there is no sync frame located at timeUs. * - * @return A Bitmap containing a representative video frame, which + * @return A Bitmap containing a representative video frame, which * can be null, if such a frame cannot be retrieved. */ public Bitmap getFrameAtTime(long timeUs, int option) { @@ -255,7 +255,58 @@ public class MediaMetadataRetriever throw new IllegalArgumentException("Unsupported option: " + option); } - return _getFrameAtTime(timeUs, option); + return _getFrameAtTime(timeUs, option, -1 /*dst_width*/, -1 /*dst_height*/); + } + + /** + * Retrieve a video frame near a given timestamp scaled to a desired size. + * Call this method after setDataSource(). This method finds a representative + * frame close to the given time position by considering the given option + * if possible, and returns it as a bitmap with same aspect ratio as the source + * while scaling it so that it fits into the desired size of dst_width by dst_height. + * This is useful for generating a thumbnail for an input data source or just to + * obtain a scaled frame at the given time position. + * + * @param timeUs The time position in microseconds where the frame will be retrieved. + * When retrieving the frame at the given time position, there is no + * guarantee that the data source has a frame located at the position. + * When this happens, a frame nearby will be returned. If timeUs is + * negative, time position and option will ignored, and any frame + * that the implementation considers as representative may be returned. + * + * @param option a hint on how the frame is found. Use + * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame + * that has a timestamp earlier than or the same as timeUs. Use + * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame + * that has a timestamp later than or the same as timeUs. Use + * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame + * that has a timestamp closest to or the same as timeUs. Use + * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may + * or may not be a sync frame but is closest to or the same as timeUs. + * {@link #OPTION_CLOSEST} often has larger performance overhead compared + * to the other options if there is no sync frame located at timeUs. + * + * @param dst_width expected output bitmap width + * @param dst_height expected output bitmap height + * @return A Bitmap of size not larger than dst_width by dst_height containing a + * scaled video frame, which can be null, if such a frame cannot be retrieved. + * @throws IllegalArgumentException if passed in invalid option or width by height + * is less than or equal to 0. + */ + public Bitmap getScaledFrameAtTime( + long timeUs, int option, int dst_width, int dst_height) { + if (option < OPTION_PREVIOUS_SYNC || + option > OPTION_CLOSEST) { + throw new IllegalArgumentException("Unsupported option: " + option); + } + if (dst_width <= 0) { + throw new IllegalArgumentException("Invalid width: " + dst_width); + } + if (dst_height <= 0) { + throw new IllegalArgumentException("Invalid height: " + dst_height); + } + + return _getFrameAtTime(timeUs, option, dst_width, dst_height); } /** @@ -273,8 +324,8 @@ public class MediaMetadataRetriever * negative, time position and option will ignored, and any frame * that the implementation considers as representative may be returned. * - * @return A Bitmap containing a representative video frame, which - * can be null, if such a frame cannot be retrieved. + * @return A Bitmap of size dst_widthxdst_height containing a representative + * video frame, which can be null, if such a frame cannot be retrieved. * * @see #getFrameAtTime(long, int) */ @@ -297,17 +348,16 @@ public class MediaMetadataRetriever * @see #getFrameAtTime(long, int) */ public Bitmap getFrameAtTime() { - return getFrameAtTime(-1, OPTION_CLOSEST_SYNC); + return _getFrameAtTime(-1, OPTION_CLOSEST_SYNC, -1 /*dst_width*/, -1 /*dst_height*/); } - private native Bitmap _getFrameAtTime(long timeUs, int option); + private native Bitmap _getFrameAtTime(long timeUs, int option, int width, int height); - /** * Call this method after setDataSource(). This method finds the optional * graphic or album/cover art associated associated with the data source. If * there are more than one pictures, (any) one of them is returned. - * + * * @return null if no such graphic is found. */ public byte[] getEmbeddedPicture() { diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 849bd019739d..5a16c36545c8 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -73,6 +73,8 @@ import java.lang.Runnable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; +import java.net.CookieHandler; +import java.net.CookieManager; import java.net.HttpCookie; import java.net.HttpURLConnection; import java.net.InetSocketAddress; @@ -1004,19 +1006,28 @@ public class MediaPlayer extends PlayerBase /** * Sets the data source as a content Uri. * - * @param context the Context to use when resolving the Uri - * @param uri the Content URI of the data you want to play - * @param headers the headers to be sent together with the request for the data - * The headers must not include cookies. Instead, use the cookies param. - * @param cookies the cookies to be sent together with the request - * @throws IllegalStateException if it is called in an invalid state - * @throws NullPointerException if context or uri is null - * @throws IOException if uri has a file scheme and an I/O error occurs + * To provide cookies for the subsequent HTTP requests, you can install your own default cookie + * handler and use other variants of setDataSource APIs instead. Alternatively, you can use + * this API to pass the cookies as a list of HttpCookie. If the app has not installed + * a CookieHandler already, this API creates a CookieManager and populates its CookieStore with + * the provided cookies. If the app has installed its own handler already, this API requires the + * handler to be of CookieManager type such that the API can update the manager’s CookieStore. * * <p><strong>Note</strong> that the cross domain redirection is allowed by default, * but that can be changed with key/value pairs through the headers parameter with * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to * disallow or allow cross domain redirection. + * + * @param context the Context to use when resolving the Uri + * @param uri the Content URI of the data you want to play + * @param headers the headers to be sent together with the request for the data + * The headers must not include cookies. Instead, use the cookies param. + * @param cookies the cookies to be sent together with the request + * @throws IllegalArgumentException if cookies are provided and the installed handler is not + * a CookieManager + * @throws IllegalStateException if it is called in an invalid state + * @throws NullPointerException if context or uri is null + * @throws IOException if uri has a file scheme and an I/O error occurs */ public void setDataSource(@NonNull Context context, @NonNull Uri uri, @Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies) @@ -1029,6 +1040,14 @@ public class MediaPlayer extends PlayerBase throw new NullPointerException("uri param can not be null."); } + if (cookies != null) { + CookieHandler cookieHandler = CookieHandler.getDefault(); + if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) { + throw new IllegalArgumentException("The cookie handler has to be of CookieManager " + + "type when cookies are provided."); + } + } + // The context and URI usually belong to the calling user. Get a resolver for that user // and strip out the userId from the URI if present. final ContentResolver resolver = context.getContentResolver(); @@ -1064,15 +1083,15 @@ public class MediaPlayer extends PlayerBase /** * Sets the data source as a content Uri. * - * @param context the Context to use when resolving the Uri - * @param uri the Content URI of the data you want to play - * @param headers the headers to be sent together with the request for the data - * @throws IllegalStateException if it is called in an invalid state - * * <p><strong>Note</strong> that the cross domain redirection is allowed by default, * but that can be changed with key/value pairs through the headers parameter with * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to * disallow or allow cross domain redirection. + * + * @param context the Context to use when resolving the Uri + * @param uri the Content URI of the data you want to play + * @param headers the headers to be sent together with the request for the data + * @throws IllegalStateException if it is called in an invalid state */ public void setDataSource(@NonNull Context context, @NonNull Uri uri, @Nullable Map<String, String> headers) @@ -1093,15 +1112,15 @@ public class MediaPlayer extends PlayerBase /** * Sets the data source (file-path or http/rtsp URL) to use. * - * @param path the path of the file, or the http/rtsp URL of the stream you want to play - * @throws IllegalStateException if it is called in an invalid state - * * <p>When <code>path</code> refers to a local file, the file may actually be opened by a * process other than the calling application. This implies that the pathname * should be an absolute path (as any other process runs with unspecified current working * directory), and that the pathname should reference a world-readable file. * As an alternative, the application could first open the file for reading, * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}. + * + * @param path the path of the file, or the http/rtsp URL of the stream you want to play + * @throws IllegalStateException if it is called in an invalid state */ public void setDataSource(String path) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java index ece19e46e479..c9b096fb124c 100644 --- a/media/java/android/media/browse/MediaBrowser.java +++ b/media/java/android/media/browse/MediaBrowser.java @@ -256,7 +256,13 @@ public final class MediaBrowser { */ private void forceCloseConnection() { if (mServiceConnection != null) { - mContext.unbindService(mServiceConnection); + try { + mContext.unbindService(mServiceConnection); + } catch (IllegalArgumentException e) { + if (DBG) { + Log.d(TAG, "unbindService failed", e); + } + } } mState = CONNECT_STATE_DISCONNECTED; mServiceConnection = null; @@ -445,6 +451,9 @@ public final class MediaBrowser { ResultReceiver receiver = new ResultReceiver(mHandler) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { + if (!isConnected()) { + return; + } if (resultCode != 0 || resultData == null || !resultData.containsKey(MediaBrowserService.KEY_MEDIA_ITEM)) { cb.onError(mediaId); diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java index 07cfbda7ac2b..df87e0f28cd9 100644 --- a/media/java/android/media/tv/ITvInputSessionWrapper.java +++ b/media/java/android/media/tv/ITvInputSessionWrapper.java @@ -367,7 +367,7 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { if (mTvInputSessionImpl == null) { // The session has been finished. finishInputEvent(event, false); diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java index b52906ddd1ae..4df645dc7b2f 100644 --- a/media/java/android/service/media/MediaBrowserService.java +++ b/media/java/android/service/media/MediaBrowserService.java @@ -700,6 +700,13 @@ public abstract class MediaBrowserService extends Service { new Result<MediaBrowser.MediaItem>(itemId) { @Override void onResultSent(MediaBrowser.MediaItem item, @ResultFlags int flag) { + if (mConnections.get(connection.callbacks.asBinder()) != connection) { + if (DBG) { + Log.d(TAG, "Not sending onLoadItem result for connection that has" + + " been disconnected. pkg=" + connection.pkg + " id=" + itemId); + } + return; + } if ((flag & RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED) != 0) { receiver.send(RESULT_ERROR, null); return; diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp index 71f3856d60d3..4659ae131f53 100644 --- a/media/jni/android_media_MediaMetadataRetriever.cpp +++ b/media/jni/android_media_MediaMetadataRetriever.cpp @@ -244,9 +244,11 @@ static void rotate(T *dst, const T *src, size_t width, size_t height, int angle) } } -static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, jobject thiz, jlong timeUs, jint option) +static jobject android_media_MediaMetadataRetriever_getFrameAtTime( + JNIEnv *env, jobject thiz, jlong timeUs, jint option, jint dst_width, jint dst_height) { - ALOGV("getFrameAtTime: %lld us option: %d", (long long)timeUs, option); + ALOGV("getFrameAtTime: %lld us option: %d dst width: %d heigh: %d", + (long long)timeUs, option, dst_width, dst_height); MediaMetadataRetriever* retriever = getRetriever(env, thiz); if (retriever == 0) { jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); @@ -274,15 +276,19 @@ static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, fields.createConfigMethod, GraphicsJNI::colorTypeToLegacyBitmapConfig(kRGB_565_SkColorType)); - uint32_t width, height; + uint32_t width, height, displayWidth, displayHeight; bool swapWidthAndHeight = false; if (videoFrame->mRotationAngle == 90 || videoFrame->mRotationAngle == 270) { width = videoFrame->mHeight; height = videoFrame->mWidth; swapWidthAndHeight = true; + displayWidth = videoFrame->mDisplayHeight; + displayHeight = videoFrame->mDisplayWidth; } else { width = videoFrame->mWidth; height = videoFrame->mHeight; + displayWidth = videoFrame->mDisplayWidth; + displayHeight = videoFrame->mDisplayHeight; } jobject jBitmap = env->CallStaticObjectMethod( @@ -308,22 +314,26 @@ static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, videoFrame->mHeight, videoFrame->mRotationAngle); - if (videoFrame->mDisplayWidth != videoFrame->mWidth || - videoFrame->mDisplayHeight != videoFrame->mHeight) { - uint32_t displayWidth = videoFrame->mDisplayWidth; - uint32_t displayHeight = videoFrame->mDisplayHeight; - if (swapWidthAndHeight) { - displayWidth = videoFrame->mDisplayHeight; - displayHeight = videoFrame->mDisplayWidth; - } + if (dst_width <= 0 || dst_height <= 0) { + dst_width = displayWidth; + dst_height = displayHeight; + } else { + float factor = std::min((float)dst_width / (float)displayWidth, + (float)dst_height / (float)displayHeight); + dst_width = std::round(displayWidth * factor); + dst_height = std::round(displayHeight * factor); + } + + if ((uint32_t)dst_width != videoFrame->mWidth || + (uint32_t)dst_height != videoFrame->mHeight) { ALOGV("Bitmap dimension is scaled from %dx%d to %dx%d", - width, height, displayWidth, displayHeight); + width, height, dst_width, dst_height); jobject scaledBitmap = env->CallStaticObjectMethod(fields.bitmapClazz, - fields.createScaledBitmapMethod, - jBitmap, - displayWidth, - displayHeight, - true); + fields.createScaledBitmapMethod, + jBitmap, + dst_width, + dst_height, + true); return scaledBitmap; } @@ -474,7 +484,7 @@ static const JNINativeMethod nativeMethods[] = { {"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaMetadataRetriever_setDataSourceFD}, {"_setDataSource", "(Landroid/media/MediaDataSource;)V", (void *)android_media_MediaMetadataRetriever_setDataSourceCallback}, - {"_getFrameAtTime", "(JI)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime}, + {"_getFrameAtTime", "(JIII)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime}, {"extractMetadata", "(I)Ljava/lang/String;", (void *)android_media_MediaMetadataRetriever_extractMetadata}, {"getEmbeddedPicture", "(I)[B", (void *)android_media_MediaMetadataRetriever_getEmbeddedPicture}, {"release", "()V", (void *)android_media_MediaMetadataRetriever_release}, diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index d07da93cd35a..7d4bc83e3385 100755 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -97,7 +97,6 @@ public class BluetoothEventManager { // Pairing broadcasts addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler()); - addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, new PairingCancelHandler()); // Fine-grained state broadcasts addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler()); @@ -344,24 +343,6 @@ public class BluetoothEventManager { } } - private class PairingCancelHandler implements Handler { - public void onReceive(Context context, Intent intent, BluetoothDevice device) { - if (device == null) { - Log.e(TAG, "ACTION_PAIRING_CANCEL with no EXTRA_DEVICE"); - return; - } - CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device); - if (cachedDevice == null) { - Log.e(TAG, "ACTION_PAIRING_CANCEL with no cached device"); - return; - } - int errorMsg = R.string.bluetooth_pairing_error_message; - if (context != null && cachedDevice != null) { - Utils.showError(context, cachedDevice.getName(), errorMsg); - } - } - } - private class DockEventHandler implements Handler { public void onReceive(Context context, Intent intent, BluetoothDevice device) { // Remove if unpair device upon undocking diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java index bffd6cc32a7a..33af403904b8 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java @@ -37,6 +37,7 @@ import android.net.wifi.IWifiManager; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.KeyMgmt; +import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkScoreCache; @@ -140,6 +141,9 @@ public class AccessPoint implements Comparable<AccessPoint> { static final String KEY_CONFIG = "key_config"; static final String KEY_FQDN = "key_fqdn"; static final String KEY_PROVIDER_FRIENDLY_NAME = "key_provider_friendly_name"; + static final String KEY_IS_CARRIER_AP = "key_is_carrier_ap"; + static final String KEY_CARRIER_AP_EAP_TYPE = "key_carrier_ap_eap_type"; + static final String KEY_CARRIER_NAME = "key_carrier_name"; static final AtomicInteger sLastId = new AtomicInteger(0); /** @@ -197,6 +201,13 @@ public class AccessPoint implements Comparable<AccessPoint> { private String mFqdn; private String mProviderFriendlyName; + private boolean mIsCarrierAp = false; + /** + * The EAP type {@link WifiEnterpriseConfig.Eap} associated with this AP if it is a carrier AP. + */ + private int mCarrierApEapType = WifiEnterpriseConfig.Eap.NONE; + private String mCarrierName = null; + public AccessPoint(Context context, Bundle savedState) { mContext = context; mConfig = savedState.getParcelable(KEY_CONFIG); @@ -233,6 +244,15 @@ public class AccessPoint implements Comparable<AccessPoint> { if (savedState.containsKey(KEY_PROVIDER_FRIENDLY_NAME)) { mProviderFriendlyName = savedState.getString(KEY_PROVIDER_FRIENDLY_NAME); } + if (savedState.containsKey(KEY_IS_CARRIER_AP)) { + mIsCarrierAp = savedState.getBoolean(KEY_IS_CARRIER_AP); + } + if (savedState.containsKey(KEY_CARRIER_AP_EAP_TYPE)) { + mCarrierApEapType = savedState.getInt(KEY_CARRIER_AP_EAP_TYPE); + } + if (savedState.containsKey(KEY_CARRIER_NAME)) { + mCarrierName = savedState.getString(KEY_CARRIER_NAME); + } update(mConfig, mInfo, mNetworkInfo); updateRssi(); updateSeen(); @@ -291,6 +311,9 @@ public class AccessPoint implements Comparable<AccessPoint> { this.mId = that.mId; this.mSpeed = that.mSpeed; this.mIsScoredNetworkMetered = that.mIsScoredNetworkMetered; + this.mIsCarrierAp = that.mIsCarrierAp; + this.mCarrierApEapType = that.mCarrierApEapType; + this.mCarrierName = that.mCarrierName; } /** @@ -670,6 +693,18 @@ public class AccessPoint implements Comparable<AccessPoint> { return null; } + public boolean isCarrierAp() { + return mIsCarrierAp; + } + + public int getCarrierApEapType() { + return mCarrierApEapType; + } + + public String getCarrierName() { + return mCarrierName; + } + public String getSavedNetworkSummary() { WifiConfiguration config = mConfig; if (config != null) { @@ -712,6 +747,9 @@ public class AccessPoint implements Comparable<AccessPoint> { // This is the active connection on passpoint summary.append(getSummary(mContext, getDetailedState(), false, config.providerFriendlyName)); + } else if (isActive() && config != null && getDetailedState() == DetailedState.CONNECTED + && mIsCarrierAp) { + summary.append(String.format(mContext.getString(R.string.connected_via_carrier), mCarrierName)); } else if (isActive()) { // This is the active connection on non-passpoint network summary.append(getSummary(mContext, getDetailedState(), @@ -745,6 +783,8 @@ public class AccessPoint implements Comparable<AccessPoint> { } } else if (config != null && config.getNetworkSelectionStatus().isNotRecommended()) { summary.append(mContext.getString(R.string.wifi_disabled_by_recommendation_provider)); + } else if (mIsCarrierAp) { + summary.append(String.format(mContext.getString(R.string.available_via_carrier), mCarrierName)); } else if (!isReachable()) { // Wifi out of range summary.append(mContext.getString(R.string.wifi_not_in_range)); } else { // In range, not disabled. @@ -1024,6 +1064,9 @@ public class AccessPoint implements Comparable<AccessPoint> { mScanResultCache.put(result.BSSID, result); updateRssi(); mSeen = result.timestamp; // even if the timestamp is old it is still valid + mIsCarrierAp = result.isCarrierAp; + mCarrierApEapType = result.carrierApEapType; + mCarrierName = result.carrierName; } public void saveWifiState(Bundle savedState) { @@ -1045,6 +1088,9 @@ public class AccessPoint implements Comparable<AccessPoint> { if (mProviderFriendlyName != null) { savedState.putString(KEY_PROVIDER_FRIENDLY_NAME, mProviderFriendlyName); } + savedState.putBoolean(KEY_IS_CARRIER_AP, mIsCarrierAp); + savedState.putInt(KEY_CARRIER_AP_EAP_TYPE, mCarrierApEapType); + savedState.putString(KEY_CARRIER_NAME, mCarrierName); } public void setListener(AccessPointListener listener) { @@ -1073,6 +1119,12 @@ public class AccessPoint implements Comparable<AccessPoint> { mAccessPointListener.onAccessPointChanged(this); } + // The carrier info in the ScanResult is set by the platform based on the SSID and will + // always be the same for all matching scan results. + mIsCarrierAp = result.isCarrierAp; + mCarrierApEapType = result.carrierApEapType; + mCarrierName = result.carrierName; + return true; } return false; diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java index 731a6072218b..93bf3c7ec20e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java @@ -53,6 +53,8 @@ public class TestAccessPointBuilder { private int mSecurity = AccessPoint.SECURITY_NONE; private WifiConfiguration mWifiConfig; private WifiInfo mWifiInfo; + private boolean mIsCarrierAp = false; + private String mCarrierName = null; Context mContext; private ArrayList<ScanResult> mScanResultCache; @@ -85,6 +87,10 @@ public class TestAccessPointBuilder { } bundle.putInt(AccessPoint.KEY_SECURITY, mSecurity); bundle.putInt(AccessPoint.KEY_SPEED, mSpeed); + bundle.putBoolean(AccessPoint.KEY_IS_CARRIER_AP, mIsCarrierAp); + if (mCarrierName != null) { + bundle.putString(AccessPoint.KEY_CARRIER_NAME, mCarrierName); + } AccessPoint ap = new AccessPoint(mContext, bundle); ap.setRssi(mRssi); @@ -222,4 +228,14 @@ public class TestAccessPointBuilder { mScanResultCache = scanResultCache; return this; } + + public TestAccessPointBuilder setIsCarrierAp(boolean isCarrierAp) { + mIsCarrierAp = isCarrierAp; + return this; + } + + public TestAccessPointBuilder setCarrierName(String carrierName) { + mCarrierName = carrierName; + return this; + } } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java index 9645c9407600..24f0c7a9af1b 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java @@ -35,6 +35,7 @@ import android.net.ScoredNetwork; import android.net.WifiKey; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; import android.net.wifi.WifiNetworkScoreCache; import android.net.wifi.WifiSsid; @@ -491,6 +492,75 @@ public class AccessPointTest { R.string.wifi_check_password_try_again)); } + @Test + public void testSummaryString_showsAvaiableViaCarrier() { + String carrierName = "Test Carrier"; + ScanResult result = new ScanResult(); + result.BSSID = "00:11:22:33:44:55"; + result.capabilities = "EAP"; + result.isCarrierAp = true; + result.carrierApEapType = WifiEnterpriseConfig.Eap.SIM; + result.carrierName = carrierName; + + AccessPoint ap = new AccessPoint(mContext, result); + assertThat(ap.getSummary()).isEqualTo(String.format(mContext.getString( + R.string.available_via_carrier), carrierName)); + assertThat(ap.isCarrierAp()).isEqualTo(true); + assertThat(ap.getCarrierApEapType()).isEqualTo(WifiEnterpriseConfig.Eap.SIM); + assertThat(ap.getCarrierName()).isEqualTo(carrierName); + } + + @Test + public void testSummaryString_showsConnectedViaCarrier() { + int networkId = 123; + int rssi = -55; + String carrierName = "Test Carrier"; + WifiConfiguration config = new WifiConfiguration(); + config.networkId = networkId; + WifiInfo wifiInfo = new WifiInfo(); + wifiInfo.setNetworkId(networkId); + wifiInfo.setRssi(rssi); + + NetworkInfo networkInfo = + new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); + networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); + + AccessPoint ap = new TestAccessPointBuilder(mContext) + .setNetworkInfo(networkInfo) + .setNetworkId(networkId) + .setRssi(rssi) + .setWifiInfo(wifiInfo) + .setIsCarrierAp(true) + .setCarrierName(carrierName) + .build(); + assertThat(ap.getSummary()).isEqualTo(String.format(mContext.getString( + R.string.connected_via_carrier), carrierName)); + } + + @Test + public void testUpdateScanResultWithCarrierInfo() { + String ssid = "ssid"; + AccessPoint ap = new TestAccessPointBuilder(mContext).setSsid(ssid).build(); + assertThat(ap.isCarrierAp()).isEqualTo(false); + assertThat(ap.getCarrierApEapType()).isEqualTo(WifiEnterpriseConfig.Eap.NONE); + assertThat(ap.getCarrierName()).isEqualTo(null); + + int carrierApEapType = WifiEnterpriseConfig.Eap.SIM; + String carrierName = "Test Carrier"; + ScanResult scanResult = new ScanResult(); + scanResult.SSID = ssid; + scanResult.BSSID = "00:11:22:33:44:55"; + scanResult.capabilities = ""; + scanResult.isCarrierAp = true; + scanResult.carrierApEapType = carrierApEapType; + scanResult.carrierName = carrierName; + assertThat(ap.update(scanResult)).isTrue(); + + assertThat(ap.isCarrierAp()).isEqualTo(true); + assertThat(ap.getCarrierApEapType()).isEqualTo(carrierApEapType); + assertThat(ap.getCarrierName()).isEqualTo(carrierName); + } + private ScoredNetwork buildScoredNetworkWithMockBadgeCurve() { Bundle attr1 = new Bundle(); attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 96f51c16796f..3d0147dbd644 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -34,6 +34,7 @@ import android.net.wifi.WifiManager; import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.provider.Settings; +import android.util.ArrayMap; import android.util.BackupUtils; import android.util.Log; @@ -62,6 +63,9 @@ public class SettingsBackupAgent extends BackupAgentHelper { private static final boolean DEBUG = false; private static final boolean DEBUG_BACKUP = DEBUG || false; + private static final byte[] NULL_VALUE = new byte[0]; + private static final int NULL_SIZE = -1; + private static final String KEY_SYSTEM = "system"; private static final String KEY_SECURE = "secure"; private static final String KEY_GLOBAL = "global"; @@ -608,7 +612,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { // Restore only the white list data. int pos = 0; - Map<String, String> cachedEntries = new HashMap<String, String>(); + final ArrayMap<String, String> cachedEntries = new ArrayMap<>(); ContentValues contentValues = new ContentValues(2); SettingsHelper settingsHelper = mSettingsHelper; ContentResolver cr = getContentResolver(); @@ -616,28 +620,36 @@ public class SettingsBackupAgent extends BackupAgentHelper { final int whiteListSize = whitelist.length; for (int i = 0; i < whiteListSize; i++) { String key = whitelist[i]; - String value = cachedEntries.remove(key); - // If the value not cached, let us look it up. - if (value == null) { + String value = null; + boolean hasValueToRestore = false; + if (cachedEntries.indexOfKey(key) >= 0) { + value = cachedEntries.remove(key); + hasValueToRestore = true; + } else { + // If the value not cached, let us look it up. while (pos < bytes) { int length = readInt(settings, pos); pos += INTEGER_BYTE_COUNT; - String dataKey = length > 0 ? new String(settings, pos, length) : null; + String dataKey = length >= 0 ? new String(settings, pos, length) : null; pos += length; length = readInt(settings, pos); pos += INTEGER_BYTE_COUNT; - String dataValue = length > 0 ? new String(settings, pos, length) : null; - pos += length; + String dataValue = null; + if (length >= 0) { + dataValue = new String(settings, pos, length); + pos += length; + } if (key.equals(dataKey)) { value = dataValue; + hasValueToRestore = true; break; } cachedEntries.put(dataKey, dataValue); } } - if (value == null) { + if (!hasValueToRestore) { continue; } @@ -724,50 +736,56 @@ public class SettingsBackupAgent extends BackupAgentHelper { * @return The byte array of extracted values. */ private byte[] extractRelevantValues(Cursor cursor, String[] settings) { - final int settingsCount = settings.length; - byte[][] values = new byte[settingsCount * 2][]; // keys and values if (!cursor.moveToFirst()) { Log.e(TAG, "Couldn't read from the cursor"); return new byte[0]; } + final int nameColumnIndex = cursor.getColumnIndex(Settings.NameValueTable.NAME); + final int valueColumnIndex = cursor.getColumnIndex(Settings.NameValueTable.VALUE); + // Obtain the relevant data in a temporary array. int totalSize = 0; int backedUpSettingIndex = 0; - Map<String, String> cachedEntries = new HashMap<String, String>(); + final int settingsCount = settings.length; + final byte[][] values = new byte[settingsCount * 2][]; // keys and values + final ArrayMap<String, String> cachedEntries = new ArrayMap<>(); for (int i = 0; i < settingsCount; i++) { - String key = settings[i]; - String value = cachedEntries.remove(key); - - final int nameColumnIndex = cursor.getColumnIndex(Settings.NameValueTable.NAME); - final int valueColumnIndex = cursor.getColumnIndex(Settings.NameValueTable.VALUE); + final String key = settings[i]; // If the value not cached, let us look it up. - if (value == null) { + String value = null; + boolean hasValueToBackup = false; + if (cachedEntries.indexOfKey(key) >= 0) { + value = cachedEntries.remove(key); + hasValueToBackup = true; + } else { while (!cursor.isAfterLast()) { - String cursorKey = cursor.getString(nameColumnIndex); - String cursorValue = cursor.getString(valueColumnIndex); + final String cursorKey = cursor.getString(nameColumnIndex); + final String cursorValue = cursor.getString(valueColumnIndex); cursor.moveToNext(); if (key.equals(cursorKey)) { value = cursorValue; + hasValueToBackup = true; break; } cachedEntries.put(cursorKey, cursorValue); } } + if (!hasValueToBackup) { + continue; + } + // Intercept the keys and see if they need special handling value = mSettingsHelper.onBackupValue(key, value); - if (value == null) { - continue; - } // Write the key and value in the intermediary array. - byte[] keyBytes = key.getBytes(); + final byte[] keyBytes = key.getBytes(); totalSize += INTEGER_BYTE_COUNT + keyBytes.length; values[backedUpSettingIndex * 2] = keyBytes; - byte[] valueBytes = value.getBytes(); + final byte[] valueBytes = (value != null) ? value.getBytes() : NULL_VALUE; totalSize += INTEGER_BYTE_COUNT + valueBytes.length; values[backedUpSettingIndex * 2 + 1] = valueBytes; @@ -783,8 +801,13 @@ public class SettingsBackupAgent extends BackupAgentHelper { int pos = 0; final int keyValuePairCount = backedUpSettingIndex * 2; for (int i = 0; i < keyValuePairCount; i++) { - pos = writeInt(result, pos, values[i].length); - pos = writeBytes(result, pos, values[i]); + final byte[] value = values[i]; + if (value != NULL_VALUE) { + pos = writeInt(result, pos, value.length); + pos = writeBytes(result, pos, value); + } else { + pos = writeInt(result, pos, NULL_SIZE); + } } return result; } diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_left_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_left_animation.xml new file mode 100644 index 000000000000..d6054c4d3422 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_left_animation.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="250" + android:propertyName="scaleX" + android:valueFrom="1.0" + android:valueTo="1.8" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_mask_1_animation.xml new file mode 100644 index 000000000000..282170c1fae4 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_mask_1_animation.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="83" + android:propertyName="pathData" + android:valueFrom="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" + android:valueTo="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" + android:valueType="pathType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="250" + android:propertyName="pathData" + android:valueFrom="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" + android:valueTo="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" + android:valueType="pathType" + android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_2" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_animation.xml new file mode 100644 index 000000000000..b59c66419080 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_animation.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="133" + android:propertyName="pathData" + android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueType="pathType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="116" + android:propertyName="pathData" + android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueType="pathType" + android:interpolator="@android:interpolator/linear" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_position_animation.xml new file mode 100644 index 000000000000..60d23966ed12 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_position_animation.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="250" + android:propertyXName="translateX" + android:propertyYName="translateY" + android:pathData="M 0.0,0.0 c 0.0,4.16667 0.0,20.83333 0.0,25.0" + android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_1" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_animation.xml new file mode 100644 index 000000000000..ef442e9ef13a --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_animation.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="33" + android:propertyName="pathData" + android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueType="pathType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="200" + android:propertyName="pathData" + android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueType="pathType" + android:interpolator="@android:interpolator/linear" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_position_animation.xml new file mode 100644 index 000000000000..97782be4f145 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_position_animation.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="233" + android:propertyXName="translateX" + android:propertyYName="translateY" + android:pathData="M 0.0,0.0 c 0.0,-4.16667 0.0,-20.83333 0.0,-25.0" + android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_0" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_right_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_right_animation.xml new file mode 100644 index 000000000000..d6054c4d3422 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_right_animation.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="250" + android:propertyName="scaleX" + android:valueFrom="1.0" + android:valueTo="1.8" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_stick_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stick_animation.xml new file mode 100644 index 000000000000..573205ffd2c8 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stick_animation.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="250" + android:propertyName="scaleY" + android:valueFrom="0.0" + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_3" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_stickito_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stickito_animation.xml new file mode 100644 index 000000000000..4b038b930c46 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stickito_animation.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="333" + android:propertyName="alpha" + android:valueFrom="1.0" + android:valueTo="0.54" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_4" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_whole_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_whole_animation.xml new file mode 100644 index 000000000000..562985a89ba9 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_whole_animation.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="83" + android:propertyName="scaleX" + android:valueFrom="1.0" + android:valueTo="1.15667" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" /> + <objectAnimator + android:duration="166" + android:propertyName="scaleX" + android:valueFrom="1.15667" + android:valueTo="0.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" /> + </set> + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="83" + android:propertyName="scaleY" + android:valueFrom="1.0" + android:valueTo="1.15667" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" /> + <objectAnimator + android:duration="166" + android:propertyName="scaleY" + android:valueFrom="1.15667" + android:valueTo="0.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml new file mode 100644 index 000000000000..6c7e75118f5c --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 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. +--> +<set xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="350" + android:propertyName="pathData" + android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 " + android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 " + android:valueType="pathType" + android:interpolator="@interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator" /> + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="333" + android:propertyName="strokeAlpha" + android:valueFrom="1" + android:valueTo="1" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="17" + android:propertyName="strokeAlpha" + android:valueFrom="1" + android:valueTo="0" + android:interpolator="@android:interpolator/linear" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml new file mode 100644 index 000000000000..c699fe280f66 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 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. +--> +<set xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="200" + android:propertyName="alpha" + android:valueFrom="0.5" + android:valueTo="0.5" + android:interpolator="@android:interpolator/fast_out_slow_in" /> + <objectAnimator + android:duration="350" + android:propertyName="alpha" + android:valueFrom="0.5" + android:valueTo="1" + android:interpolator="@android:interpolator/fast_out_slow_in" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml new file mode 100644 index 000000000000..5595e5c76297 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 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. +--> +<set xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="350" + android:propertyName="pathData" + android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" + android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" + android:valueType="pathType" + android:interpolator="@interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_left_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_left_animation.xml new file mode 100644 index 000000000000..4614bfc849e1 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_left_animation.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="83" + android:propertyName="scaleX" + android:valueFrom="1.8" + android:valueTo="1.8" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="250" + android:propertyName="scaleX" + android:valueFrom="1.8" + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_mask_1_animation.xml new file mode 100644 index 000000000000..f5cfcf91b777 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_mask_1_animation.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="250" + android:propertyName="pathData" + android:valueFrom="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" + android:valueTo="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" + android:valueType="pathType" + android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_1" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_animation.xml new file mode 100644 index 000000000000..0b74b3a4fdc5 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_animation.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="83" + android:propertyName="pathData" + android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueType="pathType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="133" + android:propertyName="pathData" + android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueType="pathType" + android:interpolator="@android:interpolator/linear" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_position_animation.xml new file mode 100644 index 000000000000..ba10224ab4db --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_position_animation.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="216" + android:propertyXName="translateX" + android:propertyYName="translateY" + android:pathData="M 0.0,25.0 c 0.0,-4.16667 0.0,-20.83333 0.0,-25.0" + android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_2" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_animation.xml new file mode 100644 index 000000000000..395bbf4802dd --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_animation.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="100" + android:propertyName="pathData" + android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueType="pathType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="199" + android:propertyName="pathData" + android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" + android:valueType="pathType" + android:interpolator="@android:interpolator/linear" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_position_animation.xml new file mode 100644 index 000000000000..0115759ab0d8 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_position_animation.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="300" + android:propertyXName="translateX" + android:propertyYName="translateY" + android:pathData="M 0.0,-25.0 c 0.0,4.16667 0.0,20.83333 0.0,25.0" + android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_4" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_right_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_right_animation.xml new file mode 100644 index 000000000000..4614bfc849e1 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_right_animation.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="83" + android:propertyName="scaleX" + android:valueFrom="1.8" + android:valueTo="1.8" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="250" + android:propertyName="scaleX" + android:valueFrom="1.8" + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_stick_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stick_animation.xml new file mode 100644 index 000000000000..6b182be01446 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stick_animation.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="83" + android:propertyName="scaleY" + android:valueFrom="1.0" + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="250" + android:propertyName="scaleY" + android:valueFrom="1.0" + android:valueTo="0.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/fast_out_slow_in" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_stickito_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stickito_animation.xml new file mode 100644 index 000000000000..828f7a289ec6 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stickito_animation.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="333" + android:propertyName="alpha" + android:valueFrom="0.54" + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_3" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_whole_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_whole_animation.xml new file mode 100644 index 000000000000..89ab5808b4ab --- /dev/null +++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_whole_animation.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="66" + android:propertyName="scaleX" + android:valueFrom="0.0" + android:valueTo="0.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="166" + android:propertyName="scaleX" + android:valueFrom="0.0" + android:valueTo="1.15667" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_5" /> + <objectAnimator + android:duration="83" + android:propertyName="scaleX" + android:valueFrom="1.15667" + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_0" /> + </set> + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="66" + android:propertyName="scaleY" + android:valueFrom="0.0" + android:valueTo="0.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="166" + android:propertyName="scaleY" + android:valueFrom="0.0" + android:valueTo="1.15667" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_5" /> + <objectAnimator + android:duration="83" + android:propertyName="scaleY" + android:valueFrom="1.15667" + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_0" /> + </set> +</set> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml index 1feb49c689c3..96d848406955 100644 --- a/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml +++ b/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml @@ -1,63 +1,121 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2015 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:name="root" - android:alpha="1.0" - android:height="42dp" +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:name="ic_signal_workmode_disable" android:width="42dp" - android:viewportHeight="42" - android:viewportWidth="42" > + android:viewportWidth="42" + android:height="42dp" + android:viewportHeight="42" > <group - android:name="ic_signal_briefcase" - android:translateX="21.9995" - android:translateY="25.73401" > + android:name="suitcase" + android:translateX="21" + android:translateY="36.9375" + android:scaleX="0.1" + android:scaleY="0.1" > <group - android:name="ic_signal_briefcase_pivot" - android:translateX="-23.21545" - android:translateY="-18.86649" > + android:name="suitcase_pivot" + android:translateY="-158" > <clip-path - android:name="mask" - android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" /> + android:name="mask_1" + android:pathData="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" /> <group - android:name="cross" > + android:name="whole" + android:translateX="-1.11523" + android:translateY="32.0918" > <path - android:name="cross_1" - android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 " + android:name="rectangle_path_1" android:strokeColor="#FFFFFFFF" - android:strokeAlpha="0" - android:strokeWidth="3.5" - android:fillColor="#00000000" /> + android:strokeWidth="65" + android:pathData="M 0.0,-66.5 l 0.0,0.0 c 36.7269358617,0.0 66.5,29.7730641383 66.5,66.5 l 0.0,0.0 c 0.0,36.7269358617 -29.7730641383,66.5 -66.5,66.5 l 0.0,0.0 c -36.7269358617,0.0 -66.5,-29.7730641383 -66.5,-66.5 l 0.0,0.0 c 0.0,-36.7269358617 29.7730641383,-66.5 66.5,-66.5 Z" /> </group> <group - android:name="briefcase" - android:translateX="23.481" - android:translateY="18.71151" > - <path - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" - android:pathData="M-4.83333,-14.3333 L-7.16667,-11.8333 L-7.16667,-9.5 L-4.83333,-9.5 L-4.83333,-11.8333 L4.83333,-11.8333 L4.83333,-9.5 L7.16667,-9.5 L7.16667,-11.8333 L4.83333,-14.3333 Z" /> + android:name="handle" + android:translateY="-100" > <path - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" - android:pathData="M13.1667,-9.5 L-13.1667,-9.5 C-14.5,-9.5,-15.5,-8.5,-15.5,-7.16666 L-15.5,0.00000286102 C-15.5,1.33334,-14.5,2.33334,-13.1667,2.33334 L-3.66667,2.33334 L-3.66667,0.00000286102 L3.5,0.00000286102 L3.5,2.33334 L13,2.33334 C14.3333,2.33334,15.3333,1.33334,15.3333,0 L15.3333,-7.16666 C15.5,-8.5,14.3333,-9.5,13.1667,-9.5 Z" /> - <path - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" - android:pathData="M-3.5,7.16667 L-3.5,4.83334 L-14.3333,4.83334 L-14.3333,10.8333 C-14.3333,12.1667,-13.3333,13.1667,-12,13.1667 L11.8333,13.1667 C13.1667,13.1667,14.1667,12.1667,14.1667,10.8333 L14.1667,4.83334 L3.5,4.83334 L3.5,7.16667 L-3.5,7.16667 Z" /> + android:name="rectangle_path_2" + android:strokeColor="#FFFFFFFF" + android:strokeWidth="35" + android:pathData="M -34.0,-50.0 l 68.0,0.0 c 8.8365559968,0.0 16.0,7.1634440032 16.0,16.0 l 0.0,68.0 c 0.0,8.8365559968 -7.1634440032,16.0 -16.0,16.0 l -68.0,0.0 c -8.8365559968,0.0 -16.0,-7.1634440032 -16.0,-16.0 l 0.0,-68.0 c 0.0,-8.8365559968 7.1634440032,-16.0 16.0,-16.0 Z" /> + </group> + <group + android:name="case" + android:translateY="32.68518" > + <group + android:name="case_pivot" + android:translateY="-32.68518" > + <group + android:name="bottom" + android:translateY="-97.62964" > + <group + android:name="bottom_pivot" + android:translateY="40" > + <group + android:name="rectangle_path_3_position" > + <path + android:name="rectangle_path_3" + android:fillColor="#FFFFFFFF" + android:pathData="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" /> + </group> + </group> + </group> + <group + android:name="top" + android:translateY="163" > + <group + android:name="top_pivot" + android:translateY="-40" > + <group + android:name="rectangle_path_4_position" > + <path + android:name="rectangle_path_4" + android:fillColor="#FFFFFFFF" + android:pathData="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" /> + </group> + </group> + </group> + <group + android:name="left" + android:translateX="-175.00635" + android:translateY="30" > + <group + android:name="left_pivot" + android:translateX="50.00635" > + <path + android:name="rectangle_path_5" + android:fillColor="#FFFFFFFF" + android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> + </group> + </group> + <group + android:name="right" + android:translateX="174.97778" + android:translateY="30" > + <group + android:name="right_pivot" + android:translateX="-49.97778" > + <path + android:name="rectangle_path_6" + android:fillColor="#FFFFFFFF" + android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> + </group> + </group> + </group> + </group> + <group + android:name="stick" + android:translateX="-166.59082" + android:translateY="-156.51367" + android:scaleY="0" + android:rotation="-45" > + <group + android:name="stick_pivot" + android:translateX="0.18161" + android:translateY="243.8158" > + <path + android:name="stickito" + android:fillColor="#FFFFFFFF" + android:pathData="M -16.5,-243.999885 l 33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 l -33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> + </group> </group> </group> </group> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml new file mode 100644 index 000000000000..4a2bd548f61d --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<animated-vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:drawable="@drawable/ic_signal_workmode_disable" > + <target + android:name="mask_1" + android:animation="@anim/ic_signal_workmode_disable_mask_1_animation" /> + <target + android:name="whole" + android:animation="@anim/ic_signal_workmode_disable_whole_animation" /> + <target + android:name="rectangle_path_3_position" + android:animation="@anim/ic_signal_workmode_disable_rectangle_path_3_position_animation" /> + <target + android:name="rectangle_path_3" + android:animation="@anim/ic_signal_workmode_disable_rectangle_path_3_animation" /> + <target + android:name="rectangle_path_4_position" + android:animation="@anim/ic_signal_workmode_disable_rectangle_path_4_position_animation" /> + <target + android:name="rectangle_path_4" + android:animation="@anim/ic_signal_workmode_disable_rectangle_path_4_animation" /> + <target + android:name="left" + android:animation="@anim/ic_signal_workmode_disable_left_animation" /> + <target + android:name="right" + android:animation="@anim/ic_signal_workmode_disable_right_animation" /> + <target + android:name="stick" + android:animation="@anim/ic_signal_workmode_disable_stick_animation" /> + <target + android:name="ic_signal_workmode_disable" + android:animation="@anim/ic_signal_workmode_disable_stickito_animation" /> +</animated-vector> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml index f96259480340..2d4f0b5d162f 100644 --- a/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml +++ b/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml @@ -1,62 +1,127 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2015 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:name="root" - android:height="42dp" +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:name="ic_signal_workmode_enable" android:width="42dp" - android:viewportHeight="42" - android:viewportWidth="42" > + android:viewportWidth="42" + android:height="42dp" + android:viewportHeight="42" > <group - android:name="ic_signal_briefcase" - android:translateX="21.9995" - android:translateY="25.73401" > + android:name="suitcase" + android:translateX="21" + android:translateY="36.9375" + android:scaleX="0.1" + android:scaleY="0.1" > <group - android:name="ic_signal_briefcase_pivot" - android:translateX="-23.21545" - android:translateY="-18.86649" > + android:name="suitcase_pivot" + android:translateY="-158" > <clip-path - android:name="mask" - android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" /> + android:name="mask_1" + android:pathData="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" /> <group - android:name="cross" > + android:name="whole" + android:translateX="-1.11523" + android:translateY="32.0918" + android:scaleX="0" + android:scaleY="0" > <path - android:name="cross_1" - android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 " + android:name="rectangle_path_1" android:strokeColor="#FFFFFFFF" - android:strokeAlpha="1" - android:strokeWidth="3.5" - android:fillColor="#00000000" /> + android:strokeWidth="65" + android:pathData="M 0.0,-66.5 l 0.0,0.0 c 36.7269358617,0.0 66.5,29.7730641383 66.5,66.5 l 0.0,0.0 c 0.0,36.7269358617 -29.7730641383,66.5 -66.5,66.5 l 0.0,0.0 c -36.7269358617,0.0 -66.5,-29.7730641383 -66.5,-66.5 l 0.0,0.0 c 0.0,-36.7269358617 29.7730641383,-66.5 66.5,-66.5 Z" /> </group> <group - android:name="briefcase" - android:translateX="23.481" - android:translateY="18.71151" > - <path - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" - android:pathData="M-4.83333,-14.3333 L-7.16667,-11.8333 L-7.16667,-9.5 L-4.83333,-9.5 L-4.83333,-11.8333 L4.83333,-11.8333 L4.83333,-9.5 L7.16667,-9.5 L7.16667,-11.8333 L4.83333,-14.3333 Z" /> + android:name="handle" + android:translateY="-100" > <path - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" - android:pathData="M13.1667,-9.5 L-13.1667,-9.5 C-14.5,-9.5,-15.5,-8.5,-15.5,-7.16666 L-15.5,0.00000286102 C-15.5,1.33334,-14.5,2.33334,-13.1667,2.33334 L-3.66667,2.33334 L-3.66667,0.00000286102 L3.5,0.00000286102 L3.5,2.33334 L13,2.33334 C14.3333,2.33334,15.3333,1.33334,15.3333,0 L15.3333,-7.16666 C15.5,-8.5,14.3333,-9.5,13.1667,-9.5 Z" /> - <path - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" - android:pathData="M-3.5,7.16667 L-3.5,4.83334 L-14.3333,4.83334 L-14.3333,10.8333 C-14.3333,12.1667,-13.3333,13.1667,-12,13.1667 L11.8333,13.1667 C13.1667,13.1667,14.1667,12.1667,14.1667,10.8333 L14.1667,4.83334 L3.5,4.83334 L3.5,7.16667 L-3.5,7.16667 Z" /> + android:name="rectangle_path_2" + android:strokeColor="#FFFFFFFF" + android:strokeWidth="35" + android:pathData="M -34.0,-50.0 l 68.0,0.0 c 8.8365559968,0.0 16.0,7.1634440032 16.0,16.0 l 0.0,68.0 c 0.0,8.8365559968 -7.1634440032,16.0 -16.0,16.0 l -68.0,0.0 c -8.8365559968,0.0 -16.0,-7.1634440032 -16.0,-16.0 l 0.0,-68.0 c 0.0,-8.8365559968 7.1634440032,-16.0 16.0,-16.0 Z" /> + </group> + <group + android:name="case" + android:translateY="32.68518" > + <group + android:name="case_pivot" + android:translateY="-32.68518" > + <group + android:name="bottom" + android:translateY="-97.62964" > + <group + android:name="bottom_pivot" + android:translateY="40" > + <group + android:name="rectangle_path_3_position" + android:translateY="25" > + <path + android:name="rectangle_path_3" + android:fillColor="#FFFFFFFF" + android:pathData="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" /> + </group> + </group> + </group> + <group + android:name="top" + android:translateY="163" > + <group + android:name="top_pivot" + android:translateY="-40" > + <group + android:name="rectangle_path_4_position" + android:translateY="-25" > + <path + android:name="rectangle_path_4" + android:fillColor="#FFFFFFFF" + android:pathData="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" /> + </group> + </group> + </group> + <group + android:name="left" + android:translateX="-175.00635" + android:translateY="30" + android:scaleX="1.8" > + <group + android:name="left_pivot" + android:translateX="50.00635" > + <path + android:name="rectangle_path_5" + android:fillColor="#FFFFFFFF" + android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> + </group> + </group> + <group + android:name="right" + android:translateX="174.97778" + android:translateY="30" + android:scaleX="1.8" > + <group + android:name="right_pivot" + android:translateX="-49.97778" > + <path + android:name="rectangle_path_6" + android:fillColor="#FFFFFFFF" + android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> + </group> + </group> + </group> + </group> + <group + android:name="stick" + android:translateX="-166.59082" + android:translateY="-156.51367" + android:rotation="-45" > + <group + android:name="stick_pivot" + android:translateX="0.18161" + android:translateY="243.8158" > + <path + android:name="stickito" + android:fillColor="#FFFFFFFF" + android:fillAlpha="1" + android:pathData="M -16.5,-243.999885 l 33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 l -33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> + </group> </group> </group> </group> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml new file mode 100644 index 000000000000..c98f800d70c1 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<animated-vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:drawable="@drawable/ic_signal_workmode_enable" > + <target + android:name="mask_1" + android:animation="@anim/ic_signal_workmode_enable_mask_1_animation" /> + <target + android:name="whole" + android:animation="@anim/ic_signal_workmode_enable_whole_animation" /> + <target + android:name="rectangle_path_3_position" + android:animation="@anim/ic_signal_workmode_enable_rectangle_path_3_position_animation" /> + <target + android:name="rectangle_path_3" + android:animation="@anim/ic_signal_workmode_enable_rectangle_path_3_animation" /> + <target + android:name="rectangle_path_4_position" + android:animation="@anim/ic_signal_workmode_enable_rectangle_path_4_position_animation" /> + <target + android:name="rectangle_path_4" + android:animation="@anim/ic_signal_workmode_enable_rectangle_path_4_animation" /> + <target + android:name="left" + android:animation="@anim/ic_signal_workmode_enable_left_animation" /> + <target + android:name="right" + android:animation="@anim/ic_signal_workmode_enable_right_animation" /> + <target + android:name="stick" + android:animation="@anim/ic_signal_workmode_enable_stick_animation" /> + <target + android:name="ic_signal_workmode_enable" + android:animation="@anim/ic_signal_workmode_enable_stickito_animation" /> +</animated-vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_disable_animation.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_disable_animation.xml deleted file mode 100644 index 1e41a31ae130..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_disable_animation.xml +++ /dev/null @@ -1,46 +0,0 @@ -<!-- -Copyright (C) 2015 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="27.0dp" - android:height="22.0dp" - android:viewportWidth="27.0" - android:viewportHeight="22.0"> - <clip-path - android:name="mask" - android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" /> - <group - android:name="cross" > - <path - android:name="cross_1" - android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 " - android:strokeColor="#FFFFFFFF" - android:strokeAlpha="1" - android:strokeWidth="3.5" - android:fillColor="#00000000" /> - </group> - <group - android:name="work_badge" - android:translateX="3.0" - android:scaleX="1.4" - android:scaleY="1.4"> - <path - android:fillColor="@android:color/white" - android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/> - <path - android:fillColor="@android:color/white" - android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2 c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_enable_animation.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_enable_animation.xml deleted file mode 100644 index d67c89ac3865..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_enable_animation.xml +++ /dev/null @@ -1,34 +0,0 @@ -<!-- -Copyright (C) 2015 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="27.0dp" - android:height="22.0dp" - android:alpha="1.0" - android:viewportWidth="27.0" - android:viewportHeight="22.0"> - <group - android:name="work_badge" - android:translateX="3.0" - android:scaleX="1.4" - android:scaleY="1.4"> - <path - android:fillColor="@android:color/white" - android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/> - <path - android:fillColor="@android:color/white" - android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2 c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml index 370f89c2e0e4..e38b4825c9fd 100644 --- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml +++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml @@ -1,42 +1,12 @@ -<!-- -Copyright (C) 2015 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. ---> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="23dp" - android:height="18dp" - android:viewportWidth="23" - android:viewportHeight="18"> -<!-- - The asset contains a briefcase symbol of 15.26dp x 13.6dp in the center. ---> + android:width="23dp" + android:height="18dp" + android:viewportWidth="23.0" + android:viewportHeight="18.0"> + <!-- + The asset contains a briefcase symbol of 14.551dp x 13.824dp in the center. + --> <path - android:fillColor="@android:color/white" - android:pathData="M15.0815,4.5903 L15.0815,3.43636 L13.9276,2.2 L9.14696,2.2 L7.99302,3.43636 -L7.99302,4.5903 L9.14696,4.5903 L9.14696,3.43636 L13.9276,3.43636 -L13.9276,4.5903 Z" /> - <path - android:fillColor="@android:color/white" - android:pathData="M18.0488,4.5903 L5.02575,4.5903 C4.36635,4.5903,3.87181,5.08485,3.87181,5.74424 -L3.87181,9.28848 C3.87181,9.94788,4.36635,10.4424,5.02575,10.4424 -L9.72393,10.4424 L9.72393,9.28848 L13.2682,9.28848 L13.2682,10.4424 -L17.9664,10.4424 C18.6257,10.4424,19.1203,9.94788,19.1203,9.28848 -L19.1203,5.74424 C19.2027,5.08485,18.6257,4.5903,18.0488,4.5903 Z" /> - <path - android:fillColor="@android:color/white" - android:pathData="M9.80635,12.8327 L9.80635,11.6788 L4.44878,11.6788 L4.44878,14.6461 -C4.44878,15.3055,4.94332,15.8,5.60272,15.8 L17.3894,15.8 -C18.0488,15.8,18.5433,15.3055,18.5433,14.6461 L18.5433,11.6788 L13.2682,11.6788 -L13.2682,12.8327 L9.80635,12.8327 Z" /> + android:pathData="M17.32,5.06h-2.91V3.6c0,-0.81 -0.65,-1.46 -1.46,-1.46h-2.91c-0.81,0 -1.46,0.65 -1.46,1.46v1.46H5.68c-0.81,0 -1.45,0.65 -1.45,1.46l-0.01,8c0,0.81 0.65,1.46 1.46,1.46h11.64c0.81,0 1.46,-0.65 1.46,-1.46v-8C18.78,5.7 18.13,5.06 17.32,5.06zM11.5,11.6c-0.8,0 -1.46,-0.65 -1.46,-1.46c0,-0.8 0.65,-1.46 1.46,-1.46s1.46,0.65 1.46,1.46C12.96,10.95 12.3,11.6 11.5,11.6zM12.96,5.06h-2.91V3.6h2.91V5.06z" + android:fillColor="#FF000000"/> </vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml index 35602b61b89f..1dedd5d4daef 100644 --- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml +++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml @@ -1,5 +1,5 @@ <!-- -Copyright (C) 2015 The Android Open Source Project +Copyright (C) 2017 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. @@ -14,40 +14,11 @@ Copyright (C) 2015 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="23dp" - android:height="18dp" - android:viewportWidth="23" - android:viewportHeight="18"> -<!-- - The asset contains a briefcase symbol of 15.26dp x 13.6dp in the center. ---> - <path - android:pathData="M0,-6 L24,-6 L24,18 L0,18 L0,-6 Z" /> - <path - android:fillColor="@android:color/white" - android:pathData="M13.9892,11.6542 L13.4088,11.6542 L13.4088,12.8152 L9.843,12.8152 L9.843,11.6542 -L4.4529,11.6542 L4.4529,14.6395 C4.4529,15.3029,4.95045,15.8005,5.61384,15.8005 -L17.4721,15.8005 C17.6379,15.8005,17.8038,15.8005,17.9696,15.7175 -L13.9892,11.6542 Z" /> - <path - android:fillColor="@android:color/white" - android:pathData="M18.7159,13.8932 L18.7159,11.6542 L16.477,11.6542 -C17.3062,12.4835,18.1355,13.3127,18.7159,13.8932 Z" /> - <path - android:fillColor="@android:color/white" - android:pathData="M6.85771,4.52272 L5.03337,4.52272 -C4.36998,4.52272,3.87243,5.02027,3.87243,5.68366 L3.87243,9.24942 -C3.87243,9.91282,4.36998,10.4104,5.03337,10.4104 L9.76008,10.4104 -L9.76008,9.24942 L11.5844,9.24942 L6.85771,4.52272 Z" /> - <path - android:fillColor="@android:color/white" - android:pathData="M9.1796,4.35687 L9.1796,3.36177 L13.9063,3.36177 L13.9063,4.52272 -L9.34545,4.52272 C11.1698,6.34706,13.3258,8.5031,15.2331,10.4104 -L18.0525,10.4104 C18.7159,10.4104,19.2135,9.91282,19.2135,9.24942 -L19.2135,5.68366 C19.2135,5.02027,18.7159,4.52272,18.0525,4.52272 -L15.0673,4.52272 L15.0673,3.36177 L13.9063,2.20083 L9.1796,2.20083 -L8.10158,3.27885 C8.43328,3.61055,8.84791,4.02517,9.1796,4.35687 Z" /> + android:width="23dp" + android:height="18dp" + android:viewportWidth="23.0" + android:viewportHeight="18.0"> <path android:fillColor="@android:color/white" - android:pathData="M3.281,3.42136 L4.51236,2.19 L18.585,16.2626 L17.3536,17.494 L3.281,3.42136 Z" /> -</vector>
\ No newline at end of file + android:pathData="M19.4,16.6l-1.1,-1.1L8,5L5.1,2.2L4.2,3.1l2,2H5.7c-0.8,0 -1.4,0.6 -1.4,1.4v8c0,0.8 0.6,1.4 1.4,1.4h11.4l1.5,1.5L19.4,16.6zM18.7,6.5c0,-0.8 -0.6,-1.4 -1.4,-1.4h-2.9V3.6c0,-0.8 -0.6,-1.4 -1.4,-1.4h-3C9.2,2.1 8.6,2.8 8.6,3.6v0.2L18.7,14C18.7,14 18.7,6.5 18.7,6.5zM12.9,5.1H10V3.6h2.9V5.1z"/> +</vector> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_0.xml new file mode 100644 index 000000000000..5009c6b7ac10 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_0.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 l 0.144628099174,0.0 l 0.855371900826,1.0 L 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_1.xml new file mode 100644 index 000000000000..678b90b24914 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_1.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 l 0.534759358289,0.0 l 0.465240641711,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_2.xml new file mode 100644 index 000000000000..6c6df6078aaa --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_2.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.313385868073,0.330828523695 0.125984191895,0.661170632677 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_3.xml new file mode 100644 index 000000000000..b1eec483cdf4 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_3.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.4,0.0 0.2,0.2 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_4.xml new file mode 100644 index 000000000000..17ff65aaa155 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_4.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.4,0.4 0.2,0.2 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_5.xml new file mode 100644 index 000000000000..aee48dc2637a --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_5.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.66666667,1.0 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml new file mode 100644 index 000000000000..66cfaffd9936 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 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. +--> +<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_0.xml new file mode 100644 index 000000000000..4a5fde9fd49b --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_0.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.83333333333,1.0 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_1.xml new file mode 100644 index 000000000000..0f35e5d01470 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_1.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.714960628748,0.0 0.678740215302,1.0 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_2.xml new file mode 100644 index 000000000000..626f9ef97881 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_2.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 l 0.392038600724,0.0 l 0.607961399276,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_3.xml new file mode 100644 index 000000000000..17ff65aaa155 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_3.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.4,0.4 0.2,0.2 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_4.xml new file mode 100644 index 000000000000..96bdb484c2f9 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_4.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 l 0.337078651685,0.0 l 0.662921348315,1.0 L 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_5.xml new file mode 100644 index 000000000000..a91610d617f2 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_5.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.66666667,1.0 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml new file mode 100644 index 000000000000..a0118d707951 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 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. +--> +<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" /> diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml new file mode 100644 index 000000000000..1820bab9e469 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 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. +--> +<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" /> diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index e5c729faae04..9c1cb4ef8c81 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -16,6 +16,7 @@ package com.android.systemui; import android.content.Context; import android.content.res.Configuration; +import android.hardware.SensorManager; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -84,6 +85,7 @@ import com.android.systemui.statusbar.policy.ZenModeControllerImpl; import com.android.systemui.tuner.TunablePadding.TunablePaddingService; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerServiceImpl; +import com.android.systemui.util.AsyncSensorManager; import com.android.systemui.util.leak.GarbageMonitor; import com.android.systemui.util.leak.LeakDetector; import com.android.systemui.util.leak.LeakReporter; @@ -156,6 +158,9 @@ public class Dependency extends SystemUI { mProviders.put(ActivityStarterDelegate.class, () -> getDependency(ActivityStarter.class)); + mProviders.put(AsyncSensorManager.class, () -> + new AsyncSensorManager(mContext.getSystemService(SensorManager.class))); + mProviders.put(BluetoothController.class, () -> new BluetoothControllerImpl(mContext, getDependency(BG_LOOPER))); diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java index 40ea4ece803c..37e2402d7f4a 100644 --- a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java +++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java @@ -119,7 +119,7 @@ public class RoundedCorners extends SystemUI implements Tunable { | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, PixelFormat.TRANSLUCENT); lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS - | WindowManager.LayoutParams.PRIVATE_FLAG_NO_MAGNIFICATION_REGION_EFFECT; + | WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; lp.setTitle("RoundedOverlay"); lp.gravity = Gravity.TOP; return lp; diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java index e92ed2f75d49..e4b405f580d4 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java @@ -35,6 +35,7 @@ import com.android.systemui.Dependency; import com.android.systemui.UiOffloadThread; import com.android.systemui.analytics.DataCollector; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.util.AsyncSensorManager; import java.io.PrintWriter; @@ -87,7 +88,7 @@ public class FalsingManager implements SensorEventListener { private FalsingManager(Context context) { mContext = context; - mSensorManager = mContext.getSystemService(SensorManager.class); + mSensorManager = Dependency.get(AsyncSensorManager.class); mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mDataCollector = DataCollector.getInstance(mContext); mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext); diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java index 9ba7be86aa0a..34c05a5a4a71 100644 --- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java +++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java @@ -21,6 +21,8 @@ import android.app.WallpaperManager; import android.content.Context; import android.os.Handler; import android.os.RemoteException; +import android.os.Trace; +import android.os.UserHandle; import android.util.Log; import android.view.Display; import android.view.IWallpaperVisibilityListener; @@ -31,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.types.ExtractionType; import com.android.internal.colorextraction.types.Tonal; +import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dumpable; import java.io.FileDescriptor; @@ -75,6 +78,14 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { Log.w(TAG, "Can't listen to wallpaper visibility changes", e); } } + + WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class); + if (wallpaperManager != null) { + // Listen to all users instead of only the current one. + wallpaperManager.removeOnColorsChangedListener(this); + wallpaperManager.addOnColorsChangedListener(this, null /* handler */, + UserHandle.USER_ALL); + } } private void updateDefaultGradients(WallpaperColors colors) { @@ -82,7 +93,12 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { } @Override - public void onColorsChanged(WallpaperColors colors, int which) { + public void onColorsChanged(WallpaperColors colors, int which, int userId) { + if (userId != KeyguardUpdateMonitor.getCurrentUser()) { + // Colors do not belong to current user, ignoring. + return; + } + super.onColorsChanged(colors, which); if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index 91ca571e9f7a..cbdabf5de876 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -24,10 +24,12 @@ import android.hardware.SensorManager; import android.os.Handler; import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.classifier.FalsingManager; import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.util.AsyncSensorManager; import com.android.systemui.util.wakelock.DelayedWakeLock; import com.android.systemui.util.wakelock.WakeLock; @@ -39,7 +41,7 @@ public class DozeFactory { /** Creates a DozeMachine with its parts for {@code dozeService}. */ public DozeMachine assembleMachine(DozeService dozeService) { Context context = dozeService; - SensorManager sensorManager = context.getSystemService(SensorManager.class); + SensorManager sensorManager = Dependency.get(AsyncSensorManager.class); AlarmManager alarmManager = context.getSystemService(AlarmManager.class); DozeHost host = getHost(dozeService); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index bf1c06035ec2..566353c74b57 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -87,25 +87,29 @@ public class DozeSensors { mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION), null /* setting */, dozeParameters.getPulseOnSigMotion(), - DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */), + DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */, + false /* touchscreen */), mPickupSensor = new TriggerSensor( mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE), Settings.Secure.DOZE_PULSE_ON_PICK_UP, config.pulseOnPickupAvailable(), - DozeLog.PULSE_REASON_SENSOR_PICKUP, false /* touchCoords */), + DozeLog.PULSE_REASON_SENSOR_PICKUP, false /* touchCoords */, + false /* touchscreen */), new TriggerSensor( findSensorWithType(config.doubleTapSensorType()), Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, true /* configured */, DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP, - dozeParameters.doubleTapReportsTouchCoordinates()), + dozeParameters.doubleTapReportsTouchCoordinates(), + true /* touchscreen */), new TriggerSensor( findSensorWithType(config.longPressSensorType()), Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, false /* settingDef */, true /* configured */, DozeLog.PULSE_REASON_SENSOR_LONG_PRESS, - true /* reports touch coordinates */), + true /* reports touch coordinates */, + true /* touchscreen */), }; mProxSensor = new ProxSensor(); @@ -141,6 +145,15 @@ public class DozeSensors { } } + /** Set the listening state of only the sensors that require the touchscreen. */ + public void setTouchscreenSensorsListening(boolean listening) { + for (TriggerSensor sensor : mSensors) { + if (sensor.mRequiresTouchscreen) { + sensor.setListening(listening); + } + } + } + public void reregisterAllSensors() { for (TriggerSensor s : mSensors) { s.setListening(false); @@ -278,25 +291,28 @@ public class DozeSensors { final String mSetting; final boolean mReportsTouchCoordinates; final boolean mSettingDefault; + final boolean mRequiresTouchscreen; private boolean mRequested; private boolean mRegistered; private boolean mDisabled; public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason, - boolean reportsTouchCoordinates) { + boolean reportsTouchCoordinates, boolean requiresTouchscreen) { this(sensor, setting, true /* settingDef */, configured, pulseReason, - reportsTouchCoordinates); + reportsTouchCoordinates, requiresTouchscreen); } public TriggerSensor(Sensor sensor, String setting, boolean settingDef, - boolean configured, int pulseReason, boolean reportsTouchCoordinates) { + boolean configured, int pulseReason, boolean reportsTouchCoordinates, + boolean requiresTouchscreen) { mSensor = sensor; mSetting = setting; mSettingDefault = settingDef; mConfigured = configured; mPulseReason = pulseReason; mReportsTouchCoordinates = reportsTouchCoordinates; + mRequiresTouchscreen = requiresTouchscreen; } public void setListening(boolean listen) { diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 15981e573ca1..45831601a0f2 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -198,6 +198,7 @@ public class DozeTriggers implements DozeMachine.Part { mDozeSensors.setListening(false); break; case DOZE_PULSING: + mDozeSensors.setTouchscreenSensorsListening(false); mDozeSensors.setProxListening(true); break; case FINISH: diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 884745213350..dc626fb4df65 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -95,17 +95,22 @@ public class DozeUi implements DozeMachine.Part { unscheduleTimeTick(); break; } - mHost.setAnimateWakeup(shouldAnimateWakeup(newState)); + updateAnimateWakeup(newState); } - private boolean shouldAnimateWakeup(DozeMachine.State state) { + private void updateAnimateWakeup(DozeMachine.State state) { switch (state) { case DOZE_REQUEST_PULSE: case DOZE_PULSING: case DOZE_PULSE_DONE: - return true; + mHost.setAnimateWakeup(true); + break; + case FINISH: + // Keep current state. + break; default: - return false; + mHost.setAnimateWakeup(false); + break; } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java index 6733421a8d0e..abc5667251ea 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java @@ -65,7 +65,7 @@ public class InputConsumerController { } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { boolean handled = true; try { // To be implemented for input handling over Pip windows diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 41db927a67bd..5eefe9ae0736 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -70,6 +70,7 @@ public class NotificationShelf extends ActivatableNotificationView implements private boolean mHasItemsInStableShelf; private NotificationIconContainer mCollapsedIcons; private int mScrollFastThreshold; + private int mIconSize; private int mStatusBarState; private float mMaxShelfEnd; private int mRelativeOffset; @@ -135,6 +136,7 @@ public class NotificationShelf extends ActivatableNotificationView implements mShelfIcons.setPadding(padding, 0, padding, 0); mScrollFastThreshold = res.getDimensionPixelOffset(R.dimen.scroll_fast_threshold); mShowNotificationShelf = res.getBoolean(R.bool.config_showNotificationShelf); + mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size); if (!mShowNotificationShelf) { setVisibility(GONE); @@ -501,12 +503,12 @@ public class NotificationShelf extends ActivatableNotificationView implements } notificationIconPosition += iconTopPadding; float shelfIconPosition = getTranslationY() + icon.getTop(); - shelfIconPosition += ((1.0f - icon.getIconScale()) * icon.getHeight()) / 2.0f; + shelfIconPosition += (icon.getHeight() - icon.getIconScale() * mIconSize) / 2.0f; float iconYTranslation = NotificationUtils.interpolate( notificationIconPosition - shelfIconPosition, 0, transitionAmount); - float shelfIconSize = icon.getHeight() * icon.getIconScale(); + float shelfIconSize = mIconSize * icon.getIconScale(); float alpha = 1.0f; boolean noIcon = !row.isShowingIcon(); if (noIcon) { @@ -518,7 +520,7 @@ public class NotificationShelf extends ActivatableNotificationView implements float newSize = NotificationUtils.interpolate(notificationIconSize, shelfIconSize, transitionAmount); if (iconState != null) { - iconState.scaleX = newSize / icon.getHeight() / icon.getIconScale(); + iconState.scaleX = newSize / shelfIconSize; iconState.scaleY = iconState.scaleX; iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon); boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index cc4c31326e68..2cff79df47d7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -572,14 +572,14 @@ public class StatusBarIconView extends AnimatedImageView { /** * Updates {@param array} such that it represents a matrix that changes RGB to {@param color} - * and multiplies A with 1+{@param alphaBoost}. + * and multiplies the alpha channel with the color's alpha+{@param alphaBoost}. */ private static void updateTintMatrix(float[] array, int color, float alphaBoost) { Arrays.fill(array, 0); array[4] = Color.red(color); array[9] = Color.green(color); array[14] = Color.blue(color); - array[18] = 1 + alphaBoost; + array[18] = Color.alpha(color) / 255f + alphaBoost; } public void setIconColor(int iconColor, boolean animate) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java index 02202cf26c38..fdfd8e88b446 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java @@ -29,6 +29,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.LatencyTracker; import com.android.systemui.Dependency; import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; /** @@ -101,6 +102,7 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { private final Context mContext; private int mPendingAuthenticatedUserId = -1; private boolean mPendingShowBouncer; + private boolean mHasScreenTurnedOnSinceAuthenticating; public FingerprintUnlockController(Context context, DozeScrimController dozeScrimController, @@ -113,6 +115,7 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context); mUpdateMonitor.registerCallback(this); Dependency.get(WakefulnessLifecycle.class).addObserver(mWakefulnessObserver); + Dependency.get(ScreenLifecycle.class).addObserver(mScreenObserver); mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class); mDozeScrimController = dozeScrimController; mKeyguardViewMediator = keyguardViewMediator; @@ -186,6 +189,7 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { } boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive(); mMode = calculateMode(); + mHasScreenTurnedOnSinceAuthenticating = false; if (mMode == MODE_WAKE_AND_UNLOCK_PULSING && pulsingOrAod()) { // If we are waking the device up while we are pulsing the clock and the // notifications would light up first, creating an unpleasant animation. @@ -228,6 +232,7 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { true /* allowEnterAnimation */); } else { Trace.beginSection("MODE_WAKE_AND_UNLOCK"); + mDozeScrimController.abortDoze(); } mStatusBarWindowManager.setStatusBarFocusable(false); @@ -354,4 +359,16 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { } } }; + + private final ScreenLifecycle.Observer mScreenObserver = + new ScreenLifecycle.Observer() { + @Override + public void onScreenTurnedOn() { + mHasScreenTurnedOnSinceAuthenticating = true; + } + }; + + public boolean hasScreenTurnedOnSinceAuthenticating() { + return mHasScreenTurnedOnSinceAuthenticating; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index 49bac99e9f92..fd95cc4adc1d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -234,8 +234,11 @@ public class KeyguardBouncer { } protected void ensureView() { - mHandler.removeCallbacks(mRemoveViewRunnable); - if (mRoot == null) { + // Removal of the view might be deferred to reduce unlock latency, + // in this case we need to force the removal, otherwise we'll + // end up in an unpredictable state. + boolean forceRemoval = mHandler.hasCallbacks(mRemoveViewRunnable); + if (mRoot == null || forceRemoval) { inflateView(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java index c4879011b9f8..87f5ca7adf73 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java @@ -158,7 +158,7 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen } @Override - public void onWallpaperColorsChanged(WallpaperColors colors, int which) { + public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) { } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index ab021b49c6a8..e95b1767ade6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -4224,6 +4224,7 @@ public class StatusBar extends SystemUI implements DemoMode, public void showKeyguard() { mKeyguardRequested = true; updateIsKeyguard(); + mAssistManager.onLockscreenShown(); } public boolean hideKeyguard() { @@ -4279,7 +4280,6 @@ public class StatusBar extends SystemUI implements DemoMode, mDraggedDownRow = null; } mPendingRemoteInputView = null; - mAssistManager.onLockscreenShown(); } private void updatePanelExpansionForKeyguard() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 252df1792845..acf42785f826 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -71,6 +71,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb protected final Context mContext; private final StatusBarWindowManager mStatusBarWindowManager; + private final boolean mDisplayBlanksAfterDoze; protected LockPatternUtils mLockPatternUtils; protected ViewMediatorCallback mViewMediatorCallback; @@ -121,6 +122,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mLockPatternUtils = lockPatternUtils; mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class); KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitorCallback); + mDisplayBlanksAfterDoze = context.getResources().getBoolean( + com.android.internal.R.bool.config_displayBlanksAfterDoze); } public void registerStatusBar(StatusBar statusBar, @@ -373,7 +376,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb if (!staying) { mStatusBarWindowManager.setKeyguardFadingAway(true); if (mFingerprintUnlockController.getMode() == MODE_WAKE_AND_UNLOCK) { - if (!mScreenTurnedOn) { + boolean turnedOnSinceAuth = + mFingerprintUnlockController.hasScreenTurnedOnSinceAuthenticating(); + if (!mScreenTurnedOn || mDisplayBlanksAfterDoze && !turnedOnSinceAuth) { + // Not ready to animate yet; either because the screen is not on yet, + // or it is on but will turn off before waking out of doze. mDeferScrimFadeOut = true; } else { @@ -404,6 +411,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public void onOverlayChanged() { mBouncer.hide(true /* destroyView */); + mBouncer.prepare(); } private void animateScrimControllerKeyguardFadingOut(long delay, long duration, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index f4197a3496ea..c060b0882060 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -249,14 +249,28 @@ public class StackScrollAlgorithm { state.paddingMap.clear(); int notGoneIndex = 0; ExpandableView lastView = null; + int firstHiddenIndex = ambientState.isDark() + ? (ambientState.hasPulsingNotifications() ? 1 : 0) + : childCount; + + // The goal here is to fill the padding map, by iterating over how much padding each child + // needs. The map is thereby reused, by first filling it with the padding amount and when + // iterating over it again, it's filled with the actual resolved value. + for (int i = 0; i < childCount; i++) { ExpandableView v = (ExpandableView) hostView.getChildAt(i); if (v.getVisibility() != View.GONE) { if (v == ambientState.getShelf()) { continue; } + if (i >= firstHiddenIndex) { + // we need normal padding now, to be in sync with what the stack calculates + lastView = null; + ExpandableViewState viewState = resultState.getViewStateForView(v); + viewState.hidden = true; + } notGoneIndex = updateNotGoneIndex(resultState, state, notGoneIndex, v); - float increasedPadding = v.getIncreasedPaddingAmount();; + float increasedPadding = v.getIncreasedPaddingAmount(); if (increasedPadding != 0.0f) { state.paddingMap.put(v, increasedPadding); if (lastView != null) { @@ -279,6 +293,8 @@ public class StackScrollAlgorithm { state.paddingMap.put(lastView, newValue); } } else if (lastView != null) { + + // Let's now resolve the value to an actual padding float newValue = getPaddingForValue(state.paddingMap.get(lastView)); state.paddingMap.put(lastView, newValue); } diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java new file mode 100644 index 000000000000..a1cabff4c7aa --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2017 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.systemui.util; + +import android.hardware.HardwareBuffer; +import android.hardware.Sensor; +import android.hardware.SensorAdditionalInfo; +import android.hardware.SensorDirectChannel; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.hardware.TriggerEventListener; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.MemoryFile; +import android.util.Log; + +import com.android.internal.util.Preconditions; + +import java.util.List; + +/** + * Wrapper around sensor manager that hides potential sources of latency. + * + * Offloads fetching (non-dynamic) sensors and (un)registering listeners onto a background thread + * without blocking. Note that this means registering listeners now always appears successful even + * if it is not. + */ +public class AsyncSensorManager extends SensorManager { + + private static final String TAG = "AsyncSensorManager"; + + private final SensorManager mInner; + private final List<Sensor> mSensorCache; + private final HandlerThread mHandlerThread = new HandlerThread("async_sensor"); + private final Handler mHandler; + + public AsyncSensorManager(SensorManager inner) { + mInner = inner; + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper()); + mSensorCache = mInner.getSensorList(Sensor.TYPE_ALL); + } + + @Override + protected List<Sensor> getFullSensorList() { + return mSensorCache; + } + + @Override + protected List<Sensor> getFullDynamicSensorList() { + return mInner.getDynamicSensorList(Sensor.TYPE_ALL); + } + + @Override + protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, + Handler handler, int maxReportLatencyUs, int reservedFlags) { + mHandler.post(() -> { + if (!mInner.registerListener(listener, sensor, delayUs, maxReportLatencyUs, handler)) { + Log.e(TAG, "Registering " + listener + " for " + sensor + " failed."); + } + }); + return true; + } + + @Override + protected boolean flushImpl(SensorEventListener listener) { + return mInner.flush(listener); + } + + @Override + protected SensorDirectChannel createDirectChannelImpl(MemoryFile memoryFile, + HardwareBuffer hardwareBuffer) { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected void destroyDirectChannelImpl(SensorDirectChannel channel) { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected int configureDirectChannelImpl(SensorDirectChannel channel, Sensor s, int rate) { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected void registerDynamicSensorCallbackImpl(DynamicSensorCallback callback, + Handler handler) { + mHandler.post(() -> mInner.registerDynamicSensorCallback(callback, handler)); + } + + @Override + protected void unregisterDynamicSensorCallbackImpl(DynamicSensorCallback callback) { + mHandler.post(() -> mInner.unregisterDynamicSensorCallback(callback)); + } + + @Override + protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) { + mHandler.post(() -> { + if (!mInner.requestTriggerSensor(listener, sensor)) { + Log.e(TAG, "Requesting " + listener + " for " + sensor + " failed."); + } + }); + return true; + } + + @Override + protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, + boolean disable) { + Preconditions.checkArgument(disable); + + mHandler.post(() -> { + if (!mInner.cancelTriggerSensor(listener, sensor)) { + Log.e(TAG, "Canceling " + listener + " for " + sensor + " failed."); + } + }); + return true; + } + + @Override + protected boolean initDataInjectionImpl(boolean enable) { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy, + long timestamp) { + throw new UnsupportedOperationException("not implemented"); + } + + @Override + protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) { + mHandler.post(() -> mInner.setOperationParameter(parameter)); + return true; + } + + @Override + protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { + mHandler.post(() -> mInner.unregisterListener(listener, sensor)); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index ad47411554f7..b08b26d77b76 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -100,7 +100,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa private final MediaSessions mMediaSessions; protected C mCallbacks = new C(); private final State mState = new State(); - private final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks(); + protected final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks(); private final Vibrator mVibrator; private final boolean mHasVibrator; private boolean mShowA11yStream; @@ -906,7 +906,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa } } - private final class MediaSessionsCallbacks implements MediaSessions.Callbacks { + protected final class MediaSessionsCallbacks implements MediaSessions.Callbacks { private final HashMap<Token, Integer> mRemoteStreams = new HashMap<>(); private int mNextStream = DYNAMIC_STREAM_START_INDEX; diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java index 12e9f7c97cde..06568f70f16c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.media.AudioManager; +import android.media.session.MediaSession; import android.support.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.keyguard.WakefulnessLifecycle; @@ -73,6 +74,18 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase { verify(mCallback, times(1)).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED); } + @Test + public void testOnRemoteVolumeChanged_newStream_noNullPointer() { + MediaSession.Token token = new MediaSession.Token(null); + mVolumeController.mMediaSessionsCallbacksW.onRemoteVolumeChanged(token, 0); + } + + @Test + public void testOnRemoteRemove_newStream_noNullPointer() { + MediaSession.Token token = new MediaSession.Token(null); + mVolumeController.mMediaSessionsCallbacksW.onRemoteRemoved(token); + } + static class TestableVolumeDialogControllerImpl extends VolumeDialogControllerImpl { public TestableVolumeDialogControllerImpl(Context context, C callback, StatusBar s) { super(context); diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index fdc0bba09a52..d60df83da68e 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -27,6 +27,7 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.database.ContentObserver; +import android.location.LocationManager; import android.net.INetworkRecommendationProvider; import android.net.INetworkScoreCache; import android.net.INetworkScoreService; @@ -113,6 +114,16 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } }; + private BroadcastReceiver mLocationModeReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (LocationManager.MODE_CHANGED_ACTION.equals(action)) { + refreshBinding(); + } + } + }; + /** * Clears scores when the active scorer package is no longer valid and * manages the service connection. @@ -241,6 +252,10 @@ public class NetworkScoreService extends INetworkScoreService.Stub { mUserIntentReceiver, UserHandle.SYSTEM, filter, null /* broadcastPermission*/, null /* scheduler */); mHandler = new ServiceHandler(looper); + IntentFilter locationModeFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); + mContext.registerReceiverAsUser( + mLocationModeReceiver, UserHandle.SYSTEM, locationModeFilter, + null /* broadcastPermission*/, mHandler); mContentObserver = new DispatchingContentObserver(context, mHandler); mServiceConnProducer = serviceConnProducer; } diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java index 42777bf33bd3..bfd4247abf40 100644 --- a/services/core/java/com/android/server/NetworkScorerAppManager.java +++ b/services/core/java/com/android/server/NetworkScorerAppManager.java @@ -18,6 +18,7 @@ package com.android.server; import android.Manifest.permission; import android.annotation.Nullable; +import android.app.AppOpsManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -79,7 +80,7 @@ public class NetworkScorerAppManager { List<NetworkScorerAppData> appDataList = new ArrayList<>(); for (int i = 0; i < resolveInfos.size(); i++) { final ServiceInfo serviceInfo = resolveInfos.get(i).serviceInfo; - if (hasPermissions(serviceInfo.packageName)) { + if (hasPermissions(serviceInfo.applicationInfo.uid, serviceInfo.packageName)) { if (VERBOSE) { Log.v(TAG, serviceInfo.packageName + " is a valid scorer/recommender."); } @@ -197,12 +198,33 @@ public class NetworkScorerAppManager { return null; } - private boolean hasPermissions(String packageName) { + private boolean hasPermissions(final int uid, final String packageName) { + return hasScoreNetworksPermission(packageName) + && canAccessLocation(uid, packageName); + } + + private boolean hasScoreNetworksPermission(String packageName) { final PackageManager pm = mContext.getPackageManager(); return pm.checkPermission(permission.SCORE_NETWORKS, packageName) == PackageManager.PERMISSION_GRANTED; } + private boolean canAccessLocation(int uid, String packageName) { + final PackageManager pm = mContext.getPackageManager(); + final AppOpsManager appOpsManager = + (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); + return isLocationModeEnabled() + && pm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName) + == PackageManager.PERMISSION_GRANTED + && appOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName) + == AppOpsManager.MODE_ALLOWED; + } + + private boolean isLocationModeEnabled() { + return mSettingsFacade.getSecureInt(mContext, Settings.Secure.LOCATION_MODE, + Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF; + } + /** * Set the specified package as the default scorer application. * @@ -270,23 +292,20 @@ public class NetworkScorerAppManager { return; } - // the active scorer isn't valid, revert to the default if it's different + int newEnabledSetting = NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF; + // the active scorer isn't valid, revert to the default if it's different and valid final String defaultPackageName = getDefaultPackageSetting(); - if (!TextUtils.equals(currentPackageName, defaultPackageName)) { - setNetworkRecommendationsPackage(defaultPackageName); + if (!TextUtils.equals(currentPackageName, defaultPackageName) + && getScorer(defaultPackageName) != null) { if (DEBUG) { - Log.d(TAG, "Defaulted the network recommendations app to: " + defaultPackageName); - } - if (getScorer(defaultPackageName) != null) { // the default is valid - if (DEBUG) Log.d(TAG, defaultPackageName + " is now the active scorer."); - setNetworkRecommendationsEnabledSetting( - NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON); - } else { // the default isn't valid either, we're disabled at this point - if (DEBUG) Log.d(TAG, defaultPackageName + " is not an active scorer."); - setNetworkRecommendationsEnabledSetting( - NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); + Log.d(TAG, "Defaulting the network recommendations app to: " + + defaultPackageName); } + setNetworkRecommendationsPackage(defaultPackageName); + newEnabledSetting = NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON; } + + setNetworkRecommendationsEnabledSetting(newEnabledSetting); } /** @@ -352,6 +371,9 @@ public class NetworkScorerAppManager { private void setNetworkRecommendationsPackage(String packageName) { mSettingsFacade.putString(mContext, Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, packageName); + if (VERBOSE) { + Log.d(TAG, Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE + " set to " + packageName); + } } private int getNetworkRecommendationsEnabledSetting() { @@ -361,6 +383,9 @@ public class NetworkScorerAppManager { private void setNetworkRecommendationsEnabledSetting(int value) { mSettingsFacade.putInt(mContext, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, value); + if (VERBOSE) { + Log.d(TAG, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED + " set to " + value); + } } /** @@ -382,5 +407,9 @@ public class NetworkScorerAppManager { public int getInt(Context context, String name, int defaultValue) { return Settings.Global.getInt(context.getContentResolver(), name, defaultValue); } + + public int getSecureInt(Context context, String name, int defaultValue) { + return Settings.Secure.getInt(context.getContentResolver(), name, defaultValue); + } } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 7860581e3319..bcad2fc09602 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -714,7 +714,9 @@ public class ActivityManagerService extends IActivityManager.Stub public boolean canShowErrorDialogs() { return mShowDialogs && !mSleeping && !mShuttingDown - && !mKeyguardController.isKeyguardShowing(); + && !mKeyguardController.isKeyguardShowing() + && !(UserManager.isDeviceInDemoMode(mContext) + && mUserController.getCurrentUser().isDemo()); } private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster( @@ -14979,7 +14981,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } else if ("starter".equals(cmd)) { synchronized (this) { - dumpActivityStarterLocked(pw); + dumpActivityStarterLocked(pw, dumpPackage); } } else if ("recents".equals(cmd) || "r".equals(cmd)) { synchronized (this) { @@ -15214,7 +15216,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } - dumpActivityStarterLocked(pw); + dumpActivityStarterLocked(pw, dumpPackage); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); @@ -15284,7 +15286,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } - dumpActivityStarterLocked(pw); + dumpActivityStarterLocked(pw, dumpPackage); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); @@ -15308,7 +15310,7 @@ public class ActivityManagerService extends IActivityManager.Stub } private void dumpLastANRLocked(PrintWriter pw) { - pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)"); + pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)"); if (mLastANRState == null) { pw.println(" <no ANR has occurred since boot>"); } else { @@ -15316,9 +15318,9 @@ public class ActivityManagerService extends IActivityManager.Stub } } - private void dumpActivityStarterLocked(PrintWriter pw) { - pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)"); - mActivityStarter.dump(pw, ""); + private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) { + pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)"); + mActivityStarter.dump(pw, "", dumpPackage); } void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, @@ -22819,11 +22821,11 @@ public class ActivityManagerService extends IActivityManager.Stub uidRec.lastBackgroundTime = 0; } final boolean wasCached = uidRec.setProcState - > ActivityManager.PROCESS_STATE_RECEIVER && uidRec.setProcState - != ActivityManager.PROCESS_STATE_NONEXISTENT; + > ActivityManager.PROCESS_STATE_RECEIVER; final boolean isCached = uidRec.curProcState > ActivityManager.PROCESS_STATE_RECEIVER; - if (wasCached != isCached) { + if (wasCached != isCached || + uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) { uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED; } uidRec.setProcState = uidRec.curProcState; @@ -24084,7 +24086,7 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(" Reason: " + reason); } pw.println(); - mActivityStarter.dump(pw, " "); + mActivityStarter.dump(pw, " ", null); pw.println(); pw.println("-------------------------------------------------------------------------------"); dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */, diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index ec20c0472e4d..2aa535064e86 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -427,11 +427,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo pw.print("\""); pw.print(" primaryColor="); pw.println(Integer.toHexString(taskDescription.getPrimaryColor())); - pw.print(prefix + " backgroundColor="); + pw.print(prefix); pw.print(" backgroundColor="); pw.println(Integer.toHexString(taskDescription.getBackgroundColor())); - pw.print(prefix + " statusBarColor="); + pw.print(prefix); pw.print(" statusBarColor="); pw.println(Integer.toHexString(taskDescription.getStatusBarColor())); - pw.print(prefix + " navigationBarColor="); + pw.print(prefix); pw.print(" navigationBarColor="); pw.println(Integer.toHexString(taskDescription.getNavigationBarColor())); } if (iconFilename == null && taskDescription.getIcon() != null) { diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 9925ba0e5dfe..79448cae7bc1 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -650,6 +650,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai return topRunningActivityLocked(false /* focusableOnly */); } + void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) { + outActivities.clear(); + for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { + mTaskHistory.get(taskNdx).getAllRunningVisibleActivitiesLocked(outActivities); + } + } + private ActivityRecord topRunningActivityLocked(boolean focusableOnly) { for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked(); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 5f42cdba39e0..e8bc68f21981 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -441,6 +441,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D final ActivityMetricsLogger mActivityMetricsLogger; + private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>(); + @Override protected int getChildCount() { return mActivityDisplays.size(); @@ -954,17 +956,21 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D if (!isFocusedStack(stack)) { continue; } - ActivityRecord hr = stack.topRunningActivityLocked(); - if (hr != null) { - if (hr.app == null && app.uid == hr.info.applicationInfo.uid - && processName.equals(hr.processName)) { + stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); + final ActivityRecord top = stack.topRunningActivityLocked(); + final int size = mTmpActivityList.size(); + for (int i = 0; i < size; i++) { + final ActivityRecord activity = mTmpActivityList.get(i); + if (activity.app == null && app.uid == activity.info.applicationInfo.uid + && processName.equals(activity.processName)) { try { - if (realStartActivityLocked(hr, app, true, true)) { + if (realStartActivityLocked(activity, app, + top == activity /* andResume */, true /* checkConfig */)) { didSomething = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new application when starting activity " - + hr.intent.getComponent().flattenToShortString(), e); + + top.intent.getComponent().flattenToShortString(), e); throw e; } } diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 09315877015d..0684f68e9e18 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -2306,40 +2306,76 @@ class ActivityStarter { return didSomething; } - void dump(PrintWriter pw, String prefix) { - pw.println(prefix + "ActivityStarter:"); + void dump(PrintWriter pw, String prefix, String dumpPackage) { prefix = prefix + " "; - pw.println(prefix + "mCurrentUser=" + mSupervisor.mCurrentUser); - pw.println(prefix + "mLastStartReason=" + mLastStartReason); - pw.println(prefix + "mLastStartActivityTimeMs=" - + DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs))); - pw.println(prefix + "mLastStartActivityResult=" + mLastStartActivityResult); + if (dumpPackage != null) { + if ((mLastStartActivityRecord[0] == null || + !dumpPackage.equals(mLastHomeActivityStartRecord[0].packageName)) && + (mLastHomeActivityStartRecord[0] == null || + !dumpPackage.equals(mLastHomeActivityStartRecord[0].packageName)) && + (mStartActivity == null || !dumpPackage.equals(mStartActivity.packageName))) { + pw.print(prefix); + pw.println("(nothing)"); + return; + } + } + + pw.print(prefix); + pw.print("mCurrentUser="); + pw.println(mSupervisor.mCurrentUser); + pw.print(prefix); + pw.print("mLastStartReason="); + pw.println(mLastStartReason); + pw.print(prefix); + pw.print("mLastStartActivityTimeMs="); + pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs))); + pw.print(prefix); + pw.print("mLastStartActivityResult="); + pw.println(mLastStartActivityResult); ActivityRecord r = mLastStartActivityRecord[0]; if (r != null) { - pw.println(prefix + "mLastStartActivityRecord:"); - r.dump(pw, prefix + " "); + pw.print(prefix); + pw.println("mLastStartActivityRecord:"); + r.dump(pw, prefix + " "); } - pw.println(prefix + "mLastHomeActivityStartResult=" + mLastHomeActivityStartResult); + pw.print(prefix); + pw.print("mLastHomeActivityStartResult="); + pw.println(mLastHomeActivityStartResult); r = mLastHomeActivityStartRecord[0]; if (r != null) { - pw.println(prefix + "mLastHomeActivityStartRecord:"); - r.dump(pw, prefix + " "); + pw.print(prefix); + pw.println("mLastHomeActivityStartRecord:"); + r.dump(pw, prefix + " "); } if (mStartActivity != null) { - pw.println(prefix + "mStartActivity:"); - mStartActivity.dump(pw, prefix + " "); + pw.print(prefix); + pw.println("mStartActivity:"); + mStartActivity.dump(pw, prefix + " "); } if (mIntent != null) { - pw.println(prefix + "mIntent=" + mIntent); + pw.print(prefix); + pw.print("mIntent="); + pw.println(mIntent); } if (mOptions != null) { - pw.println(prefix + "mOptions=" + mOptions); - } - pw.println(prefix + "mLaunchSingleTop=" + mLaunchSingleTop - + " mLaunchSingleInstance=" + mLaunchSingleInstance - + " mLaunchSingleTask=" + mLaunchSingleTask - + " mLaunchFlags=0x" + Integer.toHexString(mLaunchFlags) - + " mDoResume=" + mDoResume + " mAddingToTask=" + mAddingToTask); + pw.print(prefix); + pw.print("mOptions="); + pw.println(mOptions); + } + pw.print(prefix); + pw.print("mLaunchSingleTop="); + pw.print(mLaunchSingleTop); + pw.print(" mLaunchSingleInstance="); + pw.print(mLaunchSingleInstance); + pw.print(" mLaunchSingleTask="); + pw.println(mLaunchSingleTask); + pw.print(prefix); + pw.print("mLaunchFlags=0x"); + pw.print(Integer.toHexString(mLaunchFlags)); + pw.print(" mDoResume="); + pw.print(mDoResume); + pw.print(" mAddingToTask="); + pw.println(mAddingToTask); } } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 5753fbc5a92d..be0a1d9b3c45 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1159,6 +1159,17 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta return null; } + void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) { + if (mStack != null) { + for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) { + ActivityRecord r = mActivities.get(activityNdx); + if (!r.finishing && r.okToShowLocked() && r.visible) { + outActivities.add(r); + } + } + } + } + ActivityRecord topRunningActivityWithStartingWindowLocked() { if (mStack != null) { for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) { diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 405ee323bbe1..ceae82f1a9ac 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -671,12 +671,6 @@ final class UserController { } if (stopped) { - // Evict the user's credential encryption key - try { - getStorageManager().lockUserKey(userId); - } catch (RemoteException re) { - throw re.rethrowAsRuntimeException(); - } mInjector.systemServiceManagerCleanupUser(userId); synchronized (mLock) { mInjector.getActivityStackSupervisor().removeUserLocked(userId); @@ -685,6 +679,12 @@ final class UserController { if (getUserInfo(userId).isEphemeral()) { mInjector.getUserManager().removeUser(userId); } + // Evict the user's credential encryption key. + try { + getStorageManager().lockUserKey(userId); + } catch (RemoteException re) { + throw re.rethrowAsRuntimeException(); + } } } diff --git a/services/core/java/com/android/server/broadcastradio/TunerCallback.java b/services/core/java/com/android/server/broadcastradio/TunerCallback.java index 25f3775e27de..331b6574ee92 100644 --- a/services/core/java/com/android/server/broadcastradio/TunerCallback.java +++ b/services/core/java/com/android/server/broadcastradio/TunerCallback.java @@ -86,8 +86,8 @@ class TunerCallback implements ITunerCallback { } @Override - public void onProgramInfoChanged() { - dispatch(() -> mClientCallback.onProgramInfoChanged()); + public void onCurrentProgramInfoChanged() { + dispatch(() -> mClientCallback.onCurrentProgramInfoChanged()); } @Override diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ebd8ef00b0d5..aead98b90046 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -10004,6 +10004,7 @@ public class PackageManagerService extends IPackageManager.Stub public void shutdown() { mPackageUsage.writeNow(mPackages); mCompilerStats.writeNow(); + mDexManager.savePackageDexUsageNow(); } @Override diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index 79e02b5399de..947e01c49c59 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -592,6 +592,13 @@ public class DexManager { return existingValue == null ? newValue : existingValue; } + /** + * Saves the in-memory package dex usage to disk right away. + */ + public void savePackageDexUsageNow() { + mPackageDexUsage.writeNow(); + } + public static class RegisterDexModuleResult { public RegisterDexModuleResult() { this(false, null); diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java index 8819aa66ed6b..6ee26d32f0e0 100644 --- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java +++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java @@ -198,8 +198,12 @@ public class PackageDexUsage extends AbstractStatsBase<Void> { * Convenience method for async writes which does not force the user to pass a useless * (Void) null. */ - public void maybeWriteAsync() { - maybeWriteAsync((Void) null); + /*package*/ void maybeWriteAsync() { + maybeWriteAsync(null); + } + + /*package*/ void writeNow() { + writeInternal(null); } @Override diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index e3cf459774e9..6afd69dcf137 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -4184,7 +4184,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { boolean handled = false; try { if (event instanceof MotionEvent @@ -7049,6 +7049,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Ignore sensor when demo rotation lock is enabled. // Note that the dock orientation and HDMI rotation lock override this. preferredRotation = mDemoRotation; + } else if (mPersistentVrModeEnabled) { + // While in VR, apps always prefer a portrait rotation. This does not change + // any apps that explicitly set landscape, but does cause sensors be ignored, + // and ignored any orientation lock that the user has set (this conditional + // should remain above the ORIENTATION_LOCKED conditional below). + preferredRotation = mPortraitRotation; } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) { // Application just wants to remain locked in the last rotation. preferredRotation = lastRotation; @@ -7079,13 +7085,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { || mAllowAllRotations == 1 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) { - // In VrMode, we report the sensor as always being in default orientation so: - // 1) The orientation doesn't change as the user moves their head. - // 2) 2D apps within VR show in the device's default orientation. - // This only overwrites the sensor-provided orientation and does not affect any - // explicit orientation preferences specified by any activities. - preferredRotation = - mPersistentVrModeEnabled ? Surface.ROTATION_0 : sensorRotation; + preferredRotation = sensorRotation; } else { preferredRotation = lastRotation; } diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index e894275fe2b6..92f1c83c892e 100644 --- a/services/core/java/com/android/server/power/ShutdownThread.java +++ b/services/core/java/com/android/server/power/ShutdownThread.java @@ -57,6 +57,7 @@ import android.widget.ProgressBar; import android.widget.TextView; import com.android.internal.telephony.ITelephony; +import com.android.server.RescueParty; import com.android.server.pm.PackageManagerService; import java.io.File; @@ -293,11 +294,20 @@ public final class ShutdownThread extends Thread { com.android.internal.R.string.reboot_to_update_reboot)); } } else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) { - // Factory reset path. Set the dialog message accordingly. - pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title)); - pd.setMessage(context.getText( - com.android.internal.R.string.reboot_to_reset_message)); - pd.setIndeterminate(true); + if (RescueParty.isAttemptingFactoryReset()) { + // We're not actually doing a factory reset yet; we're rebooting + // to ask the user if they'd like to reset, so give them a less + // scary dialog message. + pd.setTitle(context.getText(com.android.internal.R.string.power_off)); + pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress)); + pd.setIndeterminate(true); + } else { + // Factory reset path. Set the dialog message accordingly. + pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title)); + pd.setMessage(context.getText( + com.android.internal.R.string.reboot_to_reset_message)); + pd.setIndeterminate(true); + } } else if (mReason != null && mReason.equals(PowerManager.SHUTDOWN_USER_REQUESTED)) { Dialog d = new Dialog(context); d.setContentView(com.android.internal.R.layout.shutdown_dialog); diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java index 88b6d870afd7..a35383f385f2 100644 --- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java +++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java @@ -29,6 +29,7 @@ import android.os.Binder; import android.os.Environment; import android.os.FileObserver; import android.os.Handler; +import android.os.HandlerThread; import android.os.Message; import android.os.ResultReceiver; import android.os.ServiceManager; @@ -154,20 +155,8 @@ public class DeviceStorageMonitorService extends SystemService { private static final String TV_NOTIFICATION_CHANNEL_ID = "devicestoragemonitor.tv"; - /** - * Handler that checks the amount of disk space on the device and sends a - * notification if the device runs low on disk space - */ - private final Handler mHandler = new Handler(IoThread.get().getLooper()) { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_CHECK: - check(); - return; - } - } - }; + private final HandlerThread mHandlerThread; + private final Handler mHandler; private State findOrCreateState(UUID uuid) { State state = mStates.get(uuid); @@ -256,6 +245,20 @@ public class DeviceStorageMonitorService extends SystemService { public DeviceStorageMonitorService(Context context) { super(context); + + mHandlerThread = new HandlerThread(TAG, android.os.Process.THREAD_PRIORITY_BACKGROUND); + mHandlerThread.start(); + + mHandler = new Handler(mHandlerThread.getLooper()) { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_CHECK: + check(); + return; + } + } + }; } private static boolean isBootImageOnDisk() { diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java index 69d8ca68522f..8f50a39a5424 100644 --- a/services/core/java/com/android/server/vr/Vr2dDisplay.java +++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java @@ -24,6 +24,7 @@ import android.service.vr.IPersistentVrStateCallbacks; import android.service.vr.IVrManager; import android.util.Log; import android.view.Surface; +import android.view.WindowManagerInternal; import com.android.server.vr.VrManagerService; @@ -74,6 +75,7 @@ class Vr2dDisplay { public static final int MIN_VR_DISPLAY_DPI = 1; private final ActivityManagerInternal mActivityManagerInternal; + private final WindowManagerInternal mWindowManagerInternal; private final DisplayManager mDisplayManager; private final IVrManager mVrManager; private final Object mVdLock = new Object(); @@ -103,9 +105,11 @@ class Vr2dDisplay { private boolean mBootsToVr = false; // The device boots into VR (standalone VR device) public Vr2dDisplay(DisplayManager displayManager, - ActivityManagerInternal activityManagerInternal, IVrManager vrManager) { + ActivityManagerInternal activityManagerInternal, + WindowManagerInternal windowManagerInternal, IVrManager vrManager) { mDisplayManager = displayManager; mActivityManagerInternal = activityManagerInternal; + mWindowManagerInternal = windowManagerInternal; mVrManager = vrManager; mVirtualDisplayWidth = DEFAULT_VIRTUAL_DISPLAY_WIDTH; mVirtualDisplayHeight = DEFAULT_VIRTUAL_DISPLAY_HEIGHT; @@ -296,13 +300,12 @@ class Vr2dDisplay { UNIQUE_DISPLAY_ID); if (mVirtualDisplay != null) { - mActivityManagerInternal.setVr2dDisplayId( - mVirtualDisplay.getDisplay().getDisplayId()); + updateDisplayId(mVirtualDisplay.getDisplay().getDisplayId()); // Now create the ImageReader to supply a Surface to the new virtual display. startImageReader(); } else { Log.w(TAG, "Virtual display id is null after createVirtualDisplay"); - mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY); + updateDisplayId(INVALID_DISPLAY); return; } } @@ -310,6 +313,11 @@ class Vr2dDisplay { Log.i(TAG, "VD created: " + mVirtualDisplay); } + private void updateDisplayId(int displayId) { + mActivityManagerInternal.setVr2dDisplayId(displayId); + mWindowManagerInternal.setVr2dDisplayId(displayId); + } + /** * Stops the virtual display with a {@link #STOP_VIRTUAL_DISPLAY_DELAY_MILLIS} timeout. * The timeout prevents the virtual display from bouncing in cases where VrMode goes in and out @@ -325,7 +333,7 @@ class Vr2dDisplay { } else { Log.i(TAG, "Stopping Virtual Display"); synchronized (mVdLock) { - mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY); + updateDisplayId(INVALID_DISPLAY); setSurfaceLocked(null); // clean up and release the surface first. if (mVirtualDisplay != null) { mVirtualDisplay.release(); diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index 425b23f29d0f..b6b964b050e3 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -58,6 +58,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; +import android.view.WindowManagerInternal; import com.android.internal.R; import com.android.internal.util.DumpUtils; @@ -633,8 +634,11 @@ public class VrManagerService extends SystemService implements EnabledComponentC DisplayManager dm = (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE); - ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class); - mVr2dDisplay = new Vr2dDisplay(dm, ami, mVrManager); + mVr2dDisplay = new Vr2dDisplay( + dm, + LocalServices.getService(ActivityManagerInternal.class), + LocalServices.getService(WindowManagerInternal.class), + mVrManager); mVr2dDisplay.init(getContext(), mBootsToVr); IntentFilter intentFilter = new IntentFilter(); diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 802054eed8ce..46097ed24cc5 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -25,6 +25,7 @@ import static android.os.ParcelFileDescriptor.MODE_TRUNCATE; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; +import android.annotation.NonNull; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; @@ -63,6 +64,7 @@ import android.os.FileObserver; import android.os.FileUtils; import android.os.Handler; import android.os.IBinder; +import android.os.IInterface; import android.os.IRemoteCallback; import android.os.ParcelFileDescriptor; import android.os.Process; @@ -331,11 +333,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } } - private void notifyWallpaperColorsChanged(WallpaperData wallpaper, int which) { + private void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper, int which) { boolean needsExtraction; synchronized (mLock) { - if (mColorsChangedListeners.getRegisteredCallbackCount() == 0) + final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners = + mColorsChangedListeners.get(wallpaper.userId); + final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners = + mColorsChangedListeners.get(UserHandle.USER_ALL); + // No-op until someone is listening to it. + if (emptyCallbackList(currentUserColorListeners) && + emptyCallbackList(userAllColorListeners)) { return; + } if (DEBUG) { Slog.v(TAG, "notifyWallpaperColorsChanged " + which); @@ -346,40 +355,66 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { // Let's notify the current values, it's fine if it's null, it just means // that we don't know yet. - notifyColorListeners(wallpaper.primaryColors, which); + notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId); if (needsExtraction) { extractColors(wallpaper); - notifyColorListeners(wallpaper.primaryColors, which); + synchronized (mLock) { + // Don't need to notify if nothing changed. + if (wallpaper.primaryColors == null) { + return; + } + } + notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId); } } - private void notifyColorListeners(WallpaperColors wallpaperColors, int which) { - final IWallpaperManagerCallback[] listeners; + private static <T extends IInterface> boolean emptyCallbackList(RemoteCallbackList<T> list) { + return (list == null || list.getRegisteredCallbackCount() == 0); + } + + private void notifyColorListeners(@NonNull WallpaperColors wallpaperColors, int which, + int userId) { final IWallpaperManagerCallback keyguardListener; + final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners; + final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners; synchronized (mLock) { - // Make a synchronized copy of the listeners to avoid concurrent list modification. - int callbackCount = mColorsChangedListeners.beginBroadcast(); - listeners = new IWallpaperManagerCallback[callbackCount]; - for (int i = 0; i < callbackCount; i++) { - listeners[i] = mColorsChangedListeners.getBroadcastItem(i); - } - mColorsChangedListeners.finishBroadcast(); + currentUserColorListeners = mColorsChangedListeners.get(userId); + userAllColorListeners = mColorsChangedListeners.get(UserHandle.USER_ALL); keyguardListener = mKeyguardListener; } - for (int i = 0; i < listeners.length; i++) { - try { - listeners[i].onWallpaperColorsChanged(wallpaperColors, which); - } catch (RemoteException e) { - // Callback is gone, it's not necessary to unregister it since - // RemoteCallbackList#getBroadcastItem will take care of it. + if (currentUserColorListeners != null) { + int count = currentUserColorListeners.beginBroadcast(); + for (int i = 0; i < count; i++) { + try { + currentUserColorListeners.getBroadcastItem(i) + .onWallpaperColorsChanged(wallpaperColors, which, userId); + } catch (RemoteException e) { + // Callback is gone, it's not necessary to unregister it since + // RemoteCallbackList#getBroadcastItem will take care of it. + } + } + currentUserColorListeners.finishBroadcast(); + } + + if (userAllColorListeners != null) { + int count = userAllColorListeners.beginBroadcast(); + for (int i = 0; i < count; i++) { + try { + userAllColorListeners.getBroadcastItem(i) + .onWallpaperColorsChanged(wallpaperColors, which, userId); + } catch (RemoteException e) { + // Callback is gone, it's not necessary to unregister it since + // RemoteCallbackList#getBroadcastItem will take care of it. + } } + userAllColorListeners.finishBroadcast(); } if (keyguardListener != null) { try { - keyguardListener.onWallpaperColorsChanged(wallpaperColors, which); + keyguardListener.onWallpaperColorsChanged(wallpaperColors, which, userId); } catch (RemoteException e) { // Oh well it went away; no big deal } @@ -595,7 +630,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { final IPackageManager mIPackageManager; final MyPackageMonitor mMonitor; final AppOpsManager mAppOpsManager; - final RemoteCallbackList<IWallpaperManagerCallback> mColorsChangedListeners; + /** + * Map of color listeners per user id. + * The key will be the id of a user or UserHandle.USER_ALL - for wildcard listeners. + */ + final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>> mColorsChangedListeners; WallpaperData mLastWallpaper; IWallpaperManagerCallback mKeyguardListener; boolean mWaitingForUnlock; @@ -858,11 +897,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { */ @Override public void onWallpaperColorsChanged(WallpaperColors primaryColors) { - // Do not override default color extraction if API isn't implemented. - if (primaryColors == null) { - return; - } - int which; synchronized (mLock) { // Do not broadcast changes on ImageWallpaper since it's handled @@ -876,7 +910,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { // Live wallpapers always are system wallpapers. which = FLAG_SYSTEM; // It's also the lock screen wallpaper when we don't have a bitmap in there - WallpaperData lockedWallpaper = mLockWallpaperMap.get(mCurrentUserId); + WallpaperData lockedWallpaper = mLockWallpaperMap.get(mWallpaper.userId); if (lockedWallpaper == null) { which |= FLAG_LOCK; } @@ -906,6 +940,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } mPaddingChanged = false; } + try { + // This will trigger onComputeColors in the wallpaper engine. + // It's fine to be locked in here since the binder is oneway. + mEngine.requestWallpaperColors(); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to request wallpaper colors", e); + } } } @@ -1096,7 +1137,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { mMonitor.register(context, null, UserHandle.ALL, true); getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs(); loadSettingsLocked(UserHandle.USER_SYSTEM, false); - mColorsChangedListeners = new RemoteCallbackList<>(); + mColorsChangedListeners = new SparseArray<>(); } private static File getWallpaperDir(int userId) { @@ -1252,16 +1293,24 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } void switchUser(int userId, IRemoteCallback reply) { + WallpaperData systemWallpaper; + WallpaperData lockWallpaper; synchronized (mLock) { mCurrentUserId = userId; - WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM); + systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM); + lockWallpaper = mLockWallpaperMap.get(userId); + if (lockWallpaper == null) { + lockWallpaper = systemWallpaper; + } // Not started watching yet, in case wallpaper data was loaded for other reasons. - if (wallpaper.wallpaperObserver == null) { - wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper); - wallpaper.wallpaperObserver.startWatching(); + if (systemWallpaper.wallpaperObserver == null) { + systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper); + systemWallpaper.wallpaperObserver.startWatching(); } - switchWallpaper(wallpaper, reply); + switchWallpaper(systemWallpaper, reply); } + notifyWallpaperColorsChanged(systemWallpaper, FLAG_SYSTEM); + notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK); } void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) { @@ -1634,16 +1683,30 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } @Override - public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb) { + public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) { + userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, true, true, "registerWallpaperColorsCallback", null); synchronized (mLock) { - mColorsChangedListeners.register(cb); + RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners = + mColorsChangedListeners.get(userId); + if (userColorsChangedListeners == null) { + userColorsChangedListeners = new RemoteCallbackList<>(); + mColorsChangedListeners.put(userId, userColorsChangedListeners); + } + userColorsChangedListeners.register(cb); } } @Override - public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb) { + public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) { + userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, true, true, "unregisterWallpaperColorsCallback", null); synchronized (mLock) { - mColorsChangedListeners.unregister(cb); + final RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners = + mColorsChangedListeners.get(userId); + if (userColorsChangedListeners != null) { + userColorsChangedListeners.unregister(cb); + } } } @@ -1657,23 +1720,25 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } @Override - public WallpaperColors getWallpaperColors(int which) throws RemoteException { + public WallpaperColors getWallpaperColors(int which, int userId) throws RemoteException { if (which != FLAG_LOCK && which != FLAG_SYSTEM) { throw new IllegalArgumentException("which should be either FLAG_LOCK or FLAG_SYSTEM"); } + userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, false, true, "getWallpaperColors", null); WallpaperData wallpaperData = null; boolean shouldExtract; synchronized (mLock) { if (which == FLAG_LOCK) { - wallpaperData = mLockWallpaperMap.get(mCurrentUserId); + wallpaperData = mLockWallpaperMap.get(userId); } // Try to get the system wallpaper anyway since it might // also be the lock screen wallpaper if (wallpaperData == null) { - wallpaperData = mWallpaperMap.get(mCurrentUserId); + wallpaperData = mWallpaperMap.get(userId); } if (wallpaperData == null) { @@ -1872,8 +1937,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { try { wallpaper.imageWallpaperPending = false; + boolean same = changingToSame(name, wallpaper); if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) { - wallpaper.primaryColors = null; + if (!same) { + wallpaper.primaryColors = null; + } wallpaper.wallpaperId = makeWallpaperIdLocked(); notifyCallbacksLocked(wallpaper); shouldNotifyColors = true; @@ -1888,26 +1956,31 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } } + private boolean changingToSame(ComponentName componentName, WallpaperData wallpaper) { + if (wallpaper.connection != null) { + if (wallpaper.wallpaperComponent == null) { + if (componentName == null) { + if (DEBUG) Slog.v(TAG, "changingToSame: still using default"); + // Still using default wallpaper. + return true; + } + } else if (wallpaper.wallpaperComponent.equals(componentName)) { + // Changing to same wallpaper. + if (DEBUG) Slog.v(TAG, "same wallpaper"); + return true; + } + } + return false; + } + boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force, boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) { if (DEBUG_LIVE) { Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName); } // Has the component changed? - if (!force) { - if (wallpaper.connection != null) { - if (wallpaper.wallpaperComponent == null) { - if (componentName == null) { - if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default"); - // Still using default wallpaper. - return true; - } - } else if (wallpaper.wallpaperComponent.equals(componentName)) { - // Changing to same wallpaper. - if (DEBUG) Slog.v(TAG, "same wallpaper"); - return true; - } - } + if (!force && changingToSame(componentName, wallpaper)) { + return true; } try { @@ -2234,15 +2307,35 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } private void migrateFromOld() { - File oldWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY); - File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY); - if (oldWallpaper.exists()) { - File newWallpaper = new File(getWallpaperDir(0), WALLPAPER); - oldWallpaper.renameTo(newWallpaper); - } - if (oldInfo.exists()) { - File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO); - oldInfo.renameTo(newInfo); + // Pre-N, what existed is the one we're now using as the display crop + File preNWallpaper = new File(getWallpaperDir(0), WALLPAPER_CROP); + // In the very-long-ago, imagery lived with the settings app + File originalWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY); + File newWallpaper = new File(getWallpaperDir(0), WALLPAPER); + + // Migrations from earlier wallpaper image storage schemas + if (preNWallpaper.exists()) { + if (!newWallpaper.exists()) { + // we've got the 'wallpaper' crop file but not the nominal source image, + // so do the simple "just take everything" straight copy of legacy data + if (DEBUG) { + Slog.i(TAG, "Migrating wallpaper schema"); + } + FileUtils.copyFile(preNWallpaper, newWallpaper); + } // else we're in the usual modern case: both source & crop exist + } else if (originalWallpaper.exists()) { + // VERY old schema; make sure things exist and are in the right place + if (DEBUG) { + Slog.i(TAG, "Migrating antique wallpaper schema"); + } + File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY); + if (oldInfo.exists()) { + File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO); + oldInfo.renameTo(newInfo); + } + + FileUtils.copyFile(originalWallpaper, preNWallpaper); + originalWallpaper.renameTo(newWallpaper); } } @@ -2303,12 +2396,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { JournaledFile journal = makeJournaledFile(userId); FileInputStream stream = null; File file = journal.chooseForRead(); - if (!file.exists()) { - // This should only happen one time, when upgrading from a legacy system - migrateFromOld(); - } + WallpaperData wallpaper = mWallpaperMap.get(userId); if (wallpaper == null) { + // Do this once per boot + migrateFromOld(); + wallpaper = new WallpaperData(userId, WALLPAPER, WALLPAPER_CROP); wallpaper.allowBackup = true; mWallpaperMap.put(userId, wallpaper); diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 78f21956f548..805250ad96d4 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -17,7 +17,7 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; -import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MAGNIFICATION_REGION_EFFECT; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -539,7 +539,7 @@ final class AccessibilityController { WindowState windowState = visibleWindows.valueAt(i); if ((windowState.mAttrs.type == TYPE_MAGNIFICATION_OVERLAY) || ((windowState.mAttrs.privateFlags - & PRIVATE_FLAG_NO_MAGNIFICATION_REGION_EFFECT) != 0)) { + & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0)) { continue; } diff --git a/services/core/java/com/android/server/wm/PointerEventDispatcher.java b/services/core/java/com/android/server/wm/PointerEventDispatcher.java index 6b0e4c9f010a..484987ec127e 100644 --- a/services/core/java/com/android/server/wm/PointerEventDispatcher.java +++ b/services/core/java/com/android/server/wm/PointerEventDispatcher.java @@ -36,11 +36,11 @@ public class PointerEventDispatcher extends InputEventReceiver { } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { try { if (event instanceof MotionEvent && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { - final MotionEvent motionEvent = (MotionEvent)event; + final MotionEvent motionEvent = (MotionEvent) event; PointerEventListener[] listeners; synchronized (mListeners) { if (mListenersArray == null) { @@ -50,7 +50,7 @@ public class PointerEventDispatcher extends InputEventReceiver { listeners = mListenersArray; } for (int i = 0; i < listeners.length; ++i) { - listeners[i].onPointerEvent(motionEvent); + listeners[i].onPointerEvent(motionEvent, displayId); } } } finally { diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 233e75bbfec7..40528d06f665 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -18,6 +18,7 @@ package com.android.server.wm; import android.content.res.Configuration; import android.graphics.Rect; +import android.hardware.display.DisplayManager; import android.hardware.power.V1_0.PowerHint; import android.os.Binder; import android.os.Debug; @@ -243,12 +244,24 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { displayId, displayInfo); mService.configureDisplayPolicyLocked(dc); - // TODO(multi-display): Create an input channel for each display with touch capability. - if (displayId == DEFAULT_DISPLAY && mService.canDispatchPointerEvents()) { - dc.mTapDetector = new TaskTapPointerEventListener( - mService, dc); + // Tap Listeners are supported for: + // 1. All physical displays (multi-display). + // 2. VirtualDisplays that support virtual touch input. (Only VR for now) + // TODO(multi-display): Support VirtualDisplays with no virtual touch input. + if ((display.getType() != Display.TYPE_VIRTUAL + || (display.getType() == Display.TYPE_VIRTUAL + // Only VR VirtualDisplays + && displayId == mService.mVr2dDisplayId)) + && mService.canDispatchPointerEvents()) { + if (DEBUG_DISPLAY) { + Slog.d(TAG, + "Registering PointerEventListener for DisplayId: " + displayId); + } + dc.mTapDetector = new TaskTapPointerEventListener(mService, dc); mService.registerPointerEventListener(dc.mTapDetector); - mService.registerPointerEventListener(mService.mMousePositionTracker); + if (displayId == DEFAULT_DISPLAY) { + mService.registerPointerEventListener(mService.mMousePositionTracker); + } } } @@ -747,12 +760,16 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { if (mUpdateRotation) { if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation"); - // TODO(multi-display): Update rotation for different displays separately. - final int displayId = defaultDisplay.getDisplayId(); - if (defaultDisplay.updateRotationUnchecked(false /* inTransaction */)) { - mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget(); - } else { - mUpdateRotation = false; + + for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { + final DisplayContent displayContent = mChildren.get(displayNdx); + final int displayId = displayContent.getDisplayId(); + if (displayContent.updateRotationUnchecked(false /* inTransaction */)) { + mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget(); + } else if (displayId == DEFAULT_DISPLAY) { + // TODO(multi-display): Track rotation updates for different displays separately + mUpdateRotation = false; + } } } diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index 0c68e2ca6d77..c58212cd8235 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -133,7 +133,7 @@ class TaskPositioner implements DimLayer.DimLayerUser { } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { if (!(event instanceof MotionEvent) || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) { return; diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java index dd9ba7355d7c..42a2d9df5fb5 100644 --- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java +++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java @@ -24,6 +24,7 @@ import android.view.WindowManagerPolicy.PointerEventListener; import com.android.server.wm.WindowManagerService.H; +import static android.view.Display.DEFAULT_DISPLAY; import static android.view.PointerIcon.TYPE_NOT_SPECIFIED; import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW; import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; @@ -45,6 +46,13 @@ public class TaskTapPointerEventListener implements PointerEventListener { } @Override + public void onPointerEvent(MotionEvent motionEvent, int displayId) { + if (displayId == getDisplayId()) { + onPointerEvent(motionEvent); + } + } + + @Override public void onPointerEvent(MotionEvent motionEvent) { final int action = motionEvent.getAction(); switch (action & MotionEvent.ACTION_MASK) { @@ -104,4 +112,8 @@ public class TaskTapPointerEventListener implements PointerEventListener { mTouchExcludeRegion.set(newRegion); } } + + private int getDisplayId() { + return mDisplayContent.getDisplayId(); + } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5db691ef10f7..83926af8a0ee 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -79,6 +79,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; @@ -357,6 +358,8 @@ public class WindowManagerService extends IWindowManager.Stub final private KeyguardDisableHandler mKeyguardDisableHandler; boolean mKeyguardGoingAway; + // VR Vr2d Display Id. + int mVr2dDisplayId = INVALID_DISPLAY; private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override @@ -767,7 +770,7 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { boolean handled = false; try { if (mDragState == null) { @@ -7565,6 +7568,16 @@ public class WindowManagerService extends IWindowManager.Stub accessibilityController.performComputeChangedWindowsNotLocked(); } } + + @Override + public void setVr2dDisplayId(int vr2dDisplayId) { + if (DEBUG_DISPLAY) { + Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId); + } + synchronized (WindowManagerService.this) { + mVr2dDisplayId = vr2dDisplayId; + } + } } void registerAppFreezeListener(AppFreezeListener listener) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 7decb11d777b..7ec21a884851 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2043,7 +2043,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP super(inputChannel, mService.mH.getLooper()); } @Override - public void onInputEvent(InputEvent event) { + public void onInputEvent(InputEvent event, int displayId) { finishInputEvent(event, true); } } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 23b515e3c5c9..c610ca381897 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -20,6 +20,7 @@ import static android.app.ActivityManager.StackId; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; import static android.view.WindowManager.LayoutParams.FLAG_SCALED; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; @@ -631,6 +632,10 @@ class WindowStateAnimator { return mSurfaceController; } + if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) { + windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT; + } + w.setHasSurface(false); if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG, diff --git a/services/core/jni/BroadcastRadio/Tuner.cpp b/services/core/jni/BroadcastRadio/Tuner.cpp index f5a85c1bbd83..aa1925ad365a 100644 --- a/services/core/jni/BroadcastRadio/Tuner.cpp +++ b/services/core/jni/BroadcastRadio/Tuner.cpp @@ -296,7 +296,7 @@ static void nativeTune(JNIEnv *env, jobject obj, jlong nativeContext, jobject jS auto selector = convert::ProgramSelectorToHal(env, jSelector); if (halTuner11 != nullptr) { - convert::ThrowIfFailed(env, halTuner11->tune_1_1(selector)); + convert::ThrowIfFailed(env, halTuner11->tuneByProgramSelector(selector)); } else { uint32_t channel, subChannel; if (!V1_1::utils::getLegacyChannel(selector, &channel, &subChannel)) { diff --git a/services/core/jni/BroadcastRadio/TunerCallback.cpp b/services/core/jni/BroadcastRadio/TunerCallback.cpp index 04bdddf61aa0..e01d8fa0b152 100644 --- a/services/core/jni/BroadcastRadio/TunerCallback.cpp +++ b/services/core/jni/BroadcastRadio/TunerCallback.cpp @@ -58,7 +58,7 @@ static struct { jmethodID handleHwFailure; jmethodID onError; jmethodID onConfigurationChanged; - jmethodID onProgramInfoChanged; + jmethodID onCurrentProgramInfoChanged; jmethodID onTrafficAnnouncement; jmethodID onEmergencyAnnouncement; jmethodID onAntennaState; @@ -111,7 +111,7 @@ public: virtual Return<void> backgroundScanAvailable(bool isAvailable); virtual Return<void> backgroundScanComplete(ProgramListResult result); virtual Return<void> programListChanged(); - virtual Return<void> programInfoChanged(); + virtual Return<void> currentProgramInfoChanged(); }; struct TunerCallbackContext { @@ -192,7 +192,7 @@ Return<void> NativeCallback::tuneComplete_1_1(Result result, const ProgramSelect mCallbackThread.enqueue([result, this](JNIEnv *env) { if (result == Result::OK) { - env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged); + env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged); } else { TunerError cause = TunerError::CANCELLED; if (result == Result::TIMEOUT) cause = TunerError::SCAN_TIMEOUT; @@ -254,7 +254,7 @@ Return<void> NativeCallback::newMetadata(uint32_t channel, uint32_t subChannel, } mCallbackThread.enqueue([this, metadata](JNIEnv *env) { - env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged); + env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged); }); return Return<void>(); @@ -297,11 +297,11 @@ Return<void> NativeCallback::programListChanged() { return Return<void>(); } -Return<void> NativeCallback::programInfoChanged() { +Return<void> NativeCallback::currentProgramInfoChanged() { ALOGV("%s", __func__); mCallbackThread.enqueue([this](JNIEnv *env) { - env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged); + env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged); }); return Return<void>(); @@ -379,8 +379,8 @@ void register_android_server_broadcastradio_TunerCallback(JavaVM *vm, JNIEnv *en gjni.TunerCallback.onError = GetMethodIDOrDie(env, tunerCbClass, "onError", "(I)V"); gjni.TunerCallback.onConfigurationChanged = GetMethodIDOrDie(env, tunerCbClass, "onConfigurationChanged", "(Landroid/hardware/radio/RadioManager$BandConfig;)V"); - gjni.TunerCallback.onProgramInfoChanged = GetMethodIDOrDie(env, tunerCbClass, - "onProgramInfoChanged", "()V"); + gjni.TunerCallback.onCurrentProgramInfoChanged = GetMethodIDOrDie(env, tunerCbClass, + "onCurrentProgramInfoChanged", "()V"); gjni.TunerCallback.onTrafficAnnouncement = GetMethodIDOrDie(env, tunerCbClass, "onTrafficAnnouncement", "(Z)V"); gjni.TunerCallback.onEmergencyAnnouncement = GetMethodIDOrDie(env, tunerCbClass, diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java index ceb92dece764..82ff0d835f33 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java @@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.Manifest.permission; +import android.app.AppOpsManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -61,15 +62,18 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class NetworkScorerAppManagerTest { + private static final int PACKAGE_UID = 924; private static String MOCK_SERVICE_LABEL = "Mock Service"; private static String MOCK_OVERRIDEN_SERVICE_LABEL = "Mock Service Label Override"; private static String MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID = "Mock Network Available Notification Channel Id"; + private static final ComponentName RECO_COMPONENT = new ComponentName("package1", "class1"); @Mock private Context mMockContext; @Mock private PackageManager mMockPm; @Mock private Resources mResources; @Mock private NetworkScorerAppManager.SettingsFacade mSettingsFacade; + @Mock private AppOpsManager mAppOpsManager; private NetworkScorerAppManager mNetworkScorerAppManager; private List<ResolveInfo> mAvailableServices; @@ -86,45 +90,69 @@ public class NetworkScorerAppManagerTest { } }), eq(PackageManager.GET_META_DATA))).thenReturn(mAvailableServices); when(mMockContext.getResources()).thenReturn(mResources); + when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); + + mockLocationModeOn(); + mockLocationPermissionGranted(PACKAGE_UID, RECO_COMPONENT.getPackageName()); mNetworkScorerAppManager = new NetworkScorerAppManager(mMockContext, mSettingsFacade); } @Test public void testGetActiveScorer_providerAvailable() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */); + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */); final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); assertNotNull(activeScorer); - assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent()); - assertEquals(924, activeScorer.packageUid); + assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); + assertEquals(PACKAGE_UID, activeScorer.packageUid); assertEquals(MOCK_SERVICE_LABEL, activeScorer.getRecommendationServiceLabel()); } @Test public void testGetActiveScorer_providerAvailable_serviceLabelOverride() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, null /* enableUseOpenWifiPackageActivityPackage*/, true /* serviceLabelOverride */); final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); assertNotNull(activeScorer); - assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent()); - assertEquals(924, activeScorer.packageUid); + assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); + assertEquals(PACKAGE_UID, activeScorer.packageUid); assertEquals(MOCK_OVERRIDEN_SERVICE_LABEL, activeScorer.getRecommendationServiceLabel()); } @Test - public void testGetActiveScorer_permissionMissing() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksDenied(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */); + public void testGetActiveScorer_scoreNetworksPermissionMissing() throws Exception { + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksDenied(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */); + + final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); + assertNull(activeScorer); + } + + @Test + public void testGetActiveScorer_locationPermissionMissing() throws Exception { + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockLocationPermissionDenied(PACKAGE_UID, RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */); + + final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); + assertNull(activeScorer); + } + + @Test + public void testGetActiveScorer_locationModeOff() throws Exception { + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockLocationPermissionGranted(PACKAGE_UID, RECO_COMPONENT.getPackageName()); + mockLocationModeOff(); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */); final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); assertNull(activeScorer); @@ -133,67 +161,63 @@ public class NetworkScorerAppManagerTest { @Test public void testGetActiveScorer_providerAvailable_enableUseOpenWifiActivityNotSet() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, null /* enableUseOpenWifiPackageActivityPackage*/); final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); assertNotNull(activeScorer); - assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent()); - assertEquals(924, activeScorer.packageUid); + assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); + assertEquals(PACKAGE_UID, activeScorer.packageUid); assertNull(activeScorer.getEnableUseOpenWifiActivity()); } @Test public void testGetActiveScorer_providerAvailable_enableUseOpenWifiActivityNotResolved() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, "package2" /* enableUseOpenWifiPackageActivityPackage*/); final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); assertNotNull(activeScorer); - assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent()); - assertEquals(924, activeScorer.packageUid); + assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); + assertEquals(PACKAGE_UID, activeScorer.packageUid); assertNull(activeScorer.getEnableUseOpenWifiActivity()); } @Test public void testGetActiveScorer_providerAvailable_enableUseOpenWifiActivityResolved() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, enableUseOpenWifiComponent.getPackageName()); mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); assertNotNull(activeScorer); - assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent()); - assertEquals(924, activeScorer.packageUid); + assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); + assertEquals(PACKAGE_UID, activeScorer.packageUid); assertEquals(enableUseOpenWifiComponent, activeScorer.getEnableUseOpenWifiActivity()); assertNull(activeScorer.getNetworkAvailableNotificationChannelId()); } @Test public void testGetActiveScorer_providerAvailable_networkAvailableNotificationChannelIdSet() { - final ComponentName recoComponent = new ComponentName("package1", "class1"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, null /* enableUseOpenWifiActivityPackage */, false /* serviceLabelOverride */, true /* setNotificationChannelId */); final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); assertNotNull(activeScorer); - assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent()); - assertEquals(924, activeScorer.packageUid); + assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); + assertEquals(PACKAGE_UID, activeScorer.packageUid); assertEquals(MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID, activeScorer.getNetworkAvailableNotificationChannelId()); } @@ -209,9 +233,8 @@ public class NetworkScorerAppManagerTest { @Test public void testGetActiveScorer_packageSettingIsInvalid() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); - setDefaultNetworkRecommendationPackage(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); + setDefaultNetworkRecommendationPackage(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); // NETWORK_RECOMMENDATIONS_PACKAGE is set to a package that isn't a recommender. final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); @@ -249,12 +272,12 @@ public class NetworkScorerAppManagerTest { @Test public void testSetActiveScorer_validPackage() throws Exception { - String packageName = "package"; String newPackage = "newPackage"; - setNetworkRecoPackageSetting(packageName); + int newAppUid = 621; final ComponentName recoComponent = new ComponentName(newPackage, "class1"); mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, null); + mockRecommendationServiceAvailable(recoComponent, newAppUid, null); + mockLocationPermissionGranted(newAppUid, recoComponent.getPackageName()); assertTrue(mNetworkScorerAppManager.setActiveScorer(newPackage)); verify(mSettingsFacade).putString(mMockContext, @@ -289,11 +312,9 @@ public class NetworkScorerAppManagerTest { @Test public void testUpdateState_currentPackageValid() throws Exception { - String packageName = "package"; - setNetworkRecoPackageSetting(packageName); - final ComponentName recoComponent = new ComponentName(packageName, "class1"); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, null); + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID , null); mNetworkScorerAppManager.updateState(); @@ -306,11 +327,13 @@ public class NetworkScorerAppManagerTest { @Test public void testUpdateState_currentPackageNotValid_validDefault() throws Exception { - String defaultPackage = "defaultPackage"; - setDefaultNetworkRecommendationPackage(defaultPackage); + final String defaultPackage = "defaultPackage"; + final int defaultAppUid = 621; final ComponentName recoComponent = new ComponentName(defaultPackage, "class1"); + setDefaultNetworkRecommendationPackage(defaultPackage); mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, null); + mockRecommendationServiceAvailable(recoComponent, defaultAppUid, null); + mockLocationPermissionGranted(defaultAppUid, defaultPackage); mNetworkScorerAppManager.updateState(); @@ -329,8 +352,6 @@ public class NetworkScorerAppManagerTest { mNetworkScorerAppManager.updateState(); - verify(mSettingsFacade).putString(mMockContext, - Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, defaultPackage); verify(mSettingsFacade).putInt(mMockContext, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); @@ -345,8 +366,9 @@ public class NetworkScorerAppManagerTest { verify(mSettingsFacade, never()).putString(any(), eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString()); - verify(mSettingsFacade, never()).putInt(any(), - eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt()); + verify(mSettingsFacade).putInt(mMockContext, + Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, + NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); } @Test @@ -358,8 +380,9 @@ public class NetworkScorerAppManagerTest { verify(mSettingsFacade, never()).putString(any(), eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString()); - verify(mSettingsFacade, never()).putInt(any(), - eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt()); + verify(mSettingsFacade).putInt(mMockContext, + Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, + NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); } @Test @@ -370,8 +393,9 @@ public class NetworkScorerAppManagerTest { mNetworkScorerAppManager.updateState(); - verify(mSettingsFacade, never()).putString(any(), - eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), any()); + verify(mSettingsFacade).putInt(mMockContext, + Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, + NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); } @Test @@ -415,11 +439,10 @@ public class NetworkScorerAppManagerTest { @Test public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiSettingIsNotEmpty() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, enableUseOpenWifiComponent.getPackageName()); mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); when(mSettingsFacade.getString(mMockContext, @@ -441,13 +464,12 @@ public class NetworkScorerAppManagerTest { @Test public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiActivityNotAvail() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); // The active component doesn't have an open wifi activity so the migration shouldn't // set USE_OPEN_WIFI_PACKAGE. - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, null /*useOpenWifiActivityPackage*/); when(mSettingsFacade.getString(mMockContext, Settings.Global.NETWORK_SCORER_APP)) @@ -466,11 +488,10 @@ public class NetworkScorerAppManagerTest { @Test public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_activity() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, enableUseOpenWifiComponent.getPackageName()); mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); // The older network scorer app setting doesn't match the new use open wifi activity package @@ -492,18 +513,17 @@ public class NetworkScorerAppManagerTest { @Test public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_service() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, enableUseOpenWifiComponent.getPackageName()); mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); // The older network scorer app setting doesn't match the active package so the migration // shouldn't set USE_OPEN_WIFI_PACKAGE. when(mSettingsFacade.getString(mMockContext, Settings.Global.NETWORK_SCORER_APP)) - .thenReturn(recoComponent.getPackageName() + ".diff"); + .thenReturn(RECO_COMPONENT.getPackageName() + ".diff"); when(mSettingsFacade.getString(mMockContext, Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null); @@ -518,11 +538,10 @@ public class NetworkScorerAppManagerTest { @Test public void testMigrateNetworkScorerAppSettingIfNeeded_packageMatch_activity() throws Exception { - final ComponentName recoComponent = new ComponentName("package1", "class1"); final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); - setNetworkRecoPackageSetting(recoComponent.getPackageName()); - mockScoreNetworksGranted(recoComponent.getPackageName()); - mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); + mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); + mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, enableUseOpenWifiComponent.getPackageName()); mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); // Old setting matches the new activity package, migration should happen. @@ -566,6 +585,33 @@ public class NetworkScorerAppManagerTest { .thenReturn(PackageManager.PERMISSION_DENIED); } + private void mockLocationModeOn() { + mockLocationModeValue(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY); + } + + private void mockLocationModeOff() { + mockLocationModeValue(Settings.Secure.LOCATION_MODE_OFF); + } + + private void mockLocationModeValue(int returnVal) { + when(mSettingsFacade.getSecureInt(eq(mMockContext), + eq(Settings.Secure.LOCATION_MODE), anyInt())).thenReturn(returnVal); + } + + private void mockLocationPermissionGranted(int uid, String packageName) { + when(mMockPm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName)) + .thenReturn(PackageManager.PERMISSION_GRANTED); + when(mAppOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName)) + .thenReturn(AppOpsManager.MODE_ALLOWED); + } + + private void mockLocationPermissionDenied(int uid, String packageName) { + when(mMockPm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName)) + .thenReturn(PackageManager.PERMISSION_DENIED); + when(mAppOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName)) + .thenReturn(AppOpsManager.MODE_IGNORED); + } + private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid) { mockRecommendationServiceAvailable(compName, packageUid, null, false); } diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java index 856e94055ed5..91eb55ba3fcf 100644 --- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java @@ -31,10 +31,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import android.content.res.Configuration; +import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.util.DisplayMetrics; import android.util.SparseIntArray; +import android.view.MotionEvent; import java.util.Arrays; import java.util.LinkedList; @@ -237,6 +240,52 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */); } + /** + * Tests tapping on a stack in different display results in window gaining focus. + */ + @Test + public void testInputEventBringsCorrectDisplayInFocus() throws Exception { + DisplayContent dc0 = sWm.getDefaultDisplayContentLocked(); + // Create a second display + final DisplayContent dc1 = createNewDisplay(); + + // Add stack with activity. + final TaskStack stack0 = createTaskStackOnDisplay(dc0); + final Task task0 = createTaskInStack(stack0, 0 /* userId */); + final WindowTestUtils.TestAppWindowToken token = + new WindowTestUtils.TestAppWindowToken(dc0); + task0.addChild(token, 0); + dc0.mTapDetector = new TaskTapPointerEventListener(sWm, dc0); + sWm.registerPointerEventListener(dc0.mTapDetector); + final TaskStack stack1 = createTaskStackOnDisplay(dc1); + final Task task1 = createTaskInStack(stack1, 0 /* userId */); + final WindowTestUtils.TestAppWindowToken token1 = + new WindowTestUtils.TestAppWindowToken(dc0); + task1.addChild(token1, 0); + dc1.mTapDetector = new TaskTapPointerEventListener(sWm, dc0); + sWm.registerPointerEventListener(dc1.mTapDetector); + + // tap on primary display (by sending ACTION_DOWN followed by ACTION_UP) + DisplayMetrics dm0 = dc0.getDisplayMetrics(); + dc0.mTapDetector.onPointerEvent( + createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, true)); + dc0.mTapDetector.onPointerEvent( + createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, false)); + + // Check focus is on primary display. + assertEquals(sWm.mCurrentFocus, dc0.findFocusedWindow()); + + // Tap on secondary display + DisplayMetrics dm1 = dc1.getDisplayMetrics(); + dc1.mTapDetector.onPointerEvent( + createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, true)); + dc1.mTapDetector.onPointerEvent( + createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, false)); + + // Check focus is on secondary. + assertEquals(sWm.mCurrentFocus, dc1.findFocusedWindow()); + } + @Test @Ignore public void testFocusedWindowMultipleDisplays() throws Exception { @@ -355,4 +404,18 @@ public class DisplayContentTests extends WindowTestsBase { } assertTrue(actualWindows.isEmpty()); } + + private MotionEvent createTapEvent(float x, float y, boolean isDownEvent) { + final long downTime = SystemClock.uptimeMillis(); + final long eventTime = SystemClock.uptimeMillis() + 100; + final int metaState = 0; + + return MotionEvent.obtain( + downTime, + eventTime, + isDownEvent ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_UP, + x, + y, + metaState); + } } diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java index 828d405b5e3b..95adc9cd5a1a 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -18,6 +18,10 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM; + +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; + +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -39,6 +43,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.view.Display; import android.view.IWindowManager; +import android.view.InputChannel; import android.view.KeyEvent; import android.view.WindowManager; import android.view.WindowManagerPolicy; @@ -91,7 +96,14 @@ class TestWindowManagerPolicy implements WindowManagerPolicy { }).when(am).notifyKeyguardFlagsChanged(any()); } - sWm = WindowManagerService.main(context, mock(InputManagerService.class), true, false, + InputManagerService ims = mock(InputManagerService.class); + // InputChannel is final and can't be mocked. + InputChannel[] input = InputChannel.openInputChannelPair(TAG_WM); + if (input != null && input.length > 1) { + doReturn(input[1]).when(ims).monitorInput(anyString()); + } + + sWm = WindowManagerService.main(context, ims, true, false, false, new TestWindowManagerPolicy()); } return sWm; diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index 177759e6751f..db4939171aa6 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -454,10 +454,6 @@ public abstract class Conference extends Conferenceable { * @param conferenceableConnections The set of connections this connection can conference with. */ public final void setConferenceableConnections(List<Connection> conferenceableConnections) { - if (Objects.equals(mConferenceableConnections, conferenceableConnections)) { - return; - } - clearConferenceableList(); for (Connection c : conferenceableConnections) { // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 8368f423c757..a78c26106ee2 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1368,17 +1368,6 @@ public class CarrierConfigManager { "notify_international_call_on_wfc_bool"; /** - * Determine whether user edited tether APN (type dun) has effect - * {@code false} - Default. APN with dun type in telephony database has no effect. - * - * {@code true} - DUN APN added/edited in ApnEditor will be used for tethering data call. - * - * @hide - */ - public static final String KEY_EDITABLE_TETHER_APN_BOOL = - "editable_tether_apn_bool"; - - /** * An array containing custom call forwarding number prefixes that will be blocked while the * device is reporting that it is roaming. By default, there are no custom call * forwarding prefixes and none of these numbers will be filtered. If one or more entries are @@ -1771,7 +1760,6 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL, true); sDefaults.putBoolean(KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL, false); - sDefaults.putBoolean(KEY_EDITABLE_TETHER_APN_BOOL, false); sDefaults.putStringArray(KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY, null); sDefaults.putInt(KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0); diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp index a7fbc2eb0206..91ca5143965e 100644 --- a/tools/bit/main.cpp +++ b/tools/bit/main.cpp @@ -50,6 +50,7 @@ struct Target { int testPassCount; int testFailCount; + int unknownFailureCount; // unknown failure == "Process crashed", etc. bool actionsWithNoTests; Target(bool b, bool i, bool t, const string& p); @@ -63,6 +64,7 @@ Target::Target(bool b, bool i, bool t, const string& p) testActionCount(0), testPassCount(0), testFailCount(0), + unknownFailureCount(0), actionsWithNoTests(false) { } @@ -188,8 +190,13 @@ public: */ void SetCurrentAction(TestAction* action); + bool IsSuccess(); + + string GetErrorMessage(); + private: TestAction* m_currentAction; + SessionStatus m_sessionStatus; }; void @@ -241,8 +248,10 @@ TestResults::OnTestStatus(TestStatus& status) } line << ": " << m_currentAction->target->name << ':' << className << "\\#" << testName; print_one_line("%s", line.str().c_str()); - } else if (resultCode == -2) { + } else if ((resultCode == -1) || (resultCode == -2)) { // test failed + // Note -2 means an assertion failure, and -1 means other exceptions. We just treat them + // all as "failures". m_currentAction->failCount++; m_currentAction->target->testFailCount++; printf("%s\n%sFailed: %s:%s\\#%s%s\n", g_escapeClearLine, g_escapeRedBold, @@ -257,9 +266,13 @@ TestResults::OnTestStatus(TestStatus& status) } void -TestResults::OnSessionStatus(SessionStatus& /*status*/) +TestResults::OnSessionStatus(SessionStatus& status) { //status.PrintDebugString(); + m_sessionStatus = status; + if (m_currentAction && !IsSuccess()) { + m_currentAction->target->unknownFailureCount++; + } } void @@ -268,6 +281,24 @@ TestResults::SetCurrentAction(TestAction* action) m_currentAction = action; } +bool +TestResults::IsSuccess() +{ + return m_sessionStatus.result_code() == -1; // Activity.RESULT_OK. +} + +string +TestResults::GetErrorMessage() +{ + bool found; + string shortMsg = get_bundle_string(m_sessionStatus.results(), &found, "shortMsg", NULL); + if (!found) { + return IsSuccess() ? "" : "Unknown failure"; + } + return shortMsg; +} + + /** * Prints the usage statement / help text. */ @@ -568,7 +599,7 @@ check_device_property(const string& property, const string& expected) /** * Run the build, install, and test actions. */ -void +bool run_phases(vector<Target*> targets, const Options& options) { int err = 0; @@ -837,6 +868,10 @@ run_phases(vector<Target*> targets, const Options& options) printf("%s%d passed%s, %d failed\n", g_escapeGreenBold, action.passCount, g_escapeEndColor, action.failCount); } + if (!testResults.IsSuccess()) { + printf("\n%sTest didn't finish successfully: %s%s\n", g_escapeRedBold, + testResults.GetErrorMessage().c_str(), g_escapeEndColor); + } } } @@ -907,6 +942,7 @@ run_phases(vector<Target*> targets, const Options& options) } // Tests + bool hasErrors = false; if (testActions.size() > 0) { printf("%sRan tests:%s\n", g_escapeBold, g_escapeEndColor); size_t maxNameLength = 0; @@ -924,12 +960,18 @@ run_phases(vector<Target*> targets, const Options& options) Target* target = targets[i]; if (target->testActionCount > 0) { printf(" %s%s", target->name.c_str(), padding.c_str() + target->name.length()); - if (target->actionsWithNoTests) { + if (target->unknownFailureCount > 0) { + printf(" %sUnknown failure, see above message.%s\n", + g_escapeRedBold, g_escapeEndColor); + hasErrors = true; + } else if (target->actionsWithNoTests) { printf(" %s%d passed, %d failed%s\n", g_escapeYellowBold, target->testPassCount, target->testFailCount, g_escapeEndColor); + hasErrors = true; } else if (target->testFailCount > 0) { printf(" %d passed, %s%d failed%s\n", target->testPassCount, g_escapeRedBold, target->testFailCount, g_escapeEndColor); + hasErrors = true; } else { printf(" %s%d passed%s, %d failed\n", g_escapeGreenBold, target->testPassCount, g_escapeEndColor, target->testFailCount); @@ -944,6 +986,7 @@ run_phases(vector<Target*> targets, const Options& options) } printf("%s--------------------------------------------%s\n", g_escapeBold, g_escapeEndColor); + return !hasErrors; } /** @@ -991,7 +1034,7 @@ main(int argc, const char** argv) exit(0); } else { // Normal run - run_phases(options.targets, options); + exit(run_phases(options.targets, options) ? 0 : 1); } return 0; diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 4dc78627ef91..a367b2310721 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -151,8 +151,9 @@ public class WifiInfo implements Parcelable { /** * This factor is used to adjust the rate output under the new algorithm * such that the result is comparable to the previous algorithm. + * This actually converts from unit 'packets per second' to 'packets per 5 seconds'. */ - private static final long OUTPUT_SCALE_FACTOR = 5000; + private static final long OUTPUT_SCALE_FACTOR = 5; private long mLastPacketCountUpdateTimeStamp; /** @@ -198,16 +199,16 @@ public class WifiInfo implements Parcelable { double currentSampleWeight = 1.0 - lastSampleWeight; txBadRate = txBadRate * lastSampleWeight - + (txbad - txBad) * OUTPUT_SCALE_FACTOR / timeDelta + + (txbad - txBad) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta * currentSampleWeight; txSuccessRate = txSuccessRate * lastSampleWeight - + (txgood - txSuccess) * OUTPUT_SCALE_FACTOR / timeDelta + + (txgood - txSuccess) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta * currentSampleWeight; rxSuccessRate = rxSuccessRate * lastSampleWeight - + (rxgood - rxSuccess) * OUTPUT_SCALE_FACTOR / timeDelta + + (rxgood - rxSuccess) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta * currentSampleWeight; txRetriesRate = txRetriesRate * lastSampleWeight - + (txretries - txRetries) * OUTPUT_SCALE_FACTOR / timeDelta + + (txretries - txRetries) * OUTPUT_SCALE_FACTOR * 1000/ timeDelta * currentSampleWeight; } else { txBadRate = 0; @@ -448,6 +449,22 @@ public class WifiInfo implements Parcelable { } /** + * @hide + * This returns txSuccessRate in packets per second. + */ + public double getTxSuccessRatePps() { + return txSuccessRate / OUTPUT_SCALE_FACTOR; + } + + /** + * @hide + * This returns rxSuccessRate in packets per second. + */ + public double getRxSuccessRatePps() { + return rxSuccessRate / OUTPUT_SCALE_FACTOR; + } + + /** * Record the MAC address of the WLAN interface * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form * @hide |