diff options
197 files changed, 2288 insertions, 4091 deletions
diff --git a/Android.mk b/Android.mk index 4695a1970cbc..69c8c2cae858 100644 --- a/Android.mk +++ b/Android.mk @@ -71,8 +71,6 @@ LOCAL_SRC_FILES += \ core/java/android/accounts/IAccountManagerResponse.aidl \ core/java/android/accounts/IAccountAuthenticator.aidl \ core/java/android/accounts/IAccountAuthenticatorResponse.aidl \ - core/java/android/app/IActivityContainer.aidl \ - core/java/android/app/IActivityContainerCallback.aidl \ core/java/android/app/IActivityController.aidl \ core/java/android/app/IActivityManager.aidl \ core/java/android/app/IActivityPendingResult.aidl \ @@ -84,6 +82,7 @@ LOCAL_SRC_FILES += \ core/java/android/app/ITaskStackListener.aidl \ core/java/android/app/IBackupAgent.aidl \ core/java/android/app/IEphemeralResolver.aidl \ + core/java/android/app/IInputForwarder.aidl \ core/java/android/app/IInstantAppResolver.aidl \ core/java/android/app/IInstrumentationWatcher.aidl \ core/java/android/app/INotificationManager.aidl \ diff --git a/api/current.txt b/api/current.txt index 856244449b8b..7a2cecd930ab 100644 --- a/api/current.txt +++ b/api/current.txt @@ -45255,11 +45255,15 @@ package android.view { public class Surface implements android.os.Parcelable { ctor public Surface(android.graphics.SurfaceTexture); method public int describeContents(); + method public boolean isAutoRefreshEnabled(); + method public boolean isSharedBufferModeEnabled(); method public boolean isValid(); method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException; method public android.graphics.Canvas lockHardwareCanvas(); method public void readFromParcel(android.os.Parcel); method public void release(); + method public void setAutoRefreshEnabled(boolean); + method public void setSharedBufferModeEnabled(boolean); method public deprecated void unlockCanvas(android.graphics.Canvas); method public void unlockCanvasAndPost(android.graphics.Canvas); method public void writeToParcel(android.os.Parcel, int); @@ -52301,6 +52305,11 @@ package dalvik.system { method protected synchronized java.lang.Package getPackage(java.lang.String); } + public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader { + ctor public DelegateLastClassLoader(java.lang.String, java.lang.ClassLoader); + ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader); + } + public class DexClassLoader extends dalvik.system.BaseDexClassLoader { ctor public DexClassLoader(java.lang.String, java.lang.String, java.lang.String, java.lang.ClassLoader); } diff --git a/api/system-current.txt b/api/system-current.txt index d0fa033d113a..60aaa6019d06 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -48911,11 +48911,15 @@ package android.view { public class Surface implements android.os.Parcelable { ctor public Surface(android.graphics.SurfaceTexture); method public int describeContents(); + method public boolean isAutoRefreshEnabled(); + method public boolean isSharedBufferModeEnabled(); method public boolean isValid(); method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException; method public android.graphics.Canvas lockHardwareCanvas(); method public void readFromParcel(android.os.Parcel); method public void release(); + method public void setAutoRefreshEnabled(boolean); + method public void setSharedBufferModeEnabled(boolean); method public deprecated void unlockCanvas(android.graphics.Canvas); method public void unlockCanvasAndPost(android.graphics.Canvas); method public void writeToParcel(android.os.Parcel, int); @@ -56330,6 +56334,11 @@ package dalvik.system { method protected synchronized java.lang.Package getPackage(java.lang.String); } + public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader { + ctor public DelegateLastClassLoader(java.lang.String, java.lang.ClassLoader); + ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader); + } + public class DexClassLoader extends dalvik.system.BaseDexClassLoader { ctor public DexClassLoader(java.lang.String, java.lang.String, java.lang.String, java.lang.ClassLoader); } diff --git a/api/test-current.txt b/api/test-current.txt index 2c2ba307a74e..282e9d0893bd 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -45660,11 +45660,15 @@ package android.view { public class Surface implements android.os.Parcelable { ctor public Surface(android.graphics.SurfaceTexture); method public int describeContents(); + method public boolean isAutoRefreshEnabled(); + method public boolean isSharedBufferModeEnabled(); method public boolean isValid(); method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException; method public android.graphics.Canvas lockHardwareCanvas(); method public void readFromParcel(android.os.Parcel); method public void release(); + method public void setAutoRefreshEnabled(boolean); + method public void setSharedBufferModeEnabled(boolean); method public deprecated void unlockCanvas(android.graphics.Canvas); method public void unlockCanvasAndPost(android.graphics.Canvas); method public void writeToParcel(android.os.Parcel, int); @@ -52738,6 +52742,11 @@ package dalvik.system { method protected synchronized java.lang.Package getPackage(java.lang.String); } + public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader { + ctor public DelegateLastClassLoader(java.lang.String, java.lang.ClassLoader); + ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader); + } + public class DexClassLoader extends dalvik.system.BaseDexClassLoader { ctor public DexClassLoader(java.lang.String, java.lang.String, java.lang.String, java.lang.ClassLoader); } diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index f003061cec3a..ab075ee0e9f2 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -16,70 +16,25 @@ package com.android.commands.am; -import static android.app.ActivityManager.RESIZE_MODE_SYSTEM; -import static android.app.ActivityManager.RESIZE_MODE_USER; -import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; - import android.app.ActivityManager; -import android.app.ActivityManager.StackInfo; -import android.app.IActivityContainer; -import android.app.IActivityController; import android.app.IActivityManager; -import android.app.IInstrumentationWatcher; -import android.app.Instrumentation; -import android.app.IStopUserCallback; -import android.app.ProfilerInfo; -import android.app.UiAutomationConnection; -import android.app.usage.ConfigurationStats; -import android.app.usage.IUsageStatsManager; -import android.app.usage.UsageStatsManager; -import android.content.ComponentCallbacks2; -import android.content.ComponentName; -import android.content.Context; -import android.content.IIntentReceiver; -import android.content.Intent; import android.content.pm.IPackageManager; -import android.content.pm.InstrumentationInfo; -import android.content.pm.ParceledListSlice; -import android.content.pm.UserInfo; -import android.content.res.Configuration; -import android.graphics.Rect; -import android.os.Binder; -import android.os.Build; -import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SELinux; import android.os.ServiceManager; import android.os.ShellCallback; -import android.os.ShellCommand; -import android.os.SystemProperties; import android.os.UserHandle; -import android.text.TextUtils; import android.util.AndroidException; -import android.util.ArrayMap; -import android.util.Log; -import android.view.IWindowManager; import com.android.internal.os.BaseCommand; -import com.android.internal.util.HexDump; -import com.android.internal.util.Preconditions; -import java.io.BufferedReader; import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStreamReader; import java.io.PrintStream; -import java.io.PrintWriter; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; public class Am extends BaseCommand { diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 29b83dc3b315..5dd47acfb940 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -1,5 +1,5 @@ -/* - * Copyright (C) 2013 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. @@ -16,17 +16,12 @@ package android.app; -import static android.app.ActivityManager.START_CANCELED; - +import android.annotation.NonNull; import android.content.Context; -import android.content.ContextWrapper; -import android.content.IIntentSender; import android.content.Intent; -import android.content.IntentSender; -import android.graphics.SurfaceTexture; -import android.os.IBinder; -import android.os.Message; -import android.os.OperationCanceledException; +import android.hardware.display.DisplayManager; +import android.hardware.display.VirtualDisplay; +import android.hardware.input.InputManager; import android.os.RemoteException; import android.util.AttributeSet; import android.util.DisplayMetrics; @@ -35,163 +30,177 @@ import android.view.InputDevice; import android.view.InputEvent; import android.view.MotionEvent; import android.view.Surface; -import android.view.TextureView; -import android.view.TextureView.SurfaceTextureListener; -import android.view.View; +import android.view.SurfaceHolder; +import android.view.SurfaceView; import android.view.ViewGroup; import android.view.WindowManager; -import dalvik.system.CloseGuard; - -import java.lang.ref.WeakReference; -import java.util.ArrayDeque; -import java.util.concurrent.Executor; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import com.android.internal.annotations.GuardedBy; +import dalvik.system.CloseGuard; -/** @hide */ +/** + * Activity container that allows launching activities into itself and does input forwarding. + * <p>Creation of this view is only allowed to callers who have + * {@link android.Manifest.permission#INJECT_EVENTS} permission. + * <p>Activity launching into this container is restricted by the same rules that apply to launching + * on VirtualDisplays. + * @hide + */ public class ActivityView extends ViewGroup { - private static final String TAG = "ActivityView"; - private static final boolean DEBUG = false; - - private static final int MSG_SET_SURFACE = 1; - - private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); - private static final int MINIMUM_POOL_SIZE = 1; - private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; - private static final int KEEP_ALIVE = 1; - - private static final ThreadFactory sThreadFactory = new ThreadFactory() { - private final AtomicInteger mCount = new AtomicInteger(1); - - public Thread newThread(Runnable r) { - return new Thread(r, "ActivityView #" + mCount.getAndIncrement()); - } - }; - - private static final BlockingQueue<Runnable> sPoolWorkQueue = - new LinkedBlockingQueue<Runnable>(128); - /** - * An {@link Executor} that can be used to execute tasks in parallel. - */ - private static final Executor sExecutor = new ThreadPoolExecutor(MINIMUM_POOL_SIZE, - MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); - - - private static class SerialExecutor implements Executor { - private final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); - private Runnable mActive; - - public synchronized void execute(final Runnable r) { - mTasks.offer(new Runnable() { - public void run() { - try { - r.run(); - } finally { - scheduleNext(); - } - } - }); - if (mActive == null) { - scheduleNext(); - } - } - - protected synchronized void scheduleNext() { - if ((mActive = mTasks.poll()) != null) { - sExecutor.execute(mActive); - } - } - } - - private final SerialExecutor mExecutor = new SerialExecutor(); + private static final String DISPLAY_NAME = "ActivityViewVirtualDisplay"; + private static final String TAG = "ActivityView"; - private final int mDensityDpi; - private final TextureView mTextureView; + private VirtualDisplay mVirtualDisplay; + private final SurfaceView mSurfaceView; + private Surface mSurface; - @GuardedBy("mActivityContainerLock") - private ActivityContainerWrapper mActivityContainer; - private Object mActivityContainerLock = new Object(); + private final SurfaceCallback mSurfaceCallback; + private StateCallback mActivityViewCallback; - private Activity mActivity; - private int mWidth; - private int mHeight; - private Surface mSurface; - private int mLastVisibility; - private ActivityViewCallback mActivityViewCallback; + private IInputForwarder mInputForwarder; + private final CloseGuard mGuard = CloseGuard.get(); + private boolean mOpened; // Protected by mGuard. public ActivityView(Context context) { - this(context, null); + this(context, null /* attrs */); } public ActivityView(Context context, AttributeSet attrs) { - this(context, attrs, 0); + this(context, attrs, 0 /* defStyle */); } public ActivityView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - while (context instanceof ContextWrapper) { - if (context instanceof Activity) { - mActivity = (Activity)context; - break; - } - context = ((ContextWrapper)context).getBaseContext(); - } - if (mActivity == null) { - throw new IllegalStateException("The ActivityView's Context is not an Activity."); - } + mSurfaceView = new SurfaceView(context); + mSurfaceCallback = new SurfaceCallback(); + mSurfaceView.getHolder().addCallback(mSurfaceCallback); + addView(mSurfaceView); - try { - mActivityContainer = new ActivityContainerWrapper( - ActivityManager.getService().createVirtualActivityContainer( - mActivity.getActivityToken(), new ActivityContainerCallback(this))); - } catch (RemoteException e) { - throw new RuntimeException("ActivityView: Unable to create ActivityContainer. " - + e); - } + mOpened = true; + mGuard.open("release"); + } - mTextureView = new TextureView(context); - mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener()); - addView(mTextureView); + /** Callback that notifies when the container is ready or destroyed. */ + public abstract static class StateCallback { + /** + * Called when the container is ready for launching activities. Calling + * {@link #startActivity(Intent)} prior to this callback will result in an + * {@link IllegalStateException}. + * + * @see #startActivity(Intent) + */ + public abstract void onActivityViewReady(ActivityView view); + /** + * Called when the container can no longer launch activities. Calling + * {@link #startActivity(Intent)} after this callback will result in an + * {@link IllegalStateException}. + * + * @see #startActivity(Intent) + */ + public abstract void onActivityViewDestroyed(ActivityView view); + } - WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE); - DisplayMetrics metrics = new DisplayMetrics(); - wm.getDefaultDisplay().getMetrics(metrics); - mDensityDpi = metrics.densityDpi; + /** + * Set the callback to be notified about state changes. + * <p>This class must finish initializing before {@link #startActivity(Intent)} can be called. + * <p>Note: If the instance was ready prior to this call being made, then + * {@link StateCallback#onActivityViewReady(ActivityView)} will be called from within + * this method call. + * + * @param callback The callback to report events to. + * + * @see StateCallback + * @see #startActivity(Intent) + */ + public void setCallback(StateCallback callback) { + mActivityViewCallback = callback; - mLastVisibility = getVisibility(); + if (mVirtualDisplay != null && mActivityViewCallback != null) { + mActivityViewCallback.onActivityViewReady(this); + } + } - if (DEBUG) Log.v(TAG, "ctor()"); + /** + * Launch a new activity into this container. + * <p>Activity resolved by the provided {@link Intent} must have + * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be + * launched here. Also, if activity is not owned by the owner of this container, it must allow + * embedding and the caller must have permission to embed. + * <p>Note: This class must finish initializing and + * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before + * this method can be called. + * + * @param intent Intent used to launch an activity. + * + * @see StateCallback + * @see #startActivity(PendingIntent) + */ + public void startActivity(@NonNull Intent intent) { + final ActivityOptions options = prepareActivityOptions(); + getContext().startActivity(intent, options.toBundle()); } - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - mTextureView.layout(0, 0, r - l, b - t); + /** + * Launch a new activity into this container. + * <p>Activity resolved by the provided {@link PendingIntent} must have + * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be + * launched here. Also, if activity is not owned by the owner of this container, it must allow + * embedding and the caller must have permission to embed. + * <p>Note: This class must finish initializing and + * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before + * this method can be called. + * + * @param pendingIntent Intent used to launch an activity. + * + * @see StateCallback + * @see #startActivity(Intent) + */ + public void startActivity(@NonNull PendingIntent pendingIntent) { + final ActivityOptions options = prepareActivityOptions(); + try { + pendingIntent.send(null /* context */, 0 /* code */, null /* intent */, + null /* onFinished */, null /* handler */, null /* requiredPermission */, + options.toBundle()); + } catch (PendingIntent.CanceledException e) { + throw new RuntimeException(e); + } } - @Override - protected void onVisibilityChanged(View changedView, final int visibility) { - super.onVisibilityChanged(changedView, visibility); + /** + * Check if container is ready to launch and create {@link ActivityOptions} to target the + * virtual display. + */ + private ActivityOptions prepareActivityOptions() { + if (mVirtualDisplay == null) { + throw new IllegalStateException( + "Trying to start activity before ActivityView is ready."); + } + final ActivityOptions options = ActivityOptions.makeBasic(); + options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId()); + return options; + } - if (mSurface != null && (visibility == View.GONE || mLastVisibility == View.GONE)) { - if (DEBUG) Log.v(TAG, "visibility changed; enqueing runnable"); - final Surface surface = (visibility == View.GONE) ? null : mSurface; - setSurfaceAsync(surface, mWidth, mHeight, mDensityDpi, false); + /** + * Release this container. Activity launching will no longer be permitted. + * <p>Note: Calling this method is allowed after + * {@link StateCallback#onActivityViewReady(ActivityView)} callback was triggered and before + * {@link StateCallback#onActivityViewDestroyed(ActivityView)}. + * + * @see StateCallback + */ + public void release() { + if (mVirtualDisplay == null) { + throw new IllegalStateException( + "Trying to release container that is not initialized."); } - mLastVisibility = visibility; + performRelease(); } - private boolean injectInputEvent(InputEvent event) { - return mActivityContainer != null && mActivityContainer.injectEvent(event); + @Override + public void onLayout(boolean changed, int l, int t, int r, int b) { + mSurfaceView.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */); } @Override @@ -209,309 +218,118 @@ public class ActivityView extends ViewGroup { return super.onGenericMotionEvent(event); } - @Override - public void onAttachedToWindow() { - if (DEBUG) Log.v(TAG, "onAttachedToWindow(): mActivityContainer=" + mActivityContainer + - " mSurface=" + mSurface); - } - - @Override - public void onDetachedFromWindow() { - if (DEBUG) Log.v(TAG, "onDetachedFromWindow(): mActivityContainer=" + mActivityContainer + - " mSurface=" + mSurface); - } - - public boolean isAttachedToDisplay() { - return mSurface != null; - } - - public void startActivity(Intent intent) { - if (mActivityContainer == null) { - throw new IllegalStateException("Attempt to call startActivity after release"); - } - if (mSurface == null) { - throw new IllegalStateException("Surface not yet created."); - } - if (DEBUG) Log.v(TAG, "startActivity(): intent=" + intent + " " + - (isAttachedToDisplay() ? "" : "not") + " attached"); - if (mActivityContainer.startActivity(intent) == START_CANCELED) { - throw new OperationCanceledException(); - } - } - - public void startActivity(IntentSender intentSender) { - if (mActivityContainer == null) { - throw new IllegalStateException("Attempt to call startActivity after release"); - } - if (mSurface == null) { - throw new IllegalStateException("Surface not yet created."); - } - if (DEBUG) Log.v(TAG, "startActivityIntentSender(): intentSender=" + intentSender + " " + - (isAttachedToDisplay() ? "" : "not") + " attached"); - final IIntentSender iIntentSender = intentSender.getTarget(); - if (mActivityContainer.startActivityIntentSender(iIntentSender) == START_CANCELED) { - throw new OperationCanceledException(); - } - } - - public void startActivity(PendingIntent pendingIntent) { - if (mActivityContainer == null) { - throw new IllegalStateException("Attempt to call startActivity after release"); - } - if (mSurface == null) { - throw new IllegalStateException("Surface not yet created."); - } - if (DEBUG) Log.v(TAG, "startActivityPendingIntent(): PendingIntent=" + pendingIntent + " " - + (isAttachedToDisplay() ? "" : "not") + " attached"); - final IIntentSender iIntentSender = pendingIntent.getTarget(); - if (mActivityContainer.startActivityIntentSender(iIntentSender) == START_CANCELED) { - throw new OperationCanceledException(); - } - } - - public void release() { - if (DEBUG) Log.v(TAG, "release() mActivityContainer=" + mActivityContainer + - " mSurface=" + mSurface); - if (mActivityContainer == null) { - Log.e(TAG, "Duplicate call to release"); - return; - } - synchronized (mActivityContainerLock) { - mActivityContainer.release(); - mActivityContainer = null; - } - - if (mSurface != null) { - mSurface.release(); - mSurface = null; - } - - mTextureView.setSurfaceTextureListener(null); - } - - private void setSurfaceAsync(final Surface surface, final int width, final int height, - final int densityDpi, final boolean callback) { - mExecutor.execute(new Runnable() { - public void run() { - try { - synchronized (mActivityContainerLock) { - if (mActivityContainer != null) { - mActivityContainer.setSurface(surface, width, height, densityDpi); - } - } - } catch (RemoteException e) { - throw new RuntimeException( - "ActivityView: Unable to set surface of ActivityContainer. ", - e); - } - if (callback) { - post(new Runnable() { - @Override - public void run() { - if (mActivityViewCallback != null) { - if (surface != null) { - mActivityViewCallback.onSurfaceAvailable(ActivityView.this); - } else { - mActivityViewCallback.onSurfaceDestroyed(ActivityView.this); - } - } - } - }); - } + private boolean injectInputEvent(InputEvent event) { + if (mInputForwarder != null) { + try { + return mInputForwarder.forwardEvent(event); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); } - }); - } - - /** - * Set the callback to use to report certain state changes. - * - * Note: If the surface has been created prior to this call being made, then - * ActivityViewCallback.onSurfaceAvailable will be called from within setCallback. - * - * @param callback The callback to report events to. - * - * @see ActivityViewCallback - */ - public void setCallback(ActivityViewCallback callback) { - mActivityViewCallback = callback; - - if (mSurface != null) { - mActivityViewCallback.onSurfaceAvailable(this); } + return false; } - public static abstract class ActivityViewCallback { - /** - * Called when all activities in the ActivityView have completed and been removed. Register - * using {@link ActivityView#setCallback(ActivityViewCallback)}. Each ActivityView may - * have at most one callback registered. - */ - public abstract void onAllActivitiesComplete(ActivityView view); - /** - * Called when the surface is ready to be drawn to. Calling startActivity prior to this - * callback will result in an IllegalStateException. - */ - public abstract void onSurfaceAvailable(ActivityView view); - /** - * Called when the surface has been removed. Calling startActivity after this callback - * will result in an IllegalStateException. - */ - public abstract void onSurfaceDestroyed(ActivityView view); - } - - private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener { + private class SurfaceCallback implements SurfaceHolder.Callback { @Override - public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, - int height) { - if (mActivityContainer == null) { - return; + public void surfaceCreated(SurfaceHolder surfaceHolder) { + if (mVirtualDisplay == null) { + mSurface = mSurfaceView.getHolder().getSurface(); + initVirtualDisplay(); + if (mVirtualDisplay != null && mActivityViewCallback != null) { + mActivityViewCallback.onActivityViewReady(ActivityView.this); + } + } else { + mVirtualDisplay.setSurface(surfaceHolder.getSurface()); } - if (DEBUG) Log.d(TAG, "onSurfaceTextureAvailable: width=" + width + " height=" - + height); - mWidth = width; - mHeight = height; - mSurface = new Surface(surfaceTexture); - setSurfaceAsync(mSurface, mWidth, mHeight, mDensityDpi, true); } @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, - int height) { - if (mActivityContainer == null) { - return; + public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { + if (mVirtualDisplay != null) { + mVirtualDisplay.resize(width, height, getBaseDisplayDensity()); } - if (DEBUG) Log.d(TAG, "onSurfaceTextureSizeChanged: w=" + width + " h=" + height); } @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { - if (mActivityContainer == null) { - return true; - } - if (DEBUG) Log.d(TAG, "onSurfaceTextureDestroyed"); + public void surfaceDestroyed(SurfaceHolder surfaceHolder) { mSurface.release(); mSurface = null; - setSurfaceAsync(null, mWidth, mHeight, mDensityDpi, true); - return true; - } - - @Override - public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { -// Log.d(TAG, "onSurfaceTextureUpdated"); + if (mVirtualDisplay != null) { + mVirtualDisplay.setSurface(null); + } } - } - private static class ActivityContainerCallback extends IActivityContainerCallback.Stub { - private final WeakReference<ActivityView> mActivityViewWeakReference; - - ActivityContainerCallback(ActivityView activityView) { - mActivityViewWeakReference = new WeakReference<>(activityView); + private void initVirtualDisplay() { + if (mVirtualDisplay != null) { + throw new IllegalStateException("Trying to initialize for the second time."); } - @Override - public void setVisible(IBinder container, boolean visible) { - if (DEBUG) Log.v(TAG, "setVisible(): container=" + container + " visible=" + visible + - " ActivityView=" + mActivityViewWeakReference.get()); + final int width = mSurfaceView.getWidth(); + final int height = mSurfaceView.getHeight(); + final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); + mVirtualDisplay = displayManager.createVirtualDisplay( + DISPLAY_NAME + "@" + System.identityHashCode(this), + width, height, getBaseDisplayDensity(), mSurface, 0 /* flags */); + if (mVirtualDisplay == null) { + Log.e(TAG, "Failed to initialize ActivityView"); + return; } - @Override - public void onAllActivitiesComplete(IBinder container) { - final ActivityView activityView = mActivityViewWeakReference.get(); - if (activityView != null) { - final ActivityViewCallback callback = activityView.mActivityViewCallback; - if (callback != null) { - final WeakReference<ActivityViewCallback> callbackRef = - new WeakReference<>(callback); - activityView.post(new Runnable() { - @Override - public void run() { - ActivityViewCallback callback = callbackRef.get(); - if (callback != null) { - callback.onAllActivitiesComplete(activityView); - } - } - }); - } - } - } + mInputForwarder = InputManager.getInstance().createInputForwarder( + mVirtualDisplay.getDisplay().getDisplayId()); } - private static class ActivityContainerWrapper { - private final IActivityContainer mIActivityContainer; - private final CloseGuard mGuard = CloseGuard.get(); - boolean mOpened; // Protected by mGuard. - - ActivityContainerWrapper(IActivityContainer container) { - mIActivityContainer = container; - mOpened = true; - mGuard.open("release"); + private void performRelease() { + if (!mOpened) { + return; } - void setSurface(Surface surface, int width, int height, int density) - throws RemoteException { - mIActivityContainer.setSurface(surface, width, height, density); - } + mSurfaceView.getHolder().removeCallback(mSurfaceCallback); - int startActivity(Intent intent) { - try { - return mIActivityContainer.startActivity(intent); - } catch (RemoteException e) { - throw new RuntimeException("ActivityView: Unable to startActivity. " + e); - } + if (mInputForwarder != null) { + mInputForwarder = null; } - int startActivityIntentSender(IIntentSender intentSender) { - try { - return mIActivityContainer.startActivityIntentSender(intentSender); - } catch (RemoteException e) { - throw new RuntimeException( - "ActivityView: Unable to startActivity from IntentSender. " + e); - } + final boolean displayReleased; + if (mVirtualDisplay != null) { + mVirtualDisplay.release(); + mVirtualDisplay = null; + displayReleased = true; + } else { + displayReleased = false; } - int getDisplayId() { - try { - return mIActivityContainer.getDisplayId(); - } catch (RemoteException e) { - return -1; - } + if (mSurface != null) { + mSurface.release(); + mSurface = null; } - boolean injectEvent(InputEvent event) { - try { - return mIActivityContainer.injectEvent(event); - } catch (RemoteException e) { - return false; - } + if (displayReleased && mActivityViewCallback != null) { + mActivityViewCallback.onActivityViewDestroyed(this); } - void release() { - synchronized (mGuard) { - if (mOpened) { - if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: release called"); - try { - mIActivityContainer.release(); - mGuard.close(); - } catch (RemoteException e) { - } - mOpened = false; - } - } - } + mGuard.close(); + mOpened = false; + } - @Override - protected void finalize() throws Throwable { - if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: finalize called"); - try { - if (mGuard != null) { - mGuard.warnIfOpen(); - release(); - } - } finally { - super.finalize(); + /** Get density of the hosting display. */ + private int getBaseDisplayDensity() { + final WindowManager wm = mContext.getSystemService(WindowManager.class); + final DisplayMetrics metrics = new DisplayMetrics(); + wm.getDefaultDisplay().getMetrics(metrics); + return metrics.densityDpi; + } + + @Override + protected void finalize() throws Throwable { + try { + if (mGuard != null) { + mGuard.warnIfOpen(); + performRelease(); } + } finally { + super.finalize(); } - } } diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl deleted file mode 100644 index 1ff3c87bef6e..000000000000 --- a/core/java/android/app/IActivityContainer.aidl +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2013, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app; - -import android.app.IActivityContainerCallback; -import android.content.Intent; -import android.content.IIntentSender; -import android.os.IBinder; -import android.view.InputEvent; -import android.view.Surface; - -/** @hide */ -interface IActivityContainer { - void addToDisplay(int displayId); - void setSurface(in Surface surface, int width, int height, int density); - int startActivity(in Intent intent); - int startActivityIntentSender(in IIntentSender intentSender); - int getDisplayId(); - int getStackId(); - boolean injectEvent(in InputEvent event); - void release(); -} diff --git a/core/java/android/app/IActivityContainerCallback.aidl b/core/java/android/app/IActivityContainerCallback.aidl deleted file mode 100644 index 99d0a6f8189e..000000000000 --- a/core/java/android/app/IActivityContainerCallback.aidl +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2013, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app; - -import android.os.IBinder; - -/** @hide */ -interface IActivityContainerCallback { - oneway void setVisible(IBinder container, boolean visible); - oneway void onAllActivitiesComplete(IBinder container); -} diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index df1a412d464e..fa9d7ca8ebc5 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -20,8 +20,6 @@ import android.app.ActivityManager; import android.app.ApplicationErrorReport; import android.app.ContentProviderHolder; import android.app.IApplicationThread; -import android.app.IActivityContainer; -import android.app.IActivityContainerCallback; import android.app.IActivityController; import android.app.IAppTask; import android.app.IInstrumentationWatcher; @@ -355,8 +353,6 @@ interface IActivityManager { void killUid(int appId, int userId, in String reason); void setUserIsMonkey(boolean monkey); void hang(in IBinder who, boolean allowRestart); - IActivityContainer createVirtualActivityContainer(in IBinder parentActivityToken, - in IActivityContainerCallback callback); void moveTaskToStack(int taskId, int stackId, boolean toTop); /** * Resizes the input stack id to the given bounds. @@ -436,7 +432,7 @@ interface IActivityManager { // Start of M transactions void notifyCleartextNetwork(int uid, in byte[] firstPacket); - IActivityContainer createStackOnDisplay(int displayId); + int createStackOnDisplay(int displayId); int getFocusedStackId(); void setTaskResizeable(int taskId, int resizeableMode); boolean requestAssistContextExtras(int requestType, in IResultReceiver receiver, diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/strings.xml b/core/java/android/app/IInputForwarder.aidl index acc3d16610ec..d6be63eb54e5 100644 --- a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/strings.xml +++ b/core/java/android/app/IInputForwarder.aidl @@ -1,5 +1,3 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- /** * Copyright (c) 2017, The Android Open Source Project * @@ -15,10 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ ---> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="sysui_overlay_light">Light</string> +package android.app; -</resources> +import android.view.InputEvent; +/** + * Forwards input events into owned activity container, used in {@link android.app.ActivityView}. + * To forward input to other apps {@link android.Manifest.permission.INJECT_EVENTS} permission is + * required. + * @hide + */ +interface IInputForwarder { + boolean forwardEvent(in InputEvent event); +}
\ No newline at end of file diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 63a2cf002aa8..2d8249acb5bf 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -126,8 +126,8 @@ public abstract class Context { * File creation mode: allow all other applications to have read access to * the created file. * <p> - * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this - * mode will throw a {@link SecurityException}. + * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this + * mode throws a {@link SecurityException}. * * @deprecated Creating world-readable files is very dangerous, and likely * to cause security holes in applications. It is strongly @@ -146,7 +146,7 @@ public abstract class Context { * File creation mode: allow all other applications to have write access to * the created file. * <p> - * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this + * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this * mode will throw a {@link SecurityException}. * * @deprecated Creating world-writable files is very dangerous, and likely @@ -1129,13 +1129,47 @@ public abstract class Context { * </ul> * <p> * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions - * are required to read or write to the returned path; it's always - * accessible to the calling app. This only applies to paths generated for - * package name of the calling application. To access paths belonging to - * other packages, - * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or - * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required. + * are required to read or write to the path that this method returns. + * However, starting from {@link android.os.Build.VERSION_CODES#M}, + * to read the OBB expansion files, you must declare the + * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission in the app manifest and ask for + * permission at runtime as follows: + * </p> + * <p> + * {@code <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" + * android:maxSdkVersion="23" />} + * </p> * <p> + * Starting from {@link android.os.Build.VERSION_CODES#N}, + * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} + * permission is not required, so don’t ask for this + * permission at runtime. To handle both cases, your app must first try to read the OBB file, + * and if it fails, you must request + * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission at runtime. + * </p> + * + * <p> + * The following code snippet shows how to do this: + * </p> + * + * <pre> + * File obb = new File(obb_filename); + * boolean open_failed = false; + * + * try { + * BufferedReader br = new BufferedReader(new FileReader(obb)); + * open_failed = false; + * ReadObbFile(br); + * } catch (IOException e) { + * open_failed = true; + * } + * + * if (open_failed) { + * // request READ_EXTERNAL_STORAGE permission before reading OBB file + * ReadObbFileWithPermission(); + * } + * </pre> + * * On devices with multiple users (as described by {@link UserManager}), * multiple users may share the same OBB storage location. Applications * should ensure that multiple instances running under different users don't diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java index 663e6e476c5a..abf9cc91dbda 100644 --- a/core/java/android/content/SyncStatusInfo.java +++ b/core/java/android/content/SyncStatusInfo.java @@ -26,7 +26,7 @@ import java.util.ArrayList; public class SyncStatusInfo implements Parcelable { private static final String TAG = "Sync"; - static final int VERSION = 3; + static final int VERSION = 4; private static final int MAX_EVENT_COUNT = 10; @@ -102,6 +102,7 @@ public class SyncStatusInfo implements Parcelable { parcel.writeLong(mLastEventTimes.get(i)); parcel.writeString(mLastEvents.get(i)); } + parcel.writeInt(numSourcePeriodic); } public SyncStatusInfo(Parcel parcel) { @@ -146,6 +147,16 @@ public class SyncStatusInfo implements Parcelable { } } } + if (version < 4) { + // Before version 4, numSourcePeriodic wasn't persisted. + numSourcePeriodic = numSyncs - numSourceLocal - numSourcePoll - numSourceServer + - numSourceUser; + if (numSourcePeriodic < 0) { // Sanity check. + numSourcePeriodic = 0; + } + } else { + numSourcePeriodic = parcel.readInt(); + } } public SyncStatusInfo(SyncStatusInfo other) { diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index 45863167fa1b..9e0c680cafa1 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -16,6 +16,7 @@ package android.hardware.input; +import android.app.IInputForwarder; import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.KeyboardLayout; import android.hardware.input.IInputDevicesChangedListener; @@ -88,4 +89,7 @@ interface IInputManager { void setCustomPointerIcon(in PointerIcon icon); void requestPointerCapture(IBinder windowToken, boolean enabled); + + /** Create input forwarder to deliver touch events to owned display. */ + IInputForwarder createInputForwarder(int displayId); } diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index 4898c1a0802f..c531a899f45d 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -19,8 +19,9 @@ package android.hardware.input; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SdkConstant; -import android.annotation.SystemService; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemService; +import android.app.IInputForwarder; import android.content.Context; import android.media.AudioAttributes; import android.os.Binder; @@ -971,6 +972,25 @@ public final class InputManager { } } + + /** + * Create an {@link IInputForwarder} targeted to provided display. + * {@link android.Manifest.permission.INJECT_EVENTS} permission is required to call this method. + * + * @param displayId Id of the target display where input events should be forwarded. + * Display must exist and must be owned by the caller. + * @return The forwarder instance. + * + * @hide + */ + public IInputForwarder createInputForwarder(int displayId) { + try { + return mIm.createInputForwarder(displayId); + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + private void populateInputDevicesLocked() { if (mInputDevicesChangedListener == null) { final InputDevicesChangedListener listener = new InputDevicesChangedListener(); diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 0e26ca215993..54d5860048ad 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -207,7 +207,7 @@ public abstract class BatteryStats implements Parcelable { * New in version 22: * - BLE scan result background count, BLE unoptimized scan time */ - static final String CHECKIN_VERSION = "23"; + static final String CHECKIN_VERSION = "24"; /** * Old version, we hit 9 and ran out of room, need to remove. diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index f5597b8eac8e..53c82e6c5237 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -10132,22 +10132,6 @@ public final class Settings { public static final String DEVICE_DEMO_MODE = "device_demo_mode"; /** - * Retail mode specific settings. This is encoded as a key=value list, separated by commas. - * Ex: "user_inactivity_timeout_ms=30000,warning_dialog_timeout_ms=10000". The following - * keys are supported: - * - * <pre> - * user_inactivity_timeout_ms (long) - * warning_dialog_timeout_ms (long) - * </pre> - * <p> - * Type: string - * - * @hide - */ - public static final String RETAIL_DEMO_MODE_CONSTANTS = "retail_demo_mode_constants"; - - /** * Indicates the maximum time that an app is blocked for the network rules to get updated. * * Type: long diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index b22501823020..6ba11b9954c4 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -85,7 +85,7 @@ public class ZenModeConfig implements Parcelable { private static final boolean DEFAULT_ALLOW_SCREEN_ON = true; private static final int XML_VERSION = 2; - private static final String ZEN_TAG = "zen"; + public static final String ZEN_TAG = "zen"; private static final String ZEN_ATT_VERSION = "version"; private static final String ZEN_ATT_USER = "user"; private static final String ALLOW_TAG = "allow"; diff --git a/core/java/android/service/vr/IVrListener.aidl b/core/java/android/service/vr/IVrListener.aidl index afb13d316503..acca3fa66ae4 100644 --- a/core/java/android/service/vr/IVrListener.aidl +++ b/core/java/android/service/vr/IVrListener.aidl @@ -20,5 +20,5 @@ import android.content.ComponentName; /** @hide */ oneway interface IVrListener { - void focusedActivityChanged(in ComponentName component); + void focusedActivityChanged(in ComponentName component, boolean running2dInVr, int pid); } diff --git a/core/java/android/service/vr/VrListenerService.java b/core/java/android/service/vr/VrListenerService.java index 5da4560f688d..fa3d065d28a7 100644 --- a/core/java/android/service/vr/VrListenerService.java +++ b/core/java/android/service/vr/VrListenerService.java @@ -70,8 +70,10 @@ public abstract class VrListenerService extends Service { private final IVrListener.Stub mBinder = new IVrListener.Stub() { @Override - public void focusedActivityChanged(ComponentName component) { - mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, component).sendToTarget(); + public void focusedActivityChanged( + ComponentName component, boolean running2dInVr, int pid) { + mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, running2dInVr ? 1 : 0, + pid, component).sendToTarget(); } }; @@ -84,7 +86,8 @@ public abstract class VrListenerService extends Service { public void handleMessage(Message msg) { switch (msg.what) { case MSG_ON_CURRENT_VR_ACTIVITY_CHANGED: { - VrListenerService.this.onCurrentVrActivityChanged((ComponentName) msg.obj); + VrListenerService.this.onCurrentVrActivityChanged( + (ComponentName) msg.obj, msg.arg1 == 1, msg.arg2); } break; } } @@ -120,6 +123,29 @@ public abstract class VrListenerService extends Service { } /** + * An extended version of onCurrentVrActivityChanged + * + * <p>This will be called when this service is initially bound, but is not + * guaranteed to be called before onUnbind. In general, this is intended to be used to + * determine when user focus has transitioned between two VR activities, or between a + * VR activity and a 2D activity. This should be overridden instead of the above + * onCurrentVrActivityChanged as that version is deprecated.</p> + * + * @param component the {@link ComponentName} of the VR activity or the 2D intent. + * @param running2dInVr true if the component is a 2D component. + * @param pid the process the component is running in. + * + * @see android.app.Activity#setVrModeEnabled + * @see android.R.attr#enableVrMode + * @hide + */ + public void onCurrentVrActivityChanged( + ComponentName component, boolean running2dInVr, int pid) { + // Override to implement. Default to old behaviour of sending null for 2D. + onCurrentVrActivityChanged(running2dInVr ? null : component); + } + + /** * Checks if the given component is enabled in user settings. * * <p>If this component is not enabled in the user's settings, it will not be started when diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 1b702326cc28..ecfc0b6cb00b 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -73,10 +73,12 @@ public class Surface implements Parcelable { private static native long nativeGetNextFrameNumber(long nativeObject); private static native int nativeSetScalingMode(long nativeObject, int scalingMode); - private static native void nativeSetBuffersTransform(long nativeObject, long transform); private static native int nativeForceScopedDisconnect(long nativeObject); private static native int nativeAttachAndQueueBuffer(long nativeObject, GraphicBuffer buffer); + private static native int nativeSetSharedBufferModeEnabled(long nativeObject, boolean enabled); + private static native int nativeSetAutoRefreshEnabled(long nativeObject, boolean enabled); + public static final Parcelable.Creator<Surface> CREATOR = new Parcelable.Creator<Surface>() { @Override @@ -114,6 +116,8 @@ public class Surface implements Parcelable { private HwuiContext mHwuiContext; private boolean mIsSingleBuffered; + private boolean mIsSharedBufferModeEnabled; + private boolean mIsAutoRefreshEnabled; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -630,6 +634,97 @@ public class Surface implements Parcelable { } /** + * <p>The shared buffer mode allows both the application and the surface compositor + * (SurfaceFlinger) to concurrently access this surface's buffer. While the + * application is still required to issue a present request + * (see {@link #unlockCanvasAndPost(Canvas)}) to the compositor when an update is required, + * the compositor may trigger an update at any time. Since the surface's buffer is shared + * between the application and the compositor, updates triggered by the compositor may + * cause visible tearing.</p> + * + * <p>The shared buffer mode can be used with + * {@link #setAutoRefreshEnabled(boolean) auto-refresh} to avoid the overhead of + * issuing present requests.</p> + * + * <p>If the application uses the shared buffer mode to reduce latency, it is + * recommended to use software rendering (see {@link #lockCanvas(Rect)} to ensure + * the graphics workloads are not affected by other applications and/or the system + * using the GPU. When using software rendering, the application should update the + * smallest possible region of the surface required.</p> + * + * <p class="note">The shared buffer mode might not be supported by the underlying + * hardware. Enabling shared buffer mode on hardware that does not support it will + * not yield an error but the application will not benefit from lower latency (and + * tearing will not be visible).</p> + * + * <p class="note">Depending on how many and what kind of surfaces are visible, the + * surface compositor may need to copy the shared buffer before it is displayed. When + * this happens, the latency benefits of shared buffer mode will be reduced.</p> + * + * @param enabled True to enable the shared buffer mode on this surface, false otherwise + * + * @see #isSharedBufferModeEnabled() + * @see #setAutoRefreshEnabled(boolean) + */ + public void setSharedBufferModeEnabled(boolean enabled) { + if (mIsSharedBufferModeEnabled != enabled) { + int error = nativeSetSharedBufferModeEnabled(mNativeObject, enabled); + if (error != 0) { + throw new RuntimeException( + "Failed to set shared buffer mode on Surface (bad object?)"); + } else { + mIsSharedBufferModeEnabled = enabled; + } + } + } + + /** + * @return True if shared buffer mode is enabled on this surface, false otherwise + * + * @see #setSharedBufferModeEnabled(boolean) + */ + public boolean isSharedBufferModeEnabled() { + return mIsSharedBufferModeEnabled; + } + + /** + * <p>When auto-refresh is enabled, the surface compositor (SurfaceFlinger) + * automatically updates the display on a regular refresh cycle. The application + * can continue to issue present requests but it is not required. Enabling + * auto-refresh may result in visible tearing.</p> + * + * <p>Auto-refresh has no effect if the {@link #setSharedBufferModeEnabled(boolean) + * shared buffer mode} is not enabled.</p> + * + * <p>Because auto-refresh will trigger continuous updates of the display, it is + * recommended to turn it on only when necessary. For example, in a drawing/painting + * application auto-refresh should be enabled on finger/pen down and disabled on + * finger/pen up.</p> + * + * @param enabled True to enable auto-refresh on this surface, false otherwise + * + * @see #isAutoRefreshEnabled() + * @see #setSharedBufferModeEnabled(boolean) + */ + public void setAutoRefreshEnabled(boolean enabled) { + if (mIsAutoRefreshEnabled != enabled) { + int error = nativeSetAutoRefreshEnabled(mNativeObject, enabled); + if (error != 0) { + throw new RuntimeException("Failed to set auto refresh on Surface (bad object?)"); + } else { + mIsAutoRefreshEnabled = enabled; + } + } + } + + /** + * @return True if auto-refresh is enabled on this surface, false otherwise + */ + public boolean isAutoRefreshEnabled() { + return mIsAutoRefreshEnabled; + } + + /** * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or * when a SurfaceTexture could not successfully be allocated. */ @@ -656,13 +751,13 @@ public class Surface implements Parcelable { return "ROTATION_0"; } case Surface.ROTATION_90: { - return "ROATATION_90"; + return "ROTATION_90"; } case Surface.ROTATION_180: { - return "ROATATION_180"; + return "ROTATION_180"; } case Surface.ROTATION_270: { - return "ROATATION_270"; + return "ROTATION_270"; } default: { throw new IllegalArgumentException("Invalid rotation: " + rotation); diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java index 68cf5cd74431..477285e63f37 100644 --- a/core/java/com/android/internal/colorextraction/ColorExtractor.java +++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java @@ -29,7 +29,9 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.colorextraction.types.ExtractionType; import com.android.internal.colorextraction.types.Tonal; +import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Iterator; /** * Class to process wallpaper colors and generate a tonal palette based on them. @@ -44,7 +46,7 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener private static final String TAG = "ColorExtractor"; private final SparseArray<GradientColors[]> mGradientColors; - private final ArrayList<OnColorsChangedListener> mOnColorsChangedListeners; + private final ArrayList<WeakReference<OnColorsChangedListener>> mOnColorsChangedListeners; private final Context mContext; private final ExtractionType mExtractionType; private WallpaperColors mSystemColors; @@ -167,8 +169,17 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener } protected void triggerColorsChanged(int which) { - for (OnColorsChangedListener listener: mOnColorsChangedListeners) { - listener.onColorsChanged(this, which); + ArrayList<WeakReference<OnColorsChangedListener>> references = + new ArrayList<>(mOnColorsChangedListeners); + final int size = references.size(); + for (int i = 0; i < size; i++) { + final WeakReference<OnColorsChangedListener> weakReference = references.get(i); + final OnColorsChangedListener listener = weakReference.get(); + if (listener == null) { + mOnColorsChangedListeners.remove(weakReference); + } else { + listener.onColorsChanged(this, which); + } } } @@ -187,11 +198,20 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener } public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) { - mOnColorsChangedListeners.add(listener); + mOnColorsChangedListeners.add(new WeakReference<>(listener)); } public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener listener) { - mOnColorsChangedListeners.remove(listener); + ArrayList<WeakReference<OnColorsChangedListener>> references = + new ArrayList<>(mOnColorsChangedListeners); + final int size = references.size(); + for (int i = 0; i < size; i++) { + final WeakReference<OnColorsChangedListener> weakReference = references.get(i); + if (weakReference.get() == listener) { + mOnColorsChangedListeners.remove(weakReference); + break; + } + } } public static class GradientColors { diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 5129cf5c1ef3..cad1b7c51a54 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -6616,9 +6616,12 @@ public class BatteryStatsImpl extends BatteryStats { * inactive so can be dropped. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public boolean reset() { + public boolean reset(long uptime, long realtime) { boolean active = false; + mOnBatteryBackgroundTimeBase.init(uptime, realtime); + mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime); + if (mWifiRunningTimer != null) { active |= !mWifiRunningTimer.reset(false); active |= mWifiRunning; @@ -6806,11 +6809,6 @@ public class BatteryStatsImpl extends BatteryStats { mLastStepUserTime = mLastStepSystemTime = 0; mCurStepUserTime = mCurStepSystemTime = 0; - mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000, - mBsi.mClocks.uptimeMillis() * 1000); - mOnBatteryScreenOffBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000, - mBsi.mClocks.uptimeMillis() * 1000); - if (!active) { if (mWifiRunningTimer != null) { mWifiRunningTimer.detach(); @@ -9463,7 +9461,7 @@ public class BatteryStatsImpl extends BatteryStats { mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0; for (int i=0; i<mUidStats.size(); i++) { - if (mUidStats.valueAt(i).reset()) { + if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) { mUidStats.remove(mUidStats.keyAt(i)); i--; } diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 215a00e7384c..3ad4da6b6580 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -537,6 +537,20 @@ static jint nativeAttachAndQueueBuffer(JNIEnv *env, jclass clazz, jlong nativeOb return err; } +static jint nativeSetSharedBufferModeEnabled(JNIEnv* env, jclass clazz, jlong nativeObject, + jboolean enabled) { + Surface* surface = reinterpret_cast<Surface*>(nativeObject); + return ((ANativeWindow*) nativeObject)->perform(surface, + NATIVE_WINDOW_SET_SHARED_BUFFER_MODE, enabled); +} + +static jint nativeSetAutoRefreshEnabled(JNIEnv* env, jclass clazz, jlong nativeObject, + jboolean enabled) { + Surface* surface = reinterpret_cast<Surface*>(nativeObject); + return ((ANativeWindow*) nativeObject)->perform(surface, + NATIVE_WINDOW_SET_AUTO_REFRESH, enabled); +} + namespace uirenderer { using namespace android::uirenderer::renderthread; @@ -618,6 +632,8 @@ static const JNINativeMethod gSurfaceMethods[] = { {"nativeSetScalingMode", "(JI)I", (void*)nativeSetScalingMode }, {"nativeForceScopedDisconnect", "(J)I", (void*)nativeForceScopedDisconnect}, {"nativeAttachAndQueueBuffer", "(JLandroid/graphics/GraphicBuffer;)I", (void*)nativeAttachAndQueueBuffer}, + {"nativeSetSharedBufferModeEnabled", "(JZ)I", (void*)nativeSetSharedBufferModeEnabled}, + {"nativeSetAutoRefreshEnabled", "(JZ)I", (void*)nativeSetAutoRefreshEnabled}, // HWUI context {"nHwuiCreate", "(JJ)J", (void*) hwui::create }, diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto index e212c432558c..fa645f4d4c6a 100644 --- a/core/proto/android/providers/settings.proto +++ b/core/proto/android/providers/settings.proto @@ -315,7 +315,6 @@ message GlobalSettingsProto { SettingProto boot_count = 270; SettingProto safe_boot_disallowed = 271; SettingProto device_demo_mode = 272; - SettingProto retail_demo_mode_constants = 273; SettingProto database_downgrade_reason = 274; SettingProto contacts_database_wal_enabled = 275; SettingProto multi_sim_voice_call_subscription = 276; diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index a35d61d544bd..5f894afbd61a 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Titelloos>"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 9f67ea29c20d..de6ad70b4102 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"ኪባ"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<ርዕስ አልባ>"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index cc277561dec6..cad9ceb3fef4 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"بايت"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"كيلوبايت"</string> - <string name="megabyteShort" msgid="6355851576770428922">"ميغابايت"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"غيغابايت"</string> - <string name="terabyteShort" msgid="231613018159186962">"تيرابايت"</string> <string name="petabyteShort" msgid="5637816680144990219">"بيتابايت"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<بلا عنوان>"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index dad5802ec0c6..ae042bfba99a 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"Başlıqsız"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 5f1ca49c6105..69038190aa68 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Bez naslova>"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 7ec47510e490..5be57f6ce594 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"б"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string> - <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string> - <string name="terabyteShort" msgid="231613018159186962">"Тб"</string> <string name="petabyteShort" msgid="5637816680144990219">"Пб"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Без назвы>"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index e61e49c981db..6303961bf40e 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"Б"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string> - <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string> - <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string> <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Без заглавие>"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 939a45ca4b7a..4a4d938b1217 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"বাইট"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<শিরোনামহীন>"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 1c1ec2565254..83e07dd4f389 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Bez naslova>"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 0dbae8b3973c..5ca03baef05a 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Sense títol>"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index a3072dcf603f..adf37f2466ee 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Bez názvu>"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 22d4c3af1df5..c2ddb43f52d8 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"b"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"Mb"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"Tb"</string> <string name="petabyteShort" msgid="5637816680144990219">"Pb"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Uden titel>"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index b22322430af4..23df4b305308 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Unbenannt>"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 88440cb1dfbf..15091c5378d4 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Χωρίς τίτλο>"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 9b5528c32e1f..f3e01e2d3206 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Untitled>"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 9b5528c32e1f..f3e01e2d3206 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Untitled>"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 9b5528c32e1f..f3e01e2d3206 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Untitled>"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 5bf170bc4bbc..49b1837c5e1a 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Sin título>"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 6c5e7e566398..28aaff0b0cf5 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Sin título>"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index b4d4cff5c4c4..5f7802fc9cae 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Pealkirjata>"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index b5234a8e3154..e72b12b09b85 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Izengabea>"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 9aeae4aff957..57e4317b5883 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"بایت"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"کیلوبایت"</string> - <string name="megabyteShort" msgid="6355851576770428922">"مگابایت"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"گیگابایت"</string> - <string name="terabyteShort" msgid="231613018159186962">"ترابایت"</string> <string name="petabyteShort" msgid="5637816680144990219">"پتابایت"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<بدون عنوان>"</string> @@ -233,7 +229,7 @@ <string name="global_action_assist" msgid="3892832961594295030">"دستیار"</string> <string name="global_action_voice_assist" msgid="7751191495200504480">"دستیار صوتی"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"اکنون قفل شود"</string> - <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"بیشتر از 999"</string> + <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"۹۹۹+"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"محتواها پنهان هستند"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"محتوا بر اساس خطمشی پنهان شده است"</string> <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"صفحهکلید مجازی"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 44c5efa6c50b..4d1a8ef3b87c 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"t"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kt"</string> - <string name="megabyteShort" msgid="6355851576770428922">"Mt"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"Gt"</string> - <string name="terabyteShort" msgid="231613018159186962">"Tt"</string> <string name="petabyteShort" msgid="5637816680144990219">"Pt"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Nimetön>"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index c6881825bfe1..c31240d6143c 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"o"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"ko"</string> - <string name="megabyteShort" msgid="6355851576770428922">"Mo"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"Go"</string> - <string name="terabyteShort" msgid="231613018159186962">"To"</string> <string name="petabyteShort" msgid="5637816680144990219">"Po"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Sans_titre>"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index a5c9b0f9c4fb..67962751125c 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"octet(s)"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"Ko"</string> - <string name="megabyteShort" msgid="6355851576770428922">"Mo"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"Go"</string> - <string name="terabyteShort" msgid="231613018159186962">"To"</string> <string name="petabyteShort" msgid="5637816680144990219">"Po"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Sans nom>"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 8db169b0276e..fe39fc604286 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Sen título>"</string> @@ -459,7 +455,7 @@ <string name="permlab_nfc" msgid="4423351274757876953">"controlar Near Field Communication"</string> <string name="permdesc_nfc" msgid="7120611819401789907">"Permite á aplicación comunicarse con etiquetas, tarxetas e lectores Near Field Communication (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivar o bloqueo da pantalla"</string> - <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite á aplicación desactivar o bloqueo do teclado e calquera seguridade dos contrasinais asociada. Por exemplo, o teléfono desactiva o bloqueo do teclado ao recibir unha chamada telefónica entrante e, a continuación, volve activar o bloqueo do teclado unha vez finalizada a chamada."</string> + <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite á aplicación desactivar o bloqueo do teclado e calquera seguranza dos contrasinais asociada. Por exemplo, o teléfono desactiva o bloqueo do teclado ao recibir unha chamada telefónica entrante e, a continuación, volve activar o bloqueo do teclado unha vez finalizada a chamada."</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"xestionar hardware de impresión dixital"</string> <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Permite que a aplicación invoque métodos para engadir e eliminar modelos de uso de impresión dixital."</string> <string name="permlab_useFingerprint" msgid="3150478619915124905">"usar hardware de impresión dixital"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 8745c647816c..abc8da093346 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<અનામાંકિત>"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index bffede48084f..cc86ecbc82a4 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<शीर्षक-रहित>"</string> @@ -516,10 +512,10 @@ <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"ऐप्स को नेटवर्क नीतियां प्रबंधित करने और ऐप्स-विशिष्ट नियमों को परिभाषित करने देता है."</string> <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"नेटवर्क उपयोग हिसाब बदलें"</string> <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"ऐप्स को यह संशोधित करने देता है कि ऐप्स की तुलना में नेटवर्क उपयोग का मूल्यांकन कैसे किया जाता है. सामान्य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string> - <string name="permlab_accessNotifications" msgid="7673416487873432268">"नोटिफिकेशन तक पहुंचें"</string> - <string name="permdesc_accessNotifications" msgid="458457742683431387">"ऐप्स को नोटिफिकेशन को प्राप्त करने, जांच करने, और साफ़ करने देता है, जिनमें अन्य ऐप्स के द्वारा पोस्ट की गई सूचनाएं भी शामिल हैं."</string> - <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"नोटिफिकेशन श्रवणकर्ता सेवा से जुड़ें"</string> - <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"धारक को नोटिफिकेशन श्रवणकर्ता सेवा के शीर्ष स्तरीय इंटरफ़ेस से जुड़ने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string> + <string name="permlab_accessNotifications" msgid="7673416487873432268">"नोटिफ़िकेशन तक पहुंचें"</string> + <string name="permdesc_accessNotifications" msgid="458457742683431387">"ऐप्स को नोटिफ़िकेशन को प्राप्त करने, जांच करने, और साफ़ करने देता है, जिनमें अन्य ऐप्स के द्वारा पोस्ट की गई सूचनाएं भी शामिल हैं."</string> + <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"नोटिफ़िकेशन श्रवणकर्ता सेवा से जुड़ें"</string> + <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"धारक को नोटिफ़िकेशन श्रवणकर्ता सेवा के शीर्ष स्तरीय इंटरफ़ेस से जुड़ने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string> <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"किसी स्थिति प्रदाता सेवा से आबद्ध हों"</string> <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"धारक को किसी स्थिति प्रदाता सेवा के शीर्ष-स्तर के इंटरफ़ेस से आबद्ध होने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string> <string name="permlab_bindDreamService" msgid="4153646965978563462">"भावी सेवा से आबद्ध करें"</string> @@ -1072,13 +1068,13 @@ <string name="volume_call" msgid="3941680041282788711">"कॉल के दौरान वॉल्यूम"</string> <string name="volume_bluetooth_call" msgid="2002891926351151534">"ब्लूटूथ कॉल के दौरान वॉल्यूम"</string> <string name="volume_alarm" msgid="1985191616042689100">"अलार्म वॉल्यूम"</string> - <string name="volume_notification" msgid="2422265656744276715">"नोटिफिकेशन वॉल्यूम"</string> + <string name="volume_notification" msgid="2422265656744276715">"नोटिफ़िकेशन वॉल्यूम"</string> <string name="volume_unknown" msgid="1400219669770445902">"आवाज़"</string> <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"ब्लूटूथ वॉल्यूम"</string> <string name="volume_icon_description_ringer" msgid="3326003847006162496">"रिंगटोन वॉल्यूम"</string> <string name="volume_icon_description_incall" msgid="8890073218154543397">"कॉल वॉल्यूम"</string> <string name="volume_icon_description_media" msgid="4217311719665194215">"मीडिया वॉल्यूम"</string> - <string name="volume_icon_description_notification" msgid="7044986546477282274">"नोटिफिकेशन वॉल्यूम"</string> + <string name="volume_icon_description_notification" msgid="7044986546477282274">"नोटिफ़िकेशन वॉल्यूम"</string> <string name="ringtone_default" msgid="3789758980357696936">"डिफ़ॉल्ट रिंगटोन"</string> <string name="ringtone_default_with_actual" msgid="1767304850491060581">"डिफ़ॉल्ट (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> <string name="ringtone_silent" msgid="7937634392408977062">"कोई नहीं"</string> @@ -1277,7 +1273,7 @@ <string name="accessibility_binding_label" msgid="4148120742096474641">"सरल उपयोग"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"वॉलपेपर"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"वॉलपेपर बदलें"</string> - <string name="notification_listener_binding_label" msgid="2014162835481906429">"नोटिफिकेशन श्रवणकर्ता"</string> + <string name="notification_listener_binding_label" msgid="2014162835481906429">"नोटिफ़िकेशन श्रवणकर्ता"</string> <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR श्रोता"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"स्थिति प्रदाता"</string> <string name="notification_ranker_binding_label" msgid="774540592299064747">"नोटिफ़िकेशन रैंकर सेवा"</string> @@ -1691,7 +1687,7 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item> </plurals> <string name="default_notification_channel_label" msgid="5929663562028088222">"अवर्गीकृत"</string> - <string name="importance_from_user" msgid="7318955817386549931">"आपने इन नोटिफिकेशन का महत्व सेट किया है."</string> + <string name="importance_from_user" msgid="7318955817386549931">"आपने इन नोटिफ़िकेशन का महत्व सेट किया है."</string> <string name="importance_from_person" msgid="9160133597262938296">"यह मौजूद व्यक्तियों के कारण महत्वपूर्ण है."</string> <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के द्वारा एक नया उपयोगकर्ता बनाने दें?"</string> <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के द्वारा एक नया उपयोगकर्ता बनाने दें (इस खाते वाला एक उपयोगकर्ता पहले से मौजूद है) ?"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 094af8d8110a..89c5d03afc16 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Bez naslova>"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 29a79e54c890..c7a498c232be 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Névtelen>"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 7cf7507e9100..b47cded04fe9 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"Բ"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"կԲ"</string> - <string name="megabyteShort" msgid="6355851576770428922">"ՄԲ"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"ԳԲ"</string> - <string name="terabyteShort" msgid="231613018159186962">"ՏԲ"</string> <string name="petabyteShort" msgid="5637816680144990219">"Պբ"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Անանուն>"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 81fe2471a59e..ed04809d2629 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Tanpa judul>"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 2ce334e187d9..5ba15a31bdc0 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Ónefnt>"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 29ebdd8b4f3b..8272d11ea009 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Senza nome>"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 426442c0734c..06ee4ac753f0 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">">ללא כותרת<"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 0dcc4e013a1c..1206432ab158 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<新規>"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 0ff01ab2100f..e4e8d30f10cf 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"ბაიტი"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"კბაიტი"</string> - <string name="megabyteShort" msgid="6355851576770428922">"მბაიტი"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"გბაიტი"</string> - <string name="terabyteShort" msgid="231613018159186962">"ტბაიტი"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"უსათაურო"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 08e1e912391b..a56f246a671e 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"Б"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MБ"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string> - <string name="terabyteShort" msgid="231613018159186962">"TБ"</string> <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Атаусыз>"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index f841721562d4..ef88958abf22 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"មេកាបៃ"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"ជីកាបៃ"</string> - <string name="terabyteShort" msgid="231613018159186962">"តេរ៉ាបៃ"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<គ្មានចំណងជើង>"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 7527362f7aad..76af3638d156 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<ಶೀರ್ಷಿಕೆ ರಹಿತ>"</string> @@ -1094,7 +1090,7 @@ <item quantity="one">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item> <item quantity="other">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item> </plurals> - <string name="wifi_available_title" msgid="3817100557900599505">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಪಡಿಸಿ"</string> + <string name="wifi_available_title" msgid="3817100557900599505">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸಿ"</string> <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗುತ್ತಿದೆ"</string> <string name="wifi_available_title_connected" msgid="7542672851522241548">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string> <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string> @@ -1419,7 +1415,7 @@ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೊ"</string> <string name="wireless_display_route_description" msgid="9070346425023979651">"ವಯರ್ಲೆಸ್ ಪ್ರದರ್ಶನ"</string> <string name="media_route_button_content_description" msgid="591703006349356016">"ಪಾತ್ರ"</string> - <string name="media_route_chooser_title" msgid="1751618554539087622">"ಸಾಧನಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಿ"</string> + <string name="media_route_chooser_title" msgid="1751618554539087622">"ಸಾಧನಕ್ಕೆ ಸಂಪರ್ಕಿಸಿ"</string> <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ಸಾಧನಕ್ಕೆ ಬಿತ್ತರಿಸುವ ಪರದೆ"</string> <string name="media_route_chooser_searching" msgid="4776236202610828706">"ಸಾಧನಗಳನ್ನು ಹುಡುಕಲಾಗುತ್ತಿದೆ…"</string> <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index bab45194f54f..f1b7a01ce2d8 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<제목 없음>"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 284253760f97..9daaf88ddfa9 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"Б"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"Кб"</string> - <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"Гб"</string> - <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string> <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Баш аты жок>"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 52d5b0b4b8cf..a65b319be20c 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<ບໍ່ມີຊື່>"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index a31dcc7e831e..befddc4f6817 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Be pavadinimo>"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 8cc3d909cb62..8970f5a84e4e 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Bez nosaukuma>"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index efac04215fe9..43235219f09c 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"Б"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string> - <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string> - <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string> <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Без наслов>"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 4f8d39dd6c3f..3ba18fead433 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<ശീർഷകമില്ലാത്ത>"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 65b6b5b0a869..409e2247f9d9 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"килобайт"</string> - <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string> - <string name="terabyteShort" msgid="231613018159186962">"TБ"</string> <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Гарчиггүй>"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index ea3705fae574..afd547703096 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<अशीर्षकांकित>"</string> @@ -191,7 +187,7 @@ <string name="silent_mode_vibrate" msgid="7072043388581551395">"रिंगर कंपन"</string> <string name="silent_mode_ring" msgid="8592241816194074353">"रिंगर चालू"</string> <string name="reboot_to_update_title" msgid="6212636802536823850">"Android सिस्टीम अद्यतन"</string> - <string name="reboot_to_update_prepare" msgid="6305853831955310890">"अद्यतनित करण्यासाठी तयार करीत आहे…"</string> + <string name="reboot_to_update_prepare" msgid="6305853831955310890">"अपडेट करण्याची तयारी करत आहे…"</string> <string name="reboot_to_update_package" msgid="3871302324500927291">"अद्यतन पॅकेजची प्रक्रिया करीत आहे…"</string> <string name="reboot_to_update_reboot" msgid="6428441000951565185">"रीस्टार्ट करीत आहे..."</string> <string name="reboot_to_reset_title" msgid="4142355915340627490">"फॅक्टरी डेटा रीसेट"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index f322d4ee581b..c2804566a4ca 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B."</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Tidak bertajuk>"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 7234cd955f32..2f3a0d5a3238 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<ခေါင်းစဉ်မဲ့>"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index dabe298900b2..4eca1657e892 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Uten navn>"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 44f17bcb3b23..4d8dfc661562 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"के.बि."</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<बिना शीर्षक>"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 3c1f06775fbf..3e78d71d5b83 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">" KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Naamloos>"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 64d267ee8e27..3f55342f8cff 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<ਬਿਨਾਂ ਸਿਰਲੇਖ>"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 1747f2759d6d..cf786e5dbf13 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Bez nazwy>"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 05af3261c9ea..22f8a3e5629c 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Sem título>"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 04a78cab1a17..068723bc3af2 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Sem nome>"</string> @@ -51,7 +47,7 @@ <string name="needPuk2" msgid="4526033371987193070">"Introduza o PUK2 para desbloquear o cartão SIM."</string> <string name="enablePin" msgid="209412020907207950">"Ação sem êxito. Ative o bloqueio do SIM/RUIM."</string> <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582"> - <item quantity="one">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item> + <item quantity="one">Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativa antes de o cartão SIM ficar bloqueado.</item> <item quantity="other">Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar bloqueado.</item> </plurals> <string name="imei" msgid="2625429890869005782">"IMEI"</string> @@ -164,7 +160,7 @@ <string name="low_memory" product="tv" msgid="516619861191025923">"O armazenamento da TV está cheio. Elimine alguns ficheiros para libertar espaço."</string> <string name="low_memory" product="default" msgid="3475999286680000541">"O armazenamento do telemóvel está cheio. Elimine alguns ficheiros para libertar espaço."</string> <plurals name="ssl_ca_cert_warning" formatted="false" msgid="5106721205300213569"> - <item quantity="one">Certificate authorities installed</item> + <item quantity="one">Autoridade de certificação instalada</item> <item quantity="other">Autoridades de certificação instaladas</item> </plurals> <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Por um terceiro desconhecido"</string> @@ -220,7 +216,7 @@ <string name="bugreport_option_full_title" msgid="6354382025840076439">"Relatório completo"</string> <string name="bugreport_option_full_summary" msgid="7210859858969115745">"Utilize esta opção para uma interferência mínima do sistema quando o dispositivo não responder ou estiver demasiado lento, ou quando precisar de todas as secções de relatório. Não permite introduzir mais detalhes ou tirar capturas de ecrã adicionais."</string> <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368"> - <item quantity="one">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item> + <item quantity="one">A tirar uma captura de ecrã do relatório de erro dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundo…</item> <item quantity="other">A tirar uma captura de ecrã do relatório de erro dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item> </plurals> <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string> @@ -856,7 +852,7 @@ <string name="oneMonthDurationPast" msgid="7396384508953779925">"Há 1 mês"</string> <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Há mais de 1 mês"</string> <plurals name="last_num_days" formatted="false" msgid="5104533550723932025"> - <item quantity="one">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item> + <item quantity="one">Últimos <xliff:g id="COUNT_1">%d</xliff:g> dia</item> <item quantity="other">Últimos <xliff:g id="COUNT_1">%d</xliff:g> dias</item> </plurals> <string name="last_month" msgid="3959346739979055432">"Último mês"</string> @@ -878,67 +874,67 @@ <string name="years" msgid="6881577717993213522">"anos"</string> <string name="now_string_shortest" msgid="8912796667087856402">"agora"</string> <plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495"> - <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>m</item> - <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>m</item> + <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> m</item> + <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item> </plurals> <plurals name="duration_hours_shortest" formatted="false" msgid="3552182110578602356"> - <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>h</item> - <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>h</item> + <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> h</item> + <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item> </plurals> <plurals name="duration_days_shortest" formatted="false" msgid="5213655532597081640"> - <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>d</item> - <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>d</item> + <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> d</item> + <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> d</item> </plurals> <plurals name="duration_years_shortest" formatted="false" msgid="7848711145196397042"> - <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>y</item> - <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>a</item> + <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> a</item> + <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item> </plurals> <plurals name="duration_minutes_shortest_future" formatted="false" msgid="3277614521231489951"> - <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>m</item> - <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>m</item> + <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> min</item> + <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> min</item> </plurals> <plurals name="duration_hours_shortest_future" formatted="false" msgid="2152452368397489370"> - <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>h</item> - <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>h</item> + <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> h</item> + <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> h</item> </plurals> <plurals name="duration_days_shortest_future" formatted="false" msgid="8088331502820295701"> - <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>d</item> - <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>d</item> + <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> d</item> + <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> d</item> </plurals> <plurals name="duration_years_shortest_future" formatted="false" msgid="2317006667145250301"> - <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>y</item> - <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>a</item> + <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> a</item> + <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> a</item> </plurals> <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192"> - <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item> + <item quantity="one">há <xliff:g id="COUNT_1">%d</xliff:g> minuto</item> <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> minutos</item> </plurals> <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411"> - <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item> + <item quantity="one">há <xliff:g id="COUNT_1">%d</xliff:g> hora</item> <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> horas</item> </plurals> <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130"> - <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item> + <item quantity="one">há <xliff:g id="COUNT_1">%d</xliff:g> dia</item> <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> dias</item> </plurals> <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734"> - <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item> + <item quantity="one">há <xliff:g id="COUNT_1">%d</xliff:g> ano</item> <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> anos</item> </plurals> <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966"> - <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item> + <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> minuto</item> <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> minutos</item> </plurals> <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891"> - <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item> + <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> hora</item> <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> horas</item> </plurals> <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992"> - <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> days</item> + <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> dia</item> <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> dias</item> </plurals> <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011"> - <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> years</item> + <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> ano</item> <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> anos</item> </plurals> <string name="VideoView_error_title" msgid="3534509135438353077">"Problema com o vídeo"</string> @@ -1087,11 +1083,11 @@ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notificação"</string> <string name="ringtone_unknown" msgid="3914515995813061520">"Desconhecido"</string> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> - <item quantity="one">Wi-Fi networks available</item> + <item quantity="one">Rede Wi-Fi disponível</item> <item quantity="other">Redes Wi-Fi disponíveis</item> </plurals> <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606"> - <item quantity="one">Open Wi-Fi networks available</item> + <item quantity="one">Rede Wi-Fi aberta disponível</item> <item quantity="other">Redes Wi-Fi abertas disponíveis</item> </plurals> <string name="wifi_available_title" msgid="3817100557900599505">"Ligar à rede Wi-Fi aberta"</string> @@ -1304,7 +1300,7 @@ <string name="no_matches" msgid="8129421908915840737">"Sem correspondências"</string> <string name="find_on_page" msgid="1946799233822820384">"Localizar na página"</string> <plurals name="matches_found" formatted="false" msgid="1210884353962081884"> - <item quantity="one"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item> + <item quantity="one"><xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g></item> <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g></item> </plurals> <string name="action_mode_done" msgid="7217581640461922289">"Concluído"</string> @@ -1590,7 +1586,7 @@ <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Os PINs não correspondem. Tente novamente."</string> <string name="restr_pin_error_too_short" msgid="8173982756265777792">"O PIN é demasiado pequeno. Deve ter, no mínimo, 4 dígitos."</string> <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688"> - <item quantity="one">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item> + <item quantity="one">Tente novamente dentro de <xliff:g id="COUNT">%d</xliff:g> segundo</item> <item quantity="other">Tente novamente dentro de <xliff:g id="COUNT">%d</xliff:g> segundos</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string> @@ -1623,35 +1619,35 @@ <string name="data_saver_enable_title" msgid="4674073932722787417">"Ativar a Poupança de dados?"</string> <string name="data_saver_enable_button" msgid="7147735965247211818">"Ativar"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> - <item quantity="one">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> - <item quantity="other">Durante %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="one">Durante %1$d minuto (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="other">Durante %1$d minutos (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> </plurals> <plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="6830154222366042597"> - <item quantity="one">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> - <item quantity="other">Durante %1$d min (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="one">Durante %1$d min (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="other">Durante %1$d min (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> </plurals> <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862"> - <item quantity="one">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> - <item quantity="other">Durante %1$d horas (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="one">Durante %1$d hora (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="other">Durante %1$d horas (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> </plurals> <plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="4787552595253082371"> - <item quantity="one">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> - <item quantity="other">Durante %1$d h (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="one">Durante %1$d h (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="other">Durante %1$d h (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> </plurals> <plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571"> - <item quantity="one">For %d minutes</item> + <item quantity="one">Durante %d minuto</item> <item quantity="other">Durante %d minutos</item> </plurals> <plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2199350154433426128"> - <item quantity="one">For %d min</item> + <item quantity="one">Durante %d min</item> <item quantity="other">Durante %d min</item> </plurals> <plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854"> - <item quantity="one">For %d hours</item> + <item quantity="one">Durante %d hora</item> <item quantity="other">Durante %d horas</item> </plurals> <plurals name="zen_mode_duration_hours_short" formatted="false" msgid="6748277774662434217"> - <item quantity="one">For %d hr</item> + <item quantity="one">Durante %d h</item> <item quantity="other">Durante %d h</item> </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> @@ -1687,7 +1683,7 @@ <string name="close_button_text" msgid="3937902162644062866">"Fechar"</string> <string name="notification_messaging_title_template" msgid="3452480118762691020">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string> <plurals name="selected_count" formatted="false" msgid="7187339492915744615"> - <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> </plurals> <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem categoria"</string> @@ -1751,7 +1747,7 @@ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Não é possível preencher automaticamente o conteúdo"</string> <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Sem sugestões do preenchimento automático"</string> <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274"> - <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item> + <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> sugestão do preenchimento automático</item> <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> sugestões do preenchimento automático</item> </plurals> <string name="autofill_save_title" msgid="3345527308992082601">"Pretende guardar no <b><xliff:g id="LABEL">%1$s</xliff:g></b>?"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 05af3261c9ea..22f8a3e5629c 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Sem título>"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 795b71be31f4..84e1c968f8f6 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TO"</string> <string name="petabyteShort" msgid="5637816680144990219">"PO"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Fără titlu>"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index d22022d88b4d..b441503994b2 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"Б"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string> - <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string> - <string name="terabyteShort" msgid="231613018159186962">"TБ"</string> <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Без названия>"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 0292f82bf37c..bc1e43333c79 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<නම් යොදා නැත>"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 4c22ae7ea01d..f93a9bf4f5ad 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Bez mena>"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index ac24366aadc1..4d3c3b2acf63 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Brez naslova>"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index c31c8a4b9d88..a677d71e8844 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"terabajt"</string> <string name="petabyteShort" msgid="5637816680144990219">"petabajt"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Pa titull>"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 02dddb882bd7..319f0001eb7f 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Без наслова>"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index b1a13511ecd7..808681c3e90e 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Okänd>"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 2eb17206205d..afac1d3bcd0c 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Haina jina>"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 714602ffe568..06406c62635f 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"பை."</string> - <string name="kilobyteShort" msgid="7542884022844556968">"கி.பை."</string> - <string name="megabyteShort" msgid="6355851576770428922">"மெ.பை."</string> - <string name="gigabyteShort" msgid="3259882455212193214">"ஜி.பை."</string> - <string name="terabyteShort" msgid="231613018159186962">"டெ.பை."</string> <string name="petabyteShort" msgid="5637816680144990219">"பெ.பை."</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<பெயரிடப்படாதது>"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 92fba6ea1f5a..2a6c5b72050d 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<శీర్షిక లేనిది>"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 3c33686d1a85..87a00b2b34ab 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<ไม่มีชื่อ>"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 2976911b3a73..866292f22d49 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Walang pamagat>"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 48c714b64658..58a69e55160c 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Adsız>"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 715a019d85d7..9399176cf25a 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"б"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"Кб"</string> - <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"Гб"</string> - <string name="terabyteShort" msgid="231613018159186962">"Тб"</string> <string name="petabyteShort" msgid="5637816680144990219">"Пб"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Без назви>"</string> @@ -1015,7 +1011,7 @@ <string name="browse" msgid="6993590095938149861">"Веб-переглядач"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Закінчується пам’ять"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Деякі системні функції можуть не працювати"</string> - <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостатньо місця для системи. Переконайтесь, що на пристрої є 250 Мб вільного місця, і повторіть спробу."</string> + <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостатньо місця для системи. Переконайтесь, що на пристрої є 250 МБ вільного місця, і повторіть спробу."</string> <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> працює"</string> <string name="app_running_notification_text" msgid="1197581823314971177">"Торкніться, щоб дізнатися більше або зупинити додаток."</string> <string name="ok" msgid="5970060430562524910">"OK"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index ca753697142e..33f74daa443c 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"بائٹس"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">">بلا عنوان<"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index e26289386e2e..07f41fc94137 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Nomsiz>"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 73a65b727e6d..661ff16040d2 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Không có tiêu đề>"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index dc0395adf6dd..40ab9e449e9b 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<未命名>"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 57798ee01ad6..8644877153f4 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<未命名>"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 39564ea543fc..9b1d9523464e 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"位元組"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<未命名>"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 85180965d084..d144ad7e7d20 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -21,10 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string> - <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> - <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> - <string name="terabyteShort" msgid="231613018159186962">"TB"</string> <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="4638956954852782576">"<Akunasihloko>"</string> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 8c26db43fc41..65c52792226b 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4538,22 +4538,10 @@ <!-- The representation of a time duration when negative. An example is -1:14. This can be used with a countdown timer for example.--> <string name="negative_duration">\u2212<xliff:g id="time" example="1:14">%1$s</xliff:g></string> - <!-- Title of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] --> - <string name="reset_retail_demo_mode_title">Reset device?</string> - <!-- Text of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] --> - <string name="reset_retail_demo_mode_text">Tap to reset device</string> <!-- Text of dialog shown when starting a demo user for the first time [CHAR LIMIT=40] --> <string name="demo_starting_message">Starting demo\u2026</string> <!-- Text of dialog shown when starting a new demo user in retail demo mode [CHAR LIMIT=40] --> <string name="demo_restarting_message">Resetting device\u2026</string> - <!-- Title of the dialog shown when user inactivity times out in retail demo mode [CHAR LIMIT=40] --> - <string name="demo_user_inactivity_timeout_title">Reset device?</string> - <!-- Warning message shown when user inactivity times out in retail demo mode [CHAR LIMIT=none] --> - <string name="demo_user_inactivity_timeout_countdown">You\u2019ll lose any changes and the demo will start again in <xliff:g id="timeout" example="9">%1$s</xliff:g> seconds\u2026</string> - <!-- Text of button to allow user to abort countdown and continue current session in retail demo mode [CHAR LIMIT=40] --> - <string name="demo_user_inactivity_timeout_left_button">Cancel</string> - <!-- Text of button to allow user to abort countdown and immediately start another session in retail demo mode [CHAR LIMIT=40] --> - <string name="demo_user_inactivity_timeout_right_button">Reset now</string> <!-- Accessibilty string added to a widget that has been suspended [CHAR LIMIT=20] --> <string name="suspended_widget_accessibility">Disabled <xliff:g id="label" example="Calendar">%1$s</xliff:g></string> diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 949fd166c14c..e292c9dfbe67 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -304,7 +304,6 @@ public class SettingsBackupTest { Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS, Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT, Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, - Settings.Global.RETAIL_DEMO_MODE_CONSTANTS, Settings.Global.SAFE_BOOT_DISALLOWED, Settings.Global.SAMPLING_PROFILER_MS, Settings.Global.SELINUX_STATUS, diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java index af4a6d92cea6..8fd4e3110569 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java @@ -400,7 +400,7 @@ public class BatteryStatsSensorTest extends TestCase { assertNotNull(sensor.getSensorBackgroundTime()); // Reset the stats. Since the sensor is still running, we should still see the timer - bi.getUidStatsLocked(UID).reset(); + bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000); sensor = uid.getSensorStats().get(SENSOR_ID); assertNotNull(sensor); @@ -410,9 +410,111 @@ public class BatteryStatsSensorTest extends TestCase { bi.noteStopSensorLocked(UID, SENSOR_ID); // Now the sensor timer has stopped so this reset should also take out the sensor. - bi.getUidStatsLocked(UID).reset(); + bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000); sensor = uid.getSensorStats().get(SENSOR_ID); assertNull(sensor); } + + @SmallTest + public void testSensorResetTimes() throws Exception { + final MockClocks clocks = new MockClocks(); + MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); + final int which = BatteryStats.STATS_SINCE_CHARGED; + bi.mForceOnBattery = true; + clocks.realtime = 100; // in ms + clocks.uptime = 100; // in ms + + // TimeBases are on for some time. + BatteryStatsImpl.TimeBase timeBase = bi.getOnBatteryTimeBase(); + BatteryStatsImpl.TimeBase bgTimeBase = bi.getOnBatteryBackgroundTimeBase(UID); + timeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000); + bgTimeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000); + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); + + clocks.realtime += 100; + clocks.uptime += 100; + + // TimeBases are turned off + timeBase.setRunning(false, clocks.uptime * 1000, clocks.realtime * 1000); + bgTimeBase.setRunning(false, clocks.uptime * 1000, clocks.realtime * 1000); + + clocks.realtime += 100; + clocks.uptime += 100; + + // Timer is turned on + bi.noteStartSensorLocked(UID, SENSOR_ID); + + clocks.realtime += 100; + clocks.uptime += 100; + + // Timebase was off so times are all 0. + BatteryStats.Uid.Sensor sensor = bi.getUidStats().get(UID).getSensorStats().get(SENSOR_ID); + BatteryStats.Timer timer = sensor.getSensorTime(); + BatteryStats.Timer bgTimer = sensor.getSensorBackgroundTime(); + assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime)); + assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime)); + + clocks.realtime += 100; + clocks.uptime += 100; + + // Reset the stats. Since the sensor is still running, we should still see the timer + // but still with 0 times. + bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000); + assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime)); + assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime)); + + clocks.realtime += 100; + clocks.uptime += 100; + + // Now stop the timer. The times should still be 0. + bi.noteStopSensorLocked(UID, SENSOR_ID); + assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime)); + assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime)); + + // Now repeat with the TimeBases turned on the entire time. + timeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000); + bgTimeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000); + clocks.realtime += 100; + clocks.uptime += 100; + + // Timer is turned on + bi.noteStartSensorLocked(UID, SENSOR_ID); + + clocks.realtime += 111; + clocks.uptime += 1111; + + // Timebase and timer was on so times have increased. + assertEquals(111_000, timer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(111, timer.getTotalDurationMsLocked(clocks.realtime)); + assertEquals(111_000, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(111, bgTimer.getTotalDurationMsLocked(clocks.realtime)); + + clocks.realtime += 100; + clocks.uptime += 100; + + // Reset the stats. Since the sensor is still running, we should still see the timer + // but with 0 times. + bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000); + assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime)); + assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime)); + + clocks.realtime += 112; + clocks.uptime += 112; + + // Now stop the timer. The times should have increased since the timebase was on. + bi.noteStopSensorLocked(UID, SENSOR_ID); + assertEquals(112_000, timer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(112, timer.getTotalDurationMsLocked(clocks.realtime)); + assertEquals(112_000, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which)); + assertEquals(112, bgTimer.getTotalDurationMsLocked(clocks.realtime)); + } } diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml index 8801f5d09801..8801f5d09801 100644 --- a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml +++ b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml diff --git a/packages/SystemUI/res/drawable/ic_signal_location.xml b/packages/SettingsLib/res/drawable/ic_signal_location.xml index 2f605805eba2..2f605805eba2 100644 --- a/packages/SystemUI/res/drawable/ic_signal_location.xml +++ b/packages/SettingsLib/res/drawable/ic_signal_location.xml diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java index fa41c8349540..f9dc0e4d090e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java +++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java @@ -91,8 +91,9 @@ public class SuggestionParser { // Shared prefs keys for storing dismissed state. // Index into current dismissed state. + @VisibleForTesting + static final String DISMISS_INDEX = "_dismiss_index"; public static final String SETUP_TIME = "_setup_time"; - private static final String DISMISS_INDEX = "_dismiss_index"; private static final String IS_DISMISSED = "_is_dismissed"; // Default dismiss control for smart suggestions. @@ -353,7 +354,8 @@ public class SuggestionParser { return elapsedTime > category.exclusiveExpireDaysInMillis; } - private boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) { + @VisibleForTesting + boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) { String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled); if (dismissControl == null) { return false; @@ -370,7 +372,11 @@ public class SuggestionParser { return false; } int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0); - int currentDismiss = parseDismissString(dismissControl)[index]; + int[] dismissRules = parseDismissString(dismissControl); + if (dismissRules.length <= index) { + return true; + } + int currentDismiss = dismissRules[index]; long time = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0), currentDismiss); if (System.currentTimeMillis() >= time) { // Dismiss timeout has passed, undismiss it. diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java index 60933cfbbbda..83911360bdfe 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java @@ -16,6 +16,8 @@ package com.android.settingslib.suggestions; +import static com.google.common.truth.Truth.assertThat; + import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -42,8 +44,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static com.google.common.truth.Truth.assertThat; - @RunWith(SettingLibRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class SuggestionParserTest { @@ -190,6 +190,24 @@ public class SuggestionParserTest { assertThat(sl.getSuggestionForCategory("category2")).hasSize(1); } + @Test + public void isSuggestionDismissed_mismatchRule_shouldDismiss() { + final Tile suggestion = new Tile(); + suggestion.metaData = new Bundle(); + suggestion.metaData.putString(SuggestionParser.META_DATA_DISMISS_CONTROL, "1,2,3"); + suggestion.intent = new Intent().setComponent(new ComponentName("pkg", "cls")); + + // Dismiss suggestion when smart suggestion is not enabled. + mSuggestionParser.dismissSuggestion(suggestion, false /* isSmartSuggestionEnabled */); + final String suggestionKey = suggestion.intent.getComponent().flattenToShortString(); + // And point to last rule in dismiss control + mPrefs.edit().putInt(suggestionKey + SuggestionParser.DISMISS_INDEX, 2).apply(); + + // Turn on smart suggestion, and check if suggestion is enabled. + assertThat(mSuggestionParser.isDismissed(suggestion, true /* isSmartSuggestionEnabled */)) + .isTrue(); + } + private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) { mSuggestionsBeforeDismiss = new ArrayList<>(); mSuggestionsAfterDismiss = new ArrayList<>(); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index b328933cd1c5..819ee3ee57ff 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -915,9 +915,6 @@ class SettingsProtoDumpUtil { Settings.Global.DEVICE_DEMO_MODE, GlobalSettingsProto.DEVICE_DEMO_MODE); dumpSetting(s, p, - Settings.Global.RETAIL_DEMO_MODE_CONSTANTS, - GlobalSettingsProto.RETAIL_DEMO_MODE_CONSTANTS); - dumpSetting(s, p, Settings.Global.DATABASE_DOWNGRADE_REASON, GlobalSettingsProto.DATABASE_DOWNGRADE_REASON); dumpSetting(s, p, diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index edd0d0df11b6..24f6c138e081 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -208,7 +208,7 @@ android:icon="@drawable/icon" android:process="com.android.systemui" android:supportsRtl="true" - android:theme="@style/systemui_theme" + android:theme="@style/Theme.SystemUI" android:defaultToDeviceProtectedStorage="true" android:directBootAware="true"> <!-- Keep theme in sync with SystemUIApplication.onCreate(). diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml index b821e7e76c60..9fdb00eebe10 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml @@ -43,7 +43,7 @@ android:layout_height="wrap_content" android:layout_width="280dp" android:layout_gravity="center_horizontal" - android:theme="@style/PasswordTheme" + android:theme="?attr/passwordStyle" > <EditText android:id="@+id/passwordEntry" diff --git a/packages/SystemUI/res-keyguard/values/attrs.xml b/packages/SystemUI/res-keyguard/values/attrs.xml index 802bd308d407..e2ce210efdcb 100644 --- a/packages/SystemUI/res-keyguard/values/attrs.xml +++ b/packages/SystemUI/res-keyguard/values/attrs.xml @@ -41,4 +41,6 @@ <declare-styleable name="CarrierText"> <attr name="allCaps" format="boolean" /> </declare-styleable> + + <attr name="passwordStyle" format="reference" /> </resources> diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml index ea867eed08b4..c6f942356833 100644 --- a/packages/SystemUI/res-keyguard/values/styles.xml +++ b/packages/SystemUI/res-keyguard/values/styles.xml @@ -60,7 +60,13 @@ <item name="android:layout_gravity">center_horizontal|bottom</item> </style> - <style name="PasswordTheme" parent="systemui_theme"> + <style name="PasswordTheme" parent="Theme.SystemUI"> + <item name="android:textColor">?attr/wallpaperTextColor</item> + <item name="android:colorControlNormal">?attr/wallpaperTextColor</item> + <item name="android:colorControlActivated">?attr/wallpaperTextColor</item> + </style> + + <style name="PasswordTheme.Light" parent="Theme.SystemUI.Light"> <item name="android:textColor">?attr/wallpaperTextColor</item> <item name="android:colorControlNormal">?attr/wallpaperTextColor</item> <item name="android:colorControlActivated">?attr/wallpaperTextColor</item> diff --git a/packages/SystemUI/res/drawable/ic_dnd.xml b/packages/SystemUI/res/drawable/ic_dnd.xml index e658e687821b..9a1d502e21e5 100644 --- a/packages/SystemUI/res/drawable/ic_dnd.xml +++ b/packages/SystemUI/res/drawable/ic_dnd.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. @@ -15,13 +15,13 @@ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" - android:viewportHeight="48.0" - android:viewportWidth="48.0" + android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24dp" android:tint="?android:attr/colorControlNormal"> <path android:fillColor="#FFFFFFFF" - android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z" /> + android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml index 0515b35fb875..e7b9fa7e6988 100644 --- a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml +++ b/packages/SystemUI/res/drawable/ic_dnd_total_silence.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. @@ -22,9 +22,6 @@ <path android:fillColor="#FFFFFFFF" - android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/> + android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10 10,-4.5 10,-10S17.5,2 12,2zM12,20.5c-4.7,0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12,3.5s8.5,3.8 8.5,8.5 -3.8,8.5 -8.5,8.5zM12,6c-3.3,0 -6,2.7 -6,6s2.7,6 6,6 6,-2.7 6,-6 -2.6,-6 -6,-6zM14,13h-4c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h4c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm.xml b/packages/SystemUI/res/drawable/ic_volume_alarm.xml index e64f445bef27..996e488e8c81 100644 --- a/packages/SystemUI/res/drawable/ic_volume_alarm.xml +++ b/packages/SystemUI/res/drawable/ic_volume_alarm.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. @@ -15,13 +15,13 @@ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24.0dp" - android:viewportHeight="48.0" - android:viewportWidth="48.0" + android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24.0dp" android:tint="?android:attr/colorControlNormal"> <path android:fillColor="#FFFFFF" - android:pathData="M44.0,11.44l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-28.24,-4.66l-2.57,-3.06 -9.19,7.71 2.57,3.06 9.19,-7.71zm9.24,9.22l-3.0,0.0l0.0,12.0l9.49,5.71 1.51,-2.47 -8.0,-4.74l0.0,-10.5zm-1.01,-8.0c-9.95,0.0 -17.99,8.06 -17.99,18.0s8.04,18.0 17.99,18.0 18.01,-8.06 18.01,-18.0 -8.06,-18.0 -18.01,-18.0zm0.01,32.0c-7.73,0.0 -14.0,-6.27 -14.0,-14.0s6.27,-14.0 14.0,-14.0 14.0,6.27 14.0,14.0 -6.26,14.0 -14.0,14.0z" /> + android:pathData="M2.7,6.5c-0.4,-0.4 -0.3,-1 0.1,-1.4l3,-2.6c0.4,-0.4 1,-0.3 1.4,0.1C7.6,3 7.5,3.7 7.1,4l-3,2.6C3.6,7 3,6.9 2.7,6.5zM21.3,5.1l-3.1,-2.6c-0.4,-0.4 -0.99,-0.31 -1.4,0.1c-0.4,0.4 -0.3,1 0.1,1.4L20,6.6c0.41,0.37 1,0.3 1.4,-0.1C21.73,6.12 21.7,5.4 21.3,5.1zM21,13c0,5 -4,9 -9,9s-9,-4 -9,-9s4,-9 9,-9S21,8 21,13zM19.1,13c0,-3.9 -3.2,-7.1 -7.1,-7.1S4.9,9.1 4.9,13s3.2,7.1 7.1,7.1S19.1,16.9 19.1,13zM11.75,8C11.34,8 11,8.34 11,8.75V14l4.14,2.48c0.34,0.21 0.77,0.1 0.98,-0.24s0.09,-0.79 -0.25,-0.99l-3.37,-2v-4.5C12.5,8.34 12.16,8 11.75,8z"/> -</vector>
\ No newline at end of file +</vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml index 37d769084b6d..02fb1e702438 100644 --- a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml +++ b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.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. @@ -15,13 +15,13 @@ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24.0dp" - android:viewportHeight="48.0" - android:viewportWidth="48.0" + android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24.0dp" android:tint="?android:attr/colorControlNormal" > <path android:fillColor="#FFFFFF" - android:pathData="M24.0,12.0c7.73,0.0 14.0,6.27 14.0,14.0 0.0,1.69 -0.31,3.3 -0.86,4.8l3.04,3.04c1.16,-2.37 1.82,-5.03 1.82,-7.84 0.0,-9.94 -8.06,-18.0 -18.01,-18.0 -2.81,0.0 -5.46,0.66 -7.84,1.81l3.05,3.05c1.5,-0.55 3.11,-0.86 4.8,-0.86zm20.0,-0.56l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-38.16,-6.85l-2.55,2.54 2.66,2.66 -2.22,1.86 2.84,2.84 2.22,-1.86 1.6,1.6c-2.73,3.16 -4.39,7.27 -4.39,11.77 0.0,9.94 8.04,18.0 17.99,18.0 4.51,0.0 8.62,-1.67 11.77,-4.4l4.4,4.4 2.54,-2.55 -34.91,-34.91 -1.95,-1.95zm27.1,32.19c-2.43,2.01 -5.54,3.22 -8.94,3.22 -7.73,0.0 -14.0,-6.27 -14.0,-14.0 0.0,-3.4 1.21,-6.51 3.22,-8.94l19.72,19.72zm-16.91,-30.23l-2.84,-2.84 -1.7,1.43 2.84,2.84 1.7,-1.43z" /> + android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM20.72,20.09a0.9,0.9 0,0 1,0 1.27,0.9 0.9,0 0,1 -1.27,0l-1.57,-1.57A8.875,8.875 0,0 1,12 22c-4.98,0 -9,-4.03 -9,-9 0,-2.25 0.83,-4.31 2.2,-5.89l-0.8,-0.8 -0.41,0.35a1,1 0,0 1,-1.35 -0.06,1 1,0 0,1 0.07,-1.47l0.27,-0.23 -0.7,-0.7a0.9,0.9 0,0 1,0 -1.27c0.35,-0.35 0.93,-0.35 1.28,0l17.16,17.16zM16.54,18.45L6.55,8.46A7.041,7.041 0,0 0,4.9 13c0,3.91 3.19,7.1 7.1,7.1 1.73,0 3.31,-0.62 4.54,-1.65zM7.17,3.98A0.997,0.997 0,1 0,5.9 2.44l-0.16,0.13 1.42,1.42 0.01,-0.01zM12,4c-1.41,0 -2.73,0.33 -3.92,0.91l1.45,1.45c0.77,-0.29 1.6,-0.46 2.47,-0.46 3.91,0 7.1,3.18 7.1,7.1 0,0.87 -0.17,1.7 -0.45,2.47l1.44,1.44c0.58,-1.18 0.91,-2.5 0.91,-3.91a9,9 0,0 0,-9 -9z"/> -</vector>
\ No newline at end of file +</vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml b/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml index 5c3c6503d7c6..b0b9404cef46 100644 --- a/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml +++ b/packages/SystemUI/res/drawable/ic_volume_bt_sco.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. @@ -15,13 +15,16 @@ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24.0dp" - android:viewportHeight="48.0" - android:viewportWidth="48.0" + android:viewportHeight="24.0" + android:viewportWidth="24.0" android:width="24.0dp" android:tint="?android:attr/colorControlNormal" > <path android:fillColor="#FFFFFF" - android:pathData="M29.41,19.0L34.0,14.41L34.0,22.0l1.0,0.0l5.71,-5.71 -4.3,-4.29 4.29,-4.29L35.0,2.0l-1.0,0.0l0.0,7.59L29.41,5.0 28.0,6.41 33.59,12.0 28.0,17.59 29.41,19.0zM36.0,5.83l1.88,1.88L36.0,9.59L36.0,5.83zm0.0,8.58l1.88,1.88L36.0,18.17l0.0,-3.76zM40.0,31.0c-2.49,0.0 -4.89,-0.4 -7.14,-1.14 -0.69,-0.22 -1.48,-0.06 -2.0,0.49l-4.4,4.41c-5.67,-2.88 -10.29,-7.51 -13.18,-13.17l4.4,-4.41c0.55,-0.5 0.71,-1.3 0.49,-2.03C17.4,12.9 17.0,10.49 17.0,8.0c0.0,-1.11 -0.89,-2.0 -2.0,-2.0L8.0,6.0c-1.11,0.0 -2.0,0.89 -2.0,2.0 0.0,18.78 15.22,34.0 34.0,34.0 1.11,0.0 2.0,-0.89 2.0,-2.0l0.0,-7.0c0.0,-1.11 -0.89,-2.0 -2.0,-2.0z" /> + android:pathData="M20,15.5c-1.25,0 -2.45,-0.2 -3.57,-0.57c-0.35,-0.11 -0.74,-0.03 -1.02,0.24l-2.2,2.2c-2.83,-1.44 -5.15,-3.75 -6.59,-6.59l2.2,-2.21c0.28,-0.26 0.36,-0.65 0.25,-1C8.7,6.45 8.5,5.25 8.5,4c0,-0.55 -0.45,-1 -1,-1H4C3.45,3 3,3.45 3,4c0,9.39 7.61,17 17,17c0.55,0 1,-0.45 1,-1v-3.5C21,15.95 20.55,15.5 20,15.5z"/> + <path + android:fillColor="#FFFFFF" + android:pathData="M17.97,6l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L17.6,1.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L16.49,6l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l2.25,-2.25c0.21,-0.21 0.21,-0.54 0,-0.74L17.97,6zM17.75,2.78l0.99,0.99l-0.99,0.99V2.78zM17.75,9.23V7.27l0.99,0.99L17.75,9.23z"/> -</vector>
\ No newline at end of file +</vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_media.xml b/packages/SystemUI/res/drawable/ic_volume_media.xml index d6892077fa58..53c0740d88ea 100644 --- a/packages/SystemUI/res/drawable/ic_volume_media.xml +++ b/packages/SystemUI/res/drawable/ic_volume_media.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. @@ -22,6 +22,6 @@ <path android:fillColor="#FFFFFF" - android:pathData="M12.0,3.0l0.0,9.28c-0.47,-0.17 -0.97,-0.28 -1.5,-0.28C8.01,12.0 6.0,14.01 6.0,16.5S8.01,21.0 10.5,21.0c2.31,0.0 4.2,-1.75 4.45,-4.0L15.0,17.0L15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0z" /> + android:pathData="M18,3h-5c-0.55,0 -1,0.45 -1,1v8.3a3.88,3.88 0,0 0,-2.9 -0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26A4.483,4.483 0,0 0,10.5 21c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1z"/> -</vector>
\ No newline at end of file +</vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt.xml index 9b7b2da72b9c..60d0184c0ba2 100644 --- a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml +++ b/packages/SystemUI/res/drawable/ic_volume_media_bt.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. @@ -22,9 +22,6 @@ <path android:fillColor="#FFFFFF" - android:pathData="M17.0,3.0l-7.0,0.0l0.0,9.3C9.5,12.1 9.0,12.0 8.5,12.0C6.0,12.0 4.0,14.0 4.0,16.5S6.0,21.0 8.5,21.0s4.5,-2.3 4.5,-4.5C13.0,14.7 13.0,6.0 13.0,6.0l4.0,0.0L17.0,3.0z"/> - <path - android:fillColor="#FFFFFF" - android:pathData="M23.4,9.9L20.5,7.0L20.0,7.0l0.0,3.8l-2.3,-2.3L17.0,9.2l2.8,2.8L17.0,14.8l0.7,0.7l2.3,-2.3L20.0,17.0l0.5,0.0l2.8,-2.8L21.2,12.0L23.4,9.9zM21.0,8.9l0.9,0.9l-0.9,1.0L21.0,8.9zM21.9,14.2L21.0,15.1l0.0,-1.9L21.9,14.2z"/> + android:pathData="M16,3h-5c-0.55,0 -1,0.45 -1,1v8.3c-0.93,-0.39 -1.96,-0.4 -2.9,-0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26C4,19 6.01,21 8.49,21c0,0 0.01,0 0.01,0c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4C17,3.45 16.55,3 16,3zM20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l0.02,-0.02l2.23,-2.23c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,10.75V8.78l0.99,0.99L20.75,10.75zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml index 17ac01d078dd..49fcfc4d4919 100644 --- a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml +++ b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.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. @@ -22,12 +22,12 @@ <path android:fillColor="#FFFFFF" - android:pathData="M13.0,6.0l4.0,0.0L17.0,3.0l-7.0,0.0l0.0,5.6l3.0,3.0C13.0,8.8 13.0,6.0 13.0,6.0z"/> + android:pathData="M13,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6z"/> <path android:fillColor="#FFFFFF" - android:pathData="M2.1,5.7L8.4,12.0C6.0,12.1 4.0,14.0 4.0,16.5S6.0,21.0 8.5,21.0c2.7,0.0 4.5,-2.3 4.5,-4.3l0.0,-0.1l3.9,3.9l1.3,-1.3L3.4,4.5L2.1,5.7z"/> + android:pathData="M4,5.1C3.67,4.76 3.12,4.75 2.78,5.08C2.41,5.42 2.4,6 2.75,6.35L8.4,12C6,12.1 4,14 4,16.5c0,2.51 2.33,4.67 4.84,4.48C11.35,20.81 13,18.62 13,16.7v-0.1l3.27,3.27c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L4,5.1z"/> <path android:fillColor="#FFFFFF" - android:pathData="M23.4,9.9L20.5,7.0L20.0,7.0l0.0,3.8l-2.3,-2.3L17.0,9.2l2.8,2.8L17.0,14.8l0.7,0.7l2.3,-2.3L20.0,17.0l0.5,0.0l2.8,-2.8L21.2,12.0L23.4,9.9zM21.0,8.9l0.9,0.9l-0.9,1.0L21.0,8.9zM21.9,14.2L21.0,15.1l0.0,-1.9L21.9,14.2z"/> + android:pathData="M20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l2.25,-2.25c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,8.78l0.99,0.99l-0.99,0.98V8.78zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/> -</vector>
\ No newline at end of file +</vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml index 267d09d7b84e..ebb86e896d21 100644 --- a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml +++ b/packages/SystemUI/res/drawable/ic_volume_media_mute.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. @@ -22,9 +22,6 @@ <path android:fillColor="#FFFFFF" - android:pathData="M15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0l0.0,5.6l3.0,3.0C15.0,8.8 15.0,6.0 15.0,6.0z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M4.8,3.9L3.5,5.1l6.9,6.9C8.0,12.1 6.0,14.0 6.0,16.5C6.0,19.0 8.0,21.0 10.5,21.0c2.7,0.0 4.5,-2.3 4.5,-4.3c0.0,0.0 0.0,-0.1 0.0,-0.1l4.0,4.0l1.3,-1.3L4.8,3.9z" /> + android:pathData="M15,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6zM4.18,4.48c-0.37,0.34 -0.38,0.92 -0.03,1.27L10.4,12C8,12.1 6,14 6,16.5c0,2.51 2.33,4.67 4.84,4.48 2.51,-0.17 4.16,-2.36 4.16,-4.28v-0.1l3.37,3.37c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L5.4,4.5a0.866,0.866 0,0 0,-1.22 -0.02z"/> -</vector>
\ No newline at end of file +</vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer.xml b/packages/SystemUI/res/drawable/ic_volume_ringer.xml index 18af711a493f..f258856696bb 100644 --- a/packages/SystemUI/res/drawable/ic_volume_ringer.xml +++ b/packages/SystemUI/res/drawable/ic_volume_ringer.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. @@ -15,13 +15,17 @@ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" - android:viewportHeight="24.0" - android:viewportWidth="24.0" + android:viewportHeight="23.4" + android:viewportWidth="23.4" android:width="24dp" android:tint="?android:attr/colorControlNormal" > - <path - android:fillColor="#FFFFFF" - android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z" /> + <group + android:translateX="-0.78" + android:translateY="-0.5" > + <path + android:fillColor="#FFFFFF" + android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.63,5.36 6,7.92 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h15.6c0.45,0 0.67,-0.54 0.35,-0.85L18,16z"/> + </group> -</vector>
\ No newline at end of file +</vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml index bc926c3340a3..106d899f1b64 100644 --- a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml +++ b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.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. @@ -15,13 +15,23 @@ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" - android:viewportHeight="48.0" - android:viewportWidth="48.0" + android:viewportHeight="23.4" + android:viewportWidth="23.3" android:width="24dp" android:tint="?android:attr/colorControlNormal" > - <path - android:fillColor="#FFFFFF" - android:pathData="M23.000000,44.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000l-8.000000,0.000000C19.000000,42.200001 20.799999,44.000000 23.000000,44.000000zM36.000000,21.000000c0.000000,-6.100000 -4.300000,-11.300000 -10.000000,-12.600000L26.000000,7.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,1.400000c-1.000000,0.200000 -2.000000,0.600000 -2.900000,1.100000L36.000000,28.400000L36.000000,21.000000zM35.500000,38.000000l4.000000,4.000000l2.500000,-2.500000L8.500000,6.000000L6.000000,8.500000l5.800000,5.800000C10.700000,16.299999 10.000000,18.600000 10.000000,21.000000l0.000000,11.000000l-4.000000,4.000000l0.000000,2.000000L35.500000,38.000000z" /> + <group + android:translateX="-0.85" + android:translateY="-0.5" > + <path + android:fillColor="#FF0" + android:pathData="M20.73,19.46l-0.6,-0.6c0,0 0,0 0,0L5.54,4.26c-0.35,-0.35 -0.92,-0.35 -1.27,0c-0.35,0.35 -0.35,0.92 0,1.27l2.4,2.4C6.25,8.85 6,9.88 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h13.53l1.73,1.73c0.35,0.35 0.92,0.35 1.27,0C21.09,20.38 21.09,19.81 20.73,19.46z"/> + <path + android:fillColor="#FF0" + android:pathData="M18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.87,4.83 9.31,5.08 8.8,5.4l9.2,9.2V11z"/> + <path + android:fillColor="#FF0" + android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> + </group> -</vector>
\ No newline at end of file +</vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml index ffbffad690ec..9db8511c3623 100644 --- a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml +++ b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.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. @@ -22,6 +22,6 @@ <path android:fillColor="#FFFFFF" - android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z" /> + android:pathData="M1,15c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v4c0,0.55 0.45,1 1,1zM4,17c0.55,0 1,-0.45 1,-1L5,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM22,10v4c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1zM20,17c0.55,0 1,-0.45 1,-1L21,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM16.5,3h-9C6.67,3 6,3.67 6,4.5v15c0,0.83 0.67,1.5 1.5,1.5h9c0.83,0 1.5,-0.67 1.5,-1.5v-15c0,-0.83 -0.67,-1.5 -1.5,-1.5zM16,19L8,19L8,5h8v14z"/> -</vector>
\ No newline at end of file +</vector> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 07f11a425fd7..18dab3d10a9e 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -16,7 +16,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android"> - <style name="RecentsTheme" parent="RecentsBase"> + <style name="RecentsTheme" parent="@android:style/Theme.Material"> <!-- NoTitle --> <item name="android:windowNoTitle">true</item> <!-- Misc --> @@ -27,13 +27,6 @@ <item name="android:ambientShadowAlpha">0.35</item> </style> - <!-- OverlayManager might replace this style entirely, use RecentsTheme to set a property - that should exist in both light and dark versions of Recents --> - <style name="RecentsBase" parent="@android:style/Theme.Material"> - <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_dark</item> - <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_dark</item> - </style> - <!-- Recents theme --> <style name="RecentsTheme.Wallpaper"> <item name="android:windowBackground">@*android:color/transparent</item> @@ -41,8 +34,13 @@ <item name="android:windowShowWallpaper">true</item> <item name="android:windowDisablePreview">true</item> <item name="clearAllStyle">@style/ClearAllButtonDefaultMargins</item> - <item name="wallpaperTextColor">?android:attr/textColorPrimaryInverse</item> - <item name="wallpaperTextColorSecondary">?android:attr/textColorSecondaryInverse</item> + <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item> + <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item> + </style> + + <style name="RecentsTheme.Wallpaper.Light"> + <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item> + <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item> </style> <style name="ClearAllButtonDefaultMargins"> @@ -300,22 +298,27 @@ <style name="Animation.StatusBar"> </style> - <!-- Overlay manager may replace this theme --> - <style name="systemui_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings" /> - - <style name="systemui_theme" parent="systemui_base"> + <style name="Theme.SystemUI" parent="@*android:style/Theme.DeviceDefault.QuickSettings"> <item name="lightIconTheme">@style/DualToneLightTheme</item> <item name="darkIconTheme">@style/DualToneDarkTheme</item> - <item name="wallpaperTextColor">?android:attr/textColorPrimaryInverse</item> - <item name="wallpaperTextColorSecondary">?android:attr/textColorSecondaryInverse</item> - <item name="android:colorControlHighlight">?android:attr/textColorSecondaryInverse</item> + <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item> + <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item> + <item name="android:colorControlHighlight">@*android:color/primary_text_material_dark</item> <item name="*android:lockPatternStyle">@style/LockPatternStyle</item> + <item name="passwordStyle">@style/PasswordTheme</item> + </style> + + <style name="Theme.SystemUI.Light" parent="@*android:style/Theme.DeviceDefault.QuickSettings"> + <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item> + <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item> + <item name="android:colorControlHighlight">@*android:color/primary_text_material_light</item> + <item name="passwordStyle">@style/PasswordTheme.Light</item> </style> <style name="LockPatternStyle"> - <item name="*android:regularColor">?android:attr/textColorPrimaryInverse</item> - <item name="*android:successColor">?android:attr/textColorPrimaryInverse</item> - <item name="*android:errorColor">?android:attr/colorError</item> + <item name="*android:regularColor">?attr/wallpaperTextColor</item> + <item name="*android:successColor">?attr/wallpaperTextColor</item> + <item name="*android:errorColor">?attr/colorError</item> </style> <!-- Overlay manager may replace this theme --> diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 211f0c75b5dd..d8da5ed71894 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -118,7 +118,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv // Set the application theme that is inherited by all services. Note that setting the // application theme in the manifest does only work for activities. Keep this in sync with // the theme set there. - setTheme(R.style.systemui_theme); + setTheme(R.style.Theme_SystemUI); SystemUIFactory.createFromConfig(this); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 81ec6a7c72a9..4e728f68890a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -19,13 +19,14 @@ package com.android.systemui.qs.tiles; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.res.Resources; +import android.os.SystemProperties; import android.service.quicksettings.Tile; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Switch; - import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.net.DataUsageController; @@ -38,7 +39,6 @@ import com.android.systemui.plugins.qs.QSTile.SignalState; import com.android.systemui.qs.CellTileView; import com.android.systemui.qs.CellTileView.SignalIcon; import com.android.systemui.qs.QSHost; -import com.android.systemui.qs.SignalTileView; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.IconState; @@ -46,8 +46,17 @@ import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; /** Quick settings tile: Cellular **/ public class CellularTile extends QSTileImpl<SignalState> { - static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName( - "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); + private static final ComponentName CELLULAR_SETTING_COMPONENT = new ComponentName( + "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"); + private static final ComponentName DATA_PLAN_CELLULAR_COMPONENT = new ComponentName( + "com.android.settings", "com.android.settings.Settings$DataPlanUsageSummaryActivity"); + + private static final Intent CELLULAR_SETTINGS = + new Intent().setComponent(CELLULAR_SETTING_COMPONENT); + private static final Intent DATA_PLAN_CELLULAR_SETTINGS = + new Intent().setComponent(DATA_PLAN_CELLULAR_COMPONENT); + + private static final String ENABLE_SETTINGS_DATA_PLAN = "enable.settings.data.plan"; private final NetworkController mController; private final DataUsageController mDataController; @@ -90,7 +99,7 @@ public class CellularTile extends QSTileImpl<SignalState> { @Override public Intent getLongClickIntent() { - return CELLULAR_SETTINGS; + return getCellularSettingIntent(mContext); } @Override @@ -103,7 +112,9 @@ public class CellularTile extends QSTileImpl<SignalState> { if (mDataController.isMobileDataSupported()) { showDetail(true); } else { - mActivityStarter.postStartActivityDismissingKeyguard(CELLULAR_SETTINGS, 0); + mActivityStarter + .postStartActivityDismissingKeyguard(getCellularSettingIntent(mContext), + 0 /* delay */); } } @@ -240,7 +251,28 @@ public class CellularTile extends QSTileImpl<SignalState> { public void setMobileDataEnabled(boolean enabled) { mDetailAdapter.setMobileDataEnabled(enabled); } - }; + } + + static Intent getCellularSettingIntent(Context context) { + // TODO(b/62349208): We should replace feature flag check below with data plans + // availability check. If the data plans are available we display the data plans usage + // summary otherwise we display data usage summary without data plans. + boolean isDataPlanFeatureEnabled = + SystemProperties.getBoolean(ENABLE_SETTINGS_DATA_PLAN, false /* default */); + context.getPackageManager() + .setComponentEnabledSetting( + DATA_PLAN_CELLULAR_COMPONENT, + isDataPlanFeatureEnabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + context.getPackageManager() + .setComponentEnabledSetting( + CELLULAR_SETTING_COMPONENT, + isDataPlanFeatureEnabled ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED + : PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + return isDataPlanFeatureEnabled ? DATA_PLAN_CELLULAR_SETTINGS : CELLULAR_SETTINGS; + } private final class CellularDetailAdapter implements DetailAdapter { @@ -258,7 +290,7 @@ public class CellularTile extends QSTileImpl<SignalState> { @Override public Intent getSettingsIntent() { - return CELLULAR_SETTINGS; + return getCellularSettingIntent(mContext); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index b7964512a2fa..8b62beb861ba 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -14,18 +14,16 @@ package com.android.systemui.qs.tiles; -import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.service.quicksettings.Tile; import android.widget.Switch; - -import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.Prefs; import com.android.systemui.R; -import com.android.systemui.qs.QSHost; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.DataSaverController; @@ -57,9 +55,8 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements @Override public Intent getLongClickIntent() { - return CellularTile.CELLULAR_SETTINGS; + return CellularTile.getCellularSettingIntent(mContext); } - @Override protected void handleClick() { if (mState.value @@ -73,12 +70,7 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements dialog.setTitle(com.android.internal.R.string.data_saver_enable_title); dialog.setMessage(com.android.internal.R.string.data_saver_description); dialog.setPositiveButton(com.android.internal.R.string.data_saver_enable_button, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - toggleDataSaver(); - } - }); + (OnClickListener) (dialogInterface, which) -> toggleDataSaver()); dialog.setNegativeButton(com.android.internal.R.string.cancel, null); dialog.setShowForAllUsers(true); dialog.show(); @@ -126,4 +118,4 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements public void onDataSaverChanged(boolean isDataSaving) { refreshState(isDataSaving); } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index f2ea6a683e95..c0550b5c52e6 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -20,11 +20,11 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.TaskStackBuilder; +import android.app.WallpaperManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; @@ -41,12 +41,15 @@ import android.view.ViewTreeObserver.OnPreDrawListener; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; +import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.LatencyTracker; import com.android.systemui.DejankUtils; +import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent; import com.android.systemui.recents.events.activity.ConfigurationChangedEvent; @@ -100,7 +103,8 @@ import java.util.List; /** * The main Recents activity that is started from RecentsComponent. */ -public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener { +public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener, + ColorExtractor.OnColorsChangedListener { private final static String TAG = "RecentsActivity"; private final static boolean DEBUG = false; @@ -129,6 +133,10 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD private DozeTrigger mIterateTrigger; private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent(); + // Theme and colors + private SysuiColorExtractor mColorExtractor; + private boolean mUsingDarkText; + /** * A common Runnable to finish Recents by launching Home with an animation depending on the * last activity launch state. Generally we always launch home when we exit Recents rather than @@ -329,6 +337,14 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD mPackageMonitor = new RecentsPackageMonitor(); mPackageMonitor.register(this); + // Select theme based on wallpaper colors + mColorExtractor = Dependency.get(SysuiColorExtractor.class); + mColorExtractor.addOnColorsChangedListener(this); + mUsingDarkText = mColorExtractor.getColors(ColorExtractor.TYPE_DARK, + WallpaperManager.FLAG_SYSTEM, true).supportsDarkText(); + setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light + : R.style.RecentsTheme_Wallpaper); + // Set the Recents layout setContentView(R.layout.recents); takeKeyEvents(true); @@ -375,13 +391,37 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true)); MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY); - // Make sure we have the right gradient and we're listening for update events - mRecentsView.onStart(); + // Getting system scrim colors ignoring wallpaper visibility since it should never be grey. + ColorExtractor.GradientColors systemColors = mColorExtractor.getColors( + ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true); + // We don't want to interpolate colors because we're defining the initial state. + // Gradient should be set/ready when you open "Recents". + mRecentsView.setScrimColors(systemColors, false); + // Notify of the next draw mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener); } @Override + public void onColorsChanged(ColorExtractor colorExtractor, int which) { + if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { + // Recents doesn't care about the wallpaper being visible or not, it always + // wants to scrim with wallpaper colors + ColorExtractor.GradientColors colors = mColorExtractor.getColors( + WallpaperManager.FLAG_SYSTEM, + ColorExtractor.TYPE_DARK, true /* ignoreVis */); + boolean darkText = colors.supportsDarkText(); + if (darkText != mUsingDarkText) { + mUsingDarkText = darkText; + setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light + : R.style.RecentsTheme_Wallpaper); + mRecentsView.reevaluateStyles(); + } + mRecentsView.setScrimColors(colors, true /* animated */); + } + } + + @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); @@ -483,12 +523,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD mLastConfig.orientation != newDeviceConfiguration.orientation, mLastConfig.densityDpi != newDeviceConfiguration.densityDpi, numStackTasks > 0)); - int configDiff = mLastConfig.updateFrom(newDeviceConfiguration); - - // Recreate activity if an overlay was enabled/disabled - if ((configDiff & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) { - recreate(); - } + mLastConfig.updateFrom(newDeviceConfiguration); } @Override @@ -508,9 +543,6 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY); Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(false); - // We don't need to update the gradient when we're not visible - mRecentsView.onStop(); - if (!isChangingConfigurations()) { // Workaround for b/22542869, if the RecentsActivity is started again, but without going // through SystemUI, we need to reset the config launch flags to ensure that we do not diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index fd37b17f3cd0..8e094813257c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -21,13 +21,12 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import android.animation.Animator; import android.animation.ObjectAnimator; import android.app.ActivityOptions.OnAnimationStartedListener; -import android.app.WallpaperColors; -import android.app.WallpaperManager; import android.content.Context; +import android.content.res.ColorStateList; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.util.ArraySet; import android.util.AttributeSet; @@ -43,12 +42,12 @@ import android.widget.FrameLayout; import android.widget.TextView; import com.android.internal.colorextraction.ColorExtractor; +import com.android.internal.colorextraction.drawable.GradientDrawable; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; +import com.android.settingslib.Utils; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsActivity; import com.android.systemui.recents.RecentsActivityLaunchState; @@ -83,8 +82,6 @@ import com.android.systemui.stackdivider.WindowManagerProxy; import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.phone.ScrimController; -import com.android.internal.colorextraction.drawable.GradientDrawable; - import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -93,7 +90,7 @@ import java.util.List; * This view is the the top level layout that contains TaskStacks (which are laid out according * to their SpaceNode bounds. */ -public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsChangedListener { +public class RecentsView extends FrameLayout { private static final String TAG = "RecentsView"; @@ -107,6 +104,9 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC private TaskStackView mTaskStackView; private TextView mStackActionButton; private TextView mEmptyView; + private final float mStackButtonShadowRadius; + private final PointF mStackButtonShadowDistance; + private final int mStackButtonShadowColor; private boolean mAwaitingFirstLayout = true; private boolean mLastTaskLaunchedWasFreeform; @@ -117,7 +117,6 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC private float mBusynessFactor; private GradientDrawable mBackgroundScrim; - private final SysuiColorExtractor mColorExtractor; private Animator mBackgroundScrimAnimator; private RecentsTransitionHelper mTransitionHelper; @@ -148,29 +147,51 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f); mBackgroundScrim = new GradientDrawable(context); mBackgroundScrim.setCallback(this); - mColorExtractor = Dependency.get(SysuiColorExtractor.class); - LayoutInflater inflater = LayoutInflater.from(context); + boolean usingDarkText = Color.luminance( + Utils.getColorAttr(mContext, R.attr.wallpaperTextColor)) < 0.5f; + LayoutInflater inflater = LayoutInflater.from(context); mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false); addView(mEmptyView); - boolean usingDarkText = - Color.luminance(mEmptyView.getTextColors().getDefaultColor()) < 0.5f; if (RecentsDebugFlags.Static.EnableStackActionButton) { + if (mStackActionButton != null) { + removeView(mStackActionButton); + } mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button, this, false); - mStackActionButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - EventBus.getDefault().send(new DismissAllTaskViewsEvent()); - } - }); - // Disable black shadow if text color is already dark. + mStackActionButton.setOnClickListener( + v -> EventBus.getDefault().send(new DismissAllTaskViewsEvent())); + + mStackButtonShadowRadius = mStackActionButton.getShadowRadius(); + mStackButtonShadowDistance = new PointF(mStackActionButton.getShadowDx(), + mStackActionButton.getShadowDy()); + mStackButtonShadowColor = mStackActionButton.getShadowColor(); + addView(mStackActionButton); + } + + reevaluateStyles(); + } + + public void reevaluateStyles() { + int textColor = Utils.getColorAttr(mContext, R.attr.wallpaperTextColor); + boolean usingDarkText = Color.luminance(textColor) < 0.5f; + + mEmptyView.setTextColor(textColor); + mEmptyView.setCompoundDrawableTintList(new ColorStateList(new int[][]{ + {android.R.attr.state_enabled}}, new int[]{textColor})); + + if (mStackActionButton != null) { + mStackActionButton.setTextColor(textColor); + // Enable/disable shadow if text color is already dark. if (usingDarkText) { mStackActionButton.setShadowLayer(0, 0, 0, 0); + } else { + mStackActionButton.setShadowLayer(mStackButtonShadowRadius, + mStackButtonShadowDistance.x, mStackButtonShadowDistance.y, + mStackButtonShadowColor); } - addView(mStackActionButton); } // Let's also require dark status and nav bars if the text is dark @@ -369,6 +390,16 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC } } + /** + * Set the color of the scrim. + * + * @param scrimColors Colors to use. + * @param animated Interpolate colors if true. + */ + public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) { + mBackgroundScrim.setColors(scrimColors, animated); + } + @Override protected void onAttachedToWindow() { EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1); @@ -888,29 +919,4 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC mTaskStackView.dump(innerPrefix, writer); } } - - @Override - public void onColorsChanged(ColorExtractor colorExtractor, int which) { - if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { - // Recents doesn't care about the wallpaper being visible or not, it always - // wants to scrim with wallpaper colors - mBackgroundScrim.setColors( - mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM, - ColorExtractor.TYPE_DARK, true)); - } - } - - public void onStart() { - mColorExtractor.addOnColorsChangedListener(this); - // Getting system scrim colors ignoring wallpaper visibility since it should never be grey. - ColorExtractor.GradientColors systemColors = mColorExtractor.getColors( - ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true); - // We don't want to interpolate colors because we're defining the initial state. - // Gradient should be set/ready when you open "Recents". - mBackgroundScrim.setColors(systemColors, false); - } - - public void onStop() { - mColorExtractor.removeOnColorsChangedListener(this); - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java index 543666407fb9..d7c6443a6c3b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; +import android.annotation.ColorInt; import android.content.Context; import android.content.res.Configuration; import android.util.AttributeSet; @@ -46,6 +47,10 @@ public class DismissView extends StackScrollerDecorView { mDismissButton = (DismissViewButton) findContentView(); } + public void setTextColor(@ColorInt int color) { + mDismissButton.setTextColor(color); + } + public void setOnButtonClickListener(OnClickListener listener) { mContent.setOnClickListener(listener); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java index 92b0890a5d2b..58adde269758 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; +import android.annotation.ColorInt; import android.content.Context; import android.content.res.Configuration; import android.util.AttributeSet; @@ -45,6 +46,10 @@ public class EmptyShadeView extends StackScrollerDecorView { return findViewById(R.id.no_notifications); } + public void setTextColor(@ColorInt int color) { + mEmptyText.setTextColor(color); + } + @Override protected void onFinishInflate() { super.onFinishInflate(); 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 353b82b6fd6a..ec5edee94a31 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -979,9 +979,6 @@ public class StatusBar extends SystemUI implements DemoMode, Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this); Dependency.get(ConfigurationController.class).addCallback(this); - - // Make sure that we're using the correct theme - onOverlayChanged(); } protected void createIconController() { @@ -994,6 +991,7 @@ public class StatusBar extends SystemUI implements DemoMode, final Context context = mContext; updateDisplaySize(); // populates mDisplayMetrics updateResources(); + updateTheme(); inflateStatusBarWindow(context); mStatusBarWindow.setService(this); @@ -1202,7 +1200,6 @@ public class StatusBar extends SystemUI implements DemoMode, }); } - PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); if (!pm.isScreenOn()) { mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); @@ -1307,14 +1304,14 @@ public class StatusBar extends SystemUI implements DemoMode, reevaluateStyles(); } - public void onOverlayChanged() { + private void reinflateViews() { reevaluateStyles(); // Clock and bottom icons mNotificationPanel.onOverlayChanged(); - + // The status bar on the keyguard is a special layout. + mKeyguardStatusBar.onOverlayChanged(); // Recreate Indication controller because internal references changed - // TODO: unregister callbacks before recreating mKeyguardIndicationController = SystemUIFactory.getInstance().createKeyguardIndicationController(mContext, mStatusBarWindow.findViewById(R.id.keyguard_indication_area), @@ -2862,17 +2859,6 @@ public class StatusBar extends SystemUI implements DemoMode, updateTheme(); } - public boolean isUsingDarkText() { - OverlayInfo themeInfo = null; - try { - themeInfo = mOverlayManager.getOverlayInfo("com.android.systemui.theme.lightwallpaper", - mCurrentUserId); - } catch (RemoteException e) { - e.printStackTrace(); - } - return themeInfo != null && themeInfo.isEnabled(); - } - public boolean isUsingDarkTheme() { OverlayInfo themeInfo = null; try { @@ -4580,24 +4566,13 @@ public class StatusBar extends SystemUI implements DemoMode, * Switches theme from light to dark and vice-versa. */ private void updateTheme() { + final boolean inflated = mStackScroller != null; - int which; - if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) { - which = WallpaperManager.FLAG_LOCK; - } else { - which = WallpaperManager.FLAG_SYSTEM; - } - - // Gradient defines if text color should be light or dark. - final boolean useDarkText = mColorExtractor.getColors(which, true /* ignoreVisibility */) - .supportsDarkText(); - // And wallpaper defines if QS should be light or dark. + // The system wallpaper defines if QS should be light or dark. WallpaperColors systemColors = mColorExtractor .getWallpaperColors(WallpaperManager.FLAG_SYSTEM); final boolean useDarkTheme = systemColors != null && (systemColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0; - - // Enable/disable dark UI. if (isUsingDarkTheme() != useDarkTheme) { try { mOverlayManager.setEnabled("com.android.systemui.theme.dark", @@ -4606,18 +4581,33 @@ public class StatusBar extends SystemUI implements DemoMode, Log.w(TAG, "Can't change theme", e); } } - // Enable/disable dark text overlay. - if (isUsingDarkText() != useDarkText) { - try { - mOverlayManager.setEnabled("com.android.systemui.theme.lightwallpaper", - useDarkText, mCurrentUserId); - } catch (RemoteException e) { - Log.w(TAG, "Can't change theme", e); + + // Lock wallpaper defines the color of the majority of the views, hence we'll use it + // to set our default theme. + final boolean lockDarkText = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true + /* ignoreVisibility */).supportsDarkText(); + final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI; + if (mContext.getThemeResId() != themeResId) { + mContext.setTheme(themeResId); + if (inflated) { + reinflateViews(); } } - // Make sure we have the correct navbar/statusbar colors. - mStatusBarWindowManager.setKeyguardDark(useDarkText); + if (inflated) { + int which; + if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) { + which = WallpaperManager.FLAG_LOCK; + } else { + which = WallpaperManager.FLAG_SYSTEM; + } + final boolean useDarkText = mColorExtractor.getColors(which, + true /* ignoreVisibility */).supportsDarkText(); + mStackScroller.updateDecorViews(useDarkText); + + // Make sure we have the correct navbar/statusbar colors. + mStatusBarWindowManager.setKeyguardDark(useDarkText); + } } private void updateDozingState() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 42cebe2632bb..4bbe895da7ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -23,6 +23,7 @@ import android.animation.PropertyValuesHolder; import android.animation.TimeAnimator; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.annotation.ColorInt; import android.annotation.FloatRange; import android.annotation.Nullable; import android.content.Context; @@ -44,6 +45,7 @@ import android.util.FloatProperty; import android.util.Log; import android.util.Pair; import android.util.Property; +import android.view.ContextThemeWrapper; import android.view.InputDevice; import android.view.MotionEvent; import android.view.VelocityTracker; @@ -61,6 +63,7 @@ import android.widget.ScrollView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settingslib.Utils; import com.android.systemui.ExpandHelper; import com.android.systemui.Interpolators; import com.android.systemui.R; @@ -363,6 +366,7 @@ public class NotificationStackScrollLayout extends ViewGroup return object.getBackgroundFadeAmount(); } }; + private boolean mUsingLightTheme; private boolean mQsExpanded; private boolean mForwardScrollable; private boolean mBackwardScrollable; @@ -3653,6 +3657,23 @@ public class NotificationStackScrollLayout extends ViewGroup mTmpSortedChildren.clear(); } + /** + * Update colors of "dismiss" and "empty shade" views. + * + * @param lightTheme True if light theme should be used. + */ + public void updateDecorViews(boolean lightTheme) { + if (lightTheme == mUsingLightTheme) { + return; + } + mUsingLightTheme = lightTheme; + Context context = new ContextThemeWrapper(mContext, + lightTheme ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI); + final int textColor = Utils.getColorAttr(context, R.attr.wallpaperTextColor); + mDismissView.setTextColor(textColor); + mEmptyShadeView.setTextColor(textColor); + } + public void goToFullShade(long delay) { if (mDismissView != null) { mDismissView.setInvisible(); diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk b/packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk deleted file mode 100644 index 4782a166146b..000000000000 --- a/packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_RRO_THEME := SysuiLightWallpaperTheme -LOCAL_CERTIFICATE := platform - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res - -LOCAL_PACKAGE_NAME := SysuiLightWallpaperThemeOverlay - -include $(BUILD_RRO_PACKAGE) diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml deleted file mode 100644 index 0a8749c64ea2..000000000000 --- a/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.systemui.theme.lightwallpaper" - android:versionCode="1" - android:versionName="1.0"> - <overlay android:targetPackage="com.android.systemui" android:priority="2"/> - - <application android:label="@string/sysui_overlay_light" android:hasCode="false"/> -</manifest> diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml deleted file mode 100644 index 53912b50df00..000000000000 --- a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <style name="systemui_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings"> - <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item> - <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item> - </style> - - <style name="RecentsBase" parent="@android:style/Theme.Material"> - <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item> - <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item> - </style> -</resources>
\ No newline at end of file diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 53190869513b..6167d85f33c7 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -4252,6 +4252,11 @@ message MetricsEvent { // OS: O MR FIELD_RANKED_POSITION = 1087; + // OPEN: Settings > Data plan usage + // CATEGORY: SETTINGS + // OS: O MR + DATA_PLAN_USAGE_SUMMARY = 1088; + // Add new aosp constants above this line. // END OF AOSP CONSTANTS } diff --git a/services/Android.mk b/services/Android.mk index 6a73d5f65351..0986e0a4aad4 100644 --- a/services/Android.mk +++ b/services/Android.mk @@ -34,7 +34,6 @@ services := \ net \ print \ restrictions \ - retaildemo \ usage \ usb \ voiceinteraction diff --git a/services/art-profile b/services/art-profile index bd6ed23fa993..140465a1c35e 100644 --- a/services/art-profile +++ b/services/art-profile @@ -11901,23 +11901,6 @@ PLcom/android/server/restrictions/RestrictionsManagerService$RestrictionsManager PLcom/android/server/restrictions/RestrictionsManagerService;->-wrap0(Lcom/android/server/restrictions/RestrictionsManagerService;Ljava/lang/String;)Landroid/os/IBinder; PLcom/android/server/restrictions/RestrictionsManagerService;-><init>(Landroid/content/Context;)V PLcom/android/server/restrictions/RestrictionsManagerService;->onStart()V -PLcom/android/server/retaildemo/RetailDemoModeService$1;-><init>(Lcom/android/server/retaildemo/RetailDemoModeService;)V -PLcom/android/server/retaildemo/RetailDemoModeService$1;->onUserActivity()V -PLcom/android/server/retaildemo/RetailDemoModeService$Injector;-><init>(Landroid/content/Context;)V -PLcom/android/server/retaildemo/RetailDemoModeService$Injector;->getContentResolver()Landroid/content/ContentResolver; -PLcom/android/server/retaildemo/RetailDemoModeService$Injector;->getContext()Landroid/content/Context; -PLcom/android/server/retaildemo/RetailDemoModeService$Injector;->publishLocalService(Lcom/android/server/retaildemo/RetailDemoModeService;Landroid/app/RetailDemoModeServiceInternal;)V -PLcom/android/server/retaildemo/RetailDemoModeService$MainHandler;-><init>(Lcom/android/server/retaildemo/RetailDemoModeService;Landroid/os/Looper;)V -PLcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;->-wrap0(Lcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;)V -PLcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;-><init>(Lcom/android/server/retaildemo/RetailDemoModeService;Landroid/os/Handler;)V -PLcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;->refreshTimeoutConstants()V -PLcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;->register()V -PLcom/android/server/retaildemo/RetailDemoModeService;->-get1(Lcom/android/server/retaildemo/RetailDemoModeService;)Lcom/android/server/retaildemo/RetailDemoModeService$Injector; -PLcom/android/server/retaildemo/RetailDemoModeService;->-wrap2(Lcom/android/server/retaildemo/RetailDemoModeService;Ljava/lang/Class;Ljava/lang/Object;)V -PLcom/android/server/retaildemo/RetailDemoModeService;-><init>(Landroid/content/Context;)V -PLcom/android/server/retaildemo/RetailDemoModeService;-><init>(Lcom/android/server/retaildemo/RetailDemoModeService$Injector;)V -PLcom/android/server/retaildemo/RetailDemoModeService;->onBootPhase(I)V -PLcom/android/server/retaildemo/RetailDemoModeService;->onStart()V PLcom/android/server/search/SearchManagerService$GlobalSearchProviderObserver;-><init>(Lcom/android/server/search/SearchManagerService;Landroid/content/ContentResolver;)V PLcom/android/server/search/SearchManagerService$Lifecycle$1;-><init>(Lcom/android/server/search/SearchManagerService$Lifecycle;I)V PLcom/android/server/search/SearchManagerService$Lifecycle$1;->run()V diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index a02802859ca7..41de97c8bcbb 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -698,6 +698,7 @@ public class BackupManagerService implements BackupManagerServiceInterface { final SparseArray<Operation> mCurrentOperations = new SparseArray<Operation>(); final Object mCurrentOpLock = new Object(); final Random mTokenGenerator = new Random(); + final AtomicInteger mNextToken = new AtomicInteger(); final SparseArray<AdbParams> mAdbBackupRestoreConfirmations = new SparseArray<AdbParams>(); @@ -770,15 +771,13 @@ public class BackupManagerService implements BackupManagerServiceInterface { @GuardedBy("mQueueLock") ArrayList<FullBackupEntry> mFullBackupQueue; - // Utility: build a new random integer token + // Utility: build a new random integer token. The low bits are the ordinal of the + // operation for near-time uniqueness, and the upper bits are random for app- + // side unpredictability. @Override public int generateRandomIntegerToken() { - int token; - do { - synchronized (mTokenGenerator) { - token = mTokenGenerator.nextInt(); - } - } while (token < 0); + int token = mTokenGenerator.nextInt() & ~0xFF; + token |= (mNextToken.incrementAndGet() & 0xFF); return token; } diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index eda283e82d79..966e553a6396 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -243,8 +243,9 @@ public class LocationManagerService extends ILocationManager.Stub { private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider; - private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider; private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; + + private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider; private IBatchedLocationCallback mGnssBatchingCallback; private LinkedCallback mGnssBatchingDeathCallback; private boolean mGnssBatchingInProgress = false; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index f59d18ebe6a4..b46e5e54d158 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -164,7 +164,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILIT import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS; import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED; import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY; @@ -211,8 +210,6 @@ import android.app.ApplicationThreadConstants; import android.app.BroadcastOptions; import android.app.ContentProviderHolder; import android.app.Dialog; -import android.app.IActivityContainer; -import android.app.IActivityContainerCallback; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IAppTask; @@ -4122,8 +4119,7 @@ public class ActivityManagerService extends IActivityManager.Stub ri.activityInfo.packageName, ri.activityInfo.name)); mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/, null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0, - null, 0, 0, 0, null, false, false, null, null, null, - "startSetupActivity"); + null, 0, 0, 0, null, false, false, null, null, "startSetupActivity"); } } } @@ -4461,26 +4457,6 @@ public class ActivityManagerService extends IActivityManager.Stub UserHandle.getCallingUserId()); } - final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) { - enforceNotIsolatedCaller("ActivityContainer.startActivity"); - final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false, - ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); - - // TODO: Switch to user app stacks here. - String mimeType = intent.getType(); - final Uri data = intent.getData(); - if (mimeType == null && data != null && "content".equals(data.getScheme())) { - mimeType = getProviderMimeType(data, userId); - } - container.checkEmbeddedAllowedInner(userId, intent, mimeType); - - intent.addFlags(FORCE_NEW_TASK_FLAGS); - return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, - null, null, 0, 0, null, null, null, null, false, userId, container, null, - "startActivity"); - } - @Override public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, @@ -4491,8 +4467,7 @@ public class ActivityManagerService extends IActivityManager.Stub // TODO: Switch to user app stacks here. return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, - profilerInfo, null, null, bOptions, false, userId, null, null, - "startActivityAsUser"); + profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser"); } @Override @@ -4555,7 +4530,7 @@ public class ActivityManagerService extends IActivityManager.Stub try { int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, - null, null, bOptions, ignoreTargetSecurity, userId, null, null, + null, null, bOptions, ignoreTargetSecurity, userId, null, "startActivityAsCaller"); return ret; } catch (SecurityException e) { @@ -4585,7 +4560,7 @@ public class ActivityManagerService extends IActivityManager.Stub // TODO: Switch to user app stacks here. mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, - bOptions, false, userId, null, null, "startActivityAndWait"); + bOptions, false, userId, null, "startActivityAndWait"); return res; } @@ -4599,7 +4574,7 @@ public class ActivityManagerService extends IActivityManager.Stub // TODO: Switch to user app stacks here. int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, - null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig"); + null, null, config, bOptions, false, userId, null, "startActivityWithConfig"); return ret; } @@ -4630,7 +4605,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null, - resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null); + resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions); return ret; } @@ -4656,7 +4631,7 @@ public class ActivityManagerService extends IActivityManager.Stub // TODO: Switch to user app stacks here. return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent, resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, - null, bOptions, false, userId, null, null, "startVoiceActivity"); + null, bOptions, false, userId, null, "startVoiceActivity"); } @Override @@ -4675,7 +4650,7 @@ public class ActivityManagerService extends IActivityManager.Stub ALLOW_FULL_ONLY, "startAssistantActivity", null); return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent, resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false, - userId, null, null, "startAssistantActivity"); + userId, null, "startAssistantActivity"); } @Override @@ -4848,7 +4823,7 @@ public class ActivityManagerService extends IActivityManager.Stub null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null, null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options, - false, false, null, null, null, "startNextMatchingActivity"); + false, false, null, null, "startNextMatchingActivity"); Binder.restoreCallingIdentity(origId); r.finishing = wasFinishing; @@ -4880,16 +4855,15 @@ public class ActivityManagerService extends IActivityManager.Stub final int startActivityInPackage(int uid, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId, - IActivityContainer container, TaskRecord inTask, String reason) { + TaskRecord inTask, String reason) { userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null); // TODO: Switch to user app stacks here. - int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent, + return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, - null, null, null, bOptions, false, userId, container, inTask, reason); - return ret; + null, null, null, bOptions, false, userId, inTask, reason); } @Override @@ -10479,44 +10453,25 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken, - IActivityContainerCallback callback) throws RemoteException { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()"); - synchronized (this) { - if (parentActivityToken == null) { - throw new IllegalArgumentException("parent token must not be null"); - } - ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken); - if (r == null) { - return null; - } - if (callback == null) { - throw new IllegalArgumentException("callback must not be null"); - } - return mStackSupervisor.createVirtualActivityContainer(r, callback); - } - } - - @Override - public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException { + public int createStackOnDisplay(int displayId) throws RemoteException { enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()"); synchronized (this) { final int stackId = mStackSupervisor.getNextStackId(); final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/); if (stack == null) { - return null; + return INVALID_STACK_ID; } - return stack.mActivityContainer; + return stack.mStackId; } } @Override public int getActivityDisplayId(IBinder activityToken) throws RemoteException { synchronized (this) { - ActivityStack stack = ActivityRecord.getStackLocked(activityToken); - if (stack != null && stack.mActivityContainer.isAttachedLocked()) { - return stack.mActivityContainer.getDisplayId(); + final ActivityStack stack = ActivityRecord.getStackLocked(activityToken); + if (stack != null && stack.mDisplayId != INVALID_DISPLAY) { + return stack.mDisplayId; } return DEFAULT_DISPLAY; } @@ -24364,7 +24319,7 @@ public class ActivityManagerService extends IActivityManager.Stub } return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent, resolvedType, null, null, null, null, 0, 0, null, null, - null, bOptions, false, callingUser, null, tr, "AppTaskImpl"); + null, bOptions, false, callingUser, tr, "AppTaskImpl"); } @Override diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 9273b3c49074..45357cb67fd1 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -19,7 +19,6 @@ package com.android.server.am; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AppGlobals; -import android.app.IActivityContainer; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IStopUserCallback; @@ -1959,9 +1958,17 @@ final class ActivityManagerShellCommand extends ShellCommand { throw new RuntimeException(e.getMessage(), e); } - IActivityContainer container = mInterface.createStackOnDisplay(displayId); - if (container != null) { - container.startActivity(intent); + final int stackId = mInterface.createStackOnDisplay(displayId); + if (stackId != INVALID_STACK_ID) { + // TODO: Need proper support if this is used by test... +// container.startActivity(intent); +// ActivityOptions options = ActivityOptions.makeBasic(); +// options.setLaunchDisplayId(displayId); +// options.setLaunchStackId(stackId); +// mInterface.startAct +// mInterface.startActivityAsUser(null, null, intent, mimeType, +// null, null, 0, mStartFlags, profilerInfo, +// options != null ? options.toBundle() : null, mUserId); } return 0; } diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 6f68c7a1df5f..9a1d9282d9bc 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -164,7 +164,6 @@ import com.android.internal.util.XmlUtils; import com.android.server.AttributeCache; import com.android.server.AttributeCache.Entry; import com.android.server.am.ActivityStack.ActivityState; -import com.android.server.am.ActivityStackSupervisor.ActivityContainer; import com.android.server.wm.AppWindowContainerController; import com.android.server.wm.AppWindowContainerListener; import com.android.server.wm.TaskWindowContainerController; @@ -306,7 +305,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo int launchCount; // count of launches since last state long lastLaunchTime; // time of last launch of this activity ComponentName requestedVrComponent; // the requested component for handling VR mode. - ArrayList<ActivityContainer> mChildContainers = new ArrayList<>(); String stringName; // for caching of toString(). @@ -320,7 +318,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo boolean mTaskOverlay = false; // Task is always on-top of other activities in the task. boolean mUpdateTaskThumbnailWhenHidden; - ActivityContainer mInitialActivityContainer; TaskDescription taskDescription; // the recents information for this activity boolean mLaunchTaskBehind; // this activity is actively being launched with @@ -798,8 +795,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo ActivityInfo aInfo, Configuration _configuration, ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified, boolean _rootVoiceInteraction, - ActivityStackSupervisor supervisor, - ActivityContainer container, ActivityOptions options, ActivityRecord sourceRecord) { + ActivityStackSupervisor supervisor, ActivityOptions options, + ActivityRecord sourceRecord) { service = _service; appToken = new Token(this); info = aInfo; @@ -830,7 +827,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo idle = false; hasBeenLaunched = false; mStackSupervisor = supervisor; - mInitialActivityContainer = container; mRotationAnimationHint = aInfo.rotationAnimation; @@ -1595,11 +1591,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo mUpdateTaskThumbnailWhenHidden = false; } setVisibility(visible); - final ArrayList<ActivityContainer> containers = mChildContainers; - for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) { - final ActivityContainer container = containers.get(containerNdx); - container.setVisible(visible); - } mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true; } @@ -2615,8 +2606,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo startFreezingScreenLocked(app, 0); - mStackSupervisor.removeChildActivityContainers(this); - try { if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this @@ -2795,7 +2784,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType, aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */, 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */, - stackSupervisor, null /* container */, null /* options */, null /* sourceRecord */); + stackSupervisor, null /* options */, null /* sourceRecord */); r.persistentState = persistentState; r.taskDescription = taskDescription; diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index ab76529cf5f6..ce8aa5edad47 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -30,6 +30,7 @@ import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; +import static android.view.Display.INVALID_DISPLAY; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_APP; @@ -124,7 +125,6 @@ import com.android.internal.app.IVoiceInteractor; import com.android.internal.os.BatteryStatsImpl; import com.android.server.Watchdog; import com.android.server.am.ActivityManagerService.ItemMatcher; -import com.android.server.am.ActivityStackSupervisor.ActivityContainer; import com.android.server.wm.StackWindowController; import com.android.server.wm.StackWindowListener; import com.android.server.wm.WindowManagerService; @@ -205,7 +205,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai @Override protected ConfigurationContainer getParent() { - return mActivityContainer.mActivityDisplay; + return getDisplay(); } @Override @@ -336,8 +336,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai int mCurrentUser; final int mStackId; - final ActivityContainer mActivityContainer; /** The other stacks, in order, on the attached display. Updated at attach/detach time. */ + // TODO: This list doesn't belong here... ArrayList<ActivityStack> mStacks; /** The attached Display's unique identifier, or -1 if detached */ int mDisplayId; @@ -447,24 +447,21 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai return count; } - ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer, - RecentTasks recentTasks, boolean onTop) { - mActivityContainer = activityContainer; - mStackSupervisor = activityContainer.getOuter(); - mService = mStackSupervisor.mService; + ActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId, + ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) { + mStackSupervisor = supervisor; + mService = supervisor.mService; mHandler = new ActivityStackHandler(mService.mHandler.getLooper()); mWindowManager = mService.mWindowManager; - mStackId = activityContainer.mStackId; + mStackId = stackId; mCurrentUser = mService.mUserController.getCurrentUserIdLocked(); mRecentTasks = recentTasks; mTaskPositioner = mStackId == FREEFORM_WORKSPACE_STACK_ID ? new LaunchingTaskPositioner() : null; - final ActivityStackSupervisor.ActivityDisplay display = mActivityContainer.mActivityDisplay; mTmpRect2.setEmpty(); mWindowContainerController = createStackWindowController(display.mDisplayId, onTop, mTmpRect2); - activityContainer.mStack = this; - mStackSupervisor.mActivityContainers.put(mStackId, activityContainer); + mStackSupervisor.mStacks.put(mStackId, this); postAddToDisplay(display, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop); } @@ -521,7 +518,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * either destroyed completely or re-parented. */ private void removeFromDisplay() { - mDisplayId = Display.INVALID_DISPLAY; + final ActivityStackSupervisor.ActivityDisplay display = getDisplay(); + if (display != null) { + display.detachStack(this); + } + mDisplayId = INVALID_DISPLAY; mStacks = null; if (mTaskPositioner != null) { mTaskPositioner.reset(); @@ -537,14 +538,18 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai /** Removes the stack completely. Also calls WindowManager to do the same on its side. */ void remove() { removeFromDisplay(); - mStackSupervisor.deleteActivityContainerRecord(mStackId); + mStackSupervisor.mStacks.remove(mStackId); mWindowContainerController.removeContainer(); mWindowContainerController = null; onParentChanged(); } + ActivityStackSupervisor.ActivityDisplay getDisplay() { + return mStackSupervisor.getActivityDisplay(mDisplayId); + } + void getDisplaySize(Point out) { - mActivityContainer.mActivityDisplay.mDisplay.getSize(out); + getDisplay().mDisplay.getSize(out); } /** @@ -829,8 +834,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } final boolean isOnHomeDisplay() { - return isAttached() && - mActivityContainer.mActivityDisplay.mDisplayId == DEFAULT_DISPLAY; + return isAttached() && mDisplayId == DEFAULT_DISPLAY; } void moveToFront(String reason) { @@ -1257,12 +1261,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai return false; } - if (mActivityContainer.mParentActivity == null) { - // Top level stack, not a child. Look for child stacks. - mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, - pauseImmediately); - } - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev); else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev); mResumedActivity = null; @@ -1965,8 +1963,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied. */ private boolean canShowWithInsecureKeyguard() { - final ActivityStackSupervisor.ActivityDisplay activityDisplay - = mActivityContainer.mActivityDisplay; + final ActivityStackSupervisor.ActivityDisplay activityDisplay = getDisplay(); if (activityDisplay == null) { throw new IllegalStateException("Stack is not attached to any display, stackId=" + mStackId); @@ -2108,7 +2105,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * occurred and the activity will be notified immediately. */ void notifyActivityDrawnLocked(ActivityRecord r) { - mActivityContainer.setDrawn(); if ((r == null) || (mUndrawnActivitiesBelowTopTranslucent.remove(r) && mUndrawnActivitiesBelowTopTranslucent.isEmpty())) { @@ -2236,12 +2232,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai final boolean hasRunningActivity = next != null; - final ActivityRecord parent = mActivityContainer.mParentActivity; - final boolean isParentNotResumed = parent != null && parent.state != ActivityState.RESUMED; - if (hasRunningActivity - && (isParentNotResumed || !mActivityContainer.isAttachedLocked())) { - // Do not resume this stack if its parent is not resumed. - // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st. + // TODO: Maybe this entire condition can get removed? + if (hasRunningActivity && getDisplay() == null) { return false; } @@ -3809,7 +3801,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } if (noActivitiesInStack) { - mActivityContainer.onTaskListEmptyLocked(); + remove(); } } @@ -3920,7 +3912,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai destIntent, null /*ephemeralIntent*/, null, aInfo, null /*rInfo*/, null, null, parent.appToken, null, 0, -1, parent.launchedFromUid, parent.launchedFromPackage, -1, parent.launchedFromUid, 0, null, - false, true, null, null, null, "navigateUpTo"); + false, true, null, null, "navigateUpTo"); foundParentInTask = res == ActivityManager.START_SUCCESS; } catch (RemoteException e) { foundParentInTask = false; @@ -4005,7 +3997,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) { - mStackSupervisor.removeChildActivityContainers(r); finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null); r.makeFinishingLocked(); if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE, @@ -4620,7 +4611,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * focus may be on another display. */ private ActivityStack getTopStackOnDisplay() { - final ArrayList<ActivityStack> stacks = mActivityContainer.mActivityDisplay.mStacks; + final ArrayList<ActivityStack> stacks = getDisplay().mStacks; return stacks.isEmpty() ? null : stacks.get(stacks.size() - 1); } @@ -5097,7 +5088,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai mStacks.add(0, this); } if (!isHomeOrRecentsStack()) { - mActivityContainer.onTaskListEmptyLocked(); + remove(); } } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 90d9149a2f66..d9b7d761a7d2 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -36,8 +36,6 @@ import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.ActivityManager.StackId.RECENTS_STACK_ID; import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY; import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN; -import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; -import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.SYSTEM_UID; import static android.os.PowerManager.PARTIAL_WAKE_LOCK; @@ -50,7 +48,6 @@ import static android.view.Display.TYPE_VIRTUAL; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; -import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; @@ -72,7 +69,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS; -import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityManagerService.ANIMATE; @@ -112,7 +108,6 @@ import android.app.ActivityManager.StackId; import android.app.ActivityManager.StackInfo; import android.app.ActivityOptions; import android.app.AppOpsManager; -import android.app.IActivityContainerCallback; import android.app.ProfilerInfo; import android.app.ResultInfo; import android.app.StatusBarManager; @@ -120,7 +115,6 @@ import android.app.WaitResult; import android.app.admin.IDevicePolicyManager; import android.content.ComponentName; import android.content.Context; -import android.content.IIntentSender; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; @@ -132,10 +126,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; -import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.DisplayManagerInternal; -import android.hardware.display.VirtualDisplay; -import android.hardware.input.InputManager; import android.hardware.input.InputManagerInternal; import android.os.Binder; import android.os.Bundle; @@ -151,7 +142,6 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.Trace; -import android.os.TransactionTooLargeException; import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; @@ -168,9 +158,8 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.Display; -import android.view.InputEvent; -import android.view.Surface; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.ReferrerIntent; import com.android.internal.logging.MetricsLogger; import com.android.internal.os.TransferPipe; @@ -194,7 +183,6 @@ import java.util.Set; public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM; - private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS; private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; private static final String TAG_IDLE = TAG + POSTFIX_IDLE; private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; @@ -205,7 +193,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D private static final String TAG_STATES = TAG + POSTFIX_STATES; private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; static final String TAG_TASKS = TAG + POSTFIX_TASKS; - private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND; /** How long we wait until giving up on the last activity telling us it is idle. */ static final int IDLE_TIMEOUT = 10 * 1000; @@ -224,10 +211,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; - static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8; static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9; static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10; - static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11; static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12; static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13; static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14; @@ -414,7 +399,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // TODO: Add listener for removal of references. /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */ - SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>(); + SparseArray<ActivityStack> mStacks = new SparseArray<>(); // TODO: There should be an ActivityDisplayController coordinating am/wm interaction. /** Mapping from displayId to display current state */ @@ -680,31 +665,15 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } boolean isFocusedStack(ActivityStack stack) { - if (stack == null) { - return false; - } - - final ActivityRecord parent = stack.mActivityContainer.mParentActivity; - if (parent != null) { - stack = parent.getStack(); - } - return stack == mFocusedStack; + return stack != null && stack == mFocusedStack; } /** The top most stack on its display. */ boolean isFrontStackOnDisplay(ActivityStack stack) { - return isFrontOfStackList(stack, stack.mActivityContainer.mActivityDisplay.mStacks); + return isFrontOfStackList(stack, stack.getDisplay().mStacks); } private boolean isFrontOfStackList(ActivityStack stack, List<ActivityStack> stackList) { - if (stack == null) { - return false; - } - - final ActivityRecord parent = stack.mActivityContainer.mParentActivity; - if (parent != null) { - stack = parent.getStack(); - } return stack == stackList.get((stackList.size() - 1)); } @@ -1097,21 +1066,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return pausing; } - void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping, - ActivityRecord resuming, boolean dontWait) { - // TODO: Put all stacks in supervisor and iterate through them instead. - for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { - ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; - for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = stacks.get(stackNdx); - if (stack.mResumedActivity != null && - stack.mActivityContainer.mParentActivity == parent) { - stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait); - } - } - } - } - void cancelInitializingActivities() { for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; @@ -2210,9 +2164,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D protected <T extends ActivityStack> T getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) { - final ActivityContainer activityContainer = mActivityContainers.get(stackId); - if (activityContainer != null) { - return (T) activityContainer.mStack; + final ActivityStack stack = mStacks.get(stackId); + if (stack != null) { + return (T) stack; } if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) { return null; @@ -2355,33 +2309,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null); } - ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity, - IActivityContainerCallback callback) { - ActivityContainer activityContainer = - new VirtualActivityContainer(parentActivity, callback); - mActivityContainers.put(activityContainer.mStackId, activityContainer); - if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, - "createActivityContainer: " + activityContainer); - parentActivity.mChildContainers.add(activityContainer); - return activityContainer; - } - - void removeChildActivityContainers(ActivityRecord parentActivity) { - final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; - for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { - ActivityContainer container = childStacks.remove(containerNdx); - if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing " - + container); - container.release(); - } - } - - void deleteActivityContainerRecord(int stackId) { - if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, - "deleteActivityContainerRecord: callers=" + Debug.getCallers(4)); - mActivityContainers.remove(stackId); - } - void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds, boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) { if (stackId == DOCKED_STACK_ID) { @@ -2646,12 +2573,18 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D if (activityDisplay == null) { return null; } + return createStack(stackId, activityDisplay, onTop); - final ActivityContainer activityContainer = - new ActivityContainer(stackId, activityDisplay, onTop); - return activityContainer.mStack; } + ActivityStack createStack(int stackId, ActivityDisplay display, boolean onTop) { + switch (stackId) { + case PINNED_STACK_ID: + return new PinnedActivityStack(display, stackId, this, mRecentTasks, onTop); + default: + return new ActivityStack(display, stackId, this, mRecentTasks, onTop); + } + } void removeStackInSurfaceTransaction(int stackId) { final ActivityStack stack = getStack(stackId); @@ -2879,23 +2812,24 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown displayId=" + displayId); } - final ActivityContainer activityContainer = mActivityContainers.get(stackId); - if (activityContainer != null) { - if (activityContainer.isAttachedLocked()) { - if (activityContainer.getDisplayId() == displayId) { - throw new IllegalArgumentException("Trying to move stackId=" + stackId - + " to its current displayId=" + displayId); - } - - activityContainer.moveToDisplayLocked(activityDisplay, onTop); - } else { - throw new IllegalStateException("moveStackToDisplayLocked: Stack with stackId=" - + stackId + " is not attached to any display."); - } - } else { + final ActivityStack stack = mStacks.get(stackId); + if (stack == null) { throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown stackId=" + stackId); } + + final ActivityDisplay currentDisplay = stack.getDisplay(); + if (currentDisplay == null) { + throw new IllegalStateException("moveStackToDisplayLocked: Stack with stack=" + stack + + " is not attached to any display."); + } + + if (currentDisplay.mDisplayId == displayId) { + throw new IllegalArgumentException("Trying to move stack=" + stack + + " to its current displayId=" + displayId); + } + + stack.reparent(activityDisplay, onTop); // TODO(multi-display): resize stacks properly if moved from split-screen. } @@ -2923,7 +2857,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Ensure that we're not moving a task to a dynamic stack if device doesn't support // multi-display. // TODO(multi-display): Support non-dynamic stacks on secondary displays. - // TODO: Check ActivityView after fixing b/35349678. if (StackId.isDynamicStack(stackId) && !mService.mSupportsMultiDisplay) { throw new IllegalArgumentException("Device doesn't support multi-display, can not" + " reparent task=" + task + " to stackId=" + stackId); @@ -3107,11 +3040,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D + stack); continue; } - if (!stack.mActivityContainer.isEligibleForNewTasks()) { - if (DEBUG_TASKS) Slog.d(TAG_TASKS, - "Skipping stack: (new task not allowed) " + stack); - continue; - } stack.findTaskLocked(r, mTmpFindTaskResult); // It is possible to have tasks in multiple stacks with the same root affinity, so // we should keep looking after finding an affinity match to see if there is a @@ -3626,7 +3554,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D pw.print(prefix); pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser); pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); - pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); + pw.print(prefix); pw.println("mStacks=" + mStacks); pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString()); final SparseArray<String[]> packages = mService.mLockTaskPackages; if (packages.size() > 0) { @@ -3920,6 +3848,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return getActivityDisplayOrCreateLocked(displayId) != null; } + ActivityDisplay getActivityDisplay(int displayId) { + return mActivityDisplays.get(displayId); + } + /** * Get an existing instance of {@link ActivityDisplay} or create new if there is a * corresponding record in display manager. @@ -4481,16 +4413,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D case HANDLE_DISPLAY_REMOVED: { handleDisplayRemoved(msg.arg1); } break; - case CONTAINER_CALLBACK_VISIBILITY: { - final ActivityContainer container = (ActivityContainer) msg.obj; - final IActivityContainerCallback callback = container.mCallback; - if (callback != null) { - try { - callback.setVisible(container.asBinder(), msg.arg1 == 1); - } catch (RemoteException e) { - } - } - } break; case LOCK_TASK_START_MSG: { // When lock task starts, we disable the status bars. try { @@ -4563,16 +4485,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED); } break; - case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { - final ActivityContainer container = (ActivityContainer) msg.obj; - final IActivityContainerCallback callback = container.mCallback; - if (callback != null) { - try { - callback.onAllActivitiesComplete(container.asBinder()); - } catch (RemoteException e) { - } - } - } break; case LAUNCH_TASK_BEHIND_COMPLETE: { synchronized (mService) { ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); @@ -4586,340 +4498,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } } - class ActivityContainer extends android.app.IActivityContainer.Stub { - final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK | - FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; - final int mStackId; - IActivityContainerCallback mCallback = null; - ActivityStack mStack; - ActivityRecord mParentActivity = null; - String mIdString; - - boolean mVisible = true; - - /** Display this ActivityStack is currently on. Null if not attached to a Display. */ - ActivityDisplay mActivityDisplay; - - final static int CONTAINER_STATE_HAS_SURFACE = 0; - final static int CONTAINER_STATE_NO_SURFACE = 1; - final static int CONTAINER_STATE_FINISHING = 2; - int mContainerState = CONTAINER_STATE_HAS_SURFACE; - - ActivityContainer(int stackId, ActivityDisplay activityDisplay, boolean onTop) { - synchronized (mService) { - mStackId = stackId; - mActivityDisplay = activityDisplay; - mIdString = "ActivtyContainer{" + mStackId + "}"; - - createStack(stackId, onTop); - if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this); - } - } - - protected void createStack(int stackId, boolean onTop) { - switch (stackId) { - case PINNED_STACK_ID: - new PinnedActivityStack(this, mRecentTasks, onTop); - break; - default: - new ActivityStack(this, mRecentTasks, onTop); - break; - } - } - - /** - * Adds the stack to specified display. Also calls WindowManager to do the same from - * {@link ActivityStack#reparent(ActivityDisplay, boolean)}. - * @param activityDisplay The display to add the stack to. - */ - void addToDisplayLocked(ActivityDisplay activityDisplay) { - if (DEBUG_STACK) Slog.d(TAG_STACK, "addToDisplayLocked: " + this - + " to display=" + activityDisplay); - if (mActivityDisplay != null) { - throw new IllegalStateException("ActivityContainer is already attached, " + - "displayId=" + mActivityDisplay.mDisplayId); - } - mActivityDisplay = activityDisplay; - mStack.reparent(activityDisplay, true /* onTop */); - } - - @Override - public void addToDisplay(int displayId) { - synchronized (mService) { - final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); - if (activityDisplay == null) { - return; - } - addToDisplayLocked(activityDisplay); - } - } - - @Override - public int getDisplayId() { - synchronized (mService) { - if (mActivityDisplay != null) { - return mActivityDisplay.mDisplayId; - } - } - return -1; - } - - @Override - public int getStackId() { - synchronized (mService) { - return mStackId; - } - } - - @Override - public boolean injectEvent(InputEvent event) { - final long origId = Binder.clearCallingIdentity(); - try { - synchronized (mService) { - if (mActivityDisplay != null) { - return mInputManagerInternal.injectInputEvent(event, - mActivityDisplay.mDisplayId, - InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); - } - } - return false; - } finally { - Binder.restoreCallingIdentity(origId); - } - } - - @Override - public void release() { - synchronized (mService) { - if (mContainerState == CONTAINER_STATE_FINISHING) { - return; - } - mContainerState = CONTAINER_STATE_FINISHING; - - long origId = Binder.clearCallingIdentity(); - try { - mStack.finishAllActivitiesLocked(false); - mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - /** - * Remove the stack completely. Must be called only when there are no tasks left in it, - * as this method does not finish running activities. - */ - void removeLocked() { - if (DEBUG_STACK) Slog.d(TAG_STACK, "removeLocked: " + this + " from display=" - + mActivityDisplay + " Callers=" + Debug.getCallers(2)); - if (mActivityDisplay != null) { - removeFromDisplayLocked(); - } - mStack.remove(); - } - - /** - * Remove the stack from its current {@link ActivityDisplay}, so it can be either destroyed - * completely or re-parented. - */ - private void removeFromDisplayLocked() { - if (DEBUG_STACK) Slog.d(TAG_STACK, "removeFromDisplayLocked: " + this - + " current displayId=" + mActivityDisplay.mDisplayId); - - mActivityDisplay.detachStack(mStack); - mActivityDisplay = null; - } - - /** - * Move the stack to specified display. - * @param activityDisplay Target display to move the stack to. - * @param onTop Indicates whether container should be place on top or on bottom. - */ - void moveToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) { - if (DEBUG_STACK) Slog.d(TAG_STACK, "moveToDisplayLocked: " + this + " from display=" - + mActivityDisplay + " to display=" + activityDisplay - + " Callers=" + Debug.getCallers(2)); - - removeFromDisplayLocked(); - - mActivityDisplay = activityDisplay; - mStack.reparent(activityDisplay, onTop); - } - - @Override - public final int startActivity(Intent intent) { - return mService.startActivity(intent, this); - } - - @Override - public final int startActivityIntentSender(IIntentSender intentSender) - throws TransactionTooLargeException { - mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); - - if (!(intentSender instanceof PendingIntentRecord)) { - throw new IllegalArgumentException("Bad PendingIntent object"); - } - - final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), mCurrentUser, false, - ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); - - final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; - checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent, - pendingIntent.key.requestResolvedType); - - return pendingIntent.sendInner(0, null, null, null, null, null, null, null, 0, - FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); - } - - void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) { - ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId); - if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { - throw new SecurityException( - "Attempt to embed activity that has not set allowEmbedded=\"true\""); - } - } - - @Override - public IBinder asBinder() { - return this; - } - - @Override - public void setSurface(Surface surface, int width, int height, int density) { - mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); - } - - ActivityStackSupervisor getOuter() { - return ActivityStackSupervisor.this; - } - - boolean isAttachedLocked() { - return mActivityDisplay != null; - } - - // TODO: Make sure every change to ActivityRecord.visible results in a call to this. - void setVisible(boolean visible) { - if (mVisible != visible) { - mVisible = visible; - if (mCallback != null) { - mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, - 0 /* unused */, this).sendToTarget(); - } - } - } - - void setDrawn() { - } - - // You can always start a new task on a regular ActivityStack. - boolean isEligibleForNewTasks() { - return true; - } - - void onTaskListEmptyLocked() { - removeLocked(); - mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); - } - - @Override - public String toString() { - return mIdString + (mActivityDisplay == null ? "N" : "A"); - } - } - - private class VirtualActivityContainer extends ActivityContainer { - Surface mSurface; - boolean mDrawn = false; - - VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { - super(getNextStackId(), parent.getStack().mActivityContainer.mActivityDisplay, - true /* onTop */); - mParentActivity = parent; - mCallback = callback; - mContainerState = CONTAINER_STATE_NO_SURFACE; - mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; - } - - @Override - public void setSurface(Surface surface, int width, int height, int density) { - super.setSurface(surface, width, height, density); - - synchronized (mService) { - final long origId = Binder.clearCallingIdentity(); - try { - setSurfaceLocked(surface, width, height, density); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - private void setSurfaceLocked(Surface surface, int width, int height, int density) { - if (mContainerState == CONTAINER_STATE_FINISHING) { - return; - } - VirtualActivityDisplay virtualActivityDisplay = - (VirtualActivityDisplay) mActivityDisplay; - if (virtualActivityDisplay == null) { - virtualActivityDisplay = - new VirtualActivityDisplay(width, height, density); - mActivityDisplay = virtualActivityDisplay; - mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); - addToDisplayLocked(virtualActivityDisplay); - } - - if (mSurface != null) { - mSurface.release(); - } - - mSurface = surface; - if (surface != null) { - resumeFocusedStackTopActivityLocked(); - } else { - mContainerState = CONTAINER_STATE_NO_SURFACE; - ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); - if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { - mStack.startPausingLocked(false, true, null, false); - } - } - - setSurfaceIfReadyLocked(); - - if (DEBUG_STACK) Slog.d(TAG_STACK, - "setSurface: " + this + " to display=" + virtualActivityDisplay); - } - - @Override - boolean isAttachedLocked() { - return mSurface != null && super.isAttachedLocked(); - } - - @Override - void setDrawn() { - synchronized (mService) { - mDrawn = true; - setSurfaceIfReadyLocked(); - } - } - - // Never start a new task on an ActivityView if it isn't explicitly specified. - @Override - boolean isEligibleForNewTasks() { - return false; - } - - private void setSurfaceIfReadyLocked() { - if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + - " mContainerState=" + mContainerState + " mSurface=" + mSurface); - if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { - ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); - mContainerState = CONTAINER_STATE_HAS_SURFACE; - } - } - } - + // TODO: Move to its own file. /** Exactly one of these classes per Display in the system. Capable of holding zero or more * attached {@link ActivityStack}s */ class ActivityDisplay extends ConfigurationContainer { @@ -4934,7 +4513,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D /** Array of all UIDs that are present on the display. */ private IntArray mDisplayAccessUIDs = new IntArray(); + @VisibleForTesting ActivityDisplay() { + mActivityDisplays.put(mDisplayId, this); } // After instantiation, check that mDisplay is not null before using this. The alternative @@ -5011,43 +4592,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } } - class VirtualActivityDisplay extends ActivityDisplay { - VirtualDisplay mVirtualDisplay; - - VirtualActivityDisplay(int width, int height, int density) { - DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); - mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null /* projection */, - VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null /* surface */, - DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | - DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null /* callback */, - null /* handler */, null /* uniqueId */); - - init(mVirtualDisplay.getDisplay()); - - mWindowManager.onDisplayAdded(mDisplayId); - } - - void setSurface(Surface surface) { - if (mVirtualDisplay != null) { - mVirtualDisplay.setSurface(surface); - } - } - - @Override - void detachStack(ActivityStack stack) { - super.detachStack(stack); - if (mVirtualDisplay != null) { - mVirtualDisplay.release(); - mVirtualDisplay = null; - } - } - - @Override - public String toString() { - return "VirtualActivityDisplay={" + mDisplayId + "}"; - } - } - ActivityStack findStackBehind(ActivityStack stack) { // TODO(multi-display): We are only looking for stacks on the default display. final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY); @@ -5154,7 +4698,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); userId = task.userId; int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null, - null, null, 0, 0, bOptions, userId, null, task, "startActivityFromRecents"); + null, null, 0, 0, bOptions, userId, task, "startActivityFromRecents"); if (launchStackId == DOCKED_STACK_ID) { setResizingDuringAnimation(task); } diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 4f04066c6076..749583225bb2 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -90,12 +90,10 @@ import android.annotation.NonNull; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AppGlobals; -import android.app.IActivityContainer; import android.app.IApplicationThread; import android.app.PendingIntent; import android.app.ProfilerInfo; import android.app.WaitResult; -import android.content.ComponentName; import android.content.IIntentSender; import android.content.Intent; import android.content.IntentSender; @@ -260,8 +258,7 @@ class ActivityStarter { IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, - ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, - TaskRecord inTask, String reason) { + ActivityRecord[] outActivity, TaskRecord inTask, String reason) { if (TextUtils.isEmpty(reason)) { throw new IllegalArgumentException("Need to specify a reason."); @@ -274,7 +271,7 @@ class ActivityStarter { aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord, - container, inTask); + inTask); if (outActivity != null) { // mLastStartActivityRecord[0] is set in the call to startActivity above. @@ -292,8 +289,7 @@ class ActivityStarter { IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, - ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, - TaskRecord inTask) { + ActivityRecord[] outActivity, TaskRecord inTask) { int err = ActivityManager.START_SUCCESS; // Pull the optional Ephemeral Installer-only bundle out of the options early. final Bundle verificationBundle @@ -505,10 +501,8 @@ class ActivityStarter { if (DEBUG_PERMISSIONS_REVIEW) { Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) + "} from uid " + callingUid + " on display " - + (container == null ? (mSupervisor.mFocusedStack == null ? - DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId) : - (container.mActivityDisplay == null ? DEFAULT_DISPLAY : - container.mActivityDisplay.mDisplayId))); + + (mSupervisor.mFocusedStack == null + ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId)); } } } @@ -530,7 +524,7 @@ class ActivityStarter { ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, - mSupervisor, container, options, sourceRecord); + mSupervisor, options, sourceRecord); if (outActivity != null) { outActivity[0] = r; } @@ -649,7 +643,7 @@ class ActivityStarter { null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/, 0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/, false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/, - null /*container*/, null /*inTask*/, "startHomeActivity: " + reason); + null /*inTask*/, "startHomeActivity: " + reason); if (mSupervisor.inResumeTopActivity) { // If we are in resume section already, home activity will be initialized, but not // resumed (to avoid recursive resume) and will stay that way until something pokes it @@ -674,7 +668,7 @@ class ActivityStarter { IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId, - IActivityContainer iContainer, TaskRecord inTask, String reason) { + TaskRecord inTask, String reason) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); @@ -727,14 +721,7 @@ class ActivityStarter { ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); ActivityOptions options = ActivityOptions.fromBundle(bOptions); - ActivityStackSupervisor.ActivityContainer container = - (ActivityStackSupervisor.ActivityContainer)iContainer; synchronized (mService) { - if (container != null && container.mParentActivity != null && - container.mParentActivity.state != RESUMED) { - // Cannot start a child activity if the parent is not resumed. - return ActivityManager.START_CANCELED; - } final int realCallingPid = Binder.getCallingPid(); final int realCallingUid = Binder.getCallingUid(); int callingPid; @@ -747,12 +734,7 @@ class ActivityStarter { callingPid = callingUid = -1; } - final ActivityStack stack; - if (container == null || container.mStack.isOnHomeDisplay()) { - stack = mSupervisor.mFocusedStack; - } else { - stack = container.mStack; - } + final ActivityStack stack = mSupervisor.mFocusedStack; stack.mConfigWillChange = globalConfig != null && mService.getGlobalConfiguration().diff(globalConfig) != 0; if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, @@ -828,8 +810,8 @@ class ActivityStarter { aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, - options, ignoreTargetSecurity, componentSpecified, outRecord, container, - inTask, reason); + options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, + reason); Binder.restoreCallingIdentity(origId); @@ -954,7 +936,7 @@ class ActivityStarter { resolvedTypes[i], aInfo, null /*rInfo*/, null, null, resultTo, null, -1, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, 0, - options, false, componentSpecified, outActivity, null, null, reason); + options, false, componentSpecified, outActivity, null, reason); if (res < 0) { return res; } @@ -2069,13 +2051,6 @@ class ActivityStarter { return currentStack; } - final ActivityStackSupervisor.ActivityContainer container = r.mInitialActivityContainer; - if (container != null) { - // The first time put it on the desired stack, after this put on task stack. - r.mInitialActivityContainer = null; - return container.mStack; - } - if (canLaunchIntoFocusedStack(r, newTask)) { if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack); @@ -2140,13 +2115,11 @@ class ActivityStarter { default: // Dynamic stacks behave similarly to the fullscreen stack and can contain any // resizeable task. - // TODO: Check ActivityView after fixing b/35349678. canUseFocusedStack = isDynamicStack(focusedStackId) && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId); } - return canUseFocusedStack - && (!newTask || focusedStack.mActivityContainer.isEligibleForNewTasks()) + return canUseFocusedStack && !newTask // We strongly prefer to launch activities on the same display as their source. && (mSourceDisplayId == focusedStack.mDisplayId); } @@ -2212,9 +2185,7 @@ class ActivityStarter { // The parent activity doesn't want to launch the activity on top of itself, but // instead tries to put it onto other side in side-by-side mode. - final ActivityStack parentStack = task != null ? task.getStack() - : r.mInitialActivityContainer != null ? r.mInitialActivityContainer.mStack - : mSupervisor.mFocusedStack; + final ActivityStack parentStack = task != null ? task.getStack(): mSupervisor.mFocusedStack; if (parentStack != mSupervisor.mFocusedStack) { // If task's parent stack is not focused - use it during adjacent launch. @@ -2265,7 +2236,6 @@ class ActivityStarter { case ASSISTANT_STACK_ID: return r.isAssistantActivity(); default: - // TODO: Check ActivityView after fixing b/35349678. if (StackId.isDynamicStack(stackId)) { return r.canBeLaunchedOnDisplay(displayId); } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 0d1c579f2b81..fc03db1203bd 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -409,10 +409,9 @@ class AppErrors { final Set<String> cats = task.intent.getCategories(); if (cats != null && cats.contains(Intent.CATEGORY_LAUNCHER)) { mService.startActivityInPackage(task.mCallingUid, - task.mCallingPackage, task.intent, - null, null, null, 0, 0, - ActivityOptions.makeBasic().toBundle(), - task.userId, null, null, "AppErrors"); + task.mCallingPackage, task.intent, null, null, null, 0, 0, + ActivityOptions.makeBasic().toBundle(), task.userId, null, + "AppErrors"); } } } diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index cad5dcf6b565..ee593866da68 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -20,7 +20,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import android.app.ActivityManager; -import android.app.IActivityContainer; import android.content.IIntentSender; import android.content.IIntentReceiver; import android.app.PendingIntent; @@ -37,7 +36,6 @@ import android.util.Slog; import android.util.TimeUtils; import com.android.internal.os.IResultReceiver; -import com.android.server.am.ActivityStackSupervisor.ActivityContainer; import java.io.PrintWriter; import java.lang.ref.WeakReference; @@ -234,30 +232,23 @@ final class PendingIntentRecord extends IIntentSender.Stub { public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver, - requiredPermission, null, null, 0, 0, 0, options, null); + requiredPermission, null, null, 0, 0, 0, options); } public int sendWithResult(int code, Intent intent, String resolvedType, IBinder whitelistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { return sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver, - requiredPermission, null, null, 0, 0, 0, options, null); + requiredPermission, null, null, 0, 0, 0, options); } int sendInner(int code, Intent intent, String resolvedType, IBinder whitelistToken, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, - int flagsMask, int flagsValues, Bundle options, IActivityContainer container) { + int flagsMask, int flagsValues, Bundle options) { if (intent != null) intent.setDefusable(true); if (options != null) options.setDefusable(true); synchronized (owner) { - final ActivityContainer activityContainer = (ActivityContainer)container; - if (activityContainer != null && activityContainer.mParentActivity != null && - activityContainer.mParentActivity.state - != ActivityStack.ActivityState.RESUMED) { - // Cannot start a child activity if the parent is not resumed. - return ActivityManager.START_CANCELED; - } if (!canceled) { sent = true; if ((key.flags&PendingIntent.FLAG_ONE_SHOT) != 0) { @@ -346,7 +337,7 @@ final class PendingIntentRecord extends IIntentSender.Stub { } else { owner.startActivityInPackage(uid, key.packageName, finalIntent, resolvedType, resultTo, resultWho, requestCode, 0, - options, userId, container, null, "PendingIntentRecord"); + options, userId, null, "PendingIntentRecord"); } } catch (RuntimeException e) { Slog.w(TAG, "Unable to send startActivity intent", e); diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java index 2010c24000e8..392fbb29d091 100644 --- a/services/core/java/com/android/server/am/PinnedActivityStack.java +++ b/services/core/java/com/android/server/am/PinnedActivityStack.java @@ -20,7 +20,6 @@ import android.app.RemoteAction; import android.content.res.Configuration; import android.graphics.Rect; -import com.android.server.am.ActivityStackSupervisor.ActivityContainer; import com.android.server.wm.PinnedStackWindowController; import com.android.server.wm.PinnedStackWindowListener; @@ -33,9 +32,9 @@ import java.util.List; class PinnedActivityStack extends ActivityStack<PinnedStackWindowController> implements PinnedStackWindowListener { - PinnedActivityStack(ActivityContainer activityContainer, - RecentTasks recentTasks, boolean onTop) { - super(activityContainer, recentTasks, onTop); + PinnedActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId, + ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) { + super(display, stackId, supervisor, recentTasks, onTop); } @Override diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 96d857354f1a..751ecef63728 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1045,8 +1045,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta } // We need to provide the current orientation of the display on which this task resides, // not the orientation of the task. - final int orientation = - getStack().mActivityContainer.mActivityDisplay.getConfiguration().orientation; + final int orientation = getStack().getDisplay().getConfiguration().orientation; return setLastThumbnailLocked(thumbnail, taskWidth, taskHeight, orientation); } diff --git a/services/core/java/com/android/server/am/VrController.java b/services/core/java/com/android/server/am/VrController.java index 048bef7b19f5..feddfe3a2169 100644 --- a/services/core/java/com/android/server/am/VrController.java +++ b/services/core/java/com/android/server/am/VrController.java @@ -163,6 +163,7 @@ final class VrController { ComponentName requestedPackage; ComponentName callingPackage; int userId; + int processId = -1; boolean changed = false; synchronized (mGlobalAmLock) { vrMode = record.requestedVrComponent != null; @@ -172,11 +173,15 @@ final class VrController { // Tell the VrController that a VR mode change is requested. changed = changeVrModeLocked(vrMode, record.app); + + if (record.app != null) { + processId = record.app.pid; + } } // Tell VrManager that a VR mode changed is requested, VrManager will handle // notifying all non-AM dependencies if needed. - vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage); + vrService.setVrMode(vrMode, requestedPackage, userId, processId, callingPackage); return changed; } diff --git a/services/core/java/com/android/server/input/InputForwarder.java b/services/core/java/com/android/server/input/InputForwarder.java new file mode 100644 index 000000000000..bebbc93e9ea5 --- /dev/null +++ b/services/core/java/com/android/server/input/InputForwarder.java @@ -0,0 +1,46 @@ +/* + * 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.server.input; + +import android.app.IInputForwarder; +import android.hardware.input.InputManagerInternal; +import android.view.InputEvent; +import android.os.Binder; + +import com.android.server.LocalServices; + +import static android.hardware.input.InputManager.INJECT_INPUT_EVENT_MODE_ASYNC; + +/** + * Basic implementation of {@link IInputForwarder}. + */ +class InputForwarder extends IInputForwarder.Stub { + + private final InputManagerInternal mInputManagerInternal; + private final int mDisplayId; + + InputForwarder(int displayId) { + mDisplayId = displayId; + mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); + } + + @Override + public boolean forwardEvent(InputEvent event) { + return mInputManagerInternal.injectInputEvent(event, mDisplayId, + INJECT_INPUT_EVENT_MODE_ASYNC); + } +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 717efbf714db..fa9b1078e8ad 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -37,6 +37,7 @@ import com.android.server.Watchdog; import org.xmlpull.v1.XmlPullParser; import android.Manifest; +import android.app.IInputForwarder; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -57,6 +58,7 @@ import android.content.res.Resources.NotFoundException; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.database.ContentObserver; +import android.hardware.display.DisplayManager; import android.hardware.display.DisplayViewport; import android.hardware.input.IInputDevicesChangedListener; import android.hardware.input.IInputManager; @@ -85,6 +87,7 @@ import android.text.TextUtils; import android.util.Slog; import android.util.SparseArray; import android.util.Xml; +import android.view.Display; import android.view.IInputFilter; import android.view.IInputFilterHost; import android.view.IWindow; @@ -1862,6 +1865,29 @@ public class InputManagerService extends IInputManager.Stub nativeMonitor(mPtr); } + // Binder call + @Override + public IInputForwarder createInputForwarder(int displayId) throws RemoteException { + if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS, + "createInputForwarder()")) { + throw new SecurityException("Requires INJECT_EVENTS permission"); + } + final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); + final Display display = displayManager.getDisplay(displayId); + if (display == null) { + throw new IllegalArgumentException( + "Can't create input forwarder for non-existent displayId: " + displayId); + } + final int callingUid = Binder.getCallingUid(); + final int displayOwnerUid = display.getOwnerUid(); + if (callingUid != displayOwnerUid) { + throw new SecurityException( + "Only owner of the display can forward input events to it."); + } + + return new InputForwarder(displayId); + } + // Native callback. private void notifyConfigurationChanged(long whenNanos) { mWindowManagerCallbacks.notifyConfigurationChanged(); diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 83bb17eeaf3c..cdf25cfe65f6 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -1754,20 +1754,32 @@ public class GnssLocationProvider implements LocationProviderInterface { } /** - * called from native code - Gps measurements callback + * called from native code - GNSS measurements callback */ private void reportMeasurementData(GnssMeasurementsEvent event) { if (!mItarSpeedLimitExceeded) { - mGnssMeasurementsProvider.onMeasurementsAvailable(event); + // send to handler to allow native to return quickly + mHandler.post(new Runnable() { + @Override + public void run() { + mGnssMeasurementsProvider.onMeasurementsAvailable(event); + } + }); } } /** - * called from native code - GPS navigation message callback + * called from native code - GNSS navigation message callback */ private void reportNavigationMessage(GnssNavigationMessage event) { if (!mItarSpeedLimitExceeded) { - mGnssNavigationMessageProvider.onNavigationMessageAvailable(event); + // send to handler to allow native to return quickly + mHandler.post(new Runnable() { + @Override + public void run() { + mGnssNavigationMessageProvider.onNavigationMessageAvailable(event); + } + }); } } diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java index caf1d6ca5e35..924520b5a0f1 100644 --- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java +++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java @@ -54,9 +54,8 @@ public abstract class GnssMeasurementsProvider } public void onGpsEnabledChanged() { - if (tryUpdateRegistrationWithService()) { - updateResult(); - } + tryUpdateRegistrationWithService(); + updateResult(); } @Override diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java index 8d2192892f74..df3c49bd2ed5 100644 --- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java +++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java @@ -55,9 +55,8 @@ public abstract class GnssNavigationMessageProvider } public void onGpsEnabledChanged() { - if (tryUpdateRegistrationWithService()) { - updateResult(); - } + tryUpdateRegistrationWithService(); + updateResult(); } @Override diff --git a/services/core/java/com/android/server/location/RemoteListenerHelper.java b/services/core/java/com/android/server/location/RemoteListenerHelper.java index ec2828b1a59f..f51bc871c04f 100644 --- a/services/core/java/com/android/server/location/RemoteListenerHelper.java +++ b/services/core/java/com/android/server/location/RemoteListenerHelper.java @@ -25,6 +25,7 @@ import android.os.IInterface; import android.os.RemoteException; import android.util.Log; +import java.lang.Runnable; import java.util.HashMap; import java.util.Map; @@ -45,7 +46,7 @@ abstract class RemoteListenerHelper<TListener extends IInterface> { private final Map<IBinder, LinkedListener> mListenerMap = new HashMap<>(); - private boolean mIsRegistered; + private boolean mIsRegistered; // must access only on handler thread private boolean mHasIsSupported; private boolean mIsSupported; @@ -83,12 +84,12 @@ abstract class RemoteListenerHelper<TListener extends IInterface> { } else if (mHasIsSupported && !mIsSupported) { result = RESULT_NOT_SUPPORTED; } else if (!isGpsEnabled()) { - result = RESULT_GPS_LOCATION_DISABLED; - } else if (!tryRegister()) { // only attempt to register if GPS is enabled, otherwise we will register once GPS // becomes available - result = RESULT_INTERNAL_ERROR; + result = RESULT_GPS_LOCATION_DISABLED; } else if (mHasIsSupported && mIsSupported) { + tryRegister(); + // initially presume success, possible internal error could follow asynchornously result = RESULT_SUCCESS; } else { // at this point if the supported flag is not set, the notification will be sent @@ -117,8 +118,8 @@ abstract class RemoteListenerHelper<TListener extends IInterface> { protected abstract boolean isAvailableInPlatform(); protected abstract boolean isGpsEnabled(); - protected abstract boolean registerWithService(); - protected abstract void unregisterFromService(); + protected abstract boolean registerWithService(); // must access only on handler thread + protected abstract void unregisterFromService(); // must access only on handler thread protected abstract ListenerOperation<TListener> getHandlerOperation(int result); protected interface ListenerOperation<TListener extends IInterface> { @@ -138,22 +139,16 @@ abstract class RemoteListenerHelper<TListener extends IInterface> { } } - protected boolean tryUpdateRegistrationWithService() { + protected void tryUpdateRegistrationWithService() { synchronized (mListenerMap) { if (!isGpsEnabled()) { tryUnregister(); - return true; + return; } if (mListenerMap.isEmpty()) { - return true; - } - if (tryRegister()) { - // registration was successful, there is no need to update the state - return true; + return; } - ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR); - foreachUnsafe(operation); - return false; + tryRegister(); } } @@ -180,19 +175,40 @@ abstract class RemoteListenerHelper<TListener extends IInterface> { } } - private boolean tryRegister() { - if (!mIsRegistered) { - mIsRegistered = registerWithService(); - } - return mIsRegistered; + private void tryRegister() { + mHandler.post(new Runnable() { + @Override + public void run() { + if (!mIsRegistered) { + mIsRegistered = registerWithService(); + } + if (!mIsRegistered) { + // post back a failure + mHandler.post(new Runnable() { + @Override + public void run() { + synchronized (mListenerMap) { + ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR); + foreachUnsafe(operation); + } + } + }); + } + } + }); } private void tryUnregister() { - if (!mIsRegistered) { - return; - } - unregisterFromService(); - mIsRegistered = false; + mHandler.post(new Runnable() { + @Override + public void run() { + if (!mIsRegistered) { + return; + } + unregisterFromService(); + mIsRegistered = false; + } + }); } private int calculateCurrentResultUnsafe() { diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java index 5cc14b5ed520..3444ef3ec2fa 100644 --- a/services/core/java/com/android/server/notification/ConditionProviders.java +++ b/services/core/java/com/android/server/notification/ConditionProviders.java @@ -35,6 +35,7 @@ import android.util.ArraySet; import android.util.Slog; import com.android.internal.R; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.notification.NotificationManagerService.DumpFilter; import java.io.PrintWriter; @@ -43,7 +44,8 @@ import java.util.Arrays; public class ConditionProviders extends ManagedServices { - private static final String TAG_ENABLED_DND_APPS = "dnd_apps"; + @VisibleForTesting + static final String TAG_ENABLED_DND_APPS = "dnd_apps"; private final ArrayList<ConditionRecord> mRecords = new ArrayList<>(); private final ArraySet<String> mSystemConditionProviderNames; @@ -84,7 +86,7 @@ public class ConditionProviders extends ManagedServices { c.caption = "condition provider"; c.serviceInterface = ConditionProviderService.SERVICE_INTERFACE; c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES; - c.managedServiceTypeTag = TAG_ENABLED_DND_APPS; + c.xmlTag = TAG_ENABLED_DND_APPS; c.secondarySettingName = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS; c.bindPermission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE; c.settingsAction = Settings.ACTION_CONDITION_PROVIDER_SETTINGS; diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 2f88740cd01b..80878131ae44 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -52,6 +52,7 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; +import com.android.internal.util.XmlUtils; import com.android.server.notification.NotificationManagerService.DumpFilter; import org.xmlpull.v1.XmlPullParser; @@ -226,7 +227,7 @@ abstract public class ManagedServices { } public void writeXml(XmlSerializer out, boolean forBackup) throws IOException { - out.startTag(null, getConfig().managedServiceTypeTag); + out.startTag(null, getConfig().xmlTag); if (forBackup) { trimApprovedListsAccordingToInstalledServices(); @@ -241,7 +242,7 @@ abstract public class ManagedServices { for (int j = 0; j < M; j++) { final boolean isPrimary = approvedByType.keyAt(j); final Set<String> approved = approvedByType.valueAt(j); - if (approved != null && approved.size() > 0) { + if (approved != null) { String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved); out.startTag(null, TAG_MANAGED_SERVICES); out.attribute(null, ATT_APPROVED_LIST, allowedItems); @@ -260,43 +261,34 @@ abstract public class ManagedServices { } } - out.endTag(null, getConfig().managedServiceTypeTag); + out.endTag(null, getConfig().xmlTag); } - /** - * @return false if modifications were made to the data on load that requires the xml file - * to be re-written - */ - public boolean readXml(XmlPullParser parser) + protected void migrateToXml() { + loadAllowedComponentsFromSettings(); + } + + public void readXml(XmlPullParser parser) throws XmlPullParserException, IOException { - boolean rewriteXml = false; - int type = parser.getEventType(); - String tag = parser.getName(); - if (type != XmlPullParser.START_TAG || !getConfig().managedServiceTypeTag.equals(tag)) { - // xml empty/invalid - read from setting instead - loadAllowedComponentsFromSettings(); - rewriteXml = true; - } else { - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { - tag = parser.getName(); - if (type == XmlPullParser.END_TAG - && getConfig().managedServiceTypeTag.equals(tag)) { - break; - } - if (type == XmlPullParser.START_TAG) { - if (TAG_MANAGED_SERVICES.equals(tag)) { - final String approved = XmlUtils.safeString(parser, ATT_APPROVED_LIST, ""); - final int userId = XmlUtils.safeInt(parser, ATT_USER_ID, 0); - final boolean isPrimary = XmlUtils.safeBool(parser, ATT_IS_PRIMARY, true); - addApprovedList(approved, userId, isPrimary); - } + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { + String tag = parser.getName(); + if (type == XmlPullParser.END_TAG + && getConfig().xmlTag.equals(tag)) { + break; + } + if (type == XmlPullParser.START_TAG) { + if (TAG_MANAGED_SERVICES.equals(tag)) { + final String approved = XmlUtils.readStringAttribute(parser, ATT_APPROVED_LIST); + final int userId = XmlUtils.readIntAttribute(parser, ATT_USER_ID, 0); + final boolean isPrimary = + XmlUtils.readBooleanAttribute(parser, ATT_IS_PRIMARY, true); + addApprovedList(approved, userId, isPrimary); + mUseXml = true; } } - mUseXml = true; } rebindServices(false); - - return rewriteXml; } private void loadAllowedComponentsFromSettings() { @@ -1119,7 +1111,7 @@ abstract public class ManagedServices { public String serviceInterface; public String secureSettingName; public String secondarySettingName; - public String managedServiceTypeTag; + public String xmlTag; public String bindPermission; public String settingsAction; public int clientLabel; diff --git a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java index 12b29cff5c13..91fee4669846 100644 --- a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java +++ b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java @@ -16,14 +16,14 @@ package com.android.server.notification; -import android.app.Notification; import android.app.NotificationManager; import android.content.Context; import android.net.Uri; -import android.service.notification.NotificationListenerService; import android.util.Log; import android.util.Slog; +import com.android.internal.annotations.VisibleForTesting; + /** * This {@link com.android.server.notification.NotificationSignalExtractor} notices noisy * notifications and marks them to get a temporary ranking bump. @@ -34,7 +34,8 @@ public class NotificationIntrusivenessExtractor implements NotificationSignalExt /** Length of time (in milliseconds) that an intrusive or noisy notification will stay at the top of the ranking order, before it falls back to its natural position. */ - private static final long HANG_TIME_MS = 10000; + @VisibleForTesting + static final long HANG_TIME_MS = 10000; public void initialize(Context ctx, NotificationUsageStats usageStats) { if (DBG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + "."); @@ -46,7 +47,8 @@ public class NotificationIntrusivenessExtractor implements NotificationSignalExt return null; } - if (record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT) { + if (record.getFreshnessMs(System.currentTimeMillis()) < HANG_TIME_MS + && record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT) { if (record.getSound() != null && record.getSound() != Uri.EMPTY) { record.setRecentlyIntrusive(true); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index c04124a4b8a0..fb391f885874 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -55,7 +55,6 @@ import static android.service.notification.NotificationListenerService.TRIM_LIGH import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; -import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import android.Manifest; import android.annotation.NonNull; @@ -162,6 +161,7 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.Preconditions; +import com.android.internal.util.XmlUtils; import com.android.server.DeviceIdleController; import com.android.server.EventLogTags; import com.android.server.LocalServices; @@ -342,7 +342,7 @@ public class NotificationManagerService extends SystemService { private final UserProfiles mUserProfiles = new UserProfiles(); private NotificationListeners mListeners; - private NotificationAssistants mNotificationAssistants; + private NotificationAssistants mAssistants; private ConditionProviders mConditionProviders; private NotificationUsageStats mUsageStats; @@ -441,24 +441,38 @@ public class NotificationManagerService extends SystemService { } } - private void readPolicyXml(InputStream stream, boolean forRestore) + void readPolicyXml(InputStream stream, boolean forRestore) throws XmlPullParserException, NumberFormatException, IOException { final XmlPullParser parser = Xml.newPullParser(); parser.setInput(stream, StandardCharsets.UTF_8.name()); - - boolean saveXml = false; - while (parser.next() != END_DOCUMENT) { - mZenModeHelper.readXml(parser, forRestore); - mRankingHelper.readXml(parser, forRestore); + XmlUtils.beginDocument(parser, TAG_NOTIFICATION_POLICY); + boolean migratedManagedServices = false; + int outerDepth = parser.getDepth(); + while (XmlUtils.nextElementWithin(parser, outerDepth)) { + if (ZenModeConfig.ZEN_TAG.equals(parser.getName())) { + mZenModeHelper.readXml(parser, forRestore); + } else if (RankingHelper.TAG_RANKING.equals(parser.getName())){ + mRankingHelper.readXml(parser, forRestore); + } // No non-system managed services are allowed on low ram devices if (!ActivityManager.isLowRamDeviceStatic()) { - saveXml |= mListeners.readXml(parser); - saveXml |= mNotificationAssistants.readXml(parser); - saveXml |= mConditionProviders.readXml(parser); + if (mListeners.getConfig().xmlTag.equals(parser.getName())) { + mListeners.readXml(parser); + migratedManagedServices = true; + } else if (mAssistants.getConfig().xmlTag.equals(parser.getName())) { + mAssistants.readXml(parser); + migratedManagedServices = true; + } else if (mConditionProviders.getConfig().xmlTag.equals(parser.getName())) { + mConditionProviders.readXml(parser); + migratedManagedServices = true; + } } } - if (saveXml) { + if (!migratedManagedServices) { + mListeners.migrateToXml(); + mAssistants.migrateToXml(); + mConditionProviders.migrateToXml(); savePolicyFile(); } } @@ -467,7 +481,7 @@ public class NotificationManagerService extends SystemService { if (DBG) Slog.d(TAG, "loadPolicyFile"); synchronized (mPolicyFile) { - FileInputStream infile = null; + InputStream infile = null; try { infile = mPolicyFile.openRead(); readPolicyXml(infile, false /*forRestore*/); @@ -523,7 +537,7 @@ public class NotificationManagerService extends SystemService { mZenModeHelper.writeXml(out, forBackup); mRankingHelper.writeXml(out, forBackup); mListeners.writeXml(out, forBackup); - mNotificationAssistants.writeXml(out, forBackup); + mAssistants.writeXml(out, forBackup); mConditionProviders.writeXml(out, forBackup); out.endTag(null, TAG_NOTIFICATION_POLICY); out.endDocument(); @@ -898,7 +912,7 @@ public class NotificationManagerService extends SystemService { } } mListeners.onPackagesChanged(removingPackage, pkgList, uidList); - mNotificationAssistants.onPackagesChanged(removingPackage, pkgList, uidList); + mAssistants.onPackagesChanged(removingPackage, pkgList, uidList); mConditionProviders.onPackagesChanged(removingPackage, pkgList, uidList); mRankingHelper.onPackagesChanged(removingPackage, changeUserId, pkgList, uidList); savePolicyFile(); @@ -970,7 +984,7 @@ public class NotificationManagerService extends SystemService { // Refresh managed services mConditionProviders.onUserSwitched(user); mListeners.onUserSwitched(user); - mNotificationAssistants.onUserSwitched(user); + mAssistants.onUserSwitched(user); mZenModeHelper.onUserSwitched(user); } else if (action.equals(Intent.ACTION_USER_ADDED)) { mUserProfiles.updateCache(context); @@ -983,7 +997,7 @@ public class NotificationManagerService extends SystemService { final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); mConditionProviders.onUserUnlocked(user); mListeners.onUserUnlocked(user); - mNotificationAssistants.onUserUnlocked(user); + mAssistants.onUserUnlocked(user); mZenModeHelper.onUserUnlocked(user); } } @@ -1231,7 +1245,7 @@ public class NotificationManagerService extends SystemService { mListeners = notificationListeners; // This is a MangedServices object that keeps track of the assistant. - mNotificationAssistants = notificationAssistants; + mAssistants = notificationAssistants; mPolicyFile = policyFile; loadPolicyFile(); @@ -1400,7 +1414,7 @@ public class NotificationManagerService extends SystemService { // bind to listener services. mSettingsObserver.observe(); mListeners.onBootPhaseAppsCanStart(); - mNotificationAssistants.onBootPhaseAppsCanStart(); + mAssistants.onBootPhaseAppsCanStart(); mConditionProviders.onBootPhaseAppsCanStart(); } } @@ -1569,7 +1583,6 @@ public class NotificationManagerService extends SystemService { Slog.e(TAG, "Not doing toast. pkg=" + pkg + " callback=" + callback); return ; } - final boolean isSystemToast = isCallerSystemOrPhone() || ("android".equals(pkg)); final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, Binder.getCallingUid()); @@ -1928,7 +1941,7 @@ public class NotificationManagerService extends SystemService { // Listener & assistant mListeners.onPackagesChanged(true, packages, uids); - mNotificationAssistants.onPackagesChanged(true, packages, uids); + mAssistants.onPackagesChanged(true, packages, uids); // Zen mConditionProviders.onPackagesChanged(true, packages, uids); @@ -2134,8 +2147,8 @@ public class NotificationManagerService extends SystemService { long identity = Binder.clearCallingIdentity(); try { ManagedServices manager = - mNotificationAssistants.isComponentEnabledForCurrentProfiles(component) - ? mNotificationAssistants + mAssistants.isComponentEnabledForCurrentProfiles(component) + ? mAssistants : mListeners; manager.setComponentState(component, true); } finally { @@ -2255,7 +2268,7 @@ public class NotificationManagerService extends SystemService { try { synchronized (mNotificationLock) { final ManagedServiceInfo info = - mNotificationAssistants.checkServiceTokenLocked(token); + mAssistants.checkServiceTokenLocked(token); unsnoozeNotificationInt(key, info); } } finally { @@ -2788,7 +2801,7 @@ public class NotificationManagerService extends SystemService { public boolean isNotificationAssistantAccessGranted(ComponentName assistant) { Preconditions.checkNotNull(assistant); checkCallerIsSystemOrSameApp(assistant.getPackageName()); - return mNotificationAssistants.isPackageOrComponentAllowed(assistant.flattenToString(), + return mAssistants.isPackageOrComponentAllowed(assistant.flattenToString(), getCallingUserHandle().getIdentifier()); } @@ -2835,7 +2848,7 @@ public class NotificationManagerService extends SystemService { if (!mActivityManager.isLowRamDevice()) { mConditionProviders.setPackageOrComponentEnabled(assistant.flattenToString(), userId, false, granted); - mNotificationAssistants.setPackageOrComponentEnabled(assistant.flattenToString(), + mAssistants.setPackageOrComponentEnabled(assistant.flattenToString(), userId, true, granted); getContext().sendBroadcastAsUser(new Intent( @@ -2854,7 +2867,7 @@ public class NotificationManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mNotificationLock) { - mNotificationAssistants.checkServiceTokenLocked(token); + mAssistants.checkServiceTokenLocked(token); int N = mEnqueuedNotifications.size(); for (int i = 0; i < N; i++) { final NotificationRecord n = mEnqueuedNotifications.get(i); @@ -2876,7 +2889,7 @@ public class NotificationManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mNotificationLock) { - mNotificationAssistants.checkServiceTokenLocked(token); + mAssistants.checkServiceTokenLocked(token); NotificationRecord n = mNotificationsByKey.get(adjustment.getKey()); applyAdjustment(n, adjustment); } @@ -2893,7 +2906,7 @@ public class NotificationManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mNotificationLock) { - mNotificationAssistants.checkServiceTokenLocked(token); + mAssistants.checkServiceTokenLocked(token); for (Adjustment adjustment : adjustments) { NotificationRecord n = mNotificationsByKey.get(adjustment.getKey()); applyAdjustment(n, adjustment); @@ -2989,9 +3002,11 @@ public class NotificationManagerService extends SystemService { if (r == null) { return; } - addAutoGroupAdjustment(r, GroupHelper.AUTOGROUP_KEY); - EventLogTags.writeNotificationAutogrouped(key); - mRankingHandler.requestSort(); + if (r.sbn.getOverrideGroupKey() == null) { + addAutoGroupAdjustment(r, GroupHelper.AUTOGROUP_KEY); + EventLogTags.writeNotificationAutogrouped(key); + mRankingHandler.requestSort(); + } } @GuardedBy("mNotificationLock") @@ -3000,9 +3015,11 @@ public class NotificationManagerService extends SystemService { if (r == null) { return; } - addAutoGroupAdjustment(r, null); - EventLogTags.writeNotificationUnautogrouped(key); - mRankingHandler.requestSort(); + if (r.sbn.getOverrideGroupKey() != null) { + addAutoGroupAdjustment(r, null); + EventLogTags.writeNotificationUnautogrouped(key); + mRankingHandler.requestSort(); + } } private void addAutoGroupAdjustment(NotificationRecord r, String overrideGroupKey) { @@ -3273,7 +3290,7 @@ public class NotificationManagerService extends SystemService { } pw.println(')'); pw.println("\n Notification assistant services:"); - mNotificationAssistants.dump(pw, filter); + mAssistants.dump(pw, filter); } if (!filter.filtered || zenOnly) { @@ -3664,7 +3681,7 @@ public class NotificationManagerService extends SystemService { cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted); updateLightsLocked(); if (mSnoozeCriterionId != null) { - mNotificationAssistants.notifyAssistantSnoozedLocked(r.sbn, mSnoozeCriterionId); + mAssistants.notifyAssistantSnoozedLocked(r.sbn, mSnoozeCriterionId); mSnoozeHelper.snooze(r); } else { mSnoozeHelper.snooze(r, mDuration); @@ -3728,8 +3745,8 @@ public class NotificationManagerService extends SystemService { mRankingHelper.extractSignals(r); // tell the assistant service about the notification - if (mNotificationAssistants.isEnabled()) { - mNotificationAssistants.onNotificationEnqueued(r); + if (mAssistants.isEnabled()) { + mAssistants.onNotificationEnqueued(r); mHandler.postDelayed(new PostNotificationRunnable(r.getKey()), DELAY_FOR_ASSISTANT_TIME); } else { @@ -5238,7 +5255,7 @@ public class NotificationManagerService extends SystemService { Config c = new Config(); c.caption = "notification assistant service"; c.serviceInterface = NotificationAssistantService.SERVICE_INTERFACE; - c.managedServiceTypeTag = TAG_ENABLED_NOTIFICATION_ASSISTANTS; + c.xmlTag = TAG_ENABLED_NOTIFICATION_ASSISTANTS; c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT; c.bindPermission = Manifest.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE; c.settingsAction = Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS; @@ -5350,7 +5367,7 @@ public class NotificationManagerService extends SystemService { Config c = new Config(); c.caption = "notification listener"; c.serviceInterface = NotificationListenerService.SERVICE_INTERFACE; - c.managedServiceTypeTag = TAG_ENABLED_NOTIFICATION_LISTENERS; + c.xmlTag = TAG_ENABLED_NOTIFICATION_LISTENERS; c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS; c.bindPermission = android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE; c.settingsAction = Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS; diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java index 0d5cc2c112d5..9622a24a2d4d 100644 --- a/services/core/java/com/android/server/notification/RankingHelper.java +++ b/services/core/java/com/android/server/notification/RankingHelper.java @@ -20,6 +20,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.util.Preconditions; +import com.android.internal.util.XmlUtils; import android.app.Notification; import android.app.NotificationChannel; @@ -64,7 +65,7 @@ public class RankingHelper implements RankingConfig { private static final int XML_VERSION = 1; - private static final String TAG_RANKING = "ranking"; + static final String TAG_RANKING = "ranking"; private static final String TAG_PACKAGE = "package"; private static final String TAG_CHANNEL = "channel"; private static final String TAG_GROUP = "channelGroup"; @@ -169,7 +170,7 @@ public class RankingHelper implements RankingConfig { } if (type == XmlPullParser.START_TAG) { if (TAG_PACKAGE.equals(tag)) { - int uid = XmlUtils.safeInt(parser, ATT_UID, Record.UNKNOWN_UID); + int uid = XmlUtils.readIntAttribute(parser, ATT_UID, Record.UNKNOWN_UID); String name = parser.getAttributeValue(null, ATT_NAME); if (!TextUtils.isEmpty(name)) { if (forRestore) { @@ -182,14 +183,21 @@ public class RankingHelper implements RankingConfig { } Record r = getOrCreateRecord(name, uid, - XmlUtils.safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE), - XmlUtils.safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY), - XmlUtils.safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY), - XmlUtils.safeBool(parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE)); - r.importance = XmlUtils.safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE); - r.priority = XmlUtils.safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY); - r.visibility = XmlUtils.safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY); - r.showBadge = XmlUtils.safeBool(parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE); + XmlUtils.readIntAttribute( + parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE), + XmlUtils.readIntAttribute(parser, ATT_PRIORITY, DEFAULT_PRIORITY), + XmlUtils.readIntAttribute( + parser, ATT_VISIBILITY, DEFAULT_VISIBILITY), + XmlUtils.readBooleanAttribute( + parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE)); + r.importance = XmlUtils.readIntAttribute( + parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE); + r.priority = XmlUtils.readIntAttribute( + parser, ATT_PRIORITY, DEFAULT_PRIORITY); + r.visibility = XmlUtils.readIntAttribute( + parser, ATT_VISIBILITY, DEFAULT_VISIBILITY); + r.showBadge = XmlUtils.readBooleanAttribute( + parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE); final int innerDepth = parser.getDepth(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT @@ -214,7 +222,7 @@ public class RankingHelper implements RankingConfig { if (TAG_CHANNEL.equals(tagName)) { String id = parser.getAttributeValue(null, ATT_ID); String channelName = parser.getAttributeValue(null, ATT_NAME); - int channelImportance = XmlUtils.safeInt( + int channelImportance = XmlUtils.readIntAttribute( parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE); if (!TextUtils.isEmpty(id) && !TextUtils.isEmpty(channelName)) { NotificationChannel channel = new NotificationChannel(id, @@ -419,8 +427,7 @@ public class RankingHelper implements RankingConfig { record.setAuthoritativeRank(i); final String groupKey = record.getGroupKey(); NotificationRecord existingProxy = mProxyByGroupTmp.get(groupKey); - if (existingProxy == null - || record.getImportance() > existingProxy.getImportance()) { + if (existingProxy == null) { mProxyByGroupTmp.put(groupKey, record); } } diff --git a/services/core/java/com/android/server/notification/XmlUtils.java b/services/core/java/com/android/server/notification/XmlUtils.java deleted file mode 100644 index 831d03970fe3..000000000000 --- a/services/core/java/com/android/server/notification/XmlUtils.java +++ /dev/null @@ -1,52 +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 com.android.server.notification; - -import android.annotation.NonNull; -import android.text.TextUtils; - -import org.xmlpull.v1.XmlPullParser; - -class XmlUtils { - - static @NonNull String safeString(XmlPullParser parser, String att, String defValue) { - final String value = parser.getAttributeValue(null, att); - if (value == null) return defValue; - return value; - } - - static @NonNull boolean safeBool(XmlPullParser parser, String att, boolean defValue) { - final String value = parser.getAttributeValue(null, att); - if (TextUtils.isEmpty(value)) return defValue; - return Boolean.parseBoolean(value); - } - - static @NonNull int safeInt(XmlPullParser parser, String att, int defValue) { - final String val = parser.getAttributeValue(null, att); - return tryParseInt(val, defValue); - } - - private static int tryParseInt(String value, int defValue) { - if (TextUtils.isEmpty(value)) return defValue; - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - return defValue; - } - } - -} diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index c68854286a19..0c72326095a6 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -53,6 +53,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; +import android.os.UserManager; import android.os.WorkSource; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; @@ -197,6 +198,9 @@ public final class PowerManagerService extends SystemService // System property indicating that the screen should remain off until an explicit user action private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent"; + // System Property indicating that retail demo mode is currently enabled. + private static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled"; + // Possible reasons for shutting down for use in data/misc/reboot/last_shutdown_reason private static final String REASON_SHUTDOWN = "shutdown"; private static final String REASON_REBOOT = "reboot"; @@ -805,6 +809,9 @@ public final class PowerManagerService extends SystemService resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.DOUBLE_TAP_TO_WAKE), false, mSettingsObserver, UserHandle.USER_ALL); + resolver.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.DEVICE_DEMO_MODE), + false, mSettingsObserver, UserHandle.USER_SYSTEM); IVrManager vrManager = (IVrManager) getBinderService(Context.VR_SERVICE); if (vrManager != null) { try { @@ -912,6 +919,11 @@ public final class PowerManagerService extends SystemService } } + final String retailDemoValue = UserManager.isDeviceInDemoMode(mContext) ? "1" : "0"; + if (!retailDemoValue.equals(SystemProperties.get(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED))) { + SystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, retailDemoValue); + } + final int oldScreenBrightnessSetting = getCurrentBrightnessSettingLocked(); mScreenBrightnessForVrSetting = Settings.System.getIntForUser(resolver, diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java index 1f7564027166..bdd9de011186 100644 --- a/services/core/java/com/android/server/vr/VrManagerInternal.java +++ b/services/core/java/com/android/server/vr/VrManagerInternal.java @@ -52,10 +52,11 @@ public abstract class VrManagerInternal { * @param enabled {@code true} to enable VR mode. * @param packageName The package name of the requested VrListenerService to bind. * @param userId the user requesting the VrListenerService component. + * @param processId the process the component is running in. * @param calling the component currently using VR mode, or null to leave unchanged. */ public abstract void setVrMode(boolean enabled, @NonNull ComponentName packageName, - int userId, @NonNull ComponentName calling); + int userId, int processId, @NonNull ComponentName calling); /** * Set whether the system has acquired a sleep token. diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index b10c9a3fd2ac..a6b8d94fb6b5 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -128,6 +128,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC private boolean mVrModeAllowed; private boolean mVrModeEnabled; private boolean mPersistentVrModeEnabled; + private boolean mRunning2dInVr; + private int mVrAppProcessId; private EnabledComponentsObserver mComponentObserver; private ManagedApplicationService mCurrentVrService; private ComponentName mDefaultVrService; @@ -178,7 +180,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC } consumeAndApplyPendingStateLocked(); if (mBootsToVr && !mVrModeEnabled) { - setVrMode(true, mDefaultVrService, 0, null); + setVrMode(true, mDefaultVrService, 0, -1, null); } } else { // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to @@ -187,12 +189,12 @@ public class VrManagerService extends SystemService implements EnabledComponentC // Set pending state to current state. mPendingState = (mVrModeEnabled && mCurrentVrService != null) - ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(), - mCurrentVrService.getUserId(), mCurrentVrModeComponent) + ? new VrState(mVrModeEnabled, mRunning2dInVr, mCurrentVrService.getComponent(), + mCurrentVrService.getUserId(), mVrAppProcessId, mCurrentVrModeComponent) : null; // Unbind current VR service and do necessary callbacks. - updateCurrentVrServiceLocked(false, null, 0, null); + updateCurrentVrServiceLocked(false, false, null, 0, -1, null); } } } @@ -274,26 +276,33 @@ public class VrManagerService extends SystemService implements EnabledComponentC private static class VrState { final boolean enabled; + final boolean running2dInVr; final int userId; + final int processId; final ComponentName targetPackageName; final ComponentName callingPackage; final long timestamp; final boolean defaultPermissionsGranted; - VrState(boolean enabled, ComponentName targetPackageName, int userId, - ComponentName callingPackage) { + + VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId, + int processId, ComponentName callingPackage) { this.enabled = enabled; + this.running2dInVr = running2dInVr; this.userId = userId; + this.processId = processId; this.targetPackageName = targetPackageName; this.callingPackage = callingPackage; this.defaultPermissionsGranted = false; this.timestamp = System.currentTimeMillis(); } - VrState(boolean enabled, ComponentName targetPackageName, int userId, - ComponentName callingPackage, boolean defaultPermissionsGranted) { + VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId, + int processId, ComponentName callingPackage, boolean defaultPermissionsGranted) { this.enabled = enabled; + this.running2dInVr = running2dInVr; this.userId = userId; + this.processId = processId; this.targetPackageName = targetPackageName; this.callingPackage = callingPackage; this.defaultPermissionsGranted = defaultPermissionsGranted; @@ -394,8 +403,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC } // There is an active service, update it if needed - updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(), - mCurrentVrService.getUserId(), mCurrentVrModeComponent); + updateCurrentVrServiceLocked(mVrModeEnabled, mRunning2dInVr, + mCurrentVrService.getComponent(), mCurrentVrService.getUserId(), + mVrAppProcessId, mCurrentVrModeComponent); } } @@ -531,9 +541,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC */ private final class LocalService extends VrManagerInternal { @Override - public void setVrMode(boolean enabled, ComponentName packageName, int userId, + public void setVrMode(boolean enabled, ComponentName packageName, int userId, int processId, ComponentName callingPackage) { - VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); + VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage); } @Override @@ -710,14 +720,16 @@ public class VrManagerService extends SystemService implements EnabledComponentC * Note: Must be called while holding {@code mLock}. * * @param enabled new state for VR mode. + * @param running2dInVr true if we have a top-level 2D intent. * @param component new component to be bound as a VR listener. * @param userId user owning the component to be bound. - * @param calling the component currently using VR mode. + * @param processId the process hosting the activity specified by calling. + * @param calling the component currently using VR mode or a 2D intent. * * @return {@code true} if the component/user combination specified is valid. */ - private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component, - int userId, ComponentName calling) { + private boolean updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr, + @NonNull ComponentName component, int userId, int processId, ComponentName calling) { boolean sendUpdatedCaller = false; final long identity = Binder.clearCallingIdentity(); @@ -777,6 +789,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC sendUpdatedCaller = true; } mCurrentVrModeComponent = calling; + mRunning2dInVr = running2dInVr; + mVrAppProcessId = processId; if (mCurrentVrModeUser != userId) { mCurrentVrModeUser = userId; @@ -794,11 +808,13 @@ public class VrManagerService extends SystemService implements EnabledComponentC if (mCurrentVrService != null && sendUpdatedCaller) { final ComponentName c = mCurrentVrModeComponent; + final boolean b = running2dInVr; + final int pid = processId; mCurrentVrService.sendEvent(new PendingEvent() { @Override public void runEvent(IInterface service) throws RemoteException { IVrListener l = (IVrListener) service; - l.focusedActivityChanged(c); + l.focusedActivityChanged(c, b, pid); } }); } @@ -1001,20 +1017,20 @@ public class VrManagerService extends SystemService implements EnabledComponentC */ private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) { if (mPendingState != null) { - updateCurrentVrServiceLocked(mPendingState.enabled, - mPendingState.targetPackageName, mPendingState.userId, + updateCurrentVrServiceLocked(mPendingState.enabled, mPendingState.running2dInVr, + mPendingState.targetPackageName, mPendingState.userId, mPendingState.processId, mPendingState.callingPackage); mPendingState = null; } else if (disconnectIfNoPendingState) { - updateCurrentVrServiceLocked(false, null, 0, null); + updateCurrentVrServiceLocked(false, false, null, 0, -1, null); } } private void logStateLocked() { ComponentName currentBoundService = (mCurrentVrService == null) ? null : mCurrentVrService.getComponent(); - VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser, - mCurrentVrModeComponent, mWasDefaultGranted); + VrState current = new VrState(mVrModeEnabled, mRunning2dInVr, currentBoundService, + mCurrentVrModeUser, mVrAppProcessId, mCurrentVrModeComponent, mWasDefaultGranted); if (mLoggingDeque.size() == EVENT_LOG_SIZE) { mLoggingDeque.removeFirst(); } @@ -1058,27 +1074,24 @@ public class VrManagerService extends SystemService implements EnabledComponentC * Implementation of VrManagerInternal calls. These are callable from system services. */ private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, - int userId, @NonNull ComponentName callingPackage) { + int userId, int processId, @NonNull ComponentName callingPackage) { synchronized (mLock) { VrState pending; ComponentName targetListener; - ComponentName foregroundVrComponent; // If the device is in persistent VR mode, then calls to disable VR mode are ignored, // and the system default VR listener is used. boolean targetEnabledState = enabled || mPersistentVrModeEnabled; - if (!enabled && mPersistentVrModeEnabled) { + boolean running2dInVr = !enabled && mPersistentVrModeEnabled; + if (running2dInVr) { targetListener = mDefaultVrService; - - // Current foreground component isn't a VR one (in 2D app case) - foregroundVrComponent = null; } else { targetListener = targetPackageName; - foregroundVrComponent = callingPackage; } - pending = new VrState( - targetEnabledState, targetListener, userId, foregroundVrComponent); + + pending = new VrState(targetEnabledState, running2dInVr, targetListener, + userId, processId, callingPackage); if (!mVrModeAllowed) { // We're not allowed to be in VR mode. Make this state pending. This will be @@ -1103,8 +1116,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC mPendingState = null; } - updateCurrentVrServiceLocked( - targetEnabledState, targetListener, userId, foregroundVrComponent); + updateCurrentVrServiceLocked(targetEnabledState, running2dInVr, targetListener, + userId, processId, callingPackage); } } @@ -1113,7 +1126,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC setPersistentModeAndNotifyListenersLocked(enabled); // Disabling persistent mode when not showing a VR should disable the overall vr mode. if (!enabled && mCurrentVrModeComponent == null) { - setVrMode(false, null, 0, null); + setVrMode(false, null, 0, -1, null); } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 9b8d1a7c1c0c..847e7d2c88ab 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3584,7 +3584,6 @@ public class WindowManagerService extends IWindowManager.Stub } private void updateCircularDisplayMaskIfNeeded() { - // we're fullscreen and not hosted in an ActivityView if (mContext.getResources().getConfiguration().isScreenRound() && mContext.getResources().getBoolean( com.android.internal.R.bool.config_windowShowCircularMask)) { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 85747287cf93..3757b7d0c53d 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -99,7 +99,6 @@ import com.android.server.power.PowerManagerService; import com.android.server.power.ShutdownThread; import com.android.server.broadcastradio.BroadcastRadioService; import com.android.server.restrictions.RestrictionsManagerService; -import com.android.server.retaildemo.RetailDemoModeService; import com.android.server.security.KeyAttestationApplicationIdProviderService; import com.android.server.security.KeyChainSystemService; import com.android.server.soundtrigger.SoundTriggerService; @@ -1536,10 +1535,6 @@ public final class SystemServer { mmsService = mSystemServiceManager.startService(MmsServiceBroker.class); traceEnd(); - traceBeginAndSlog("StartRetailDemoModeService"); - mSystemServiceManager.startService(RetailDemoModeService.class); - traceEnd(); - if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOFILL)) { traceBeginAndSlog("StartAutoFillService"); mSystemServiceManager.startService(AUTO_FILL_MANAGER_SERVICE_CLASS); diff --git a/services/retaildemo/Android.mk b/services/retaildemo/Android.mk deleted file mode 100644 index 670c6bfa1e6a..000000000000 --- a/services/retaildemo/Android.mk +++ /dev/null @@ -1,12 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := services.retaildemo - -LOCAL_SRC_FILES += \ - $(call all-java-files-under,java) - -LOCAL_JAVA_LIBRARIES := services.core - -include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java deleted file mode 100644 index 90c58d0279a7..000000000000 --- a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * 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 - */ - -package com.android.server.retaildemo; - -import android.app.AppGlobals; -import android.app.PackageInstallObserver; -import android.content.Context; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.os.Environment; -import android.os.RemoteException; -import android.os.UserHandle; -import android.provider.Settings; -import android.util.ArrayMap; -import android.util.Log; -import android.util.Slog; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.ArrayUtils; - -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.Map; - -/** - * Helper class for installing preloaded APKs - */ -class PreloadAppsInstaller { - private static final String SYSTEM_SERVER_PACKAGE_NAME = "android"; - private static String TAG = PreloadAppsInstaller.class.getSimpleName(); - private static final String PRELOAD_APK_EXT = ".apk.preload"; - private static boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - private final IPackageManager mPackageManager; - private final File preloadsAppsDirectory; - private final Context mContext; - - private final Map<String, String> mApkToPackageMap; - - PreloadAppsInstaller(Context context) { - this(context, AppGlobals.getPackageManager(), Environment.getDataPreloadsAppsDirectory()); - } - - @VisibleForTesting - PreloadAppsInstaller(Context context, IPackageManager packageManager, File preloadsAppsDirectory) { - mContext = context; - mPackageManager = packageManager; - mApkToPackageMap = Collections.synchronizedMap(new ArrayMap<>()); - this.preloadsAppsDirectory = preloadsAppsDirectory; - } - - void installApps(int userId) { - File[] files = preloadsAppsDirectory.listFiles(); - AppInstallCounter counter = new AppInstallCounter(mContext, userId); - if (ArrayUtils.isEmpty(files)) { - counter.setExpectedAppsCount(0); - return; - } - int expectedCount = 0; - for (File file : files) { - String apkName = file.getName(); - if (apkName.endsWith(PRELOAD_APK_EXT) && file.isFile()) { - String packageName = mApkToPackageMap.get(apkName); - if (packageName != null) { - try { - expectedCount++; - installExistingPackage(packageName, userId, counter); - } catch (Exception e) { - Slog.e(TAG, "Failed to install existing package " + packageName, e); - } - } else { - try { - installPackage(file, userId, counter); - expectedCount++; - } catch (Exception e) { - Slog.e(TAG, "Failed to install package from " + file, e); - } - } - } - } - counter.setExpectedAppsCount(expectedCount); - } - - private void installExistingPackage(String packageName, int userId, - AppInstallCounter counter) { - if (DEBUG) { - Log.d(TAG, "installExistingPackage " + packageName + " u" + userId); - } - try { - mPackageManager.installExistingPackageAsUser(packageName, userId, - 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } finally { - counter.appInstallFinished(); - } - } - - private void installPackage(File file, final int userId, AppInstallCounter counter) - throws IOException, RemoteException { - final String apkName = file.getName(); - if (DEBUG) { - Log.d(TAG, "installPackage " + apkName + " u" + userId); - } - mPackageManager.installPackageAsUser(file.getPath(), new PackageInstallObserver() { - @Override - public void onPackageInstalled(String basePackageName, int returnCode, String msg, - Bundle extras) { - if (DEBUG) { - Log.d(TAG, "Package " + basePackageName + " installed u" + userId - + " returnCode: " + returnCode + " msg: " + msg); - } - // Don't notify the counter for now, we'll do it in installExistingPackage - if (returnCode == PackageManager.INSTALL_SUCCEEDED) { - mApkToPackageMap.put(apkName, basePackageName); - // Install on user 0 so that the package is cached when demo user is re-created - installExistingPackage(basePackageName, UserHandle.USER_SYSTEM, counter); - } else if (returnCode == PackageManager.INSTALL_FAILED_ALREADY_EXISTS) { - // This can only happen in first session after a reboot - if (!mApkToPackageMap.containsKey(apkName)) { - mApkToPackageMap.put(apkName, basePackageName); - } - installExistingPackage(basePackageName, userId, counter); - } else { - Log.e(TAG, "Package " + basePackageName + " cannot be installed from " - + apkName + ": " + msg + " (returnCode " + returnCode + ")"); - counter.appInstallFinished(); - } - } - }.getBinder(), 0, SYSTEM_SERVER_PACKAGE_NAME, userId); - } - - private static class AppInstallCounter { - private int expectedCount = -1; // -1 means expectedCount not set - private int finishedCount; - private final Context mContext; - private final int userId; - - AppInstallCounter(Context context, int userId) { - mContext = context; - this.userId = userId; - } - - synchronized void appInstallFinished() { - this.finishedCount++; - checkIfAllFinished(); - } - - synchronized void setExpectedAppsCount(int expectedCount) { - this.expectedCount = expectedCount; - checkIfAllFinished(); - } - - private void checkIfAllFinished() { - if (expectedCount == finishedCount) { - Log.i(TAG, "All preloads finished installing for user " + userId); - Settings.Secure.putStringForUser(mContext.getContentResolver(), - Settings.Secure.DEMO_USER_SETUP_COMPLETE, "1", userId); - } - } - } -} diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java deleted file mode 100644 index 711d4d9d8a91..000000000000 --- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java +++ /dev/null @@ -1,868 +0,0 @@ -/* - * 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 - */ - -package com.android.server.retaildemo; - -import android.Manifest; -import android.app.ActivityManager; -import android.app.ActivityManagerInternal; -import android.app.AppGlobals; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.RetailDemoModeServiceInternal; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.ContentResolver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.UserInfo; -import android.content.res.Configuration; -import android.database.ContentObserver; -import android.hardware.camera2.CameraAccessException; -import android.hardware.camera2.CameraCharacteristics; -import android.hardware.camera2.CameraManager; -import android.media.AudioManager; -import android.media.AudioSystem; -import android.net.Uri; -import android.net.wifi.WifiManager; -import android.os.Environment; -import android.os.FileUtils; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.PowerManager; -import android.os.RemoteException; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.os.UserHandle; -import android.os.UserManager; -import android.provider.CallLog; -import android.provider.MediaStore; -import android.provider.Settings; -import android.text.TextUtils; -import android.util.KeyValueListParser; -import android.util.Slog; - -import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; -import com.android.internal.notification.SystemNotificationChannels; -import com.android.internal.os.BackgroundThread; -import com.android.internal.R; -import com.android.internal.annotations.GuardedBy; -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.logging.MetricsLogger; -import com.android.internal.widget.LockPatternUtils; -import com.android.server.LocalServices; -import com.android.server.PreloadsFileCacheExpirationJobService; -import com.android.server.ServiceThread; -import com.android.server.SystemService; -import com.android.server.am.ActivityManagerService; -import com.android.server.retaildemo.UserInactivityCountdownDialog.OnCountDownExpiredListener; - -import java.io.File; -import java.util.ArrayList; - -public class RetailDemoModeService extends SystemService { - private static final boolean DEBUG = false; - - private static final String TAG = RetailDemoModeService.class.getSimpleName(); - private static final String DEMO_USER_NAME = "Demo"; - private static final String ACTION_RESET_DEMO = - "com.android.server.retaildemo.ACTION_RESET_DEMO"; - @VisibleForTesting - static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled"; - - private static final int MSG_TURN_SCREEN_ON = 0; - private static final int MSG_INACTIVITY_TIME_OUT = 1; - private static final int MSG_START_NEW_SESSION = 2; - - private static final long SCREEN_WAKEUP_DELAY = 2500; - private static final long USER_INACTIVITY_TIMEOUT_MIN = 10000; - private static final long USER_INACTIVITY_TIMEOUT_DEFAULT = 90000; - private static final long WARNING_DIALOG_TIMEOUT_DEFAULT = 0; - private static final long MILLIS_PER_SECOND = 1000; - - @VisibleForTesting - static final int[] VOLUME_STREAMS_TO_MUTE = { - AudioSystem.STREAM_RING, - AudioSystem.STREAM_MUSIC - }; - - // Tron Vars - private static final String DEMO_SESSION_COUNT = "retail_demo_session_count"; - private static final String DEMO_SESSION_DURATION = "retail_demo_session_duration"; - - boolean mDeviceInDemoMode; - boolean mIsCarrierDemoMode; - int mCurrentUserId = UserHandle.USER_SYSTEM; - long mUserInactivityTimeout; - long mWarningDialogTimeout; - private Injector mInjector; - Handler mHandler; - private ServiceThread mHandlerThread; - private String[] mCameraIdsWithFlash; - private PreloadAppsInstaller mPreloadAppsInstaller; - - final Object mActivityLock = new Object(); - // Whether the newly created demo user has interacted with the screen yet - @GuardedBy("mActivityLock") - boolean mUserUntouched; - @GuardedBy("mActivityLock") - long mFirstUserActivityTime; - @GuardedBy("mActivityLock") - long mLastUserActivityTime; - - private boolean mSafeBootRestrictionInitialState; - private int mPackageVerifierEnableInitialState; - - private IntentReceiver mBroadcastReceiver = null; - - private final class IntentReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (!mDeviceInDemoMode) { - return; - } - final String action = intent.getAction(); - switch (action) { - case Intent.ACTION_SCREEN_OFF: - mHandler.removeMessages(MSG_TURN_SCREEN_ON); - mHandler.sendEmptyMessageDelayed(MSG_TURN_SCREEN_ON, SCREEN_WAKEUP_DELAY); - break; - case ACTION_RESET_DEMO: - mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); - break; - } - } - }; - - final class MainHandler extends Handler { - - MainHandler(Looper looper) { - super(looper, null, true); - } - - @Override - public void handleMessage(Message msg) { - if (!mDeviceInDemoMode) { - return; - } - switch (msg.what) { - case MSG_TURN_SCREEN_ON: - if (mInjector.isWakeLockHeld()) { - mInjector.releaseWakeLock(); - } - mInjector.acquireWakeLock(); - break; - case MSG_INACTIVITY_TIME_OUT: - if (!mIsCarrierDemoMode && isDemoLauncherDisabled()) { - Slog.i(TAG, "User inactivity timeout reached"); - showInactivityCountdownDialog(); - } - break; - case MSG_START_NEW_SESSION: - if (DEBUG) { - Slog.d(TAG, "Switching to a new demo user"); - } - removeMessages(MSG_START_NEW_SESSION); - removeMessages(MSG_INACTIVITY_TIME_OUT); - if (!mIsCarrierDemoMode && mCurrentUserId != UserHandle.USER_SYSTEM) { - logSessionDuration(); - } - - final UserManager um = mInjector.getUserManager(); - UserInfo demoUser = null; - if (mIsCarrierDemoMode) { - // Re-use the existing demo user in carrier demo mode. - for (UserInfo user : um.getUsers()) { - if (user.isDemo()) { - demoUser = user; - break; - } - } - } - - if (demoUser == null) { - // User in carrier demo mode should survive reboots. - final int flags = UserInfo.FLAG_DEMO - | (mIsCarrierDemoMode ? 0 : UserInfo.FLAG_EPHEMERAL); - demoUser = um.createUser(DEMO_USER_NAME, flags); - } - - if (demoUser != null && mCurrentUserId != demoUser.id) { - setupDemoUser(demoUser); - mInjector.switchUser(demoUser.id); - } - break; - } - } - } - - @VisibleForTesting - class SettingsObserver extends ContentObserver { - - private final static String KEY_USER_INACTIVITY_TIMEOUT = "user_inactivity_timeout_ms"; - private final static String KEY_WARNING_DIALOG_TIMEOUT = "warning_dialog_timeout_ms"; - - private final Uri mDeviceDemoModeUri = Settings.Global - .getUriFor(Settings.Global.DEVICE_DEMO_MODE); - private final Uri mDeviceProvisionedUri = Settings.Global - .getUriFor(Settings.Global.DEVICE_PROVISIONED); - private final Uri mRetailDemoConstantsUri = Settings.Global - .getUriFor(Settings.Global.RETAIL_DEMO_MODE_CONSTANTS); - - private final KeyValueListParser mParser = new KeyValueListParser(','); - - public SettingsObserver(Handler handler) { - super(handler); - } - - public void register() { - final ContentResolver cr = mInjector.getContentResolver(); - cr.registerContentObserver(mDeviceDemoModeUri, false, this, UserHandle.USER_SYSTEM); - cr.registerContentObserver(mDeviceProvisionedUri, false, this, UserHandle.USER_SYSTEM); - cr.registerContentObserver(mRetailDemoConstantsUri, false, this, - UserHandle.USER_SYSTEM); - } - - @Override - public void onChange(boolean selfChange, Uri uri) { - if (mRetailDemoConstantsUri.equals(uri)) { - refreshTimeoutConstants(); - return; - } - - // If device is provisioned and left demo mode - run the cleanup in demo folder - if (isDeviceProvisioned()) { - if (UserManager.isDeviceInDemoMode(getContext())) { - startDemoMode(); - } else { - mInjector.systemPropertiesSet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "0"); - - // Run on the bg thread to not block the fg thread - BackgroundThread.getHandler().post(() -> { - if (!deletePreloadsFolderContents()) { - Slog.w(TAG, "Failed to delete preloads folder contents"); - } - PreloadsFileCacheExpirationJobService.schedule(mInjector.getContext()); - }); - - stopDemoMode(); - - if (mInjector.isWakeLockHeld()) { - mInjector.releaseWakeLock(); - } - } - } - } - - private void refreshTimeoutConstants() { - try { - mParser.setString(Settings.Global.getString(mInjector.getContentResolver(), - Settings.Global.RETAIL_DEMO_MODE_CONSTANTS)); - } catch (IllegalArgumentException exc) { - Slog.e(TAG, "Invalid string passed to KeyValueListParser"); - // Consuming the exception to fall back to default values. - } - mWarningDialogTimeout = mParser.getLong(KEY_WARNING_DIALOG_TIMEOUT, - WARNING_DIALOG_TIMEOUT_DEFAULT); - mUserInactivityTimeout = mParser.getLong(KEY_USER_INACTIVITY_TIMEOUT, - USER_INACTIVITY_TIMEOUT_DEFAULT); - mUserInactivityTimeout = Math.max(mUserInactivityTimeout, USER_INACTIVITY_TIMEOUT_MIN); - } - } - - private void showInactivityCountdownDialog() { - UserInactivityCountdownDialog dialog = new UserInactivityCountdownDialog(getContext(), - mWarningDialogTimeout, MILLIS_PER_SECOND); - dialog.setNegativeButtonClickListener(null); - dialog.setPositiveButtonClickListener(new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); - } - }); - dialog.setOnCountDownExpiredListener(new OnCountDownExpiredListener() { - @Override - public void onCountDownExpired() { - mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); - } - }); - dialog.show(); - } - - public RetailDemoModeService(Context context) { - this(new Injector(context)); - } - - @VisibleForTesting - RetailDemoModeService(Injector injector) { - super(injector.getContext()); - - mInjector = injector; - synchronized (mActivityLock) { - mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis(); - } - } - - boolean isDemoLauncherDisabled() { - int enabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; - try { - final IPackageManager iPm = mInjector.getIPackageManager(); - final String demoLauncherComponent = - getContext().getString(R.string.config_demoModeLauncherComponent); - enabledState = iPm.getComponentEnabledSetting( - ComponentName.unflattenFromString(demoLauncherComponent), mCurrentUserId); - } catch (RemoteException re) { - Slog.e(TAG, "Error retrieving demo launcher enabled setting", re); - } - return enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED; - } - - private void setupDemoUser(UserInfo userInfo) { - final UserManager um = mInjector.getUserManager(); - final UserHandle user = UserHandle.of(userInfo.id); - um.setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user); - um.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user); - um.setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user); - um.setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user); - um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user); - um.setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user); - // Set this to false because the default is true on user creation - um.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user); - // Disallow rebooting in safe mode - controlled by user 0 - um.setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM); - if (mIsCarrierDemoMode) { - // Enable SMS in carrier demo mode. - um.setUserRestriction(UserManager.DISALLOW_SMS, false, user); - } - - Settings.Secure.putIntForUser(mInjector.getContentResolver(), - Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id); - Settings.Global.putInt(mInjector.getContentResolver(), - Settings.Global.PACKAGE_VERIFIER_ENABLE, 0); - - grantRuntimePermissionToCamera(user); - clearPrimaryCallLog(); - - if (!mIsCarrierDemoMode) { - // Enable demo launcher. - final String demoLauncher = getContext().getString( - R.string.config_demoModeLauncherComponent); - if (!TextUtils.isEmpty(demoLauncher)) { - final ComponentName componentToEnable = - ComponentName.unflattenFromString(demoLauncher); - final String packageName = componentToEnable.getPackageName(); - try { - final IPackageManager iPm = AppGlobals.getPackageManager(); - iPm.setComponentEnabledSetting(componentToEnable, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id); - iPm.setApplicationEnabledSetting(packageName, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null); - } catch (RemoteException re) { - // Internal, shouldn't happen - } - } - } else { - // Set the carrier demo mode setting for the demo user. - final String carrierDemoModeSetting = getContext().getString( - R.string.config_carrierDemoModeSetting); - Settings.Secure.putIntForUser(getContext().getContentResolver(), - carrierDemoModeSetting, 1, userInfo.id); - - // Enable packages for carrier demo mode. - final String packageList = getContext().getString( - R.string.config_carrierDemoModePackages); - final String[] packageNames = packageList == null ? new String[0] - : TextUtils.split(packageList, ","); - final IPackageManager iPm = AppGlobals.getPackageManager(); - for (String packageName : packageNames) { - try { - iPm.setApplicationEnabledSetting(packageName, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null); - } catch (RemoteException re) { - Slog.e(TAG, "Error enabling application: " + packageName, re); - } - } - } - } - - private void grantRuntimePermissionToCamera(UserHandle user) { - final Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - final PackageManager pm = mInjector.getPackageManager(); - final ResolveInfo handler = pm.resolveActivityAsUser(cameraIntent, - PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - user.getIdentifier()); - if (handler == null || handler.activityInfo == null) { - return; - } - try { - pm.grantRuntimePermission(handler.activityInfo.packageName, - Manifest.permission.ACCESS_FINE_LOCATION, user); - } catch (Exception e) { - // Ignore - } - } - - private void clearPrimaryCallLog() { - final ContentResolver resolver = mInjector.getContentResolver(); - - // Deleting primary user call log so that it doesn't get copied to the new demo user - final Uri uri = CallLog.Calls.CONTENT_URI; - try { - resolver.delete(uri, null, null); - } catch (Exception e) { - Slog.w(TAG, "Deleting call log failed: " + e); - } - } - - void logSessionDuration() { - final int sessionDuration; - synchronized (mActivityLock) { - sessionDuration = (int) ((mLastUserActivityTime - mFirstUserActivityTime) / 1000); - } - mInjector.logSessionDuration(sessionDuration); - } - - private boolean isDeviceProvisioned() { - return Settings.Global.getInt( - mInjector.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0; - } - - /** - * Deletes contents of {@link Environment#getDataPreloadsDirectory()}, - * but leave {@link Environment#getDataPreloadsFileCacheDirectory()} - * @return true if contents was sucessfully deleted - */ - private boolean deletePreloadsFolderContents() { - final File dir = mInjector.getDataPreloadsDirectory(); - final File[] files = FileUtils.listFilesOrEmpty(dir); - final File fileCacheDirectory = mInjector.getDataPreloadsFileCacheDirectory(); - Slog.i(TAG, "Deleting contents of " + dir); - boolean success = true; - for (File file : files) { - if (file.isFile()) { - if (!file.delete()) { - success = false; - Slog.w(TAG, "Cannot delete file " + file); - } - } else { - // Do not remove file_cache dir - if (!file.equals(fileCacheDirectory)) { - if (!FileUtils.deleteContentsAndDir(file)) { - success = false; - Slog.w(TAG, "Cannot delete dir and its content " + file); - } - } else { - Slog.i(TAG, "Skipping directory with file cache " + file); - } - } - } - return success; - } - - private void registerBroadcastReceiver() { - if (mBroadcastReceiver != null) { - return; - } - - final IntentFilter filter = new IntentFilter(); - if (!mIsCarrierDemoMode) { - filter.addAction(Intent.ACTION_SCREEN_OFF); - } - filter.addAction(ACTION_RESET_DEMO); - mBroadcastReceiver = new IntentReceiver(); - getContext().registerReceiver(mBroadcastReceiver, filter); - } - - private void unregisterBroadcastReceiver() { - if (mBroadcastReceiver != null) { - getContext().unregisterReceiver(mBroadcastReceiver); - mBroadcastReceiver = null; - } - } - - private String[] getCameraIdsWithFlash() { - ArrayList<String> cameraIdsList = new ArrayList<String>(); - final CameraManager cm = mInjector.getCameraManager(); - if (cm != null) { - try { - for (String cameraId : cm.getCameraIdList()) { - CameraCharacteristics c = cm.getCameraCharacteristics(cameraId); - if (Boolean.TRUE.equals(c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE))) { - cameraIdsList.add(cameraId); - } - } - } catch (CameraAccessException e) { - Slog.e(TAG, "Unable to access camera while getting camera id list", e); - } - } - return cameraIdsList.toArray(new String[cameraIdsList.size()]); - } - - private void muteVolumeStreams() { - for (int stream : VOLUME_STREAMS_TO_MUTE) { - mInjector.getAudioManager().setStreamVolume(stream, - mInjector.getAudioManager().getStreamMinVolume(stream), 0); - } - } - - private void startDemoMode() { - mDeviceInDemoMode = true; - - mPreloadAppsInstaller = mInjector.getPreloadAppsInstaller(); - mInjector.initializeWakeLock(); - if (mCameraIdsWithFlash == null) { - mCameraIdsWithFlash = getCameraIdsWithFlash(); - } - registerBroadcastReceiver(); - - final String carrierDemoModeSetting = - getContext().getString(R.string.config_carrierDemoModeSetting); - mIsCarrierDemoMode = !TextUtils.isEmpty(carrierDemoModeSetting) - && (Settings.Secure.getInt(getContext().getContentResolver(), - carrierDemoModeSetting, 0) == 1); - - mInjector.systemPropertiesSet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "1"); - mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); - - mSafeBootRestrictionInitialState = mInjector.getUserManager().hasUserRestriction( - UserManager.DISALLOW_SAFE_BOOT, UserHandle.SYSTEM); - mPackageVerifierEnableInitialState = Settings.Global.getInt(mInjector.getContentResolver(), - Settings.Global.PACKAGE_VERIFIER_ENABLE, 1); - } - - private void stopDemoMode() { - mPreloadAppsInstaller = null; - mCameraIdsWithFlash = null; - mInjector.destroyWakeLock(); - unregisterBroadcastReceiver(); - - if (mDeviceInDemoMode) { - mInjector.getUserManager().setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, - mSafeBootRestrictionInitialState, UserHandle.SYSTEM); - Settings.Global.putInt(mInjector.getContentResolver(), - Settings.Global.PACKAGE_VERIFIER_ENABLE, - mPackageVerifierEnableInitialState); - } - - mDeviceInDemoMode = false; - mIsCarrierDemoMode = false; - } - - @Override - public void onStart() { - if (DEBUG) { - Slog.d(TAG, "Service starting up"); - } - mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, - false); - mHandlerThread.start(); - mHandler = new MainHandler(mHandlerThread.getLooper()); - mInjector.publishLocalService(this, mLocalService); - } - - @Override - public void onBootPhase(int bootPhase) { - switch (bootPhase) { - case PHASE_THIRD_PARTY_APPS_CAN_START: - final SettingsObserver settingsObserver = new SettingsObserver(mHandler); - settingsObserver.register(); - settingsObserver.refreshTimeoutConstants(); - break; - case PHASE_BOOT_COMPLETED: - if (UserManager.isDeviceInDemoMode(getContext())) { - startDemoMode(); - } - break; - } - } - - @Override - public void onSwitchUser(int userId) { - if (!mDeviceInDemoMode) { - return; - } - if (DEBUG) { - Slog.d(TAG, "onSwitchUser: " + userId); - } - final UserInfo ui = mInjector.getUserManager().getUserInfo(userId); - if (!ui.isDemo()) { - Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode"); - return; - } - if (!mIsCarrierDemoMode && !mInjector.isWakeLockHeld()) { - mInjector.acquireWakeLock(); - } - mCurrentUserId = userId; - mInjector.getActivityManagerInternal().updatePersistentConfigurationForUser( - mInjector.getSystemUsersConfiguration(), userId); - - mInjector.turnOffAllFlashLights(mCameraIdsWithFlash); - muteVolumeStreams(); - if (!mInjector.getWifiManager().isWifiEnabled()) { - mInjector.getWifiManager().setWifiEnabled(true); - } - - // Disable lock screen for demo users. - mInjector.getLockPatternUtils().setLockScreenDisabled(true, userId); - - if (!mIsCarrierDemoMode) { - // Show reset notification (except in carrier demo mode). - mInjector.getNotificationManager().notifyAsUser(TAG, SystemMessage.NOTE_RETAIL_RESET, - mInjector.createResetNotification(), UserHandle.of(userId)); - - synchronized (mActivityLock) { - mUserUntouched = true; - } - mInjector.logSessionCount(1); - mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT); - mHandler.post(new Runnable() { - @Override - public void run() { - mPreloadAppsInstaller.installApps(userId); - } - }); - } - } - - private RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() { - private static final long USER_ACTIVITY_DEBOUNCE_TIME = 2000; - - @Override - public void onUserActivity() { - if (!mDeviceInDemoMode || mIsCarrierDemoMode) { - return; - } - long timeOfActivity = SystemClock.uptimeMillis(); - synchronized (mActivityLock) { - if (timeOfActivity < mLastUserActivityTime + USER_ACTIVITY_DEBOUNCE_TIME) { - return; - } - mLastUserActivityTime = timeOfActivity; - if (mUserUntouched && isDemoLauncherDisabled()) { - Slog.d(TAG, "retail_demo first touch"); - mUserUntouched = false; - mFirstUserActivityTime = timeOfActivity; - } - } - mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT); - mHandler.sendEmptyMessageDelayed(MSG_INACTIVITY_TIME_OUT, mUserInactivityTimeout); - } - }; - - static class Injector { - private Context mContext; - private UserManager mUm; - private PackageManager mPm; - private NotificationManager mNm; - private ActivityManagerService mAms; - private ActivityManagerInternal mAmi; - private AudioManager mAudioManager; - private PowerManager mPowerManager; - private CameraManager mCameraManager; - private PowerManager.WakeLock mWakeLock; - private WifiManager mWifiManager; - private Configuration mSystemUserConfiguration; - private PendingIntent mResetDemoPendingIntent; - private PreloadAppsInstaller mPreloadAppsInstaller; - - Injector(Context context) { - mContext = context; - } - - Context getContext() { - return mContext; - } - - WifiManager getWifiManager() { - if (mWifiManager == null) { - mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); - } - return mWifiManager; - } - - UserManager getUserManager() { - if (mUm == null) { - mUm = getContext().getSystemService(UserManager.class); - } - return mUm; - } - - void switchUser(int userId) { - if (mAms == null) { - mAms = (ActivityManagerService) ActivityManager.getService(); - } - mAms.switchUser(userId); - } - - AudioManager getAudioManager() { - if (mAudioManager == null) { - mAudioManager = getContext().getSystemService(AudioManager.class); - } - return mAudioManager; - } - - private PowerManager getPowerManager() { - if (mPowerManager == null) { - mPowerManager = (PowerManager) getContext().getSystemService( - Context.POWER_SERVICE); - } - return mPowerManager; - } - - NotificationManager getNotificationManager() { - if (mNm == null) { - mNm = NotificationManager.from(getContext()); - } - return mNm; - } - - ActivityManagerInternal getActivityManagerInternal() { - if (mAmi == null) { - mAmi = LocalServices.getService(ActivityManagerInternal.class); - } - return mAmi; - } - - CameraManager getCameraManager() { - if (mCameraManager == null) { - mCameraManager = (CameraManager) getContext().getSystemService( - Context.CAMERA_SERVICE); - } - return mCameraManager; - } - - PackageManager getPackageManager() { - if (mPm == null) { - mPm = getContext().getPackageManager(); - } - return mPm; - } - - IPackageManager getIPackageManager() { - return AppGlobals.getPackageManager(); - } - - ContentResolver getContentResolver() { - return getContext().getContentResolver(); - } - - PreloadAppsInstaller getPreloadAppsInstaller() { - if (mPreloadAppsInstaller == null) { - mPreloadAppsInstaller = new PreloadAppsInstaller(getContext()); - } - return mPreloadAppsInstaller; - } - - void systemPropertiesSet(String key, String value) { - SystemProperties.set(key, value); - } - - void turnOffAllFlashLights(String[] cameraIdsWithFlash) { - for (String cameraId : cameraIdsWithFlash) { - try { - getCameraManager().setTorchMode(cameraId, false); - } catch (CameraAccessException e) { - Slog.e(TAG, "Unable to access camera " + cameraId - + " while turning off flash", e); - } - } - } - - void initializeWakeLock() { - if (mWakeLock == null) { - mWakeLock = getPowerManager().newWakeLock( - PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG); - } - } - - void destroyWakeLock() { - mWakeLock = null; - } - - boolean isWakeLockHeld() { - return mWakeLock != null && mWakeLock.isHeld(); - } - - void acquireWakeLock() { - mWakeLock.acquire(); - } - - void releaseWakeLock() { - mWakeLock.release(); - } - - void logSessionDuration(int duration) { - MetricsLogger.histogram(getContext(), DEMO_SESSION_DURATION, duration); - } - - void logSessionCount(int count) { - MetricsLogger.count(getContext(), DEMO_SESSION_COUNT, count); - } - - Configuration getSystemUsersConfiguration() { - if (mSystemUserConfiguration == null) { - Settings.System.getConfiguration(getContentResolver(), - mSystemUserConfiguration = new Configuration()); - } - return mSystemUserConfiguration; - } - - LockPatternUtils getLockPatternUtils() { - return new LockPatternUtils(getContext()); - } - - Notification createResetNotification() { - return new Notification.Builder(getContext(), SystemNotificationChannels.RETAIL_MODE) - .setContentTitle(getContext().getString(R.string.reset_retail_demo_mode_title)) - .setContentText(getContext().getString(R.string.reset_retail_demo_mode_text)) - .setOngoing(true) - .setSmallIcon(R.drawable.platlogo) - .setShowWhen(false) - .setVisibility(Notification.VISIBILITY_PUBLIC) - .setContentIntent(getResetDemoPendingIntent()) - .setColor(getContext().getColor(R.color.system_notification_accent_color)) - .build(); - } - - private PendingIntent getResetDemoPendingIntent() { - if (mResetDemoPendingIntent == null) { - Intent intent = new Intent(ACTION_RESET_DEMO); - mResetDemoPendingIntent = PendingIntent.getBroadcast(getContext(), 0, intent, 0); - } - return mResetDemoPendingIntent; - } - - File getDataPreloadsDirectory() { - return Environment.getDataPreloadsDirectory(); - } - - File getDataPreloadsFileCacheDirectory() { - return Environment.getDataPreloadsFileCacheDirectory(); - } - - void publishLocalService(RetailDemoModeService service, - RetailDemoModeServiceInternal localService) { - service.publishLocalService(RetailDemoModeServiceInternal.class, localService); - } - } -} diff --git a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java b/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java deleted file mode 100644 index 013eab8679a8..000000000000 --- a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 - */ - -package com.android.server.retaildemo; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.os.CountDownTimer; -import android.view.WindowManager; -import android.widget.TextView; - -import com.android.internal.R; - -public class UserInactivityCountdownDialog extends AlertDialog { - - private OnCountDownExpiredListener mOnCountDownExpiredListener; - private CountDownTimer mCountDownTimer; - private long mCountDownDuration; - private long mRefreshInterval; - - UserInactivityCountdownDialog(Context context, long duration, long refreshInterval) { - super(context); - mCountDownDuration = duration; - mRefreshInterval = refreshInterval; - - getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); - WindowManager.LayoutParams attrs = getWindow().getAttributes(); - attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; - getWindow().setAttributes(attrs); - - setTitle(R.string.demo_user_inactivity_timeout_title); - setMessage(getContext().getString(R.string.demo_user_inactivity_timeout_countdown, - duration)); - } - - public void setOnCountDownExpiredListener( - OnCountDownExpiredListener onCountDownExpiredListener) { - mOnCountDownExpiredListener = onCountDownExpiredListener; - } - - public void setPositiveButtonClickListener(OnClickListener onClickListener) { - setButton(Dialog.BUTTON_POSITIVE, - getContext().getString(R.string.demo_user_inactivity_timeout_right_button), - onClickListener); - } - - public void setNegativeButtonClickListener(OnClickListener onClickListener) { - setButton(Dialog.BUTTON_NEGATIVE, - getContext().getString(R.string.demo_user_inactivity_timeout_left_button), - onClickListener); - } - - @Override - public void show() { - super.show(); - final TextView messageView = findViewById(R.id.message); - messageView.post(new Runnable() { - @Override - public void run() { - mCountDownTimer = new CountDownTimer(mCountDownDuration, mRefreshInterval) { - - @Override - public void onTick(long millisUntilFinished) { - String msg = getContext().getString( - R.string.demo_user_inactivity_timeout_countdown, - millisUntilFinished / 1000); - messageView.setText(msg); - } - - @Override - public void onFinish() { - dismiss(); - if (mOnCountDownExpiredListener != null) - mOnCountDownExpiredListener.onCountDownExpired(); - } - }.start(); - } - }); - } - - @Override - public void onStop() { - if (mCountDownTimer != null) { - mCountDownTimer.cancel(); - } - } - - interface OnCountDownExpiredListener { - void onCountDownExpired(); - } -} diff --git a/services/tests/notification/Android.mk b/services/tests/notification/Android.mk index 0ffe6e4db6b8..597a5849a1a0 100644 --- a/services/tests/notification/Android.mk +++ b/services/tests/notification/Android.mk @@ -18,7 +18,6 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ services.core \ services.devicepolicy \ services.net \ - services.retaildemo \ services.usage \ guava \ android-support-test \ diff --git a/services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java index ffbd8d493899..bd65f571d20b 100644 --- a/services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java @@ -170,7 +170,7 @@ public class ManagedServicesTest extends NotificationTestCase { null); writeExpectedValuesToSettings(approvalLevel); - assertTrue(service.readXml(parser)); + service.migrateToXml(); verifyExpectedApprovedEntries(service); } @@ -182,7 +182,7 @@ public class ManagedServicesTest extends NotificationTestCase { ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, approvalLevel); - assertFalse(loadXml(service)); + loadXml(service); verifyExpectedApprovedEntries(service); } @@ -239,7 +239,7 @@ public class ManagedServicesTest extends NotificationTestCase { parser.setInput(new BufferedInputStream( new ByteArrayInputStream(baos.toByteArray())), null); parser.nextTag(); - assertFalse(service.readXml(parser)); + service.readXml(parser); verifyExpectedApprovedEntries(service); assertFalse(service.isPackageOrComponentAllowed("this.is.a.package.name", 0)); @@ -341,11 +341,8 @@ public class ManagedServicesTest extends NotificationTestCase { for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, approvalLevel); - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})), - null); writeExpectedValuesToSettings(approvalLevel); - service.readXml(parser); + service.migrateToXml(); mExpectedPrimaryPackages.put(0, "another.package"); mExpectedPrimaryComponentNames.put(0, "another.package/B1"); @@ -360,11 +357,8 @@ public class ManagedServicesTest extends NotificationTestCase { for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, approvalLevel); - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})), - null); writeExpectedValuesToSettings(approvalLevel); - service.readXml(parser); + service.migrateToXml(); mExpectedSecondaryComponentNames.put(10, "component/2"); mExpectedSecondaryPackages.put(10, "component"); @@ -516,9 +510,9 @@ public class ManagedServicesTest extends NotificationTestCase { assertEquals(0, service.getAllowedComponents(10).size()); } - private boolean loadXml(ManagedServices service) throws Exception { + private void loadXml(ManagedServices service) throws Exception { final StringBuffer xml = new StringBuffer(); - xml.append("<" + service.getConfig().managedServiceTypeTag + ">\n"); + xml.append("<" + service.getConfig().xmlTag + ">\n"); for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) { xml.append(getXmlEntry( mExpectedPrimary.get(service.mApprovalLevel).get(userId), userId, true)); @@ -527,13 +521,13 @@ public class ManagedServicesTest extends NotificationTestCase { xml.append(getXmlEntry( mExpectedSecondary.get(service.mApprovalLevel).get(userId), userId, false)); } - xml.append("</" + service.getConfig().managedServiceTypeTag + ">"); + xml.append("</" + service.getConfig().xmlTag + ">"); XmlPullParser parser = Xml.newPullParser(); parser.setInput(new BufferedInputStream( new ByteArrayInputStream(xml.toString().getBytes())), null); parser.nextTag(); - return service.readXml(parser); + service.readXml(parser); } private void addExpectedServices(final ManagedServices service, final List<String> packages, @@ -674,7 +668,7 @@ public class ManagedServicesTest extends NotificationTestCase { @Override protected Config getConfig() { final Config c = new Config(); - c.managedServiceTypeTag= "test"; + c.xmlTag = "test"; c.secureSettingName = SETTING; c.secondarySettingName = SECONDARY_SETTING; c.bindPermission = "permission"; diff --git a/services/tests/notification/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java b/services/tests/notification/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java index d2f608e63e53..85852f90c281 100644 --- a/services/tests/notification/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java +++ b/services/tests/notification/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java @@ -19,6 +19,9 @@ package com.android.server.notification; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_LOW; +import static com.android.server.notification.NotificationIntrusivenessExtractor.HANG_TIME_MS; + +import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; @@ -59,9 +62,29 @@ public class NotificationIntrusivenessExtractorTest extends NotificationTestCase Notification n = builder.build(); StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0, - 0, n, UserHandle.ALL, null, System.currentTimeMillis()); + 0, n, UserHandle.ALL, null, + System.currentTimeMillis()); NotificationRecord r = new NotificationRecord(getContext(), sbn, channel); assertNotNull(new NotificationIntrusivenessExtractor().process(r)); } + + @Test + public void testOldNotificationsNotIntrusive() { + NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); + final Notification.Builder builder = new Notification.Builder(getContext()) + .setContentTitle("foo") + .setFullScreenIntent(PendingIntent.getActivity( + getContext(), 0, new Intent(""), 0), true) + .setSmallIcon(android.R.drawable.sym_def_app_icon); + + Notification n = builder.build(); + StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0, + 0, n, UserHandle.ALL, null, + System.currentTimeMillis() - HANG_TIME_MS); + + NotificationRecord r = new NotificationRecord(getContext(), sbn, channel); + assertNull(new NotificationIntrusivenessExtractor().process(r)); + assertFalse(r.isRecentlyIntrusive()); + } } diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java index d462c2ff1a6a..09af1e2fd7d4 100644 --- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -20,9 +20,6 @@ import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.content.pm.PackageManager.PERMISSION_DENIED; -import static com.android.server.notification.NotificationManagerService - .MESSAGE_SEND_RANKING_UPDATE; - import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; @@ -34,12 +31,10 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -60,35 +55,34 @@ import android.content.pm.ParceledListSlice; import android.graphics.Color; import android.media.AudioManager; import android.os.Binder; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; import android.os.Process; import android.os.UserHandle; import android.provider.Settings.Secure; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; +import android.service.notification.ZenModeConfig; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; import android.util.ArrayMap; import android.util.AtomicFile; -import android.util.Log; -import android.util.Slog; import com.android.server.lights.Light; import com.android.server.lights.LightsManager; +import com.android.server.notification.NotificationManagerService.NotificationAssistants; +import com.android.server.notification.NotificationManagerService.NotificationListeners; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.stubbing.Answer; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -115,7 +109,6 @@ public class NotificationManagerServiceTest extends NotificationTestCase { private TestableLooper mTestableLooper; @Mock private RankingHelper mRankingHelper; - @Mock AtomicFile mPolicyFile; File mFile; @Mock @@ -129,8 +122,8 @@ public class NotificationManagerServiceTest extends NotificationTestCase { private NotificationChannel mTestNotificationChannel = new NotificationChannel( TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT); @Mock - private NotificationManagerService.NotificationListeners mNotificationListeners; - @Mock private NotificationManagerService.NotificationAssistants mNotificationAssistants; + private NotificationListeners mListeners; + @Mock private NotificationAssistants mAssistants; @Mock private ConditionProviders mConditionProviders; private ManagedServices.ManagedServiceInfo mListener; @Mock private ICompanionDeviceManager mCompanionMgr; @@ -182,18 +175,34 @@ public class NotificationManagerServiceTest extends NotificationTestCase { when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class)); when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); + // write to a test file; the system file isn't readable from tests mFile = new File(mContext.getCacheDir(), "test.xml"); mFile.createNewFile(); - when(mPolicyFile.openRead()).thenReturn(new FileInputStream(mFile)); - when(mPolicyFile.startWrite()).thenReturn(new FileOutputStream(mFile)); - - mListener = mNotificationListeners.new ManagedServiceInfo( + final String preupgradeXml = "<notification-policy></notification-policy>"; + mPolicyFile = new AtomicFile(mFile); + FileOutputStream fos = mPolicyFile.startWrite(); + fos.write(preupgradeXml.getBytes()); + mPolicyFile.finishWrite(fos); + FileInputStream fStream = new FileInputStream(mFile); + + // Setup managed services + mListener = mListeners.new ManagedServiceInfo( null, new ComponentName(PKG, "test_class"), mUid, true, null, 0); - when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener); + when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener); + ManagedServices.Config listenerConfig = new ManagedServices.Config(); + listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS; + when(mListeners.getConfig()).thenReturn(listenerConfig); + ManagedServices.Config assistantConfig = new ManagedServices.Config(); + assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS; + when(mAssistants.getConfig()).thenReturn(assistantConfig); + ManagedServices.Config dndConfig = new ManagedServices.Config(); + dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS; + when(mConditionProviders.getConfig()).thenReturn(dndConfig); + try { mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager, mPackageManagerClient, mockLightsManager, - mNotificationListeners, mNotificationAssistants, mConditionProviders, + mListeners, mAssistants, mConditionProviders, mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper); } catch (SecurityException e) { @@ -827,13 +836,13 @@ public class NotificationManagerServiceTest extends NotificationTestCase { eq(channel2.getId()), anyBoolean())) .thenReturn(channel2); - reset(mNotificationListeners); + reset(mListeners); mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2))); - verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), + verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), eq(Process.myUserHandle()), eq(mTestNotificationChannel), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED)); - verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), + verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), eq(Process.myUserHandle()), eq(channel2), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED)); } @@ -847,13 +856,13 @@ public class NotificationManagerServiceTest extends NotificationTestCase { NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b"); NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m"); - reset(mNotificationListeners); + reset(mListeners); mBinderService.createNotificationChannelGroups(PKG, new ParceledListSlice(Arrays.asList(group1, group2))); - verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG), + verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG), eq(Process.myUserHandle()), eq(group1), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED)); - verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG), + verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG), eq(Process.myUserHandle()), eq(group2), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED)); } @@ -869,9 +878,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase { eq(mTestNotificationChannel.getId()), anyBoolean())) .thenReturn(mTestNotificationChannel); - reset(mNotificationListeners); + reset(mListeners); mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel); - verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), + verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), eq(Process.myUserHandle()), eq(mTestNotificationChannel), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); } @@ -885,9 +894,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase { when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean())) .thenReturn(mTestNotificationChannel); - reset(mNotificationListeners); + reset(mListeners); mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId()); - verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), + verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), eq(Process.myUserHandle()), eq(mTestNotificationChannel), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED)); } @@ -901,9 +910,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase { mNotificationManagerService.setRankingHelper(mRankingHelper); when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt())) .thenReturn(ncg); - reset(mNotificationListeners); + reset(mListeners); mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId()); - verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG), + verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG), eq(Process.myUserHandle()), eq(ncg), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED)); } @@ -920,7 +929,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase { verify(mRankingHelper, times(1)).updateNotificationChannel(anyString(), anyInt(), any()); - verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG), + verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), eq(Process.myUserHandle()), eq(mTestNotificationChannel), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); } @@ -941,7 +950,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase { verify(mRankingHelper, never()).updateNotificationChannel(anyString(), anyInt(), any()); - verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG), + verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), eq(Process.myUserHandle()), eq(mTestNotificationChannel), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); } @@ -955,7 +964,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase { mListener = mock(ManagedServices.ManagedServiceInfo.class); mListener.component = new ComponentName(PKG, PKG); when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false); - when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener); + when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener); try { mBinderService.updateNotificationChannelFromPrivilegedListener( @@ -967,7 +976,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase { verify(mRankingHelper, never()).updateNotificationChannel(anyString(), anyInt(), any()); - verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG), + verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), eq(Process.myUserHandle()), eq(mTestNotificationChannel), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); } @@ -1012,7 +1021,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase { when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); mListener = mock(ManagedServices.ManagedServiceInfo.class); when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false); - when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener); + when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener); try { mBinderService.getNotificationChannelsFromPrivilegedListener( @@ -1063,7 +1072,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase { when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); mListener = mock(ManagedServices.ManagedServiceInfo.class); when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false); - when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener); + when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener); try { mBinderService.getNotificationChannelGroupsFromPrivilegedListener( @@ -1232,11 +1241,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase { } } - verify(mNotificationListeners, times(1)).setPackageOrComponentEnabled( + verify(mListeners, times(1)).setPackageOrComponentEnabled( c.flattenToString(), 0, true, true); verify(mConditionProviders, times(1)).setPackageOrComponentEnabled( c.flattenToString(), 0, false, true); - verify(mNotificationAssistants, never()).setPackageOrComponentEnabled( + verify(mAssistants, never()).setPackageOrComponentEnabled( any(), anyInt(), anyBoolean(), anyBoolean()); } @@ -1251,11 +1260,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase { } } - verify(mNotificationAssistants, times(1)).setPackageOrComponentEnabled( + verify(mAssistants, times(1)).setPackageOrComponentEnabled( c.flattenToString(), 0, true, true); verify(mConditionProviders, times(1)).setPackageOrComponentEnabled( c.flattenToString(), 0, false, true); - verify(mNotificationListeners, never()).setPackageOrComponentEnabled( + verify(mListeners, never()).setPackageOrComponentEnabled( any(), anyInt(), anyBoolean(), anyBoolean()); } @@ -1272,9 +1281,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase { verify(mConditionProviders, times(1)).setPackageOrComponentEnabled( c.getPackageName(), 0, true, true); - verify(mNotificationAssistants, never()).setPackageOrComponentEnabled( + verify(mAssistants, never()).setPackageOrComponentEnabled( any(), anyInt(), anyBoolean(), anyBoolean()); - verify(mNotificationListeners, never()).setPackageOrComponentEnabled( + verify(mListeners, never()).setPackageOrComponentEnabled( any(), anyInt(), anyBoolean(), anyBoolean()); } @@ -1284,11 +1293,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase { ComponentName c = ComponentName.unflattenFromString("package/Component"); mBinderService.setNotificationListenerAccessGranted(c, true); - verify(mNotificationListeners, never()).setPackageOrComponentEnabled( + verify(mListeners, never()).setPackageOrComponentEnabled( c.flattenToString(), 0, true, true); verify(mConditionProviders, never()).setPackageOrComponentEnabled( c.flattenToString(), 0, false, true); - verify(mNotificationAssistants, never()).setPackageOrComponentEnabled( + verify(mAssistants, never()).setPackageOrComponentEnabled( any(), anyInt(), anyBoolean(), anyBoolean()); } @@ -1299,11 +1308,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase { mBinderService.setNotificationAssistantAccessGranted(c, true); - verify(mNotificationListeners, never()).setPackageOrComponentEnabled( + verify(mListeners, never()).setPackageOrComponentEnabled( c.flattenToString(), 0, true, true); verify(mConditionProviders, never()).setPackageOrComponentEnabled( c.flattenToString(), 0, false, true); - verify(mNotificationAssistants, never()).setPackageOrComponentEnabled( + verify(mAssistants, never()).setPackageOrComponentEnabled( any(), anyInt(), anyBoolean(), anyBoolean()); } @@ -1313,11 +1322,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase { ComponentName c = ComponentName.unflattenFromString("package/Component"); mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true); - verify(mNotificationListeners, never()).setPackageOrComponentEnabled( + verify(mListeners, never()).setPackageOrComponentEnabled( c.flattenToString(), 0, true, true); verify(mConditionProviders, never()).setPackageOrComponentEnabled( c.flattenToString(), 0, false, true); - verify(mNotificationAssistants, never()).setPackageOrComponentEnabled( + verify(mAssistants, never()).setPackageOrComponentEnabled( any(), anyInt(), anyBoolean(), anyBoolean()); } @@ -1425,16 +1434,41 @@ public class NotificationManagerServiceTest extends NotificationTestCase { } @Test - public void testModifyAutogroup_requestsSort() throws Exception { + public void testAddAutogroup_requestsSort() throws Exception { RankingHandler rh = mock(RankingHandler.class); mNotificationManagerService.setRankingHandler(rh); final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); mNotificationManagerService.addNotification(r); mNotificationManagerService.addAutogroupKeyLocked(r.getKey()); + + verify(rh, times(1)).requestSort(); + } + + @Test + public void testRemoveAutogroup_requestsSort() throws Exception { + RankingHandler rh = mock(RankingHandler.class); + mNotificationManagerService.setRankingHandler(rh); + + final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); + r.setOverrideGroupKey("TEST"); + mNotificationManagerService.addNotification(r); mNotificationManagerService.removeAutogroupKeyLocked(r.getKey()); - verify(rh, times(2)).requestSort(); + verify(rh, times(1)).requestSort(); + } + + @Test + public void testReaddAutogroup_noSort() throws Exception { + RankingHandler rh = mock(RankingHandler.class); + mNotificationManagerService.setRankingHandler(rh); + + final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); + r.setOverrideGroupKey("TEST"); + mNotificationManagerService.addNotification(r); + mNotificationManagerService.addAutogroupKeyLocked(r.getKey()); + + verify(rh, never()).requestSort(); } @Test @@ -1470,4 +1504,50 @@ public class NotificationManagerServiceTest extends NotificationTestCase { mNotificationManagerService.handleRankingSort(); verify(handler, never()).scheduleSendRankingUpdate(); } + + @Test + public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception { + final String preupgradeXml = "<notification-policy version=\"1\">" + + "<zen></zen>" + + "<ranking></ranking>" + + "<enabled_listeners>" + + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />" + + "</enabled_listeners>" + + "<enabled_assistants>" + + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />" + + "</enabled_assistants>" + + "<dnd_apps>" + + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />" + + "</dnd_apps>" + + "</notification-policy>"; + mNotificationManagerService.readPolicyXml( + new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false); + verify(mListeners, times(1)).readXml(any()); + verify(mConditionProviders, times(1)).readXml(any()); + verify(mAssistants, times(1)).readXml(any()); + + // numbers are inflated for setup + verify(mListeners, times(1)).migrateToXml(); + verify(mConditionProviders, times(1)).migrateToXml(); + verify(mAssistants, times(1)).migrateToXml(); + } + + @Test + public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception { + final String preupgradeXml = "<notification-policy version=\"1\">" + + "<zen></zen>" + + "<ranking></ranking>" + + "</notification-policy>"; + mNotificationManagerService.readPolicyXml( + new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false); + verify(mListeners, never()).readXml(any()); + verify(mConditionProviders, never()).readXml(any()); + verify(mAssistants, never()).readXml(any()); + + // numbers are inflated for setup + verify(mListeners, times(2)).migrateToXml(); + verify(mConditionProviders, times(2)).migrateToXml(); + verify(mAssistants, times(2)).migrateToXml(); + } + } diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk index 0ff11c1f58f8..507b4830e455 100644 --- a/services/tests/servicestests/Android.mk +++ b/services/tests/servicestests/Android.mk @@ -19,7 +19,6 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ services.core \ services.devicepolicy \ services.net \ - services.retaildemo \ services.usage \ guava \ android-support-test \ diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java index 16bc011f97b5..04b5bdebdca1 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java @@ -16,6 +16,7 @@ package com.android.server.am; +import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.any; @@ -78,7 +79,7 @@ public class ActivityTestsBase { int stackId, int displayId, boolean onTop) { if (service.mStackSupervisor instanceof TestActivityStackSupervisor) { return ((TestActivityStackSupervisor) service.mStackSupervisor) - .createTestStack(service, stackId, onTop); + .createTestStack(stackId, onTop); } return null; @@ -96,8 +97,7 @@ public class ActivityTestsBase { 0 /* launchedFromPid */, 0, null, intent, null, aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */, 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */, - service.mStackSupervisor, null /* container */, null /* options */, - null /* sourceRecord */); + service.mStackSupervisor, null /* options */, null /* sourceRecord */); activity.mWindowContainerController = mock(AppWindowContainerController.class); if (task != null) { @@ -187,12 +187,24 @@ public class ActivityTestsBase { boolean preserveWindows) { } - public <T extends ActivityStack> T createTestStack(ActivityManagerService service, - int stackId, boolean onTop) { - final TestActivityContainer container = - new TestActivityContainer(service, stackId, mDisplay, onTop); - mActivityContainers.put(stackId, container); - return (T) container.getStack(); + <T extends ActivityStack> T createTestStack(int stackId, boolean onTop) { + return (T) createStack(stackId, mDisplay, onTop); + } + + @Override + ActivityStack createStack(int stackId, ActivityDisplay display, boolean onTop) { + final RecentTasks recents = + new RecentTasks(mService, mService.mStackSupervisor); + if (stackId == PINNED_STACK_ID) { + return new PinnedActivityStack(display, stackId, this, recents, onTop) { + @Override + Rect getDefaultPictureInPictureBounds(float aspectRatio) { + return new Rect(50, 50, 100, 100); + } + }; + } else { + return new TestActivityStack(display, stackId, this, recents, onTop); + } } @Override @@ -204,49 +216,7 @@ public class ActivityTestsBase { return stack; } - return createTestStack(mService, stackId, createOnTop); - } - - private class TestActivityContainer extends ActivityContainer { - private final ActivityManagerService mService; - - private boolean mOnTop; - private int mStackId; - private ActivityStack mStack; - - TestActivityContainer(ActivityManagerService service, int stackId, - ActivityDisplay activityDisplay, boolean onTop) { - super(stackId, activityDisplay, onTop); - mService = service; - } - - @Override - protected void createStack(int stackId, boolean onTop) { - // normally stack creation is done here. However we need to do it on demand since - // we cannot set {@link mService} by the time the super constructor calling this - // method is invoked. - mOnTop = onTop; - mStackId = stackId; - } - - public ActivityStack getStack() { - if (mStack == null) { - final RecentTasks recents = - new RecentTasks(mService, mService.mStackSupervisor); - if (mStackId == ActivityManager.StackId.PINNED_STACK_ID) { - mStack = new PinnedActivityStack(this, recents, mOnTop) { - @Override - Rect getDefaultPictureInPictureBounds(float aspectRatio) { - return new Rect(50, 50, 100, 100); - } - }; - } else { - mStack = new TestActivityStack(this, recents, mOnTop); - } - } - - return mStack; - } + return createTestStack(stackId, createOnTop); } } @@ -277,9 +247,9 @@ public class ActivityTestsBase { extends ActivityStack<T> implements ActivityStackReporter { private int mOnActivityRemovedFromStackCount = 0; private T mContainerController; - TestActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer, - RecentTasks recentTasks, boolean onTop) { - super(activityContainer, recentTasks, onTop); + TestActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId, + ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) { + super(display, stackId, supervisor, recentTasks, onTop); } @Override diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java deleted file mode 100644 index cf27a503efd4..000000000000 --- a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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. - */ - -package com.android.server.retaildemo; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.ContextWrapper; -import android.content.pm.IPackageInstallObserver2; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; -import android.os.FileUtils; -import android.os.UserHandle; -import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; -import android.test.mock.MockContentResolver; - -import com.android.internal.util.test.FakeSettingsProvider; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -import java.io.File; -import java.util.ArrayList; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class PreloadAppsInstallerTest { - private static final int TEST_DEMO_USER = 111; - - private Context mContext; - private @Mock IPackageManager mIpm; - private MockContentResolver mContentResolver; - private File mPreloadsAppsDirectory; - private String[] mPreloadedApps = - new String[] {"test1.apk.preload", "test2.apk.preload", "test3.apk.preload"}; - private ArrayList<String> mPreloadedAppPaths = new ArrayList<>(); - - private PreloadAppsInstaller mInstaller; - - @BeforeClass - @AfterClass - public static void clearSettingsProvider() { - FakeSettingsProvider.clearSettingsProvider(); - } - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); - mContentResolver = new MockContentResolver(mContext); - mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); - when(mContext.getContentResolver()).thenReturn(mContentResolver); - initializePreloadedApps(); - Settings.Secure.putStringForUser(mContentResolver, - Settings.Secure.DEMO_USER_SETUP_COMPLETE, "0", TEST_DEMO_USER); - - mInstaller = new PreloadAppsInstaller(mContext, mIpm, mPreloadsAppsDirectory); - } - - private void initializePreloadedApps() throws Exception { - mPreloadsAppsDirectory = new File(InstrumentationRegistry.getContext().getFilesDir(), - "test_preload_apps_dir"); - mPreloadsAppsDirectory.mkdir(); - for (String name : mPreloadedApps) { - final File f = new File(mPreloadsAppsDirectory, name); - f.createNewFile(); - mPreloadedAppPaths.add(f.getPath()); - } - } - - @After - public void tearDown() { - if (mPreloadsAppsDirectory != null) { - FileUtils.deleteContentsAndDir(mPreloadsAppsDirectory); - } - } - - @Test - public void testInstallApps() throws Exception { - mInstaller.installApps(TEST_DEMO_USER); - for (String path : mPreloadedAppPaths) { - ArgumentCaptor<IPackageInstallObserver2> observer = - ArgumentCaptor.forClass(IPackageInstallObserver2.class); - verify(mIpm).installPackageAsUser(eq(path), observer.capture(), anyInt(), - anyString(), eq(TEST_DEMO_USER)); - observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_SUCCEEDED, - null, null); - // Verify that we try to install the package in system user. - verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM, - 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN); - } - assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed", - "1", - Settings.Secure.getStringForUser(mContentResolver, - Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER)); - } - - @Test - public void testInstallApps_noPreloads() throws Exception { - // Delete all files in preloaded apps directory - no preloaded apps - FileUtils.deleteContents(mPreloadsAppsDirectory); - mInstaller.installApps(TEST_DEMO_USER); - assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed", - "1", - Settings.Secure.getStringForUser(mContentResolver, - Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER)); - } - - @Test - public void testInstallApps_installationFails() throws Exception { - mInstaller.installApps(TEST_DEMO_USER); - for (int i = 0; i < mPreloadedAppPaths.size(); ++i) { - ArgumentCaptor<IPackageInstallObserver2> observer = - ArgumentCaptor.forClass(IPackageInstallObserver2.class); - final String path = mPreloadedAppPaths.get(i); - verify(mIpm).installPackageAsUser(eq(path), observer.capture(), anyInt(), - anyString(), eq(TEST_DEMO_USER)); - if (i == 0) { - observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_FAILED_DEXOPT, - null, null); - continue; - } - observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_SUCCEEDED, - null, null); - // Verify that we try to install the package in system user. - verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM, - 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN); - } - assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed", - "1", - Settings.Secure.getStringForUser(mContentResolver, - Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER)); - } -} diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java deleted file mode 100644 index a93f64396d57..000000000000 --- a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java +++ /dev/null @@ -1,484 +0,0 @@ -/* - * 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. - */ - -package com.android.server.retaildemo; - -import static com.android.server.retaildemo.RetailDemoModeService.SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.Manifest; -import android.app.ActivityManagerInternal; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.RetailDemoModeServiceInternal; -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.ContextWrapper; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.UserInfo; -import android.content.res.Configuration; -import android.media.AudioManager; -import android.net.Uri; -import android.net.wifi.WifiManager; -import android.os.FileUtils; -import android.os.Handler; -import android.os.Looper; -import android.os.UserHandle; -import android.os.UserManager; -import android.provider.CallLog; -import android.provider.MediaStore; -import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; -import android.test.mock.MockContentProvider; -import android.test.mock.MockContentResolver; -import android.util.ArrayMap; - -import com.android.internal.util.test.FakeSettingsProvider; -import com.android.internal.widget.LockPatternUtils; -import com.android.server.SystemService; -import com.android.server.retaildemo.RetailDemoModeService.Injector; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.mockito.compat.ArgumentMatcher; - -import java.io.File; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class RetailDemoModeServiceTest { - private static final int TEST_DEMO_USER = 111; - private static final long SETUP_COMPLETE_TIMEOUT_MS = 2000; // 2 sec - private static final String TEST_CAMERA_PKG = "test.cameraapp"; - private static final String TEST_PRELOADS_DIR_NAME = "test_preloads"; - - private Context mContext; - private @Mock UserManager mUm; - private @Mock PackageManager mPm; - private @Mock IPackageManager mIpm; - private @Mock NotificationManager mNm; - private @Mock ActivityManagerInternal mAmi; - private @Mock AudioManager mAudioManager; - private @Mock WifiManager mWifiManager; - private @Mock LockPatternUtils mLockPatternUtils; - private @Mock JobScheduler mJobScheduler; - private MockPreloadAppsInstaller mPreloadAppsInstaller; - private MockContentResolver mContentResolver; - private MockContactsProvider mContactsProvider; - private Configuration mConfiguration; - private File mTestPreloadsDir; - private CountDownLatch mLatch; - - private RetailDemoModeService mService; - private TestInjector mInjector; - - @BeforeClass - @AfterClass - public static void clearSettingsProvider() { - FakeSettingsProvider.clearSettingsProvider(); - } - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); - when(mContext.getSystemServiceName(eq(JobScheduler.class))).thenReturn( - Context.JOB_SCHEDULER_SERVICE); - when(mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE)).thenReturn(mJobScheduler); - when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUm); - mContentResolver = new MockContentResolver(mContext); - mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); - mContactsProvider = new MockContactsProvider(mContext); - mContentResolver.addProvider(CallLog.AUTHORITY, mContactsProvider); - when(mContext.getContentResolver()).thenReturn(mContentResolver); - mPreloadAppsInstaller = new MockPreloadAppsInstaller(mContext); - mConfiguration = new Configuration(); - mTestPreloadsDir = new File(InstrumentationRegistry.getContext().getFilesDir(), - TEST_PRELOADS_DIR_NAME); - - Settings.Global.putString(mContentResolver, Settings.Global.RETAIL_DEMO_MODE_CONSTANTS, ""); - Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 1); - Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_DEMO_MODE, 1); - - // Initialize RetailDemoModeService - mInjector = new TestInjector(); - mService = new RetailDemoModeService(mInjector); - mService.onStart(); - } - - @After - public void tearDown() { - if (mTestPreloadsDir != null) { - FileUtils.deleteContentsAndDir(mTestPreloadsDir); - } - } - - @Test - public void testDemoUserSetup() throws Exception { - mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); - - mLatch = new CountDownLatch(1); - final UserInfo userInfo = new UserInfo(); - userInfo.id = TEST_DEMO_USER; - when(mUm.createUser(anyString(), anyInt())).thenReturn(userInfo); - - setCameraPackage(TEST_CAMERA_PKG); - mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); - assertEquals(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED + " property not set", - "1", mInjector.systemPropertiesGet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED)); - - final ArgumentCaptor<IntentFilter> intentFilter = - ArgumentCaptor.forClass(IntentFilter.class); - verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture()); - assertTrue("Not registered for " + Intent.ACTION_SCREEN_OFF, - intentFilter.getValue().hasAction(Intent.ACTION_SCREEN_OFF)); - - // Wait for the setup to complete. - mLatch.await(SETUP_COMPLETE_TIMEOUT_MS, TimeUnit.MILLISECONDS); - ArgumentCaptor<Integer> flags = ArgumentCaptor.forClass(Integer.class); - verify(mUm).createUser(anyString(), flags.capture()); - assertTrue("FLAG_DEMO not set during user creation", - (flags.getValue() & UserInfo.FLAG_DEMO) != 0); - assertTrue("FLAG_EPHEMERAL not set during user creation", - (flags.getValue() & UserInfo.FLAG_EPHEMERAL) != 0); - // Verify if necessary restrictions are being set. - final UserHandle user = UserHandle.of(TEST_DEMO_USER); - verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user); - verify(mUm).setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user); - verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user); - verify(mUm).setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user); - verify(mUm).setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user); - verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user); - verify(mUm).setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user); - verify(mUm).setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM); - // Verify if necessary settings are updated. - assertEquals("SKIP_FIRST_USE_HINTS setting is not set for demo user", - Settings.Secure.getIntForUser(mContentResolver, - Settings.Secure.SKIP_FIRST_USE_HINTS, TEST_DEMO_USER), - 1); - assertEquals("PACKAGE_VERIFIER_ENABLE settings should be set to 0 for demo user", - Settings.Global.getInt(mContentResolver, - Settings.Global.PACKAGE_VERIFIER_ENABLE), - 0); - // Verify if camera is granted location permission. - verify(mPm).grantRuntimePermission(TEST_CAMERA_PKG, - Manifest.permission.ACCESS_FINE_LOCATION, user); - // Verify call logs are cleared. - assertTrue("Call logs should be deleted", mContactsProvider.isCallLogDeleted()); - } - - @Test - public void testSettingsObserver_disableDemoMode() throws Exception { - final RetailDemoModeService.SettingsObserver observer = - mService.new SettingsObserver(new Handler(Looper.getMainLooper())); - final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE); - when(mUm.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT, UserHandle.SYSTEM)) - .thenReturn(false); - Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1); - // Settings.Global.DEVICE_DEMO_MODE has been set to 1 initially. - observer.onChange(false, deviceDemoModeUri); - final ArgumentCaptor<BroadcastReceiver> receiver = - ArgumentCaptor.forClass(BroadcastReceiver.class); - verify(mContext).registerReceiver(receiver.capture(), any(IntentFilter.class)); - - Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0); - new File(mTestPreloadsDir, "dir1").mkdirs(); - new File(mTestPreloadsDir, "file1").createNewFile(); - Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_DEMO_MODE, 0); - observer.onChange(false, deviceDemoModeUri); - verify(mContext).unregisterReceiver(receiver.getValue()); - verify(mUm).setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, false, UserHandle.SYSTEM); - assertEquals("Package verifier enable value has not been reset", 1, - Settings.Global.getInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE)); - Thread.sleep(20); // Wait for the deletion to complete. - // verify that the preloaded directory is emptied. - assertEquals("Preloads directory is not emptied", - 0, mTestPreloadsDir.list().length); - // Verify that the expiration job was scheduled - verify(mJobScheduler).schedule(any(JobInfo.class)); - } - - @Test - public void testSettingsObserver_enableDemoMode() throws Exception { - final RetailDemoModeService.SettingsObserver observer = - mService.new SettingsObserver(new Handler(Looper.getMainLooper())); - final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE); - // Settings.Global.DEVICE_DEMO_MODE has been set to 1 initially. - observer.onChange(false, deviceDemoModeUri); - assertEquals(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED + " property not set", - "1", mInjector.systemPropertiesGet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED)); - - final ArgumentCaptor<IntentFilter> intentFilter = - ArgumentCaptor.forClass(IntentFilter.class); - verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture()); - assertTrue("Not registered for " + Intent.ACTION_SCREEN_OFF, - intentFilter.getValue().hasAction(Intent.ACTION_SCREEN_OFF)); - } - - @Test - public void testSwitchToDemoUser() { - // To make the RetailDemoModeService update it's internal state. - mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); - final RetailDemoModeService.SettingsObserver observer = - mService.new SettingsObserver(new Handler(Looper.getMainLooper())); - observer.onChange(false, Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE)); - - final UserInfo userInfo = new UserInfo(TEST_DEMO_USER, "demo_user", - UserInfo.FLAG_DEMO | UserInfo.FLAG_EPHEMERAL); - when(mUm.getUserInfo(TEST_DEMO_USER)).thenReturn(userInfo); - when(mWifiManager.isWifiEnabled()).thenReturn(false); - final int minVolume = -111; - for (int stream : RetailDemoModeService.VOLUME_STREAMS_TO_MUTE) { - when(mAudioManager.getStreamMinVolume(stream)).thenReturn(minVolume); - } - - mService.onSwitchUser(TEST_DEMO_USER); - verify(mAmi).updatePersistentConfigurationForUser(mConfiguration, TEST_DEMO_USER); - for (int stream : RetailDemoModeService.VOLUME_STREAMS_TO_MUTE) { - verify(mAudioManager).setStreamVolume(stream, minVolume, 0); - } - verify(mLockPatternUtils).setLockScreenDisabled(true, TEST_DEMO_USER); - verify(mWifiManager).setWifiEnabled(true); - } - - private void setCameraPackage(String pkgName) { - final ResolveInfo ri = new ResolveInfo(); - final ActivityInfo ai = new ActivityInfo(); - ai.packageName = pkgName; - ri.activityInfo = ai; - when(mPm.resolveActivityAsUser( - argThat(new IntentMatcher(MediaStore.ACTION_IMAGE_CAPTURE)), - anyInt(), - eq(TEST_DEMO_USER))).thenReturn(ri); - } - - private class IntentMatcher extends ArgumentMatcher<Intent> { - private final Intent mIntent; - - IntentMatcher(String action) { - mIntent = new Intent(action); - } - - @Override - public boolean matchesObject(Object argument) { - if (argument instanceof Intent) { - return ((Intent) argument).filterEquals(mIntent); - } - return false; - } - - @Override - public String toString() { - return "Expected: " + mIntent; - } - } - - private class MockContactsProvider extends MockContentProvider { - private boolean mCallLogDeleted; - - MockContactsProvider(Context context) { - super(context); - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - if (CallLog.Calls.CONTENT_URI.equals(uri)) { - mCallLogDeleted = true; - } - return 0; - } - - public boolean isCallLogDeleted() { - return mCallLogDeleted; - } - } - - private class MockPreloadAppsInstaller extends PreloadAppsInstaller { - MockPreloadAppsInstaller(Context context) { - super(context); - } - - @Override - public void installApps(int userId) { - } - } - - private class TestInjector extends Injector { - private ArrayMap<String, String> mSystemProperties = new ArrayMap<>(); - - TestInjector() { - super(mContext); - } - - @Override - Context getContext() { - return mContext; - } - - @Override - UserManager getUserManager() { - return mUm; - } - - @Override - WifiManager getWifiManager() { - return mWifiManager; - } - - @Override - void switchUser(int userId) { - if (mLatch != null) { - mLatch.countDown(); - } - } - - @Override - AudioManager getAudioManager() { - return mAudioManager; - } - - @Override - NotificationManager getNotificationManager() { - return mNm; - } - - @Override - ActivityManagerInternal getActivityManagerInternal() { - return mAmi; - } - - @Override - PackageManager getPackageManager() { - return mPm; - } - - @Override - IPackageManager getIPackageManager() { - return mIpm; - } - - @Override - ContentResolver getContentResolver() { - return mContentResolver; - } - - @Override - PreloadAppsInstaller getPreloadAppsInstaller() { - return mPreloadAppsInstaller; - } - - @Override - void systemPropertiesSet(String key, String value) { - mSystemProperties.put(key, value); - } - - @Override - void turnOffAllFlashLights(String[] cameraIdsWithFlash) { - } - - @Override - void initializeWakeLock() { - } - - @Override - void destroyWakeLock() { - } - - @Override - boolean isWakeLockHeld() { - return false; - } - - @Override - void acquireWakeLock() { - } - - @Override - void releaseWakeLock() { - } - - @Override - void logSessionDuration(int duration) { - } - - @Override - void logSessionCount(int count) { - } - - @Override - Configuration getSystemUsersConfiguration() { - return mConfiguration; - } - - @Override - LockPatternUtils getLockPatternUtils() { - return mLockPatternUtils; - } - - @Override - Notification createResetNotification() { - return null; - } - - @Override - File getDataPreloadsDirectory() { - return mTestPreloadsDir; - } - - @Override - File getDataPreloadsFileCacheDirectory() { - return new File(mTestPreloadsDir, "file_cache"); - } - - @Override - void publishLocalService(RetailDemoModeService service, - RetailDemoModeServiceInternal localService) { - } - - String systemPropertiesGet(String key) { - return mSystemProperties.get(key); - } - } -} diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java index 0060901578cd..cb6a83d2644b 100644 --- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java +++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java @@ -16,12 +16,14 @@ package com.android.internal.colorextraction; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.mockito.Mockito.any; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; import android.graphics.Color; @@ -29,7 +31,6 @@ import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.ColorExtractor.GradientColors; import com.android.internal.colorextraction.types.ExtractionType; import com.android.internal.colorextraction.types.Tonal; @@ -78,10 +79,10 @@ public class ColorExtractorTest { ExtractionType type = (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark, outGradientColorsExtraDark) -> { - outGradientColorsNormal.set(colorsExpectedNormal); - outGradientColorsDark.set(colorsExpectedDark); - outGradientColorsExtraDark.set(colorsExpectedExtraDark); - }; + outGradientColorsNormal.set(colorsExpectedNormal); + outGradientColorsDark.set(colorsExpectedDark); + outGradientColorsExtraDark.set(colorsExpectedExtraDark); + }; ColorExtractor extractor = new ColorExtractor(mContext, type); GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, @@ -92,4 +93,22 @@ public class ColorExtractorTest { colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_EXTRA_DARK); assertEquals("Extracted colors not being used!", colors, colorsExpectedExtraDark); } + + @Test + public void addOnColorsChangedListener_invokesListener() { + ColorExtractor.OnColorsChangedListener mockedListeners = + mock(ColorExtractor.OnColorsChangedListener.class); + ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext)); + extractor.addOnColorsChangedListener(mockedListeners); + + extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null), + WallpaperManager.FLAG_LOCK); + verify(mockedListeners, times(1)).onColorsChanged(any(), + eq(WallpaperManager.FLAG_LOCK)); + + extractor.removeOnColorsChangedListener(mockedListeners); + extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null), + WallpaperManager.FLAG_LOCK); + verifyNoMoreInteractions(mockedListeners); + } } diff --git a/tests/UiBench/Android.mk b/tests/UiBench/Android.mk index 71067aef52c7..e6af4b024700 100644 --- a/tests/UiBench/Android.mk +++ b/tests/UiBench/Android.mk @@ -15,21 +15,24 @@ LOCAL_RESOURCE_DIR := \ frameworks/support/design/res \ frameworks/support/v7/appcompat/res \ frameworks/support/v7/cardview/res \ - frameworks/support/v7/recyclerview/res + frameworks/support/v7/recyclerview/res \ + frameworks/support/v17/leanback/res LOCAL_AAPT_FLAGS := \ --auto-add-overlay \ --extra-packages android.support.design \ --extra-packages android.support.v7.appcompat \ --extra-packages android.support.v7.cardview \ - --extra-packages android.support.v7.recyclerview + --extra-packages android.support.v7.recyclerview \ + --extra-packages android.support.v17.leanback LOCAL_STATIC_JAVA_LIBRARIES := \ android-support-design \ android-support-v4 \ android-support-v7-appcompat \ android-support-v7-cardview \ - android-support-v7-recyclerview + android-support-v7-recyclerview \ + android-support-v17-leanback LOCAL_PACKAGE_NAME := UiBench diff --git a/tests/UiBench/AndroidManifest.xml b/tests/UiBench/AndroidManifest.xml index c20be5141df5..2521dc9f82ae 100644 --- a/tests/UiBench/AndroidManifest.xml +++ b/tests/UiBench/AndroidManifest.xml @@ -257,5 +257,15 @@ <category android:name="com.android.test.uibench.TEST" /> </intent-filter> </activity> + + <activity + android:name=".leanback.BrowseActivity" + android:theme="@style/Theme.Leanback.Browse" + android:label="Leanback/Browse Fragment" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="com.android.test.uibench.TEST" /> + </intent-filter> + </activity> </application> </manifest> diff --git a/tests/UiBench/build.gradle b/tests/UiBench/build.gradle index 03ef7f106de5..fa2cfcd438fd 100644 --- a/tests/UiBench/build.gradle +++ b/tests/UiBench/build.gradle @@ -36,4 +36,5 @@ dependencies { compile 'com.android.support:cardview-v7:23.0.1' compile 'com.android.support:recyclerview-v7:23.0.1' compile 'com.android.support:design:23.0.1' + compile 'com.android.support:leanback-v17:23.0.1' } diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/BitmapLoader.java b/tests/UiBench/src/com/android/test/uibench/leanback/BitmapLoader.java new file mode 100644 index 000000000000..8af9d3bca647 --- /dev/null +++ b/tests/UiBench/src/com/android/test/uibench/leanback/BitmapLoader.java @@ -0,0 +1,144 @@ +/* + * 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.test.uibench.leanback; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.os.AsyncTask; +import android.support.v4.util.LruCache; +import android.util.DisplayMetrics; +import android.widget.ImageView; + +/** + * This class simulates a typical Bitmap memory cache with up to 1.5 times of screen pixels. + * The sample bitmap is generated in worker threads in AsyncTask.THREAD_POOL_EXECUTOR. + * The class does not involve decoding, disk cache i/o, network i/o, as the test is mostly focusing + * on the graphics side. + * There will be two general use cases for cards in leanback test: + * 1. As a typical app, each card has its own id and load its own Bitmap, the test result will + * include impact of texture upload. + * 2. All cards share same id/Bitmap and there wont be texture upload. + */ +public class BitmapLoader { + + /** + * Caches bitmaps with bytes adds up to 1.5 x screen + * DO NOT CHANGE this defines baseline of test result. + */ + static final float CACHE_SIZE_TO_SCREEN = 1.5f; + /** + * 4 bytes per pixel for RGBA_8888 + */ + static final int BYTES_PER_PIXEL = 4; + + static LruCache<Long, Bitmap> sLruCache; + static Paint sTextPaint = new Paint(); + + static { + sTextPaint.setColor(Color.BLACK); + } + + /** + * get or initialize LruCache, the max is set to full screen pixels. + */ + static LruCache<Long, Bitmap> getLruCache(Context context) { + if (sLruCache == null) { + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + int width = metrics.widthPixels; + int height = metrics.heightPixels; + int maxBytes = (int) (width * height * BYTES_PER_PIXEL * CACHE_SIZE_TO_SCREEN); + sLruCache = new LruCache<Long, Bitmap>(maxBytes) { + @Override + protected int sizeOf(Long key, Bitmap value) { + return value.getByteCount(); + } + }; + } + return sLruCache; + } + + static class BitmapAsyncTask extends AsyncTask<Void, Void, Bitmap> { + + ImageView mImageView; + long mId; + int mWidth; + int mHeight; + + BitmapAsyncTask(ImageView view, long id, int width, int height) { + mImageView = view; + mId = id; + mImageView.setTag(this); + mWidth = width; + mHeight = height; + } + + @Override + protected Bitmap doInBackground(Void... voids) { + // generate a sample bitmap: white background and text showing id + Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + canvas.drawARGB(0xff, 0xff, 0xff, 0xff); + canvas.drawText(Long.toString(mId), 0f, mHeight / 2, sTextPaint); + canvas.setBitmap(null); + bitmap.prepareToDraw(); + return bitmap; + } + + @Override + protected void onCancelled() { + if (mImageView.getTag() == this) { + mImageView.setTag(null); + } + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (mImageView.getTag() == this) { + mImageView.setTag(null); + sLruCache.put(mId, bitmap); + mImageView.setImageBitmap(bitmap); + } + } + } + + public static void loadBitmap(ImageView view, long id, int width, int height) { + Context context = view.getContext(); + Bitmap bitmap = getLruCache(context).get(id); + if (bitmap != null) { + view.setImageBitmap(bitmap); + return; + } + new BitmapAsyncTask(view, id, width, height) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + public static void cancel(ImageView view) { + BitmapAsyncTask task = (BitmapAsyncTask) view.getTag(); + if (task != null && task.mImageView == view) { + task.mImageView.setTag(null); + task.cancel(false); + } + } + + public static void clear() { + if (sLruCache != null) { + sLruCache.evictAll(); + } + } +} diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/BrowseActivity.java b/tests/UiBench/src/com/android/test/uibench/leanback/BrowseActivity.java new file mode 100644 index 000000000000..d29f0eaf6fdc --- /dev/null +++ b/tests/UiBench/src/com/android/test/uibench/leanback/BrowseActivity.java @@ -0,0 +1,31 @@ +/* + * 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.test.uibench.leanback; + +import android.support.v4.app.FragmentActivity; +import android.app.Activity; +import android.os.Bundle; + +public class BrowseActivity extends FragmentActivity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState == null) { + getSupportFragmentManager().beginTransaction() + .add(android.R.id.content, new BrowseFragment()) + .commit(); + } + } + +} diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/BrowseFragment.java b/tests/UiBench/src/com/android/test/uibench/leanback/BrowseFragment.java new file mode 100644 index 000000000000..11ea36132dcc --- /dev/null +++ b/tests/UiBench/src/com/android/test/uibench/leanback/BrowseFragment.java @@ -0,0 +1,40 @@ +/* + * 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.test.uibench.leanback; + +import android.os.Bundle; + +public class BrowseFragment extends android.support.v17.leanback.app.BrowseSupportFragment { + + public BrowseFragment() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + BitmapLoader.clear(); + TestHelper.initBackground(getActivity()); + boolean runEntranceTransition = TestHelper.runEntranceTransition(getActivity()); + if (runEntranceTransition) { + prepareEntranceTransition(); + } + setAdapter(TestHelper.initRowsAdapterBuilder(getActivity()).build()); + if (runEntranceTransition) { + startEntranceTransition(); + } + } + +} diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/CardPresenter.java b/tests/UiBench/src/com/android/test/uibench/leanback/CardPresenter.java new file mode 100644 index 000000000000..5194555aca01 --- /dev/null +++ b/tests/UiBench/src/com/android/test/uibench/leanback/CardPresenter.java @@ -0,0 +1,62 @@ +/* + * 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.test.uibench.leanback; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.support.v17.leanback.widget.ImageCardView; +import android.support.v17.leanback.widget.Presenter; +import android.support.v4.content.res.ResourcesCompat; +import android.view.ContextThemeWrapper; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; + +public class CardPresenter extends Presenter { + + private int mImageWidth = 0; + private int mImageHeight = 0; + + public CardPresenter(int width, int height) { + mImageWidth = width; + mImageHeight = height; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent) { + Context context = parent.getContext(); + ImageCardView v = new ImageCardView(context); + v.setFocusable(true); + v.setFocusableInTouchMode(true); + v.setMainImageAdjustViewBounds(true); + v.setMainImageDimensions(mImageWidth, mImageHeight); + return new ViewHolder(v); + } + + @Override + public void onBindViewHolder(ViewHolder viewHolder, Object item) { + PhotoItem photoItem = (PhotoItem) item; + ImageCardView cardView = (ImageCardView) viewHolder.view; + cardView.setTitleText(photoItem.getTitle()); + BitmapLoader.loadBitmap(cardView.getMainImageView(), photoItem.getId(), + mImageWidth, mImageHeight); + } + + @Override + public void onUnbindViewHolder(ViewHolder viewHolder) { + ImageCardView cardView = (ImageCardView) viewHolder.view; + BitmapLoader.cancel(cardView.getMainImageView()); + } +} diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/PhotoItem.java b/tests/UiBench/src/com/android/test/uibench/leanback/PhotoItem.java new file mode 100644 index 000000000000..acb9a5d05a7f --- /dev/null +++ b/tests/UiBench/src/com/android/test/uibench/leanback/PhotoItem.java @@ -0,0 +1,72 @@ +/* + * 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.test.uibench.leanback; + +import android.os.Parcel; +import android.os.Parcelable; + +public class PhotoItem implements Parcelable { + + private String mTitle; + private long mId; + + public PhotoItem(String title, long id) { + mTitle = title; + mId = id; + } + + public long getId() { + return mId; + } + + public String getTitle() { + return mTitle; + } + + @Override + public String toString() { + return mTitle; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mTitle); + dest.writeLong(mId); + } + + public static final Creator<PhotoItem> CREATOR + = new Creator<PhotoItem>() { + @Override + public PhotoItem createFromParcel(Parcel in) { + return new PhotoItem(in); + } + + @Override + public PhotoItem[] newArray(int size) { + return new PhotoItem[size]; + } + }; + + private PhotoItem(Parcel in) { + mTitle = in.readString(); + mId = in.readLong(); + } +} diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/TestHelper.java b/tests/UiBench/src/com/android/test/uibench/leanback/TestHelper.java new file mode 100644 index 000000000000..2bf388501ba0 --- /dev/null +++ b/tests/UiBench/src/com/android/test/uibench/leanback/TestHelper.java @@ -0,0 +1,238 @@ +/* + * 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.test.uibench.leanback; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.support.v17.leanback.app.BackgroundManager; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.ObjectAdapter; +import android.support.v17.leanback.widget.Presenter; +import android.util.DisplayMetrics; +import android.util.TypedValue; + +public class TestHelper { + + public static final String EXTRA_BACKGROUND = "extra_bg"; + public static final String EXTRA_ROWS = "extra_rows"; + public static final String EXTRA_CARDS_PER_ROW = "extra_cards_per_row"; + public static final String EXTRA_CARD_HEIGHT_DP = "extra_card_height"; + public static final String EXTRA_CARD_WIDTH_DP = "extra_card_width"; + public static final String EXTRA_CARD_SHADOW = "extra_card_shadow"; + public static final String EXTRA_CARD_ROUND_RECT = "extra_card_round_rect"; + public static final String EXTRA_ENTRANCE_TRANSITION = "extra_entrance_transition"; + public static final String EXTRA_BITMAP_UPLOAD = "extra_bitmap_upload"; + + /** + * Dont change the default values, they gave baseline for measuring the performance + */ + static final int DEFAULT_CARD_HEIGHT_DP = 180; + static final int DEFAULT_CARD_WIDTH_DP = 125; + static final int DEFAULT_CARDS_PER_ROW = 20; + static final int DEFAULT_ROWS = 10; + static final boolean DEFAULT_ENTRANCE_TRANSITION = false; + static final boolean DEFAULT_BACKGROUND = true; + static final boolean DEFAULT_CARD_SHADOW = true; + static final boolean DEFAULT_CARD_ROUND_RECT = true; + static final boolean DEFAULT_BITMAP_UPLOAD = true; + + static long sCardIdSeed = 0; + static long sRowIdSeed = 0; + + public static class ListRowPresenterBuilder { + + boolean mShadow = DEFAULT_CARD_SHADOW; + boolean mRoundedCorner = DEFAULT_CARD_ROUND_RECT; + + ListRowPresenterBuilder(Context context) { + } + + public ListRowPresenterBuilder configShadow(boolean shadow) { + mShadow = shadow; + return this; + } + + public ListRowPresenterBuilder configRoundedCorner(boolean roundedCorner) { + mRoundedCorner = roundedCorner; + return this; + } + + public ListRowPresenter build() { + ListRowPresenter listRowPresenter = new ListRowPresenter(); + listRowPresenter.setShadowEnabled(mShadow); + listRowPresenter.enableChildRoundedCorners(mRoundedCorner); + return listRowPresenter; + } + } + + public static class CardPresenterBuilder { + Context mContext; + int mWidthDP = DEFAULT_CARD_WIDTH_DP; + int mHeightDP = DEFAULT_CARD_HEIGHT_DP; + + CardPresenterBuilder(Context context) { + mContext = context; + } + + public CardPresenterBuilder configWidthDP(int widthDP) { + mWidthDP = widthDP; + return this; + } + + public CardPresenterBuilder configHeightDP(int hightDP) { + mHeightDP = hightDP; + return this; + } + + public Presenter build() { + DisplayMetrics dm = mContext.getResources().getDisplayMetrics(); + return new CardPresenter( + (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mWidthDP, dm), + (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHeightDP, dm)); + } + } + + public static class RowsAdapterBuilder { + + Context mContext; + int mCardsPerRow = DEFAULT_CARDS_PER_ROW; + int mRows = DEFAULT_ROWS; + CardPresenterBuilder mCardPresenterBuilder; + ListRowPresenterBuilder mListRowPresenterBuilder; + Presenter mCardPresenter; + boolean mBitmapUpload = DEFAULT_BITMAP_UPLOAD; + + static final String[] sSampleStrings = new String[] { + "Hello world", "This is a test", "Android TV", "UI Jank Test", + "Scroll Up", "Scroll Down", "Load Bitmaps" + }; + + /** + * Create a RowsAdapterBuilder with default settings + */ + public RowsAdapterBuilder(Context context) { + mContext = context; + mCardPresenterBuilder = new CardPresenterBuilder(context); + mListRowPresenterBuilder = new ListRowPresenterBuilder(context); + } + + public ListRowPresenterBuilder getListRowPresenterBuilder() { + return mListRowPresenterBuilder; + } + + public CardPresenterBuilder getCardPresenterBuilder() { + return mCardPresenterBuilder; + } + + public RowsAdapterBuilder configRows(int rows) { + mRows = rows; + return this; + } + + public RowsAdapterBuilder configCardsPerRow(int cardsPerRow) { + mCardsPerRow = cardsPerRow; + return this; + } + + public RowsAdapterBuilder configBitmapUpLoad(boolean bitmapUpload) { + mBitmapUpload = bitmapUpload; + return this; + } + + public ListRow buildListRow() { + ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(mCardPresenter); + ListRow listRow = new ListRow(new HeaderItem(sRowIdSeed++, "Row"), listRowAdapter); + int indexSample = 0; + for (int i = 0; i < mCardsPerRow; i++) { + // when doing bitmap upload, use different id so each card has different bitmap + // otherwise all cards share the same bitmap + listRowAdapter.add(new PhotoItem(sSampleStrings[indexSample], + (mBitmapUpload ? sCardIdSeed++ : 0))); + indexSample++; + if (indexSample >= sSampleStrings.length) { + indexSample = 0; + } + } + return listRow; + } + + public ObjectAdapter build() { + try { + mCardPresenter = mCardPresenterBuilder.build(); + ArrayObjectAdapter adapter = new ArrayObjectAdapter( + mListRowPresenterBuilder.build()); + for (int i = 0; i < mRows; i++) { + adapter.add(buildListRow()); + } + return adapter; + } finally { + mCardPresenter = null; + } + } + } + + public static boolean runEntranceTransition(Activity activity) { + return activity.getIntent().getBooleanExtra(EXTRA_ENTRANCE_TRANSITION, + DEFAULT_ENTRANCE_TRANSITION); + } + + public static RowsAdapterBuilder initRowsAdapterBuilder(Activity activity) { + RowsAdapterBuilder builder = new RowsAdapterBuilder(activity); + boolean shadow = activity.getIntent().getBooleanExtra(EXTRA_CARD_SHADOW, + DEFAULT_CARD_SHADOW); + boolean roundRect = activity.getIntent().getBooleanExtra(EXTRA_CARD_ROUND_RECT, + DEFAULT_CARD_ROUND_RECT); + int widthDp = activity.getIntent().getIntExtra(EXTRA_CARD_WIDTH_DP, + DEFAULT_CARD_WIDTH_DP); + int heightDp = activity.getIntent().getIntExtra(EXTRA_CARD_HEIGHT_DP, + DEFAULT_CARD_HEIGHT_DP); + int rows = activity.getIntent().getIntExtra(EXTRA_ROWS, DEFAULT_ROWS); + int cardsPerRow = activity.getIntent().getIntExtra(EXTRA_CARDS_PER_ROW, + DEFAULT_CARDS_PER_ROW); + boolean bitmapUpload = activity.getIntent().getBooleanExtra(EXTRA_BITMAP_UPLOAD, + DEFAULT_BITMAP_UPLOAD); + builder.configRows(rows) + .configCardsPerRow(cardsPerRow) + .configBitmapUpLoad(bitmapUpload); + builder.getListRowPresenterBuilder() + .configRoundedCorner(roundRect) + .configShadow(shadow); + builder.getCardPresenterBuilder() + .configWidthDP(widthDp) + .configHeightDP(heightDp); + return builder; + } + + public static void initBackground(Activity activity) { + if (activity.getIntent().getBooleanExtra(EXTRA_BACKGROUND, DEFAULT_BACKGROUND)) { + BackgroundManager manager = BackgroundManager.getInstance(activity); + manager.attach(activity.getWindow()); + DisplayMetrics metrics = activity.getResources().getDisplayMetrics(); + int width = metrics.widthPixels; + int height = metrics.heightPixels; + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + canvas.drawARGB(255, 128, 128, 128); + canvas.setBitmap(null); + manager.setBitmap(bitmap); + } + } +} |