Merge "getConnectionInfo should take calling package name as argument" into oc-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 3b868ad..e299720 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22742,6 +22742,7 @@
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 fc1b6ed..1b292cc 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24686,6 +24686,7 @@
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 f50ef55..7aeb52e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -22878,6 +22878,7 @@
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 c6d83f5..b69ef1c 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 @@
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 @@
@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 4a4bab5..43693e1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5718,6 +5718,7 @@
// 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 @@
"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 0e33934..49d58eb 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -144,15 +144,15 @@
* 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 0cfbaef..ea0ceab 100644
--- a/core/java/android/app/IWallpaperManagerCallback.aidl
+++ b/core/java/android/app/IWallpaperManagerCallback.aidl
@@ -34,6 +34,6 @@
/**
* 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 8858172..34343e9 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -204,7 +204,12 @@
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 d0791cf..2a8130f 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -408,4 +408,13 @@
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 0398b47..16d0214 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -307,13 +307,14 @@
* 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 @@
* 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 @@
}
@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 @@
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 @@
* @param listener A listener to register
*/
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
- sGlobals.addOnColorsChangedListener(listener, null);
+ addOnColorsChangedListener(listener, null);
}
/**
@@ -868,25 +871,61 @@
*/
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 @@
}
@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 @@
* @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 f987468..36f5f96 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -18,20 +18,19 @@
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 @@
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 @@
@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 @@
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 ea675fb..c3ebf55 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1406,8 +1406,9 @@
// 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 63eedf5..55343a2 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -73,8 +73,10 @@
* 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 @@
* 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 @@
* {@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 c3bbaec..a09a686 100644
--- a/core/java/android/hardware/radio/ITunerCallback.aidl
+++ b/core/java/android/hardware/radio/ITunerCallback.aidl
@@ -23,7 +23,7 @@
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 00a36c8..02ca52e 100644
--- a/core/java/android/hardware/radio/TunerCallbackAdapter.java
+++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java
@@ -49,7 +49,7 @@
synchronized (mLock) {
if (mTuner != null) throw new IllegalStateException();
mTuner = tuner;
- if (mPendingProgramInfoChanged) onProgramInfoChanged();
+ if (mPendingProgramInfoChanged) onCurrentProgramInfoChanged();
}
}
@@ -64,7 +64,7 @@
}
@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 ed223d1..d2e3510 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.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 @@
}
@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 fdb4ba0..a70c97b 100644
--- a/core/java/android/net/NetworkRecommendationProvider.java
+++ b/core/java/android/net/NetworkRecommendationProvider.java
@@ -35,6 +35,7 @@
* 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 7e0c9ce..060af0d 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -38,7 +38,8 @@
*
* <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 54d5860..cc6b5e1 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -3544,6 +3544,7 @@
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 f45efda..0df6361 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -441,6 +441,11 @@
*
* <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 10331b9..2efb0f5 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -1782,6 +1782,7 @@
* <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 712bbaa..459aeb0 100644
--- a/core/java/android/os/SharedMemory.java
+++ b/core/java/android/os/SharedMemory.java
@@ -28,6 +28,7 @@
import java.io.FileDescriptor;
import java.nio.ByteBuffer;
import java.nio.DirectByteBuffer;
+import java.nio.NioUtils;
import sun.misc.Cleaner;
@@ -191,11 +192,16 @@
}
/**
- * 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 @@
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 @@
}
/**
- * 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 53c82e6..dc9a26e 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -576,21 +576,6 @@
"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 eff52e6..fb6f637 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -30,5 +30,6 @@
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 424967f..65d66dc 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -105,6 +105,7 @@
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 @@
}
@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 @@
}
Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
mCaller.sendMessage(msg);
- } else {
- event.recycle();
+ } else {event.recycle();
}
}
@@ -1192,6 +1192,11 @@
}
}
+ 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 @@
mEngine = engine;
mActiveEngines.add(engine);
engine.attach(this);
- engine.notifyColorsChanged();
return;
}
case DO_DETACH: {
@@ -1268,6 +1272,16 @@
}
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 d773158..a507f2b 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 @@
* 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 48e5ca9..af26a88 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -193,6 +193,8 @@
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 @@
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 20ab539..c566a65 100644
--- a/core/java/android/view/InputEventReceiver.java
+++ b/core/java/android/view/InputEventReceiver.java
@@ -111,9 +111,10 @@
* 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 @@
// 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 22329f4..44c88e1 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -272,6 +272,15 @@
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 6af01f66..eea692a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9711,6 +9711,7 @@
* @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 @@
// 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 05f9da5..6bf4845 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6752,7 +6752,7 @@
}
@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 4041bcf..be763af 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1413,11 +1413,12 @@
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 4c9cf40..98f8dc8 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -347,4 +347,11 @@
* 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 668d25e..49b7ed8 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 @@
* 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 23c7842..0000000
--- 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 efc88e2..d7b0776 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 @@
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 209813a..0000000
--- 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 727412b..ef98a5e 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.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 @@
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 @@
@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 3599e64..e59cf84 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3632,7 +3632,12 @@
}
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 5375651..a96b5dd 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.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 @@
// 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 @@
// 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 @@
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 @@
}
}
}
-
- @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 31e954b..c457ab0 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -233,8 +233,9 @@
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 @@
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 @@
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 420ff2a..58ccef18 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -39,6 +39,8 @@
// 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 @@
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
deleted file mode 100644
index 06c5135..0000000
--- a/core/res/res/drawable-hdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_corp_icon.png b/core/res/res/drawable-mdpi/ic_corp_icon.png
deleted file mode 100644
index 79372b2..0000000
--- a/core/res/res/drawable-mdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_corp_icon.png b/core/res/res/drawable-xhdpi/ic_corp_icon.png
deleted file mode 100644
index 3626c7d..0000000
--- a/core/res/res/drawable-xhdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_corp_icon.png b/core/res/res/drawable-xxhdpi/ic_corp_icon.png
deleted file mode 100644
index d33319f..0000000
--- a/core/res/res/drawable-xxhdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/ic_corp_icon.png b/core/res/res/drawable-xxxhdpi/ic_corp_icon.png
deleted file mode 100644
index 359e210..0000000
--- a/core/res/res/drawable-xxxhdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
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 0000000..78cce58
--- /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 0b6028c..2d11ee6 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 78322a9..8f7fb70 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 6799bf7..4774f31 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 0000000..a6b68f1
--- /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 d62eda4..dd653c6 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 e742c0b..8f7fb70 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 23809d5..6a0d902 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 053b4f4..d57bd6a 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 2c08bf7..db586ec 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 536906c..fd78500 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 4038010..4b64e3f 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 f392ea0..e7a95c8 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 e127896..ab9912a 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 0000000..8873015
--- /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 0000000..206ff81
--- /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 0000000..36ea01d
--- /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 29447ed..2a6c22e 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.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 @@
}
@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 @@
}
};
}
-
- 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 55eeb7f..61b3876 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -241,7 +241,8 @@
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 6677178..59597af 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -2101,9 +2101,7 @@
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 7dd70d4..6664456 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -246,7 +246,7 @@
* {@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 @@
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 @@
* 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 @@
* @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 849bd01..5a16c36 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -73,6 +73,8 @@
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 @@
/**
* 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 @@
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 @@
/**
* 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 @@
/**
* 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 ece19e4..c9b096f 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -256,7 +256,13 @@
*/
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 @@
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 07cfbda..df87e0f 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -367,7 +367,7 @@
}
@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 b52906d..4df645d 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -700,6 +700,13 @@
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 71f3856..4659ae1 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -244,9 +244,11 @@
}
}
-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 @@
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 @@
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 @@
{"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 d07da93..7d4bc83 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 @@
// 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 @@
}
}
- 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 bffd6cc..33af4039 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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
}
} 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 @@
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 @@
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 @@
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 731a607..93bf3c7 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 @@
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 @@
}
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 @@
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 9645c94..24f0c7a 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.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 @@
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 96f51c1..3d0147d 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.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 @@
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 @@
// 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 @@
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 @@
* @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 @@
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 0000000..d6054c4
--- /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 0000000..282170c
--- /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 0000000..b59c664
--- /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 0000000..60d2396
--- /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 0000000..ef442e9
--- /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 0000000..97782be
--- /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 0000000..d6054c4
--- /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 0000000..573205f
--- /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 0000000..4b038b9
--- /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 0000000..562985a8
--- /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 0000000..6c7e751
--- /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 0000000..c699fe2
--- /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 0000000..5595e5c
--- /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 0000000..4614bfc
--- /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 0000000..f5cfcf9
--- /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 0000000..0b74b3a
--- /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 0000000..ba10224
--- /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 0000000..395bbf4
--- /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 0000000..0115759
--- /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 0000000..4614bfc
--- /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 0000000..6b182be
--- /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 0000000..828f7a2
--- /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 0000000..89ab580
--- /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 1feb49c..96d8484 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" >
+ android:name="handle"
+ android:translateY="-100" >
<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" />
- <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 0000000..4a2bd54
--- /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 f962594..2d4f0b5 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" >
+ android:name="handle"
+ android:translateY="-100" >
<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" />
- <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 0000000..c98f800
--- /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 1e41a31..0000000
--- 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 d67c89ac..0000000
--- 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 370f89c..e38b482 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 35602b6..1dedd5d 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 @@
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" />
+ android:width="23dp"
+ android:height="18dp"
+ android:viewportWidth="23.0"
+ android:viewportHeight="18.0">
<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" />
- <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 0000000..5009c6b
--- /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 0000000..678b90b
--- /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 0000000..6c6df60
--- /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 0000000..b1eec48
--- /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 0000000..17ff65a
--- /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 0000000..aee48dc
--- /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 0000000..66cfaff
--- /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 0000000..4a5fde9
--- /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 0000000..0f35e5d
--- /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 0000000..626f9ef
--- /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 0000000..17ff65a
--- /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 0000000..96bdb48
--- /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 0000000..a91610d
--- /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 0000000..a0118d70
--- /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 0000000..1820bab
--- /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 e5c729f..9c1cb4e 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -16,6 +16,7 @@
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.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 @@
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 40ea4ec..37e2402 100644
--- a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
+++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
@@ -119,7 +119,7 @@
| 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 e92ed2f..e4b405f 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.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 @@
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 9ba7be8..34c05a5 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.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.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 @@
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 @@
}
@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 91ca571..cbdabf5 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.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 @@
/** 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 bf1c060..566353c 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 @@
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 @@
}
}
+ /** 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 @@
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 15981e5..4583160 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 @@
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 8847452..dc626fb 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 @@
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 6733421..abc5667 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 @@
}
@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 41db927..5eefe9a 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 @@
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 @@
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 @@
}
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 @@
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 cc4c313..2cff79d 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 @@
/**
* 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 02202cf..fdfd8e8 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.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 @@
private final Context mContext;
private int mPendingAuthenticatedUserId = -1;
private boolean mPendingShowBouncer;
+ private boolean mHasScreenTurnedOnSinceAuthenticating;
public FingerprintUnlockController(Context context,
DozeScrimController dozeScrimController,
@@ -113,6 +115,7 @@
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 @@
}
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 @@
true /* allowEnterAnimation */);
} else {
Trace.beginSection("MODE_WAKE_AND_UNLOCK");
+
mDozeScrimController.abortDoze();
}
mStatusBarWindowManager.setStatusBarFocusable(false);
@@ -354,4 +359,16 @@
}
}
};
+
+ 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 49bac99..fd95cc4 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 @@
}
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 c487901..87f5ca7 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 @@
}
@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 ab021b4..e95b176 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 void showKeyguard() {
mKeyguardRequested = true;
updateIsKeyguard();
+ mAssistManager.onLockscreenShown();
}
public boolean hideKeyguard() {
@@ -4279,7 +4280,6 @@
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 252df17..acf4278 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 @@
protected final Context mContext;
private final StatusBarWindowManager mStatusBarWindowManager;
+ private final boolean mDisplayBlanksAfterDoze;
protected LockPatternUtils mLockPatternUtils;
protected ViewMediatorCallback mViewMediatorCallback;
@@ -121,6 +122,8 @@
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 @@
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 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 f4197a3..c060b08 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 @@
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 @@
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 0000000..a1cabff
--- /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 ad47411..b08b26d 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 @@
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 @@
}
}
- 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 12e9f7c..06568f7 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 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 @@
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 fdc0bba..d60df83 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.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 @@
}
};
+ 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 @@
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 42777bf..bfd4247 100644
--- a/services/core/java/com/android/server/NetworkScorerAppManager.java
+++ b/services/core/java/com/android/server/NetworkScorerAppManager.java
@@ -18,6 +18,7 @@
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 @@
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 @@
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 @@
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);
+ Log.d(TAG, "Defaulting 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);
- }
+ setNetworkRecommendationsPackage(defaultPackageName);
+ newEnabledSetting = NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON;
}
+
+ setNetworkRecommendationsEnabledSetting(newEnabledSetting);
}
/**
@@ -352,6 +371,9 @@
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 @@
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 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 7860581..bcad2fc 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 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 @@
}
} 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 @@
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- dumpActivityStarterLocked(pw);
+ dumpActivityStarterLocked(pw, dumpPackage);
pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
@@ -15284,7 +15286,7 @@
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- dumpActivityStarterLocked(pw);
+ dumpActivityStarterLocked(pw, dumpPackage);
pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
@@ -15308,7 +15310,7 @@
}
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 @@
}
}
- 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 @@
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 @@
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 ec20c04..2aa5350 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 @@
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 9925ba0..79448ca 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 @@
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 5f42cdb..e8bc68f 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 @@
final ActivityMetricsLogger mActivityMetricsLogger;
+ private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
+
@Override
protected int getChildCount() {
return mActivityDisplays.size();
@@ -954,17 +956,21 @@
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 0931587..0684f68 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 @@
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.print(prefix);
+ pw.print("mOptions=");
+ pw.println(mOptions);
}
- pw.println(prefix + "mLaunchSingleTop=" + mLaunchSingleTop
- + " mLaunchSingleInstance=" + mLaunchSingleInstance
- + " mLaunchSingleTask=" + mLaunchSingleTask
- + " mLaunchFlags=0x" + Integer.toHexString(mLaunchFlags)
- + " mDoResume=" + mDoResume + " mAddingToTask=" + mAddingToTask);
+ 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 5753fbc..be0a1d9 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 @@
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 405ee32..ceae82f 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 @@
}
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 @@
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 25f3775..331b657 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 @@
}
@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 ebd8ef0..aead98b 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 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 79e02b5..947e01c4 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 @@
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 8819aa6..6ee26d3 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 @@
* 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 e3cf459..6afd69d 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 @@
}
@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 @@
// 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 @@
|| 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 e894275..92f1c83 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.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 @@
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 88b6d87..a35383f 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.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 @@
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 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 69d8ca6..8f50a39 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.IVrManager;
import android.util.Log;
import android.view.Surface;
+import android.view.WindowManagerInternal;
import com.android.server.vr.VrManagerService;
@@ -74,6 +75,7 @@
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 @@
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 @@
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 @@
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 @@
} 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 425b23f..b6b964b 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.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 @@
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 802054e..46097ed 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.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.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 @@
}
}
- 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 @@
// 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 @@
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 @@
*/
@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 @@
// 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 @@
}
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 @@
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 @@
}
void switchUser(int userId, IRemoteCallback reply) {
+ WallpaperData systemWallpaper;
+ WallpaperData lockWallpaper;
synchronized (mLock) {
mCurrentUserId = userId;
- WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
- // 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();
+ systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
+ lockWallpaper = mLockWallpaperMap.get(userId);
+ if (lockWallpaper == null) {
+ lockWallpaper = systemWallpaper;
}
- switchWallpaper(wallpaper, reply);
+ // Not started watching yet, in case wallpaper data was loaded for other reasons.
+ if (systemWallpaper.wallpaperObserver == null) {
+ systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
+ systemWallpaper.wallpaperObserver.startWatching();
+ }
+ switchWallpaper(systemWallpaper, reply);
}
+ notifyWallpaperColorsChanged(systemWallpaper, FLAG_SYSTEM);
+ notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK);
}
void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
@@ -1634,16 +1683,30 @@
}
@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 @@
}
@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 @@
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 @@
}
}
+ 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 @@
}
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 @@
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 78f2195..805250a 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 @@
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 6b0e4c9..484987e 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 @@
}
@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 @@
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 233e75b..40528d0 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 @@
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 @@
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 @@
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 0c68e2c..c58212c 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 @@
}
@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 dd9ba73..42a2d9d 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 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 @@
}
@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 @@
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 5db691e..83926af 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_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 @@
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 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
boolean handled = false;
try {
if (mDragState == null) {
@@ -7565,6 +7568,16 @@
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 7decb11..7ec21a8 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 @@
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 23b515e..c610ca3 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.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 @@
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 f5a85c1..aa1925a 100644
--- a/services/core/jni/BroadcastRadio/Tuner.cpp
+++ b/services/core/jni/BroadcastRadio/Tuner.cpp
@@ -296,7 +296,7 @@
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 04bdddf..e01d8fa 100644
--- a/services/core/jni/BroadcastRadio/TunerCallback.cpp
+++ b/services/core/jni/BroadcastRadio/TunerCallback.cpp
@@ -58,7 +58,7 @@
jmethodID handleHwFailure;
jmethodID onError;
jmethodID onConfigurationChanged;
- jmethodID onProgramInfoChanged;
+ jmethodID onCurrentProgramInfoChanged;
jmethodID onTrafficAnnouncement;
jmethodID onEmergencyAnnouncement;
jmethodID onAntennaState;
@@ -111,7 +111,7 @@
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 @@
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 @@
}
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 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 @@
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 ceb92de..82ff0d8 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.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 @@
@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 @@
}
}), 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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
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 @@
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 @@
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 @@
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 @@
@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 @@
@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 @@
@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 @@
@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 @@
@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 @@
.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 856e940..91eb55b 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.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 @@
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 @@
}
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 828d405..95adc9c 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 @@
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.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 @@
}).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 177759e..db49391 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -454,10 +454,6 @@
* @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 8368f42..a78c261 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1368,17 +1368,6 @@
"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 @@
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 a7fbc2e..91ca514 100644
--- a/tools/bit/main.cpp
+++ b/tools/bit/main.cpp
@@ -50,6 +50,7 @@
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 @@
testActionCount(0),
testPassCount(0),
testFailCount(0),
+ unknownFailureCount(0),
actionsWithNoTests(false)
{
}
@@ -188,8 +190,13 @@
*/
void SetCurrentAction(TestAction* action);
+ bool IsSuccess();
+
+ string GetErrorMessage();
+
private:
TestAction* m_currentAction;
+ SessionStatus m_sessionStatus;
};
void
@@ -241,8 +248,10 @@
}
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 @@
}
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 @@
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 @@
/**
* Run the build, install, and test actions.
*/
-void
+bool
run_phases(vector<Target*> targets, const Options& options)
{
int err = 0;
@@ -837,6 +868,10 @@
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 @@
}
// 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 @@
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 @@
}
printf("%s--------------------------------------------%s\n", g_escapeBold, g_escapeEndColor);
+ return !hasErrors;
}
/**
@@ -991,7 +1034,7 @@
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 4dc7862..a367b23 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -151,8 +151,9 @@
/**
* 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 @@
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 @@
}
/**
+ * @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