diff options
284 files changed, 2839 insertions, 1068 deletions
@@ -28617,7 +28617,6 @@ package android.widget { method public void setHeight(int); method public void setHorizontalOffset(int); method public void setInputMethodMode(int); - method public void setLayoutDirection(int); method public void setListSelector(android.graphics.drawable.Drawable); method public void setModal(boolean); method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener); diff --git a/api/current.txt b/api/current.txt index b5aa2c1..5462aee 100644 --- a/api/current.txt +++ b/api/current.txt @@ -8263,6 +8263,7 @@ package android.graphics { method public int getScaledWidth(int); method public final int getWidth(); method public final boolean hasAlpha(); + method public final boolean hasMipMap(); method public final boolean isMutable(); method public final boolean isPremultiplied(); method public final boolean isRecycled(); @@ -8271,6 +8272,7 @@ package android.graphics { method public boolean sameAs(android.graphics.Bitmap); method public void setDensity(int); method public void setHasAlpha(boolean); + method public final void setHasMipMap(boolean); method public void setPixel(int, int, int); method public void setPixels(int[], int, int, int, int, int, int); method public void writeToParcel(android.os.Parcel, int); @@ -28617,7 +28619,6 @@ package android.widget { method public void setHeight(int); method public void setHorizontalOffset(int); method public void setInputMethodMode(int); - method public void setLayoutDirection(int); method public void setListSelector(android.graphics.drawable.Drawable); method public void setModal(boolean); method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener); diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 5cde65c..03e0c0f 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -247,7 +247,6 @@ public class AccountManagerService } public void systemReady() { - initUser(UserHandle.USER_OWNER); } private UserManager getUserManager() { diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 7492629..67d3930 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -2809,6 +2809,15 @@ class ActivityManagerProxy implements IActivityManager return success; } + public void clearPendingBackup() throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + mRemote.transact(CLEAR_PENDING_BACKUP_TRANSACTION, data, reply, 0); + reply.recycle(); + data.recycle(); + } + public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 5f65f08..456d757 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -29,6 +29,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.InstrumentationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ProviderInfo; @@ -2396,12 +2397,31 @@ public final class ActivityThread { private void handleCreateBackupAgent(CreateBackupAgentData data) { if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); + // Sanity check the requested target package's uid against ours + try { + PackageInfo requestedPackage = getPackageManager().getPackageInfo( + data.appInfo.packageName, 0, UserHandle.myUserId()); + if (requestedPackage.applicationInfo.uid != Process.myUid()) { + Slog.w(TAG, "Asked to instantiate non-matching package " + + data.appInfo.packageName); + return; + } + } catch (RemoteException e) { + Slog.e(TAG, "Can't reach package manager", e); + return; + } + // no longer idle; we have backup work to do unscheduleGcIdler(); // instantiate the BackupAgent class named in the manifest LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); String packageName = packageInfo.mPackageName; + if (packageName == null) { + Slog.d(TAG, "Asked to create backup agent for nonexistent package"); + return; + } + if (mBackupAgents.get(packageName) != null) { Slog.d(TAG, "BackupAgent " + " for " + packageName + " already exists"); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 97250e9..8fc1c86 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -152,6 +152,7 @@ public interface IActivityManager extends IInterface { public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode) throws RemoteException; + public void clearPendingBackup() throws RemoteException; public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException; public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException; public void killApplicationProcess(String processName, int uid) throws RemoteException; @@ -619,4 +620,5 @@ public interface IActivityManager extends IInterface { int GET_RUNNING_USER_IDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+156; int REQUEST_BUG_REPORT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+157; int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158; + int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159; } diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index aba8710..8cbf5b1 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; +import java.util.UUID; import android.net.LocalSocket; import java.nio.ByteOrder; import java.nio.ByteBuffer; @@ -140,7 +141,9 @@ public final class BluetoothSocket implements Closeable { throw new IOException("Invalid RFCOMM channel: " + port); } } - mUuid = uuid; + if(uuid != null) + mUuid = uuid; + else mUuid = new ParcelUuid(new UUID(0, 0)); mType = type; mAuth = auth; mEncrypt = encrypt; diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 1e4ad76..bb0c686 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -21,7 +21,6 @@ import android.accounts.AccountAndUser; import android.accounts.AccountManager; import android.accounts.AccountManagerService; import android.app.ActivityManager; -import android.app.ActivityManagerNative; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; @@ -56,6 +55,7 @@ import android.text.format.Time; import android.util.EventLog; import android.util.Log; import android.util.Pair; +import android.util.Slog; import com.android.internal.R; import com.android.internal.util.IndentingPrintWriter; @@ -154,7 +154,9 @@ public class SyncManager { private AlarmManager mAlarmService = null; private SyncStorageEngine mSyncStorageEngine; - final public SyncQueue mSyncQueue; + + // @GuardedBy("mSyncQueue") + private final SyncQueue mSyncQueue; protected final ArrayList<ActiveSyncContext> mActiveSyncContexts = Lists.newArrayList(); @@ -310,13 +312,10 @@ public class SyncManager { if (userId == UserHandle.USER_NULL) return; if (Intent.ACTION_USER_REMOVED.equals(action)) { - Log.i(TAG, "User removed: u" + userId); onUserRemoved(userId); } else if (Intent.ACTION_USER_STARTING.equals(action)) { - Log.i(TAG, "User starting: u" + userId); onUserStarting(userId); } else if (Intent.ACTION_USER_STOPPING.equals(action)) { - Log.i(TAG, "User stopping: u" + userId); onUserStopping(userId); } } @@ -337,6 +336,10 @@ public class SyncManager { } } + /** + * Should only be created after {@link ContentService#systemReady()} so that + * {@link PackageManager} is ready to query. + */ public SyncManager(Context context, boolean factoryTest) { // Initialize the SyncStorageEngine first, before registering observers // and creating threads and so on; it may fail if the disk is full. @@ -440,9 +443,6 @@ public class SyncManager { UserHandle.ALL, new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION), null, null); - - // do this synchronously to ensure we have the accounts before this call returns - onUserStarting(UserHandle.USER_OWNER); } // Pick a random second in a day to seed all periodic syncs @@ -902,7 +902,9 @@ public class SyncManager { updateRunningAccounts(); - mSyncQueue.addPendingOperations(userId); + synchronized (mSyncQueue) { + mSyncQueue.addPendingOperations(userId); + } // Schedule sync for any accounts under started user final Account[] accounts = AccountManagerService.getSingleton().getAccounts(userId); @@ -1957,10 +1959,10 @@ public class SyncManager { synchronized (mSyncQueue) { if (isLoggable) { Log.v(TAG, "build the operation array, syncQueue size is " - + mSyncQueue.mOperationsMap.size()); + + mSyncQueue.getOperations().size()); } - Iterator<SyncOperation> operationIterator = - mSyncQueue.mOperationsMap.values().iterator(); + final Iterator<SyncOperation> operationIterator = mSyncQueue.getOperations() + .iterator(); final ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); @@ -2153,7 +2155,7 @@ public class SyncManager { runSyncFinishedOrCanceledLocked(null, toReschedule); scheduleSyncOperation(toReschedule.mSyncOperation); } - synchronized (mSyncQueue){ + synchronized (mSyncQueue) { mSyncQueue.remove(candidate); } dispatchSyncOperation(candidate); diff --git a/core/java/android/content/SyncQueue.java b/core/java/android/content/SyncQueue.java index 395658c..c9a325e 100644 --- a/core/java/android/content/SyncQueue.java +++ b/core/java/android/content/SyncQueue.java @@ -27,11 +27,14 @@ import android.util.Pair; import com.google.android.collect.Maps; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** + * Queue of pending sync operations. Not inherently thread safe, external + * callers are responsible for locking. * * @hide */ @@ -43,13 +46,11 @@ public class SyncQueue { // A Map of SyncOperations operationKey -> SyncOperation that is designed for // quick lookup of an enqueued SyncOperation. - public final HashMap<String, SyncOperation> mOperationsMap = Maps.newHashMap(); + private final HashMap<String, SyncOperation> mOperationsMap = Maps.newHashMap(); public SyncQueue(SyncStorageEngine syncStorageEngine, final SyncAdaptersCache syncAdapters) { mSyncStorageEngine = syncStorageEngine; mSyncAdapters = syncAdapters; - - addPendingOperations(UserHandle.USER_OWNER); } public void addPendingOperations(int userId) { @@ -198,6 +199,10 @@ public class SyncQueue { } } + public Collection<SyncOperation> getOperations() { + return mOperationsMap.values(); + } + public void dump(StringBuilder sb) { final long now = SystemClock.elapsedRealtime(); sb.append("SyncQueue: ").append(mOperationsMap.size()).append(" operation(s)\n"); diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java index de97481..10e7bff 100644 --- a/core/java/android/content/SyncStorageEngine.java +++ b/core/java/android/content/SyncStorageEngine.java @@ -609,23 +609,25 @@ public class SyncStorageEngine extends Handler { public void clearAllBackoffs(SyncQueue syncQueue) { boolean changed = false; synchronized (mAuthorities) { - for (AccountInfo accountInfo : mAccounts.values()) { - for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { - if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE - || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "clearAllBackoffs:" - + " authority:" + authorityInfo.authority - + " account:" + accountInfo.accountAndUser.account.name - + " user:" + accountInfo.accountAndUser.userId - + " backoffTime was: " + authorityInfo.backoffTime - + " backoffDelay was: " + authorityInfo.backoffDelay); + synchronized (syncQueue) { + for (AccountInfo accountInfo : mAccounts.values()) { + for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { + if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE + || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "clearAllBackoffs:" + + " authority:" + authorityInfo.authority + + " account:" + accountInfo.accountAndUser.account.name + + " user:" + accountInfo.accountAndUser.userId + + " backoffTime was: " + authorityInfo.backoffTime + + " backoffDelay was: " + authorityInfo.backoffDelay); + } + authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE; + authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; + syncQueue.onBackoffChanged(accountInfo.accountAndUser.account, + accountInfo.accountAndUser.userId, authorityInfo.authority, 0); + changed = true; } - authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE; - authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; - syncQueue.onBackoffChanged(accountInfo.accountAndUser.account, - accountInfo.accountAndUser.userId, authorityInfo.authority, 0); - changed = true; } } } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index a0283d3..32cc7fd 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -554,6 +554,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { manageSpaceActivityName = orig.manageSpaceActivityName; descriptionRes = orig.descriptionRes; uiOptions = orig.uiOptions; + backupAgentName = orig.backupAgentName; } diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index 0b91786..6def4a1 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -264,7 +264,8 @@ public abstract class RegisteredServicesCache<V> { if (user.services == null) { generateServicesMap(userId); } - return Collections.unmodifiableCollection(user.services.values()); + return Collections.unmodifiableCollection( + new ArrayList<ServiceInfo<V>>(user.services.values())); } } diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 69e1de9..ce5f163 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -110,7 +110,7 @@ import java.util.concurrent.atomic.AtomicInteger; * <h2>The 4 steps</h2> * <p>When an asynchronous task is executed, the task goes through 4 steps:</p> * <ol> - * <li>{@link #onPreExecute()}, invoked on the UI thread immediately after the task + * <li>{@link #onPreExecute()}, invoked on the UI thread before the task * is executed. This step is normally used to setup the task, for instance by * showing a progress bar in the user interface.</li> * <li>{@link #doInBackground}, invoked on the background thread diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 4820c5e..6c9290b 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -51,12 +51,17 @@ import com.android.internal.policy.PolicyManager; * an exhibition/lean-back experience.</p> * * <p>The Dream lifecycle is as follows:</p> - * <ul> - * <li>onAttachedToWindow</li> - * <li>onDreamingStarted</li> - * <li>onDreamingStopped</li> - * <li>onDetachedFromWindow</li> - * </ul> + * <ol> + * <li>{@link #onAttachedToWindow} + * <p>Use this for initial setup, such as calling {@link #setContentView setContentView()}.</li> + * <li>{@link #onDreamingStarted} + * <p>Your dream has started, so you should begin animations or other behaviors here.</li> + * <li>{@link #onDreamingStopped} + * <p>Use this to stop the things you started in {@link #onDreamingStarted}.</li> + * <li>{@link #onDetachedFromWindow} + * <p>Use this to dismantle resources your dream set up. For example, detach from handlers + * and listeners.</li> + * </ol> * * <p>In addition, onCreate and onDestroy (from the Service interface) will also be called, but * initialization and teardown should be done by overriding the hooks above.</p> @@ -80,14 +85,40 @@ import com.android.internal.policy.PolicyManager; * android:resource="@xml/my_dream" /> * </service> * </pre> - * <p>If specified, additional information for the dream is defined using the - * <code><{@link android.R.styleable#Dream dream}></code> element. For example:</p> - * <pre> - * (in res/xml/my_dream.xml) * + * <p>If specified with the {@code <meta-data>} element, + * additional information for the dream is defined using the + * {@link android.R.styleable#Dream <dream>} element in a separate XML file. + * Currently, the only addtional + * information you can provide is for a settings activity that allows the user to configure + * the dream behavior. For example:</p> + * <p class="code-caption">res/xml/my_dream.xml</p> + * <pre> * <dream xmlns:android="http://schemas.android.com/apk/res/android" * android:settingsActivity="com.example.app/.MyDreamSettingsActivity" /> * </pre> + * <p>This makes a Settings button available alongside your dream's listing in the + * system settings, which when pressed opens the specified activity.</p> + * + * + * <p>To specify your dream layout, call {@link #setContentView}, typically during the + * {@link #onAttachedToWindow} callback. For example:</p> + * <pre> + * public class MyDream extends DreamService { + * + * @Override + * public void onAttachedToWindow() { + * super.onAttachedToWindow(); + * + * // Exit dream upon user touch + * setInteractive(false); + * // Hide system UI + * setFullscreen(true); + * // Set the dream layout + * setContentView(R.layout.dream); + * } + * } + * </pre> */ public class DreamService extends Service implements Window.Callback { private final String TAG = DreamService.class.getSimpleName() + "[" + getClass().getSimpleName() + "]"; @@ -323,11 +354,12 @@ public class DreamService extends Service implements Window.Callback { /** * Sets a view to be the content view for this Dream. - * Behaves similarly to {@link android.app.Activity#setContentView(android.view.View)}, + * Behaves similarly to {@link android.app.Activity#setContentView(android.view.View)} in an activity, * including using {@link ViewGroup.LayoutParams#MATCH_PARENT} as the layout height and width of the view. * - * <p>Note: Requires a window, do not call before {@link #onAttachedToWindow()}</p> - * @param view The desired content to display. + * <p>Note: This requires a window, so you should usually call it during + * {@link #onAttachedToWindow()} and never earlier (you <strong>cannot</strong> call it + * during {@link #onCreate}).</p> * * @see #setContentView(int) * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) @@ -339,9 +371,12 @@ public class DreamService extends Service implements Window.Callback { /** * Sets a view to be the content view for this Dream. * Behaves similarly to - * {@link android.app.Activity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}. + * {@link android.app.Activity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams)} + * in an activity. * - * <p>Note: Requires a window, do not call before {@link #onAttachedToWindow()}</p> + * <p>Note: This requires a window, so you should usually call it during + * {@link #onAttachedToWindow()} and never earlier (you <strong>cannot</strong> call it + * during {@link #onCreate}).</p> * * @param view The desired content to display. * @param params Layout parameters for the view. diff --git a/core/java/android/view/IDisplayContentChangeListener.aidl b/core/java/android/view/IDisplayContentChangeListener.aidl index 8f23ff6..ef7edea 100644 --- a/core/java/android/view/IDisplayContentChangeListener.aidl +++ b/core/java/android/view/IDisplayContentChangeListener.aidl @@ -28,5 +28,6 @@ import android.graphics.Rect; oneway interface IDisplayContentChangeListener { void onWindowTransition(int displayId, int transition, in WindowInfo info); void onRectangleOnScreenRequested(int displayId, in Rect rectangle, boolean immediate); + void onWindowLayersChanged(int displayId); void onRotationChanged(int rotation); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 158e0c0..b36db7f 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4906,7 +4906,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @param outRect The output location */ - private void getBoundsOnScreen(Rect outRect) { + void getBoundsOnScreen(Rect outRect) { if (mAttachInfo == null) { return; } @@ -8661,7 +8661,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Return the visible drawing bounds of your view. Fills in the output * rectangle with the values from getScrollX(), getScrollY(), - * getWidth(), and getHeight(). + * getWidth(), and getHeight(). These bounds do not account for any + * transformation properties currently set on the view, such as + * {@link #setScaleX(float)} or {@link #setRotation(float)}. * * @param outRect The (scrolled) drawing bounds of the view. */ @@ -10000,8 +10002,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Resolve the layout parameters depending on the resolved layout direction + * + * @hide */ - private void resolveLayoutParams() { + public void resolveLayoutParams() { if (mLayoutParams != null) { mLayoutParams.resolveLayoutDirection(getLayoutDirection()); } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 6c1049b..dabdf5a 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3383,7 +3383,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } if (child.isLayoutDirectionInherited()) { - child.resetResolvedLayoutDirection(); + child.resetRtlProperties(); child.resolveRtlPropertiesIfNeeded(); } @@ -5362,6 +5362,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @hide */ @Override + public void resolveLayoutParams() { + super.resolveLayoutParams(); + int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + child.resolveLayoutParams(); + } + } + + /** + * @hide + */ + @Override public void resetRtlProperties() { super.resetRtlProperties(); int count = getChildCount(); @@ -5977,6 +5990,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ @Override public void resolveLayoutDirection(int layoutDirection) { + // No need to resolve if it is the same layout direction as before + if (this.layoutDirection == layoutDirection) { + return; + } + setLayoutDirection(layoutDirection); if (!isMarginRelative()) return; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 0475283..67452ec 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -29,12 +29,14 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Canvas; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.Region; import android.graphics.drawable.Drawable; import android.media.AudioManager; @@ -885,11 +887,13 @@ public final class ViewRootImpl implements ViewParent, // Intersect with the bounds of the window to skip // updates that lie outside of the visible region final float appScale = mAttachInfo.mApplicationScale; - localDirty.intersect(0, 0, - (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f)); - - if (!mWillDrawSoon) { - scheduleTraversals(); + if (localDirty.intersect(0, 0, + (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f))) { + if (!mWillDrawSoon) { + scheduleTraversals(); + } + } else { + localDirty.setEmpty(); } return null; @@ -1182,6 +1186,7 @@ public final class ViewRootImpl implements ViewParent, viewVisibilityChanged = false; mLastConfiguration.setTo(host.getResources().getConfiguration()); mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility; + host.setLayoutDirection(mLastConfiguration.getLayoutDirection()); host.dispatchAttachedToWindow(attachInfo, 0); mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets); host.fitSystemWindows(mFitSystemWindowsInsets); @@ -2319,24 +2324,14 @@ public final class ViewRootImpl implements ViewParent, mAccessibilityFocusedHost.getAccessibilityNodeProvider(); Rect bounds = mView.mAttachInfo.mTmpInvalRect; if (provider == null) { - mAccessibilityFocusedHost.getDrawingRect(bounds); - if (mView instanceof ViewGroup) { - ViewGroup viewGroup = (ViewGroup) mView; - try { - viewGroup.offsetDescendantRectToMyCoords(mAccessibilityFocusedHost, bounds); - } catch (IllegalArgumentException iae) { - Log.e(TAG, "Temporary detached view that was neither removed not reattached: " - + mAccessibilityFocusedHost); - return; - } - } + mAccessibilityFocusedHost.getBoundsOnScreen(bounds); } else { if (mAccessibilityFocusedVirtualView == null) { return; } mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds); - bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop); } + bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop); drawable.setBounds(bounds); drawable.draw(canvas); } @@ -2684,7 +2679,12 @@ public final class ViewRootImpl implements ViewParent, // the one in them which may be newer. config = mView.getResources().getConfiguration(); if (force || mLastConfiguration.diff(config) != 0) { + final int lastLayoutDirection = mLastConfiguration.getLayoutDirection(); + final int currentLayoutDirection = config.getLayoutDirection(); mLastConfiguration.setTo(config); + if (lastLayoutDirection != currentLayoutDirection) { + mView.setLayoutDirection(currentLayoutDirection); + } mView.dispatchConfigurationChanged(config); } } diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index 646fe7e..3b5e75b 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -241,6 +241,7 @@ public abstract class AbsSeekBar extends ProgressBar { @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); updateThumbPos(w, h); } @@ -555,4 +556,23 @@ public abstract class AbsSeekBar extends ProgressBar { } return false; } + + @Override + public void onRtlPropertiesChanged(int layoutDirection) { + super.onRtlPropertiesChanged(layoutDirection); + + int max = getMax(); + float scale = max > 0 ? (float) getProgress() / (float) max : 0; + + Drawable thumb = mThumb; + if (thumb != null) { + setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE); + /* + * Since we draw translated, the drawable's bounds that it signals + * for invalidation won't be the actual bounds we want invalidated, + * so just invalidate this whole view. + */ + invalidate(); + } + } } diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 75d1471..f0eb94f 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -1093,7 +1093,6 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED); mPopup.setListItemExpandMax(EXPAND_MAX); } - mPopup.setLayoutDirection(getLayoutDirection()); mPopup.show(); mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS); } diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 1c81d11..3d6b69e 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -1021,8 +1021,6 @@ public class ListPopupWindow { mDropDownList.setOnItemSelectedListener(mItemSelectedListener); } - mDropDownList.setLayoutDirection(mLayoutDirection); - dropDownView = mDropDownList; View hintView = mPromptView; @@ -1132,21 +1130,6 @@ public class ListPopupWindow { } /** - * Set the layout direction for this popup. Should be a resolved direction as the - * popup as no capacity to do the resolution on his own. - * - * @param layoutDirection One of {@link View#LAYOUT_DIRECTION_LTR}, - * {@link View#LAYOUT_DIRECTION_RTL}, - * - */ - public void setLayoutDirection(int layoutDirection) { - mLayoutDirection = layoutDirection; - if (mDropDownList != null) { - mDropDownList.setLayoutDirection(mLayoutDirection); - } - } - - /** * <p>Wrapper class for a ListView. This wrapper can hijack the focus to * make sure the list uses the appropriate drawables and states when * displayed on screen within a drop down. The focus is never actually diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 751ed7c..8e5ff40 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -6321,7 +6321,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (mDeferScroll >= 0) { int curs = mDeferScroll; mDeferScroll = -1; - bringPointIntoView(curs); + bringPointIntoView(Math.min(curs, mText.length())); } if (changed && mEditor != null) mEditor.invalidateTextDisplayList(); } diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index fd7a6a7..f485e03 100644 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -7,7 +7,7 @@ #include "SkUnPreMultiply.h"
#include <binder/Parcel.h>
-#include "android_os_Parcel.h" +#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include "android_nio_utils.h"
#include "CreateJavaOutputStreamAdaptor.h"
@@ -353,6 +353,15 @@ static void Bitmap_setHasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap, bitmap->setIsOpaque(!hasAlpha);
}
+static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap) {
+ return bitmap->hasHardwareMipMap();
+}
+
+static void Bitmap_setHasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap,
+ jboolean hasMipMap) {
+ bitmap->setHasHardwareMipMap(hasMipMap);
+}
+
///////////////////////////////////////////////////////////////////////////////
static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
@@ -666,6 +675,8 @@ static JNINativeMethod gBitmapMethods[] = { { "nativeConfig", "(I)I", (void*)Bitmap_config },
{ "nativeHasAlpha", "(I)Z", (void*)Bitmap_hasAlpha },
{ "nativeSetHasAlpha", "(IZ)V", (void*)Bitmap_setHasAlpha },
+ { "nativeHasMipMap", "(I)Z", (void*)Bitmap_hasMipMap },
+ { "nativeSetHasMipMap", "(IZ)V", (void*)Bitmap_setHasMipMap },
{ "nativeCreateFromParcel",
"(Landroid/os/Parcel;)Landroid/graphics/Bitmap;",
(void*)Bitmap_createFromParcel },
diff --git a/core/jni/android/graphics/YuvToJpegEncoder.cpp b/core/jni/android/graphics/YuvToJpegEncoder.cpp index 8333e00..f386905 100644 --- a/core/jni/android/graphics/YuvToJpegEncoder.cpp +++ b/core/jni/android/graphics/YuvToJpegEncoder.cpp @@ -90,8 +90,9 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo, // process 16 lines of Y and 8 lines of U/V each time. while (cinfo->next_scanline < cinfo->image_height) { //deitnerleave u and v - deinterleave(vuPlanar, uRows, vRows, cinfo->next_scanline, width); + deinterleave(vuPlanar, uRows, vRows, cinfo->next_scanline, width, height); + // Jpeg library ignores the rows whose indices are greater than height. for (int i = 0; i < 16; i++) { // y row y[i] = yPlanar + (cinfo->next_scanline + i) * fStrides[0]; @@ -112,8 +113,10 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo, } void Yuv420SpToJpegEncoder::deinterleave(uint8_t* vuPlanar, uint8_t* uRows, - uint8_t* vRows, int rowIndex, int width) { - for (int row = 0; row < 8; ++row) { + uint8_t* vRows, int rowIndex, int width, int height) { + int numRows = (height - rowIndex) / 2; + if (numRows > 8) numRows = 8; + for (int row = 0; row < numRows; ++row) { int offset = ((rowIndex >> 1) + row) * fStrides[1]; uint8_t* vu = vuPlanar + offset; for (int i = 0; i < (width >> 1); ++i) { @@ -164,6 +167,7 @@ void Yuv422IToJpegEncoder::compress(jpeg_compress_struct* cinfo, while (cinfo->next_scanline < cinfo->image_height) { deinterleave(yuvOffset, yRows, uRows, vRows, cinfo->next_scanline, width, height); + // Jpeg library ignores the rows whose indices are greater than height. for (int i = 0; i < 16; i++) { // y row y[i] = yRows + i * width; @@ -185,7 +189,9 @@ void Yuv422IToJpegEncoder::compress(jpeg_compress_struct* cinfo, void Yuv422IToJpegEncoder::deinterleave(uint8_t* yuv, uint8_t* yRows, uint8_t* uRows, uint8_t* vRows, int rowIndex, int width, int height) { - for (int row = 0; row < 16; ++row) { + int numRows = height - rowIndex; + if (numRows > 16) numRows = 16; + for (int row = 0; row < numRows; ++row) { uint8_t* yuvSeg = yuv + (rowIndex + row) * fStrides[0]; for (int i = 0; i < (width >> 1); ++i) { int indexY = row * width + (i << 1); diff --git a/core/jni/android/graphics/YuvToJpegEncoder.h b/core/jni/android/graphics/YuvToJpegEncoder.h index 97106ce..0d418ed 100644 --- a/core/jni/android/graphics/YuvToJpegEncoder.h +++ b/core/jni/android/graphics/YuvToJpegEncoder.h @@ -55,7 +55,7 @@ private: void deinterleaveYuv(uint8_t* yuv, int width, int height, uint8_t*& yPlanar, uint8_t*& uPlanar, uint8_t*& vPlanar); void deinterleave(uint8_t* vuPlanar, uint8_t* uRows, uint8_t* vRows, - int rowIndex, int width); + int rowIndex, int width, int height); void compress(jpeg_compress_struct* cinfo, uint8_t* yuv, int* offsets); }; diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 1b71b43..5d306d2 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -829,7 +829,6 @@ static void android_view_GLES20Canvas_clearLayerTexture(JNIEnv* env, jobject cla static void android_view_GLES20Canvas_setTextureLayerTransform(JNIEnv* env, jobject clazz, Layer* layer, SkMatrix* matrix) { - layer->getTransform().load(*matrix); } diff --git a/core/res/res/drawable-hdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-hdpi/ic_notify_wifidisplay.png Binary files differnew file mode 100644 index 0000000..35f27df --- /dev/null +++ b/core/res/res/drawable-hdpi/ic_notify_wifidisplay.png diff --git a/core/res/res/drawable-mdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-mdpi/ic_notify_wifidisplay.png Binary files differnew file mode 100644 index 0000000..f9c8678 --- /dev/null +++ b/core/res/res/drawable-mdpi/ic_notify_wifidisplay.png diff --git a/core/res/res/drawable-xhdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-xhdpi/ic_notify_wifidisplay.png Binary files differnew file mode 100644 index 0000000..4cc0ee8 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ic_notify_wifidisplay.png diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml index 20726d0..981fe6d 100644 --- a/core/res/res/layout-port/keyguard_host_view.xml +++ b/core/res/res/layout-port/keyguard_host_view.xml @@ -33,7 +33,8 @@ <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper android:id="@+id/view_flipper" - android:layout_height="0dp" + android:layout_width="match_parent" + android:layout_height="0dip" android:clipChildren="false" android:clipToPadding="false" android:layout_weight="1" diff --git a/core/res/res/layout-port/keyguard_status_area.xml b/core/res/res/layout-port/keyguard_status_area.xml index e0a49dc..c1f6aab 100644 --- a/core/res/res/layout-port/keyguard_status_area.xml +++ b/core/res/res/layout-port/keyguard_status_area.xml @@ -45,6 +45,8 @@ <TextView android:id="@+id/alarm_status" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_marginEnd="@dimen/kg_status_line_font_right_margin" android:singleLine="true" android:ellipsize="marquee" @@ -93,4 +95,4 @@ android:textSize="@dimen/kg_status_line_font_size" /> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml index f21254a..405ac14 100644 --- a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml +++ b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml @@ -78,4 +78,4 @@ android:textAppearance="?android:attr/textAppearance" android:textSize="@dimen/kg_status_line_font_size" /> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/core/res/res/layout/default_navigation.xml b/core/res/res/layout/default_navigation.xml index b13103c..b216ded 100644 --- a/core/res/res/layout/default_navigation.xml +++ b/core/res/res/layout/default_navigation.xml @@ -18,6 +18,8 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/keyguard_click_area" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:gravity="center"> <!-- message area for security screen --> diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml index ab8aa85..81916f7 100644 --- a/core/res/res/layout/keyguard_password_view.xml +++ b/core/res/res/layout/keyguard_password_view.xml @@ -53,6 +53,7 @@ since the backspace/IME switcher looks better inside --> <LinearLayout android:layout_gravity="center_vertical|fill_horizontal" + android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal" android:background="#70000000" diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml index 163dc15..ae59d1d 100644 --- a/core/res/res/layout/keyguard_sim_pin_view.xml +++ b/core/res/res/layout/keyguard_sim_pin_view.xml @@ -91,6 +91,7 @@ <!-- Numeric keyboard --> <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard" android:layout_width="match_parent" + android:layout_height="wrap_content" android:layout_marginStart="4dip" android:layout_marginEnd="4dip" android:paddingTop="4dip" diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml index 6e45b0b..414806f 100644 --- a/core/res/res/layout/keyguard_sim_puk_view.xml +++ b/core/res/res/layout/keyguard_sim_puk_view.xml @@ -93,6 +93,7 @@ <!-- Numeric keyboard --> <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard" android:layout_width="match_parent" + android:layout_height="wrap_content" android:layout_marginStart="4dip" android:layout_marginEnd="4dip" android:paddingTop="4dip" diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 0f73ff5..3e8892b 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Moet volume bo veilige vlak verhoog word?"\n"Deur vir lang tydperke op hoë volume te luister, kan jou gehoor beskadig."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hou aan met twee vingers inhou om toeganklikheid te aktiveer."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Toeganklikheid geaktiveer."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toeganklikheid gekanselleer."</string> <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index f60ac3e..495c0e2 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊ ቱኮዎን እንዲከፍቱ ይጠየቃሉ።"\n\n" ከ<xliff:g id="NUMBER_2">%d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።"\n\n"እባክዎ ከ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"ድምጽ አደጋ ከሌለው መጠን በላይ ይጨመር??"\n"ለረጅም ጊዜ በከፍተኛ ድምጽ መስማት የመስማት ችሎታዎን ሊጎዳይ ይችላል።"</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ተደራሽነትን ለማንቃት ሁለት ጣቶችዎን ባሉበት ያቆዩዋቸው።"</string> <string name="accessibility_enabled" msgid="1381972048564547685">"ተደራሽነት ነቅቷል።"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ተደራሽነት ተሰርዟል።"</string> <string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index dfa8834..61ec74d 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"هل تريد رفع مستوى الصوت فوق المستوى الآمن؟"\n"قد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"اضغط بإصبعين لأسفل مع الاستمرار لتمكين تسهيل الدخول."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"تم تمكين إمكانية الدخول."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"تم إلغاء تسهيل الدخول."</string> <string name="user_switched" msgid="3768006783166984410">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 4403f97..dd16a34 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -1419,8 +1419,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Павялiчыць гук больш за рэкамендаваны ўзровень?"\n"Доўгае слуханне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Утрымлiвайце два пальцы, каб уключыць доступ."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Даступнасць уключана."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Даступнасць адменена."</string> <string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index b46e30a..ad806db 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством имейл адрес."\n\n" Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес."\n\n" Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Да се увеличи ли силата на звука над безопасното ниво?"\n"Продължителното слушане при висока сила на звука може да увреди слуха ви."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Продължете да натискате с два пръста, за да активирате функцията за достъпност."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Достъпността е активирана."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Функцията за достъпност е анулирана."</string> <string name="user_switched" msgid="3768006783166984410">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 501946b..6fa8b50 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vols augmentar el volum per sobre del nivell de seguretat?"\n"Escoltar música a un volum alt durant períodes llargs pot perjudicar l\'oïda."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén premuts els dos dits per activar l\'accessibilitat."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"S\'ha activat l\'accessibilitat."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilitat cancel·lada."</string> <string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 7381366..5d43397 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Chcete hlasitost zvýšit nad bezpečnou úroveň?"\n"Dlouhodobý poslech hlasitého zvuku může poškodit sluch."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Usnadnění zapnete dlouhým stisknutím dvěma prsty."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Usnadnění přístupu je aktivováno."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Usnadnění zrušeno."</string> <string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index e14e7de..db09717 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto"\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto."\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Skal lydstyrken være over det sikre niveau?"\n"Du kan skade din hørelse ved at lytte ved høj lydstyrke i længere tid."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hold fortsat to fingre nede for at aktivere tilgængelighed."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Tilgængelighed aktiveret."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgængelighed er annulleret."</string> <string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index c938ca5..d66665b 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Lautstärke höher als Schwellenwert stellen?"\n"Wenn Sie über längere Zeiträume hinweg Musik in hoher Lautstärke hören, kann dies Ihr Gehör schädigen."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Drücken Sie mit zwei Fingern, um die Bedienungshilfen zu aktivieren."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Bedienungshilfen aktiviert"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Bedienungshilfen abgebrochen"</string> <string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 9ced98c..e55a272 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Αύξηση έντασης ήχου πάνω από το επίπεδο ασφαλείας;"\n"Αν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Αγγίξτε παρατεταμένα με δύο δάχτυλα για να ενεργοποιήσετε τη λειτουργία προσβασιμότητας."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Ενεργοποιήθηκε η προσβασιμότητα."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Η λειτουργία προσβασιμότητας ακυρώθηκε."</string> <string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 9011e9d..a96995a 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Raise volume above safe level?"\n"Listening at high volume for long periods may damage your hearing."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Keep holding down two fingers to enable accessibility."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Accessibility enabled."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibility cancelled."</string> <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index d0a1cd9..ef6962f 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tableta mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"¿Aumentar el volumen por encima del nivel seguro?"\n"Si escuchas con el volumen alto durante períodos prolongados, puedes dañar tu audición."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén presionado con dos dedos para activar la accesibilidad."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Se activó la accesibilidad."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Se canceló la accesibilidad."</string> <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index b45f001..d41ce82 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"¿Subir el volumen por encima del nivel de seguridad?"\n"Escuchar sonidos a alto volumen durante largos períodos de tiempo puede dañar tus oídos."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén la pantalla pulsada con dos dedos para habilitar las funciones de accesibilidad."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Accesibilidad habilitada"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accesibilidad cancelada"</string> <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index fbb9f3e..cf237dc 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Kas suurendada helitugevust üle ohutu piiri?"\n"Pikaajaline suure helitugevusega muusika kuulamine võib kahjustada kuulmist."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hõlbustuse lubamiseks hoidke kaht sõrme all."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Hõlbustus on lubatud."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hõlbustus on tühistatud."</string> <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index ae0ca2b..a50947c 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیدهاید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیدهاید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"صدا به بالاتر از سطح ایمن افزایش یابد؟"\n"گوش دادن به صدای بلند برای زمانهای طولانی میتواند به شنوایی شما آسیب برساند."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"برای فعال کردن قابلیت دسترسی، با دو انگشت خود همچنان به طرف پایین فشار دهید."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"قابلیت دسترسی فعال شد."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"قابلیت دسترسی لغو شد."</string> <string name="user_switched" msgid="3768006783166984410">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index ae2a4cb..ef2f047 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Nostetaanko äänenvoimakkuus turvallista tasoa voimakkaammaksi?"\n"Jos kuuntelet suurella äänenvoimakkuudella pitkiä aikoja, kuulosi voi vahingoittua."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Ota esteettömyystila käyttöön koskettamalla pitkään kahdella sormella."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Esteettömyystila käytössä."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Esteettömyystila peruutettu."</string> <string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index aa4f91e..cefc2b8 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Augmenter le volume au-dessus du niveau de sécurité ?"\n"L\'écoute à un volume élevé pendant des périodes prolongées peut endommager votre audition."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Pour activer l\'accessibilité, appuyez de manière prolongée avec deux doigts."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"L\'accessibilité a bien été activée."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilité annulée."</string> <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index d0f1dc5..6bf3d09 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1262,7 +1262,7 @@ <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB संग्रहण का उपयोग वर्तमान में एक कंप्यूटर द्वारा किया जा रहा है."</string> <string name="media_shared" product="default" msgid="5706130568133540435">"SD कार्ड का उपयोग वर्तमान में एक कंप्यूटर द्वारा किया जा रहा है."</string> <string name="media_unknown_state" msgid="729192782197290385">"बाह्य मीडिया अज्ञात स्थिति में है."</string> - <string name="share" msgid="1778686618230011964">"शेयर करें"</string> + <string name="share" msgid="1778686618230011964">"साझा करें"</string> <string name="find" msgid="4808270900322985960">"ढूंढें"</string> <string name="websearch" msgid="4337157977400211589">"वेब खोज"</string> <string name="find_next" msgid="5742124618942193978">"अगला ढूंढें"</string> @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"आपने अपने अनलॉक प्रतिमान को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपने अपने अनलॉक प्रतिमान को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"वॉल्यूम को सुरक्षित स्तर से अधिक करें?"\n"अधिक देर तक उच्च वॉल्यूम पर सुनने से आपकी सुनने की क्षमता को नुकसान हो सकता है."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"पहुंच-योग्यता को सक्षम करने के लिए दो अंगुलियों से नीचे दबाए रखें."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"पहुंच-योग्यता सक्षम कर दी है."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"पहुंच-योग्यता रद्द की गई."</string> <string name="user_switched" msgid="3768006783166984410">"वर्तमान उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index f223fa6..588960b 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati tabletno računalo pomoću računa e-pošte."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon pomoću računa e-pošte."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Pojačati iznad sigurne razine?"\n"Dulje slušanje preglasne glazbe može vam oštetiti sluh."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Nastavite držati s dva prsta kako biste omogućili pristupačnost."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Dostupnost je omogućena."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pristupačnost otkazana."</string> <string name="user_switched" msgid="3768006783166984410">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 3815c38..4645842 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a táblagépét."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"A biztonságos szint fölé emeli a hangerőt?"\n"Ha hosszú ideig hangosan hallgatja a zenét, az károsíthatja a hallását."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Továbbra is tartsa lenyomva két ujját a hozzáférés engedélyezéséhez."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Hozzáférés engedélyezve"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hozzáférés megszakítva."</string> <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 17b4944..7b04c96 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Naikkan volume di atas tingkat aman?"\n"Mendengarkan volume tinggi dalam jangka waktu yang lama dapat merusak pendengaran Anda."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Tahan terus dua jari untuk mengaktifkan aksesibilitas."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Aksesibilitas diaktifkan."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Aksesibilitas dibatalkan."</string> <string name="user_switched" msgid="3768006783166984410">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 3a91039..5357009 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Aumentare il volume oltre il livello di sicurezza?"\n"Ascoltare musica ad alto volume per lunghi periodi potrebbe danneggiare l\'udito."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Continua a tenere premuto con due dita per attivare l\'accessibilità."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Accessibilità attivata."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilità annullata."</string> <string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index bd1ffb7..46ca017 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון דוא\"ל."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון דוא\"ל."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"האם להעלות את עוצמת הקול מעל לרמה הבטוחה?"\n"האזנה בעוצמת קול גבוהה למשך זמן ארוך עלולה לפגוע בשמיעה."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"המשך לגעת בשתי אצבעות כדי להפעיל נגישות."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"נגישות הופעלה."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"נגישות בוטלה."</string> <string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 97a1675..d97753b 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にメールアカウントが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒以内にもう一度お試しください。"</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にメールアカウントが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒以内にもう一度お試しください。"</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"安全レベルを超えるまで音量を上げますか?"\n"大音量で長時間聞き続けると、聴力を損なう恐れがあります。"</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ユーザー補助機能を有効にするには2本の指で押し続けてください。"</string> <string name="accessibility_enabled" msgid="1381972048564547685">"ユーザー補助が有効になりました。"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ユーザー補助をキャンセルしました。"</string> <string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index e10fd3f..332e320 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"안전한 수준 이상으로 볼륨을 높이시겠습니까?"\n"높은 볼륨으로 장시간 청취하면 청력에 손상이 올 수 있습니다."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"두 손가락으로 길게 누르면 접근성을 사용하도록 설정됩니다."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"접근성을 사용 설정했습니다."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"접근성이 취소되었습니다."</string> <string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index ee0260a..1240d6c 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Padidinti garsumą viršijant saugų lygį?"\n"Ilgai klausantis dideliu garsumu gali sutrikti klausa."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Laikykite palietę dviem pirštais, kad įgalintumėte pritaikymo neįgaliesiems režimą."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Pritaikymas neįgaliesiems įgalintas."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pritaikymo neįgaliesiems režimas atšauktas."</string> <string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index dd26946..25c036b 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vai palielināt skaļumu virs drošības līmeņa?"\n"Ilgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Lai iespējotu pieejamību, turiet nospiestus divus pirkstus."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Pieejamības režīms ir iespējots."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pieejamība ir atcelta."</string> <string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 79eefef..920865b 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Tingkatkan kelantangan di atas tahap selamat?"\n"Mendengar pada kelantangan tinggi untuk tempoh yang panjang boleh merosakkan pendengaran anda."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Teruskan menahan dengan dua jari untuk mendayakan kebolehcapaian."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Kebolehcapaian didayakan."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Kebolehcapaian dibatalkan."</string> <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index c10d7b4..78cc0e9 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vil du øke lydnivået over trygt nivå?"\n"Lytting på høyt lydnivå i lange perioder kan skade hørselen din."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Fortsett å holde nede to fingre for å aktivere tilgjengelighet."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Tilgjengelighet er aktivert."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgjengelighetstjenesten ble avbrutt."</string> <string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 41037d6..df8ec78 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Wilt u het volume verhogen tot boven het aanbevolen geluidsniveau?"\n"Te lang luisteren op een te hoog volume kan leiden tot gehoorbeschadiging."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Blijf het scherm met twee vingers aanraken om toegankelijkheid in te schakelen."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Toegankelijkheid ingeschakeld."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toegankelijkheid geannuleerd."</string> <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 7381794b..6fa3c51 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1419,8 +1419,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Chcesz ustawić głośność powyżej bezpiecznego poziomu?"\n"Słuchanie przy dużym poziomie głośności przez dłuższy czas może doprowadzić do uszkodzenia słuchu."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Aby włączyć ułatwienia dostępu, przytrzymaj dwa palce."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Włączono ułatwienia dostępu."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ułatwienia dostępu zostały anulowane."</string> <string name="user_switched" msgid="3768006783166984410">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 9a06263..1a22702 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Aumentar o volume acima do nível de segurança?"\n"Ouvir em volume alto durante longos períodos de tempo poderá prejudicar a sua audição."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantenha os dois dedos para ativar a acessibilidade."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Acessibilidade ativada."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string> <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 55f727a2..36f2ded 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Aumentar o volume acima do nível seguro?"\n"A audição em volume elevado por períodos longos pode prejudicar sua audição."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantenha pressionado com dois dedos para ativar a acessibilidade."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Acessibilidade ativada."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string> <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 81aaaa0..263e56b 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Ridicaţi volumul mai sus de nivelul sigur?"\n"Ascultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Menţineţi două degete pe ecran pentru a activa accesibilitatea."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"S-a activat accesibilitatea."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accesibilitatea a fost anulată"</string> <string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 0b3d009..f008479 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google."\n\n"Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google."\n\n"Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Увеличить громкость до небезопасного уровня?"\n"Долговременное прослушивание на такой громкости может повредить слух."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Чтобы включить специальные возможности, удерживайте пальцы на экране."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Специальные возможности включены."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Специальные возможности не будут включены."</string> <string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index e6a3b38..9be07a9 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Chcete zvýšiť hlasitosť nad bezpečnú úroveň?"\n"Dlhodobé počúvanie pri vysokej hlasitosti môže viesť k poškodeniu vášho sluchu."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Zjednodušenie ovládania povolíte dlhým stlačením dvoma prstami."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Zjednodušenie ovládania je povolené."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Zjednodušenie ovládania bolo zrušené."</string> <string name="user_switched" msgid="3768006783166984410">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index cdd8d11..42cf0af 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da tablični računalnik odklenete z e-poštnim računom."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Želite povečati glasnost nad varno raven?"\n"Dolgotrajna izpostavljenost glasnim tonom lahko poškoduje sluh."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Če želite omogočiti pripomočke za ljudi s posebnimi potrebami, na zaslonu pridržite z dvema prstoma."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Pripomočki za ljudi s posebnimi potrebami so omogočeni."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Omogočanje pripomočkov za ljudi s posebnimi potrebami preklicano."</string> <string name="user_switched" msgid="3768006783166984410">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index bfeb021..e69bd5d 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште."\n\n"Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу налога е-поште."\n\n"Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Желите да појачате звук изнад безбедног нивоа?"\n"Ако дуже време слушате гласну музику, може доћи до оштећења слуха."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Држите са два прста да бисте омогућили приступачност."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Приступачност је омогућена."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Приступачност је отказана."</string> <string name="user_switched" msgid="3768006783166984410">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 428e3d6..e295e2d 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp surfplattan med ett e-postkonto."\n\n" Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto."\n\n" Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vill du höja volymen över den säkra nivån?"\n"Om du lyssnar på hög volym under långa perioder kan din hörsel skadas."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Fortsätt trycka med två fingrar om du vill aktivera tillgänglighetsläget."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Tillgänglighetsläget har aktiverats."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Byte till tillgänglighetsläge avbrutet."</string> <string name="user_switched" msgid="3768006783166984410">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index ddc4e04..b712146 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1304,8 +1304,8 @@ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Songa"</string> <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ingiza"</string> <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Chagua programu"</string> - <string name="shareactionprovider_share_with" msgid="806688056141131819">"Gawa na"</string> - <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Gawa na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> + <string name="shareactionprovider_share_with" msgid="806688056141131819">"Shiriki na"</string> + <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Shiriki na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> <string name="content_description_sliding_handle" msgid="415975056159262248">"Utambo unaosonga. Gusa & shika"</string> <string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> <string name="description_direction_down" msgid="5087739728639014595">"Sogeza chini kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Ongeza sauti zaidi ya kiwango salama? "\n"Kusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Endelea kushikilia chini kwa vidole vyako viwili ili kuwezesha ufikivu."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Ufikivu umewezeshwa."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ufikivu umeghairiwa."</string> <string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index a619a36..3dc4bff 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล"\n\n" โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้ับัญชีอีเมล"\n\n" โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"เพิ่มระดับเสียงจนเกินระดับที่ปลอดภัยหรือไม่"\n"การฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ใช้สองนิ้วแตะค้างไว้เพื่อเปิดใช้งานการเข้าถึง"</string> <string name="accessibility_enabled" msgid="1381972048564547685">"เปิดใช้งานการเข้าถึงแล้ว"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ยกเลิกการเข้าถึงแล้ว"</string> <string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index cfe58c7..201d77b 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Lakasan ang volume nang lagpas sa ligtas na antas?"\n"Maaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Panatilihing nakapindot nang matagal ang iyong dalawang daliri upang paganahin ang pagiging naa-access."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Pinagana ang accessibility."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Nakansela ang pagiging naa-access."</string> <string name="user_switched" msgid="3768006783166984410">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 2c9407b..fd59e41 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi bir e-posta hesabı kullanarak açmanız istenir."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Ses düzeyi güvenli seviyenin üzerine çıkarılsın mı?"\n"Yüksek sesle uzun süre dinlemek işitme yetinize zarar verebilir."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Erişilebilirliği etkinleştirmek için iki parmağınızı basılı tutmaya devam edin."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Erişilebilirlik etkinleştirildi."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Erişilebilirlik iptal edildi."</string> <string name="user_switched" msgid="3768006783166984410">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 3072cb9..5547f56 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати планшетний ПК за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Збільшити гучність понад безпечний рівень?"\n"Надто гучне прослуховування впродовж тривалого періоду може пошкодити слух."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Утримуйте двома пальцями, щоб увімкнути доступність."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Доступність увімкнено."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Доступність скасовано."</string> <string name="user_switched" msgid="3768006783166984410">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 3dbe71b..df5d184 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Tăng âm lượng trên mức an toàn?"\n"Nghe ở âm lượng cao trong thời gian dài có thể gây hại cho thính giác của bạn."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Tiếp tục giữ hai ngón tay để bật trợ năng."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Trợ năng đã được bật."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Đã hủy trợ năng."</string> <string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index ea55480..d4c8ac0 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -777,7 +777,7 @@ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"“暂停”按钮"</string> <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"“播放”按钮"</string> <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"“停止”按钮"</string> - <string name="emergency_calls_only" msgid="6733978304386365407">"只能使用紧急呼救"</string> + <string name="emergency_calls_only" msgid="6733978304386365407">"只能拨打紧急呼救电话"</string> <string name="lockscreen_network_locked_message" msgid="143389224986028501">"网络已锁定"</string> <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM 卡已用 PUK 码锁定"</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"请参阅《用户指南》或与客服人员联系。"</string> @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"将音量调高到安全级别以上?"\n"长时间聆听高音量可能会损伤听力。"</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持续按住双指即可启用辅助功能。"</string> <string name="accessibility_enabled" msgid="1381972048564547685">"辅助功能已启用。"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"已取消辅助功能。"</string> <string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 3301945..12c7f41 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"要將音量調高到安全等級以上嗎?"\n"長時間聆聽偏高音量可能會損害您的聽力。"</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持續用兩指按住即可啟用協助工具。"</string> <string name="accessibility_enabled" msgid="1381972048564547685">"協助工具已啟用。"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"協助工具已取消。"</string> <string name="user_switched" msgid="3768006783166984410">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index ef48346..75142fb 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1418,8 +1418,7 @@ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi kwengu-<xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string> <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string> <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Khulisa ivolomu ngaphezu kweleveli yokuphepha?"\n"Ukulalela ngevolomu ephezulu izikhathi ezide kungalimaza ukuzwa kwakho."</string> - <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) --> - <skip /> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Gcina ucindezele iminwe yakho emibili ukuze unike amandla ukufinyelela."</string> <string name="accessibility_enabled" msgid="1381972048564547685">"Ukufinyelela kunikwe amandla."</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ukufinyelela kukhanseliwe."</string> <string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 4698002..afd847f 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -636,19 +636,12 @@ of new location providers at run-time. The new package does not have to be explicitly listed here, however it must have a signature that matches the signature of at least one package on this list. - Platforms should overlay additional packages in - config_overlay_locationProviderPackageNames, instead of overlaying - this config, if they only want to append packages and not replace - the entire array. --> <string-array name="config_locationProviderPackageNames" translatable="false"> + <!-- The standard AOSP fused location provider --> <item>com.android.location.fused</item> </string-array> - <!-- Pacakge name(s) supplied by overlay, and appended to - config_locationProviderPackageNames. --> - <string-array name="config_overlay_locationProviderPackageNames" translatable="false" /> - <!-- Boolean indicating if current platform supports bluetooth SCO for off call use cases --> <bool name="config_bluetooth_sco_off_call">true</bool> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 72de22c..f8dbd84 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3821,6 +3821,13 @@ <!-- Title text to show within the overlay. [CHAR LIMIT=50] --> <string name="display_manager_overlay_display_title"><xliff:g id="name">%1$s</xliff:g>: <xliff:g id="width">%2$d</xliff:g>x<xliff:g id="height">%3$d</xliff:g>, <xliff:g id="dpi">%4$d</xliff:g> dpi</string> + <!-- Title of the notification to indicate an active wifi display connection. [CHAR LIMIT=50] --> + <string name="wifi_display_notification_title">Wireless display is connected</string> + <!-- Message of the notification to indicate an active wifi display connection. [CHAR LIMIT=80] --> + <string name="wifi_display_notification_message">This screen is showing on another device</string> + <!-- Label of a button to disconnect an active wifi display connection. [CHAR LIMIT=25] --> + <string name="wifi_display_notification_disconnect">Disconnect</string> + <!-- Keyguard strings --> <!-- Label shown on emergency call button in keyguard --> <string name="kg_emergency_call_label">Emergency call</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e76b67b..7c0547e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1475,7 +1475,6 @@ <java-symbol type="array" name="radioAttributes" /> <java-symbol type="array" name="config_oemUsbModeOverride" /> <java-symbol type="array" name="config_locationProviderPackageNames" /> - <java-symbol type="array" name="config_overlay_locationProviderPackageNames" /> <java-symbol type="bool" name="config_animateScreenLights" /> <java-symbol type="bool" name="config_automatic_brightness_available" /> <java-symbol type="bool" name="config_sf_limitedAlpha" /> @@ -1486,6 +1485,7 @@ <java-symbol type="bool" name="show_ongoing_ime_switcher" /> <java-symbol type="color" name="config_defaultNotificationColor" /> <java-symbol type="drawable" name="ic_notification_ime_default" /> + <java-symbol type="drawable" name="ic_notify_wifidisplay" /> <java-symbol type="drawable" name="stat_notify_car_mode" /> <java-symbol type="drawable" name="stat_notify_disabled" /> <java-symbol type="drawable" name="stat_notify_disk_full" /> @@ -1621,6 +1621,9 @@ <java-symbol type="string" name="vpn_lockdown_error" /> <java-symbol type="string" name="vpn_lockdown_reset" /> <java-symbol type="string" name="wallpaper_binding_label" /> + <java-symbol type="string" name="wifi_display_notification_title" /> + <java-symbol type="string" name="wifi_display_notification_message" /> + <java-symbol type="string" name="wifi_display_notification_disconnect" /> <java-symbol type="style" name="Theme.Dialog.AppError" /> <java-symbol type="style" name="Theme.Toast" /> <java-symbol type="xml" name="storage_list" /> diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml index 05f8b39..1bbc7df 100644 --- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml +++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml @@ -72,5 +72,6 @@ <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.DEVICE_POWER" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> </manifest> diff --git a/data/fonts/DroidNaskh-Bold.ttf b/data/fonts/DroidNaskh-Bold.ttf Binary files differindex 692b796..14d8768 100644 --- a/data/fonts/DroidNaskh-Bold.ttf +++ b/data/fonts/DroidNaskh-Bold.ttf diff --git a/data/fonts/DroidNaskh-Regular.ttf b/data/fonts/DroidNaskh-Regular.ttf Binary files differindex da9a45f..03662f2 100644 --- a/data/fonts/DroidNaskh-Regular.ttf +++ b/data/fonts/DroidNaskh-Regular.ttf diff --git a/data/sounds/AudioPackage10.mk b/data/sounds/AudioPackage10.mk new file mode 100755 index 0000000..cb55bba --- /dev/null +++ b/data/sounds/AudioPackage10.mk @@ -0,0 +1,64 @@ +# +# Audio Package 10 - Mako +# +# Include this file in a product makefile to include these audio files +# +# + +LOCAL_PATH:= frameworks/base/data/sounds + +PRODUCT_COPY_FILES += \ + $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \ + $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \ + $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ + $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \ + $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ + $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \ + $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Atria.ogg:system/media/audio/ringtones/Atria.ogg \ + $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:system/media/audio/ringtones/Kuma.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Rasalas.ogg:system/media/audio/ringtones/Rasalas.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg diff --git a/data/sounds/AudioPackage9.mk b/data/sounds/AudioPackage9.mk new file mode 100755 index 0000000..73e4fd3 --- /dev/null +++ b/data/sounds/AudioPackage9.mk @@ -0,0 +1,47 @@ +# +# Audio Package 9 - Manta +# +# Include this file in a product makefile to include these audio files +# +# + +LOCAL_PATH:= frameworks/base/data/sounds + +PRODUCT_COPY_FILES += \ + $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \ + $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \ + $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ + $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \ + $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ + $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \ + $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg diff --git a/data/sounds/alarms/ogg/Argon.ogg b/data/sounds/alarms/ogg/Argon.ogg Binary files differnew file mode 100644 index 0000000..35addf5 --- /dev/null +++ b/data/sounds/alarms/ogg/Argon.ogg diff --git a/data/sounds/alarms/ogg/Carbon.ogg b/data/sounds/alarms/ogg/Carbon.ogg Binary files differnew file mode 100644 index 0000000..b02a1cc --- /dev/null +++ b/data/sounds/alarms/ogg/Carbon.ogg diff --git a/data/sounds/alarms/ogg/Helium.ogg b/data/sounds/alarms/ogg/Helium.ogg Binary files differnew file mode 100644 index 0000000..36694cb --- /dev/null +++ b/data/sounds/alarms/ogg/Helium.ogg diff --git a/data/sounds/alarms/ogg/Krypton.ogg b/data/sounds/alarms/ogg/Krypton.ogg Binary files differnew file mode 100755 index 0000000..48f956b --- /dev/null +++ b/data/sounds/alarms/ogg/Krypton.ogg diff --git a/data/sounds/alarms/ogg/Neon.ogg b/data/sounds/alarms/ogg/Neon.ogg Binary files differnew file mode 100644 index 0000000..3089a27 --- /dev/null +++ b/data/sounds/alarms/ogg/Neon.ogg diff --git a/data/sounds/alarms/ogg/Oxygen.ogg b/data/sounds/alarms/ogg/Oxygen.ogg Binary files differnew file mode 100644 index 0000000..4dc8ade --- /dev/null +++ b/data/sounds/alarms/ogg/Oxygen.ogg diff --git a/data/sounds/alarms/ogg/Platinum.ogg b/data/sounds/alarms/ogg/Platinum.ogg Binary files differnew file mode 100644 index 0000000..d5f0893 --- /dev/null +++ b/data/sounds/alarms/ogg/Platinum.ogg diff --git a/data/sounds/alarms/ogg/Promethium.ogg b/data/sounds/alarms/ogg/Promethium.ogg Binary files differindex 2a195a3..d5f0893 100644 --- a/data/sounds/alarms/ogg/Promethium.ogg +++ b/data/sounds/alarms/ogg/Promethium.ogg diff --git a/data/sounds/alarms/wav/Argon.wav b/data/sounds/alarms/wav/Argon.wav Binary files differnew file mode 100755 index 0000000..56e57fc --- /dev/null +++ b/data/sounds/alarms/wav/Argon.wav diff --git a/data/sounds/alarms/wav/Carbon.wav b/data/sounds/alarms/wav/Carbon.wav Binary files differnew file mode 100755 index 0000000..2b855e1 --- /dev/null +++ b/data/sounds/alarms/wav/Carbon.wav diff --git a/data/sounds/alarms/wav/Helium.wav b/data/sounds/alarms/wav/Helium.wav Binary files differnew file mode 100644 index 0000000..17710b0 --- /dev/null +++ b/data/sounds/alarms/wav/Helium.wav diff --git a/data/sounds/alarms/wav/Krypton.wav b/data/sounds/alarms/wav/Krypton.wav Binary files differnew file mode 100644 index 0000000..9095e30 --- /dev/null +++ b/data/sounds/alarms/wav/Krypton.wav diff --git a/data/sounds/alarms/wav/Neon.wav b/data/sounds/alarms/wav/Neon.wav Binary files differnew file mode 100644 index 0000000..0e9101a --- /dev/null +++ b/data/sounds/alarms/wav/Neon.wav diff --git a/data/sounds/alarms/wav/Oxygen.wav b/data/sounds/alarms/wav/Oxygen.wav Binary files differnew file mode 100644 index 0000000..bd41869 --- /dev/null +++ b/data/sounds/alarms/wav/Oxygen.wav diff --git a/data/sounds/alarms/wav/Platinum.wav b/data/sounds/alarms/wav/Platinum.wav Binary files differnew file mode 100755 index 0000000..08ea03e --- /dev/null +++ b/data/sounds/alarms/wav/Platinum.wav diff --git a/data/sounds/ringtones/ogg/ArgoNavis.ogg b/data/sounds/ringtones/ogg/ArgoNavis.ogg Binary files differindex 8bee29e..d25b5e8 100644 --- a/data/sounds/ringtones/ogg/ArgoNavis.ogg +++ b/data/sounds/ringtones/ogg/ArgoNavis.ogg diff --git a/data/sounds/ringtones/ogg/Perseus.ogg b/data/sounds/ringtones/ogg/Perseus.ogg Binary files differindex e5f3fc2..48348e5 100644 --- a/data/sounds/ringtones/ogg/Perseus.ogg +++ b/data/sounds/ringtones/ogg/Perseus.ogg diff --git a/data/sounds/ringtones/ogg/Rigel.ogg b/data/sounds/ringtones/ogg/Rigel.ogg Binary files differindex 4fcb3c0..de3d92f 100644 --- a/data/sounds/ringtones/ogg/Rigel.ogg +++ b/data/sounds/ringtones/ogg/Rigel.ogg diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd index 62c054a..3cfed13 100644 --- a/docs/html/guide/topics/ui/dialogs.jd +++ b/docs/html/guide/topics/ui/dialogs.jd @@ -119,7 +119,7 @@ onCreateDialog()} callback method.</p> a {@link android.support.v4.app.DialogFragment}:</p> <pre> -public class FireMissilesDialog extends DialogFragment { +public class FireMissilesDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction @@ -469,7 +469,7 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - NoticeDialog.this.getDialog().cancel(); + LoginDialogFragment.this.getDialog().cancel(); } }); return builder.create(); @@ -497,15 +497,15 @@ in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <p>When the user touches one of the dialog's action buttons or selects an item from its list, your {@link android.support.v4.app.DialogFragment} might perform the necessary action itself, but often you'll want to deliver the event to the activity or fragment that -opened the dialog. To do this, define an interface with a method for each type of click event, -then implement that interface in the host component that will +opened the dialog. To do this, define an interface with a method for each type of click event. +Then implement that interface in the host component that will receive the action events from the dialog.</p> <p>For example, here's a {@link android.support.v4.app.DialogFragment} that defines an interface through which it delivers the events back to the host activity:</p> <pre> -public class NoticeDialog extends DialogFragment { +public class NoticeDialogFragment extends DialogFragment { /* The activity that creates an instance of this dialog fragment must * implement this interface in order to receive event callbacks. @@ -516,48 +516,44 @@ public class NoticeDialog extends DialogFragment { } // Use this instance of the interface to deliver action events - static NoticeDialogListener mListener; - - /* Call this to instantiate a new NoticeDialog. - * @param activity The activity hosting the dialog, which must implement the - * NoticeDialogListener to receive event callbacks. - * @returns A new instance of NoticeDialog. - * @throws ClassCastException if the host activity does not - * implement NoticeDialogListener - */ - public static NoticeDialog newInstance(Activity activity) { + NoticeDialogListener mListener; + + // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); // Verify that the host activity implements the callback interface try { - // Instantiate the NoticeDialogListener so we can send events with it + // Instantiate the NoticeDialogListener so we can send events to the host mListener = (NoticeDialogListener) activity; } catch (ClassCastException e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(activity.toString() + " must implement NoticeDialogListener"); } - NoticeDialog frag = new NoticeDialog(); - return frag; } - ... } </pre> -<p>The activity hosting the dialog creates and shows an instance of the dialog -by calling {@code NoticeDialog.newInstance()} and receives the dialog's +<p>The activity hosting the dialog creates an instance of the dialog +with the dialog fragment's constructor and receives the dialog's events through an implementation of the {@code NoticeDialogListener} interface:</p> <pre> public class MainActivity extends FragmentActivity - implements NoticeDialog.NoticeDialogListener{ + implements NoticeDialogFragment.NoticeDialogListener{ ... public void showNoticeDialog() { // Create an instance of the dialog fragment and show it - DialogFragment dialog = NoticeDialog.newInstance(this); - dialog.show(getSupportFragmentManager(), "NoticeDialog"); + DialogFragment dialog = new NoticeDialogFragment(); + dialog.show(getSupportFragmentManager(), "NoticeDialogFragment"); } + // The dialog fragment receives a reference to this Activity through the + // Fragment.onAttach() callback, which it uses to call the following methods + // defined by the NoticeDialogFragment.NoticeDialogListener interface @Override public void onDialogPositiveClick(DialogFragment dialog) { // User touched the dialog's positive button @@ -573,11 +569,12 @@ public class MainActivity extends FragmentActivity </pre> <p>Because the host activity implements the {@code NoticeDialogListener}—which is -enforced by the {@code newInstance()} method shown above—the dialog fragment can use the +enforced by the {@link android.support.v4.app.Fragment#onAttach onAttach()} +callback method shown above—the dialog fragment can use the interface callback methods to deliver click events to the activity:</p> <pre> -public class NoticeDialog extends DialogFragment { +public class NoticeDialogFragment extends DialogFragment { ... @Override @@ -588,13 +585,13 @@ public class NoticeDialog extends DialogFragment { .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Send the positive button event back to the host activity - mListener.onDialogPositiveClick(NoticeDialog.this); + mListener.onDialogPositiveClick(NoticeDialogFragment.this); } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Send the negative button event back to the host activity - mListener.onDialogPositiveClick(NoticeDialog.this); + mListener.onDialogPositiveClick(NoticeDialogFragment.this); } }); return builder.create(); @@ -604,8 +601,6 @@ public class NoticeDialog extends DialogFragment { - - <h2 id="ShowingADialog">Showing a Dialog</h2> <p>When you want to show your dialog, create an instance of your {@link @@ -621,7 +616,7 @@ android.support.v4.app.Fragment}. For example:</p> <pre> public void confirmFireMissiles() { - DialogFragment newFragment = FireMissilesDialog.newInstance(this); + DialogFragment newFragment = new FireMissilesDialogFragment(); newFragment.show(getSupportFragmentManager(), "missiles"); } </pre> @@ -653,7 +648,7 @@ onCreateView()} callback.</p> dialog or an embeddable fragment (using a layout named <code>purchase_items.xml</code>):</p> <pre> -public class CustomLayoutDialog extends DialogFragment { +public class CustomDialogFragment extends DialogFragment { /** The system calls this to get the DialogFragment's layout, regardless of whether it's being displayed as a dialog or an embedded fragment. */ @Override @@ -683,7 +678,7 @@ or a fullscreen UI, based on the screen size:</p> <pre> public void showDialog() { FragmentManager fragmentManager = getSupportFragmentManager(); - CustomLayoutDialog newFragment = new CustomLayoutDialog(); + CustomDialogFragment newFragment = new CustomDialogFragment(); if (mIsLargeLayout) { // The device is using a large layout, so show the fragment as a dialog diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 6238edb..22ecc61 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -1030,6 +1030,51 @@ public final class Bitmap implements Parcelable { } /** + * Indicates whether the renderer responsible for drawing this + * bitmap should attempt to use mipmaps when this bitmap is drawn + * scaled down. + * + * If you know that you are going to draw this bitmap at less than + * 50% of its original size, you may be able to obtain a higher + * quality + * + * This property is only a suggestion that can be ignored by the + * renderer. It is not guaranteed to have any effect. + * + * @return true if the renderer should attempt to use mipmaps, + * false otherwise + * + * @see #setHasMipMap(boolean) + */ + public final boolean hasMipMap() { + return nativeHasMipMap(mNativeBitmap); + } + + /** + * Set a hint for the renderer responsible for drawing this bitmap + * indicating that it should attempt to use mipmaps when this bitmap + * is drawn scaled down. + * + * If you know that you are going to draw this bitmap at less than + * 50% of its original size, you may be able to obtain a higher + * quality by turning this property on. + * + * Note that if the renderer respects this hint it might have to + * allocate extra memory to hold the mipmap levels for this bitmap. + * + * This property is only a suggestion that can be ignored by the + * renderer. It is not guaranteed to have any effect. + * + * @param hasMipMap indicates whether the renderer should attempt + * to use mipmaps + * + * @see #hasMipMap() + */ + public final void setHasMipMap(boolean hasMipMap) { + nativeSetHasMipMap(mNativeBitmap, hasMipMap); + } + + /** * Fills the bitmap's pixels with the specified {@link Color}. * * @throws IllegalStateException if the bitmap is not mutable. @@ -1356,7 +1401,6 @@ public final class Bitmap implements Parcelable { private static native int nativeHeight(int nativeBitmap); private static native int nativeRowBytes(int nativeBitmap); private static native int nativeConfig(int nativeBitmap); - private static native boolean nativeHasAlpha(int nativeBitmap); private static native int nativeGetPixel(int nativeBitmap, int x, int y); private static native void nativeGetPixels(int nativeBitmap, int[] pixels, @@ -1385,7 +1429,10 @@ public final class Bitmap implements Parcelable { int[] offsetXY); private static native void nativePrepareToDraw(int nativeBitmap); + private static native boolean nativeHasAlpha(int nativeBitmap); private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha); + private static native boolean nativeHasMipMap(int nativeBitmap); + private static native void nativeSetHasMipMap(int nBitmap, boolean hasMipMap); private static native boolean nativeSameAs(int nb0, int nb1); /* package */ final int ni() { diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java index 2a04b42..11164e3 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java @@ -63,7 +63,7 @@ public final class ScriptIntrinsicBlur extends ScriptIntrinsic { */ public void setInput(Allocation ain) { mInput = ain; - bindAllocation(ain, 1); + setVar(1, ain); } /** diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java index d7e9f32..91efa02 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java @@ -68,7 +68,7 @@ public final class ScriptIntrinsicConvolve3x3 extends ScriptIntrinsic { */ public void setInput(Allocation ain) { mInput = ain; - bindAllocation(ain, 1); + setVar(1, ain); } /** diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java index ff31270..1f52e3f 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java @@ -61,7 +61,7 @@ public final class ScriptIntrinsicConvolve5x5 extends ScriptIntrinsic { */ public void setInput(Allocation ain) { mInput = ain; - bindAllocation(ain, 1); + setVar(1, ain); } /** diff --git a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java index 188e04c..41bdd25 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java @@ -41,7 +41,7 @@ public final class ScriptIntrinsicLUT extends ScriptIntrinsic { mCache[ct + 512] = (byte)ct; mCache[ct + 768] = (byte)ct; } - bindAllocation(mTables, 0); + setVar(0, mTables); } /** diff --git a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java index 415061c..dc8a5aa 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java @@ -56,7 +56,7 @@ public final class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic { */ public void setInput(Allocation ain) { mInput = ain; - bindAllocation(ain, 0); + setVar(0, ain); } /** diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index d18a5b0..e7085b0 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -399,9 +399,20 @@ bool Caches::setScissor(GLint x, GLint y, GLint width, GLint height) { if (scissorEnabled && (x != mScissorX || y != mScissorY || width != mScissorWidth || height != mScissorHeight)) { - if (x < 0) x = 0; - if (y < 0) y = 0; - + if (x < 0) { + width += x; + x = 0; + } + if (y < 0) { + height += y; + y = 0; + } + if (width < 0) { + width = 0; + } + if (height < 0) { + height = 0; + } glScissor(x, y, width, height); mScissorX = x; diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 69be317..448e3da 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -209,6 +209,9 @@ struct Layer { } inline void allocateTexture(GLenum format, GLenum storage) { +#if DEBUG_LAYERS + ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight()); +#endif glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, format, storage, NULL); } diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 2b50091..b6be5b3 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -49,7 +49,7 @@ namespace uirenderer { #define ALPHA_THRESHOLD 0 -#define FILTER(paint) (paint && paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST) +#define FILTER(paint) (!paint || paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST) /////////////////////////////////////////////////////////////////////////////// // Globals @@ -895,12 +895,6 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) { float alpha = layer->getAlpha() / 255.0f; - mat4& transform = layer->getTransform(); - if (!transform.isIdentity()) { - save(0); - mSnapshot->transform->multiply(transform); - } - setupDraw(); if (layer->getRenderTarget() == GL_TEXTURE_2D) { setupDrawWithTexture(); @@ -937,10 +931,6 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) { glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); finishDrawTexture(); - - if (!transform.isIdentity()) { - restore(); - } } void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) { @@ -1730,35 +1720,22 @@ status_t OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, float* vertices, int* colors, SkPaint* paint) { - // TODO: Do a quickReject if (!vertices || mSnapshot->isIgnored()) { return DrawGlInfo::kStatusDone; } - mCaches.activeTexture(0); - Texture* texture = mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; - const AutoTexture autoCleanup(texture); - - texture->setWrap(GL_CLAMP_TO_EDGE, true); - texture->setFilter(FILTER(paint), true); - - int alpha; - SkXfermode::Mode mode; - getAlphaAndMode(paint, &alpha, &mode); - - const uint32_t count = meshWidth * meshHeight * 6; - + // TODO: We should compute the bounding box when recording the display list float left = FLT_MAX; float top = FLT_MAX; float right = FLT_MIN; float bottom = FLT_MIN; - const bool hasActiveLayer = hasLayer(); + const uint32_t count = meshWidth * meshHeight * 6; // TODO: Support the colors array TextureVertex mesh[count]; TextureVertex* vertex = mesh; + for (int32_t y = 0; y < meshHeight; y++) { for (int32_t x = 0; x < meshWidth; x++) { uint32_t i = (y * (meshWidth + 1) + x) * 2; @@ -1785,17 +1762,31 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes TextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1); TextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2); - if (hasActiveLayer) { - // TODO: This could be optimized to avoid unnecessary ops - left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx]))); - top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy]))); - right = fmaxf(right, fmaxf(vertices[ax], fmaxf(vertices[bx], vertices[cx]))); - bottom = fmaxf(bottom, fmaxf(vertices[ay], fmaxf(vertices[by], vertices[cy]))); - } + // TODO: This could be optimized to avoid unnecessary ops + left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx]))); + top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy]))); + right = fmaxf(right, fmaxf(vertices[ax], fmaxf(vertices[bx], vertices[cx]))); + bottom = fmaxf(bottom, fmaxf(vertices[ay], fmaxf(vertices[by], vertices[cy]))); } } - if (hasActiveLayer) { + if (quickReject(left, top, right, bottom)) { + return DrawGlInfo::kStatusDone; + } + + mCaches.activeTexture(0); + Texture* texture = mCaches.textureCache.get(bitmap); + if (!texture) return DrawGlInfo::kStatusDone; + const AutoTexture autoCleanup(texture); + + texture->setWrap(GL_CLAMP_TO_EDGE, true); + texture->setFilter(FILTER(paint), true); + + int alpha; + SkXfermode::Mode mode; + getAlphaAndMode(paint, &alpha, &mode); + + if (hasLayer()) { dirtyLayer(left, top, right, bottom, *mSnapshot->transform); } @@ -2791,12 +2782,24 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pain return DrawGlInfo::kStatusDone; } + mat4* transform = NULL; + if (layer->isTextureLayer()) { + transform = &layer->getTransform(); + if (!transform->isIdentity()) { + save(0); + mSnapshot->transform->multiply(*transform); + } + } + Rect transformed; Rect clip; const bool rejected = quickRejectNoScissor(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), transformed, clip); if (rejected) { + if (transform && !transform->isIdentity()) { + restore(); + } return DrawGlInfo::kStatusDone; } @@ -2857,6 +2860,10 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pain } } + if (transform && !transform->isIdentity()) { + restore(); + } + return DrawGlInfo::kStatusDrew; } diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index 03e2172..8d88bdc 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -36,6 +36,8 @@ struct Texture { minFilter = GL_NEAREST; magFilter = GL_NEAREST; + mipMap = false; + firstFilter = true; firstWrap = true; @@ -83,6 +85,8 @@ struct Texture { glBindTexture(renderTarget, id); } + if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR; + glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min); glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag); } @@ -116,7 +120,12 @@ struct Texture { * Optional, size of the original bitmap. */ uint32_t bitmapSize; + /** + * Indicates whether this texture will use trilinear filtering. + */ + bool mipMap; +private: /** * Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE. */ @@ -129,7 +138,6 @@ struct Texture { GLenum minFilter; GLenum magFilter; -private: bool firstFilter; bool firstWrap; }; // struct Texture diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 9fb61e4..10d112a 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -22,6 +22,7 @@ #include <utils/threads.h> +#include "Caches.h" #include "TextureCache.h" #include "Properties.h" @@ -216,8 +217,15 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege return; } + // We could also enable mipmapping if both bitmap dimensions are powers + // of 2 but we'd have to deal with size changes. Let's keep this simple + const bool canMipMap = Caches::getInstance().extensions.hasNPot(); + + // If the texture had mipmap enabled but not anymore, + // force a glTexImage2D to discard the mipmap levels const bool resize = !regenerate || bitmap->width() != int(texture->width) || - bitmap->height() != int(texture->height); + bitmap->height() != int(texture->height) || + (regenerate && canMipMap && texture->mipMap && !bitmap->hasHardwareMipMap()); if (!regenerate) { glGenTextures(1, &texture->id); @@ -228,25 +236,22 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege texture->height = bitmap->height(); glBindTexture(GL_TEXTURE_2D, texture->id); - if (!regenerate) { - glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); - } switch (bitmap->getConfig()) { case SkBitmap::kA8_Config: - if (!regenerate) { - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height, GL_UNSIGNED_BYTE, bitmap->getPixels()); texture->blend = true; break; case SkBitmap::kRGB_565_Config: + glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); uploadToTexture(resize, GL_RGB, bitmap->rowBytesAsPixels(), texture->height, GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels()); texture->blend = false; break; case SkBitmap::kARGB_8888_Config: + glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); uploadToTexture(resize, GL_RGBA, bitmap->rowBytesAsPixels(), texture->height, GL_UNSIGNED_BYTE, bitmap->getPixels()); // Do this after calling getPixels() to make sure Skia's deferred @@ -255,6 +260,7 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege break; case SkBitmap::kARGB_4444_Config: case SkBitmap::kIndex8_Config: + glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); uploadLoFiTexture(resize, bitmap, texture->width, texture->height); texture->blend = !bitmap->isOpaque(); break; @@ -263,6 +269,13 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege break; } + if (canMipMap) { + texture->mipMap = bitmap->hasHardwareMipMap(); + if (texture->mipMap) { + glGenerateMipmap(GL_TEXTURE_2D); + } + } + if (!regenerate) { texture->setFilter(GL_NEAREST); texture->setWrap(GL_CLAMP_TO_EDGE); diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java index cb291ea..6871ee2 100644 --- a/location/java/android/location/LocationRequest.java +++ b/location/java/android/location/LocationRequest.java @@ -221,6 +221,18 @@ public final class LocationRequest implements Parcelable { /** @hide */ public LocationRequest() { } + /** @hide */ + public LocationRequest(LocationRequest src) { + mQuality = src.mQuality; + mInterval = src.mInterval; + mFastestInterval = src.mFastestInterval; + mExplicitFastestInterval = src.mExplicitFastestInterval; + mExpireAt = src.mExpireAt; + mNumUpdates = src.mNumUpdates; + mSmallestDisplacement = src.mSmallestDisplacement; + mProvider = src.mProvider; + } + /** * Set the quality of the request. * diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java index 9b1098e..1c60401 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java @@ -114,10 +114,10 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<Med mProcMemWriter = new BufferedWriter(new FileWriter (new File(MEDIA_PROCMEM_OUTPUT), true)); mProcMemWriter.write(this.getName() + "\n"); - mMemWriter = new BufferedWriter(new FileWriter - (new File(MEDIA_MEMORY_OUTPUT), true)); } - + mMemWriter = new BufferedWriter(new FileWriter + (new File(MEDIA_MEMORY_OUTPUT), true)); + mMemWriter.write(this.getName() + "\n"); } @Override @@ -126,10 +126,10 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<Med MediaTestUtil.getNativeHeapDump(this.getName() + "_after"); if (MediaFrameworkPerfTestRunner.mGetProcmem) { - mMemWriter.write("\n"); mProcMemWriter.close(); - mMemWriter.close(); } + mMemWriter.write("\n"); + mMemWriter.close(); super.tearDown(); } diff --git a/packages/FusedLocation/AndroidManifest.xml b/packages/FusedLocation/AndroidManifest.xml index 4c57401..10b9064 100644 --- a/packages/FusedLocation/AndroidManifest.xml +++ b/packages/FusedLocation/AndroidManifest.xml @@ -18,7 +18,8 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.location.fused" - coreApp="true"> + coreApp="true" + android:sharedUserId="android.uid.system"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> @@ -39,7 +40,7 @@ <intent-filter> <action android:name="com.android.location.service.FusedLocationProvider" /> </intent-filter> - <meta-data android:name="version" android:value="1" /> + <meta-data android:name="serviceVersion" android:value="0" /> </service> </application> </manifest> diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notifications_normal.png Binary files differnew file mode 100644 index 0000000..62afe76 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_notifications_normal.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png Binary files differindex a54761f..ead184d 100644 --- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png +++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png Binary files differindex f3f336c..203e232 100644 --- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png +++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png Binary files differnew file mode 100644 index 0000000..2adafea --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_pressed.png Binary files differnew file mode 100644 index 0000000..8521ffc --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png Binary files differindex 55c46b0..4436359 100644 --- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png +++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png Binary files differindex e30cb8f..c86710d 100644 --- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png +++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notifications_normal.png Binary files differnew file mode 100644 index 0000000..62afe76 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_notifications_normal.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png Binary files differindex b44b527..5dacccb 100644 --- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png +++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png Binary files differindex 94c8165..f1f6b00 100644 --- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png +++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png Binary files differnew file mode 100644 index 0000000..2ab0cd7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_pressed.png Binary files differnew file mode 100644 index 0000000..49ac94b --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png Binary files differindex b1910cf..09d2c55 100644 --- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png +++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png Binary files differindex 3abafdd..322d1a7 100644 --- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png +++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notifications_normal.png Binary files differnew file mode 100644 index 0000000..983302c --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_notifications_normal.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png Binary files differindex 870beb4..c882e9a 100644 --- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png +++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png Binary files differindex 94a4646..992b50d 100644 --- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png +++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png Binary files differnew file mode 100644 index 0000000..b0e35a1 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_pressed.png Binary files differnew file mode 100644 index 0000000..42bbbbc --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_pressed.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png Binary files differindex 5dc93c2..2d445279 100644 --- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png +++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png Binary files differindex a97de79..ddf2c7a 100644 --- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png +++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png diff --git a/packages/SystemUI/res/drawable/ic_notifications.xml b/packages/SystemUI/res/drawable/ic_notifications.xml new file mode 100644 index 0000000..68c4774 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_notifications.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" + android:drawable="@drawable/ic_notifications_normal" /> + <item + android:drawable="@drawable/ic_notifications_normal" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/ic_notify_button_bg.xml b/packages/SystemUI/res/drawable/ic_notify_button_bg.xml new file mode 100644 index 0000000..85f1ea2 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_notify_button_bg.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@*android:drawable/list_selector_pressed_holo_dark" /> + <item android:drawable="@*android:drawable/list_selector_disabled_holo_dark" /> +</selector> diff --git a/packages/SystemUI/res/drawable/ic_notify_clear.xml b/packages/SystemUI/res/drawable/ic_notify_clear.xml index 9c432b2..2163198 100644 --- a/packages/SystemUI/res/drawable/ic_notify_clear.xml +++ b/packages/SystemUI/res/drawable/ic_notify_clear.xml @@ -16,6 +16,6 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" - android:drawable="@drawable/ic_notify_clear_pressed" /> + android:drawable="@drawable/ic_notify_clear_normal" /> <item android:drawable="@drawable/ic_notify_clear_normal" /> </selector> diff --git a/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml index d8ea524..7cf3175 100644 --- a/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml +++ b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml @@ -16,7 +16,7 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" - android:drawable="@drawable/ic_notify_quicksettings_pressed" /> + android:drawable="@drawable/ic_notify_quicksettings_normal" /> <item android:drawable="@drawable/ic_notify_quicksettings_normal" /> </selector> diff --git a/packages/SystemUI/res/drawable/ic_notify_settings.xml b/packages/SystemUI/res/drawable/ic_notify_settings.xml index 6579d8e..9303ca4 100644 --- a/packages/SystemUI/res/drawable/ic_notify_settings.xml +++ b/packages/SystemUI/res/drawable/ic_notify_settings.xml @@ -16,7 +16,7 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" - android:drawable="@drawable/ic_notify_settings_pressed" /> + android:drawable="@drawable/ic_notify_settings_normal" /> <item android:drawable="@drawable/ic_notify_settings_normal" /> </selector> diff --git a/packages/SystemUI/res/layout/flip_settings.xml b/packages/SystemUI/res/layout/flip_settings.xml new file mode 100644 index 0000000..1b8898c5 --- /dev/null +++ b/packages/SystemUI/res/layout/flip_settings.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 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. +--> + +<com.android.systemui.statusbar.phone.QuickSettingsScrollView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/close_handle_underlap" + android:overScrollMode="ifContentScrolls" + > + <com.android.systemui.statusbar.phone.QuickSettingsContainerView + android:id="@+id/quick_settings_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:animateLayoutChanges="true" + android:columnCount="@integer/quick_settings_num_columns" + /> +</com.android.systemui.statusbar.phone.QuickSettingsScrollView>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml index 5a5769b..f7b1d78 100644 --- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml +++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml @@ -21,6 +21,8 @@ <ImageView android:id="@+id/brightness_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingRight="10dp" android:src="@drawable/ic_qs_brightness_auto_off" diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index cb4c227..b71025e 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -50,7 +50,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="@dimen/close_handle_underlap" android:orientation="vertical" - android:animateLayoutChanges="true" + android:animateLayoutChanges="false" > <include layout="@layout/status_bar_expanded_header" @@ -63,24 +63,35 @@ android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network.EmergencyOnly" android:layout_height="wrap_content" android:layout_width="match_parent" - android:paddingBottom="4dp" + android:padding="4dp" android:gravity="center" android:visibility="gone" /> - <ScrollView - android:id="@+id/scroll" + <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:fadingEdge="none" - android:overScrollMode="ifContentScrolls" > - <com.android.systemui.statusbar.policy.NotificationRowLayout - android:id="@+id/latestItems" + <ViewStub android:id="@+id/flip_settings_stub" + android:layout="@layout/flip_settings" android:layout_width="match_parent" android:layout_height="wrap_content" - systemui:rowHeight="@dimen/notification_row_min_height" /> - </ScrollView> + + <ScrollView + android:id="@+id/scroll" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fadingEdge="none" + android:overScrollMode="ifContentScrolls" + > + <com.android.systemui.statusbar.policy.NotificationRowLayout + android:id="@+id/latestItems" + android:layout_width="match_parent" + android:layout_height="wrap_content" + systemui:rowHeight="@dimen/notification_row_min_height" + /> + </ScrollView> + </FrameLayout> </LinearLayout> </com.android.systemui.statusbar.phone.NotificationPanelView><!-- end of sliding panel --> diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml index c921837..03f03e2 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml @@ -20,37 +20,40 @@ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" android:id="@+id/header" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="@dimen/notification_panel_header_height" android:background="@drawable/notification_header_bg" android:orientation="horizontal" android:gravity="center_vertical" android:baselineAligned="false" > - <LinearLayout + <RelativeLayout + android:id="@+id/datetime" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="horizontal" + android:layout_height="match_parent" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:background="@drawable/ic_notify_button_bg" + android:enabled="false" > <com.android.systemui.statusbar.policy.Clock android:id="@+id/clock" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginLeft="8dp" + android:layout_marginRight="8dp" android:singleLine="true" android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" - android:gravity="bottom" + android:layout_centerVertical="true" /> <com.android.systemui.statusbar.policy.DateView android:id="@+id/date" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginLeft="8dp" - android:layout_marginRight="8dp" android:singleLine="true" android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date" - android:gravity="bottom" + android:layout_toRightOf="@id/clock" + android:layout_alignBaseline="@id/clock" /> - </LinearLayout> + </RelativeLayout> <Space android:layout_width="0dp" @@ -70,21 +73,37 @@ android:textColor="#00A040" android:padding="2dp" /> - - <ImageView android:id="@+id/settings_button" - android:layout_width="50dp" - android:layout_height="50dp" - android:scaleType="center" - android:src="@drawable/ic_notify_settings" - android:contentDescription="@string/accessibility_settings_button" - /> <ImageView android:id="@+id/clear_all_button" android:layout_width="50dp" android:layout_height="50dp" - android:layout_marginLeft="12dp" + android:layout_marginRight="12dp" android:scaleType="center" android:src="@drawable/ic_notify_clear" + android:background="@drawable/ic_notify_button_bg" android:contentDescription="@string/accessibility_clear_all" /> + + <FrameLayout + android:layout_width="50dp" + android:layout_height="50dp" + > + <ImageView android:id="@+id/settings_button" + android:layout_width="50dp" + android:layout_height="50dp" + android:scaleType="center" + android:src="@drawable/ic_notify_settings" + android:background="@drawable/ic_notify_button_bg" + android:contentDescription="@string/accessibility_settings_button" + /> + <ImageView android:id="@+id/notification_button" + android:layout_width="50dp" + android:layout_height="50dp" + android:scaleType="center" + android:src="@drawable/ic_notifications" + android:background="@drawable/ic_notify_button_bg" + android:visibility="gone" + android:contentDescription="@string/accessibility_notifications_button" + /> + </FrameLayout> </LinearLayout> diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml index 07aca6c..2b56618 100644 --- a/packages/SystemUI/res/layout/super_status_bar.xml +++ b/packages/SystemUI/res/layout/super_status_bar.xml @@ -36,7 +36,6 @@ android:id="@+id/panel_holder" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginTop="@*android:dimen/status_bar_height" > <include layout="@layout/status_bar_expanded" android:layout_width="match_parent" diff --git a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml index 2d1bda4..59544f4 100644 --- a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml +++ b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml @@ -170,7 +170,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_sysbar_quicksettings" - android:contentDescription="@string/accessibility_settings_button" + android:contentDescription="@string/accessibility_desc_quick_settings" /> <ImageView diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index d536793..69355d5 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Kennisgewing is toegemaak."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Kennisgewingskerm."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Vinnige instellings."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Onlangse programme."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Gebruiker <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobiele <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index a588b42..735da78 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ማሳወቂያ ተወግዷል።"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"የማሳወቂያ ጥላ።"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ፈጣን ቅንብሮች።"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"የቅርብ ጊዜ መተግበሪያዎች።"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ተጠቃሚ <xliff:g id="USER">%s</xliff:g>።"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>። <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"ተንቀሳቃሽ ስልክ <xliff:g id="SIGNAL">%1$s</xliff:g>። <xliff:g id="TYPE">%2$s</xliff:g>። <xliff:g id="NETWORK">%3$s</xliff:g>።"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index f7f963e..da78d29 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"تم تجاهل الإشعار."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"مركز الإشعارات."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"الإعدادات السريعة."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"التطبيقات الحديثة"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"المستخدم <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"الجوال <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 4b8aad2..79bc53a 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Апавяшчэнне прапушчана."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Цень апавяшчэння.."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Хуткія налады."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Апошнія прыкладанні."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Карыстальнік: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мабiльны сiгнал: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index c05fc59..59ba693 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Известието е отхвърлено."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Падащ панел с известия."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Бързи настройки."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Скорошни приложения."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Потребител: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобилно устройство: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 13fb675..bf10ce2 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificació omesa."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Capa de notificació."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuració ràpida."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicacions recents."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuari <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mòbil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 72fe18e..5e632fa 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Oznámení je zavřeno."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Panel oznámení."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Rychlé nastavení."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Naposledy použité aplikace"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Uživatel <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index a04673b..671f292 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Underretningen er annulleret."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Underretningspanel."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Hurtige indstillinger."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Seneste apps"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Bruger <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 2575d2c..3e767a0 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Benachrichtigung geschlossen"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Benachrichtigungsleiste"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Schnelleinstellungen"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Kürzlich geöffnete Apps"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Nutzer: <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobilfunkverbindung: <xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="TYPE">%2$s</xliff:g>, <xliff:g id="NETWORK">%3$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index a73c113..0665020 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Η ειδοποίηση έχει απορριφθεί."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Πλαίσιο σκίασης ειδοποιήσεων."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Γρήγορες ρυθμίσεις."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Πρόσφατες εφαρμογές"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Χρήστης <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Κινητό <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 1ad2c06..906b5c6 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Notification shade."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Quick settings."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Recent apps"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"User <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobile <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 1460996..9bbd5d7 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación ignorada"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Pantalla de notificaciones"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuración rápida"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicaciones recientes"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuario <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Móvil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 9f0fbda..90f93b2 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación ignorada"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Pantalla de notificaciones"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Ajustes rápidos"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicaciones recientes"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuario <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Móvil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 7b4c31a..d77b26a 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Märguandest on loobutud."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Märguande vari."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Kiirseaded."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Hiljutised rakendused"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Kasutaja <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobiili <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index d984bf8..6accc9f 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"اعلان ردشد."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"مجموعه اعلان."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"تنظیمات سریع."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"برنامههای اخیر"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"کاربر <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"تلفن همراه <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 9d28900..3bc0371 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Ilmoitus hylätty."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Ilmoitusalue."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Pika-asetukset."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Viimeaikaiset sovellukset"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Käyttäjä: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobiiliverkkoyhteys: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index ab98d24..02eb529 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification masquée"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Volet des notifications"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Paramètres rapides"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Applications récentes"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utilisateur <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Signal mobile : <xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="TYPE">%2$s</xliff:g>, <xliff:g id="NETWORK">%3$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 718d267..e2bc2c3 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना खारिज की गई."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"सूचना शेड."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"त्वरित सेटिंग."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"हाल ही के एप्लिकेशन."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"उपयोगकर्ता <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"मोबाइल <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index bd19a44..e318120 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obavijest je odbačena."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Zaslon obavijesti."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Brze postavke."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Nedavne aplikacije."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Korisnik <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobitel <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 96bb897..3dafd2b 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Értesítés elvetve."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Értesítési felület."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Gyorsbeállítások."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Legutóbbi alkalmazások"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Felhasználó: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index dce8076..c26cdce 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pemberitahuan disingkirkan."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bayangan pemberitahuan."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Setelan cepat."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplikasi terkini."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Pengguna <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Seluler <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 8ce9f64..b5be2ac 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notifica eliminata."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Area notifiche."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Impostazioni rapide."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Applicazioni recenti."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utente <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Cellulare: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index a1e7aba..0481d63 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"הודעה נדחתה."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"תריס התראות."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"הגדרות מהירות."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"יישומים אחרונים"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"משתמש <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"נייד <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 23babd0..1b89e13 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"通知が削除されました。"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"通知シェード"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"クイック設定"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"最近使ったアプリです。"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ユーザー: <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>、<xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"モバイル: <xliff:g id="SIGNAL">%1$s</xliff:g>、<xliff:g id="TYPE">%2$s</xliff:g>、<xliff:g id="NETWORK">%3$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index f01d7eb..71d305f 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"알림이 제거되었습니다."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"알림 세부정보"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"빠른 설정"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"최근 앱"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"사용자 <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"모바일 <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index c6ed8d2..76de197 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pranešimo atsisakyta."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Pranešimų gaubtas."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Spartieji nustatymai."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Naujausios programos."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Naudotojas <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobilusis ryšys <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 6d1b313..21299b2 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Paziņojums netiek rādīts."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Paziņojumu panelis"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Ātrie iestatījumi"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Pēdējās izmantotās lietotnes"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Lietotājs: <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobilo sakaru tīkls. <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index a70c12e..01751b0 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pemberitahuan diketepikan."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bidai pemberitahuan."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Tetapan pantas."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Apl terbaru."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Pengguna <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mudah Alih <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 88096b3..ccba8e5 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Varselet ble skjult."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Varselskygge."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Hurtiginnstillinger."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Nylige apper."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Bruker: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil – <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 24b6ff7..9978b76 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Melding verwijderd."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Meldingenpaneel."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Snelle instellingen."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Recente apps."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Gebruiker: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobiel <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index d3df443..98f13c7 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Zamknięto powiadomienie."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Obszar powiadomień."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Szybkie ustawienia."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Ostatnii używane aplikacje."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Użytkownik: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Sieć komórkowa: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index c2ecb5a..639201c 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação ignorada."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Painel de notificações."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Definições rápidas."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicações recentes"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utilizador <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Dispositivo Móvel <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index a4a871e..9eeb01b 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação dispensada."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Aba de notificações."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configurações rápidas."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicativos recentes."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuário <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Celular <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index a73ad1a..616ddb7 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificarea a fost închisă."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Fereastră pentru notificări."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Setări rapide."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicaţii recente"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utilizatorul <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Semnal mobil: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index a04d732..6e10de4 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Уведомление закрыто"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Панель уведомлений"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Быстрые настройки"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Недавние приложения"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Пользователь <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="NETWORK">%2$s</xliff:g>: <xliff:g id="SIGNAL">%1$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобильная сеть: <xliff:g id="NETWORK">%3$s</xliff:g> (<xliff:g id="TYPE">%2$s</xliff:g>, <xliff:g id="SIGNAL">%1$s</xliff:g>)"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 6d126b1..9151512 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Upozornenie bolo zrušené."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Panel upozornení."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Rýchle nastavenia."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Nedávne aplikácie"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Používateľ: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 2d4006b..7be851c 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obvestilo je bilo odstranjeno."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Zaslon z obvestili."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Hitre nastavitve."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Nedavne aplikacije."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Uporabnik: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobilni telefon: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index fce2c57..9d9da87 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Обавештење је одбачено."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Прозор са обавештењима."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Брза подешавања."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Недавне апликације."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Корисник: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобилна мрежа: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 16b8316..bae649d 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Meddelandet ignorerades."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Meddelandepanel."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Snabbinställningar."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Senaste apparna"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Användare <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 905e1dd..3b29b39 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -145,8 +145,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Arifa imetupwa."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Kivuli cha arifa."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Mipangilio ya haraka."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Programu za hivi karibuni."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Mtumiaji <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Simu <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml index 50575d0..48a02ab 100644 --- a/packages/SystemUI/res/values-sw600dp/config.xml +++ b/packages/SystemUI/res/values-sw600dp/config.xml @@ -31,4 +31,7 @@ <!-- Whether rotation lock shows up in quick settings or not --> <bool name="quick_settings_show_rotation_lock">true</bool> + + <!-- Enable the "flip settings" panel --> + <bool name="config_hasFlipSettingsPanel">false</bool> </resources> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index df6ed19..fc80f5c 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -47,4 +47,8 @@ <!-- Minimum fraction of the screen that should be taken up by the notification panel. --> <item type="dimen" name="notification_panel_min_height_frac">40%</item> + + <!-- How far to slide the panel out when you touch it --> + <!-- On tablets this is just the close_handle_height --> + <dimen name="peek_height">@dimen/close_handle_height</dimen> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 646225d..668504e 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ปิดการแจ้งเตือนแล้ว"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"หน้าต่างแจ้งเตือน"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"การตั้งค่าด่วน"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"แอปพลิเคชันล่าสุด"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ผู้ใช้ <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g> <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"มือถือ <xliff:g id="SIGNAL">%1$s</xliff:g> <xliff:g id="TYPE">%2$s</xliff:g> <xliff:g id="NETWORK">%3$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 7baad61..312d8fd 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Na-dismiss ang notification."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Notification shade."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Mga mabilisang setting."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Kamakailang apps."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"User na si <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobile <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index c6ba738..5012bc5 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Bildirim kapatıldı."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bildirim gölgesi."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Hızlı ayarlar."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Son uygulamalar."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Kullanıcı: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 26ae34b..ba36be6 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Сповіщення відхилено."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Панель сповіщень."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Швидке налаштування."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Нещодавні програми."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Користувач <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобільне передавання даних: <xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="TYPE">%2$s</xliff:g>, <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 468375f..ce90afc 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -147,8 +147,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Đã loại bỏ thông báo."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bóng thông báo."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Cài đặt nhanh."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Ứng dụng gần đây."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Người dùng <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Di động <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 4cfb7d0..ba0d9c8 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"已关闭通知。"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"通知栏。"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"快速设置。"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"最近使用的应用。"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"用户:<xliff:g id="USER">%s</xliff:g>。"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>,<xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"移动数据连接:<xliff:g id="SIGNAL">%1$s</xliff:g>,<xliff:g id="TYPE">%2$s</xliff:g>,<xliff:g id="NETWORK">%3$s</xliff:g>。"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index d0323f0..a77dd8c 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -149,8 +149,7 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"已關閉通知。"</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"通知欄。"</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"快速設定。"</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"最近使用的應用程式。"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"使用者:<xliff:g id="USER">%s</xliff:g>。"</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>,<xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"行動數據連線:<xliff:g id="SIGNAL">%1$s</xliff:g>,<xliff:g id="TYPE">%2$s</xliff:g>,<xliff:g id="NETWORK">%3$s</xliff:g>。"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 8cc8738..8ad1881 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -105,7 +105,7 @@ <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Ibha elilodwa le-WiFi."</string> <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Amabha amabili we-WiFi."</string> <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Amabha amathathu we-WiFi."</string> - <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Isignali ye-WiFi igcwele."</string> + <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Isiginali ye-WiFi igcwele."</string> <string name="accessibility_no_wimax" msgid="4329180129727630368">"Ayikho i-WiMAX."</string> <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Ibha eyodwa ye-WiMAX."</string> <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Amabha amabili we-WiMAX."</string> @@ -117,7 +117,7 @@ <string name="accessibility_one_bar" msgid="1685730113192081895">"Ibha elilodwa."</string> <string name="accessibility_two_bars" msgid="6437363648385206679">"Amabha amabili."</string> <string name="accessibility_three_bars" msgid="2648241415119396648">"Amabha amathathu."</string> - <string name="accessibility_signal_full" msgid="9122922886519676839">"Isignali egcwele."</string> + <string name="accessibility_signal_full" msgid="9122922886519676839">"Isiginali egcwele."</string> <string name="accessibility_desc_on" msgid="2385254693624345265">"Vula."</string> <string name="accessibility_desc_off" msgid="6475508157786853157">"Vala."</string> <string name="accessibility_desc_connected" msgid="8366256693719499665">"Ixhunyiwe."</string> @@ -147,13 +147,12 @@ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Isaziso sichithiwe."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Umthunzi wesaziso."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Izilingiselelo ezisheshayo."</string> - <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Izinhlelo zokusebenza zakamuva"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Umsebenzisi <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Iselula <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Ibhethri <xliff:g id="STATE">%s</xliff:g>."</string> - <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"I-Airplane Mode <xliff:g id="STATE">%s</xliff:g>."</string> + <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Imodi yendiza <xliff:g id="STATE">%s</xliff:g>."</string> <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"I-Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string> <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"I-alamu isethiwe ngo-<xliff:g id="TIME">%s</xliff:g>."</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"idatha ye-2G-3G ivimbelwe"</string> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index aec9555..a27630d 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -97,7 +97,10 @@ <integer name="blinds_pop_duration_ms">10</integer> - <!-- Disable quick settings by default --> - <bool name="config_hasSettingsPanel">false</bool> + <!-- Disable the separate quick settings panel --> + <bool name="config_hasSettingsPanel">true</bool> + + <!-- Enable the "flip settings" panel --> + <bool name="config_hasFlipSettingsPanel">true</bool> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 4de0891..ed08115 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -201,4 +201,8 @@ <!-- The size of the gesture span needed to activate the "pull" notification expansion --> <dimen name="pull_span_min">25dp</dimen> + + <!-- How far to slide the panel out when you touch it --> + <!-- For phones, this is close_handle_height + header_height --> + <dimen name="peek_height">84dp</dimen> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index 6877cba..0a7dd7c 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -31,8 +31,10 @@ import android.os.SystemProperties; import android.renderscript.Matrix4f; import android.service.wallpaper.WallpaperService; import android.util.Log; +import android.view.Display; import android.view.MotionEvent; import android.view.SurfaceHolder; +import android.view.WindowManager; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; @@ -107,7 +109,8 @@ public class ImageWallpaper extends WallpaperService { private WallpaperObserver mReceiver; Bitmap mBackground; - int mBackgroundWidth = -1, mBackgroundHeight = -1; + int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; + int mLastRotation = -1; float mXOffset; float mYOffset; @@ -153,10 +156,10 @@ public class ImageWallpaper extends WallpaperService { } synchronized (mLock) { - mBackgroundWidth = mBackgroundHeight = -1; + mLastSurfaceWidth = mLastSurfaceHeight = -1; mBackground = null; mRedrawNeeded = true; - drawFrameLocked(false); + drawFrameLocked(); } } } @@ -169,6 +172,9 @@ public class ImageWallpaper extends WallpaperService { public void trimMemory(int level) { if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW && mBackground != null && mIsHwAccelerated) { + if (DEBUG) { + Log.d(TAG, "trimMemory"); + } mBackground.recycle(); mBackground = null; mWallpaperManager.forgetLoadedWallpaper(); @@ -225,7 +231,7 @@ public class ImageWallpaper extends WallpaperService { @Override public void onVisibilityChanged(boolean visible) { if (DEBUG) { - Log.d(TAG, "onVisibilityChanged: visible=" + visible); + Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible); } synchronized (mLock) { @@ -234,7 +240,7 @@ public class ImageWallpaper extends WallpaperService { Log.d(TAG, "Visibility changed to visible=" + visible); } mVisible = visible; - drawFrameLocked(false); + drawFrameLocked(); } } } @@ -263,7 +269,7 @@ public class ImageWallpaper extends WallpaperService { mYOffset = yOffset; mOffsetsChanged = true; } - drawFrameLocked(false); + drawFrameLocked(); } } @@ -276,80 +282,101 @@ public class ImageWallpaper extends WallpaperService { super.onSurfaceChanged(holder, format, width, height); synchronized (mLock) { - mRedrawNeeded = true; - mBackgroundWidth = mBackgroundHeight = -1; - drawFrameLocked(true); + drawFrameLocked(); } } @Override + public void onSurfaceDestroyed(SurfaceHolder holder) { + super.onSurfaceDestroyed(holder); + mLastSurfaceWidth = mLastSurfaceHeight = -1; + } + + @Override + public void onSurfaceCreated(SurfaceHolder holder) { + super.onSurfaceCreated(holder); + mLastSurfaceWidth = mLastSurfaceHeight = -1; + } + + @Override public void onSurfaceRedrawNeeded(SurfaceHolder holder) { if (DEBUG) { - Log.d(TAG, "onSurfaceRedrawNeeded:"); + Log.d(TAG, "onSurfaceRedrawNeeded"); } super.onSurfaceRedrawNeeded(holder); synchronized (mLock) { - mRedrawNeeded = true; - drawFrameLocked(false); + drawFrameLocked(); } } - void drawFrameLocked(boolean force) { - if (!force) { - if (!mVisible) { + void drawFrameLocked() { + SurfaceHolder sh = getSurfaceHolder(); + final Rect frame = sh.getSurfaceFrame(); + final int dw = frame.width(); + final int dh = frame.height(); + int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)). + getDefaultDisplay().getRotation(); + boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth || dh != mLastSurfaceHeight; + + boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation; + if (!redrawNeeded && !mOffsetsChanged) { + if (DEBUG) { + Log.d(TAG, "Suppressed drawFrame since redraw is not needed " + + "and offsets have not changed."); + } + return; + } + mLastRotation = newRotation; + + // Load bitmap if it is not yet loaded or if it was loaded at a different size + if (mBackground == null || surfaceDimensionsChanged) { + if (DEBUG) { + Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " + + mBackground + ", " + + ((mBackground == null) ? 0 : mBackground.getWidth()) + ", " + + ((mBackground == null) ? 0 : mBackground.getHeight()) + ", " + + dw + ", " + dh); + } + updateWallpaperLocked(); + if (mBackground == null) { if (DEBUG) { - Log.d(TAG, "Suppressed drawFrame since wallpaper is not visible."); + Log.d(TAG, "Unable to load bitmap"); } return; } - if (!mRedrawNeeded && !mOffsetsChanged) { - if (DEBUG) { - Log.d(TAG, "Suppressed drawFrame since redraw is not needed " - + "and offsets have not changed."); + if (DEBUG) { + if (dw != mBackground.getWidth() || dh != mBackground.getHeight()) { + Log.d(TAG, "Surface != bitmap dimensions: surface w/h, bitmap w/h: " + + dw + ", " + dh + ", " + mBackground.getWidth() + ", " + + mBackground.getHeight()); } - return; } } - // If we don't yet know the size of the wallpaper bitmap, - // we need to get it now. - boolean updateWallpaper = mBackgroundWidth < 0 || mBackgroundHeight < 0 ; - - // If we somehow got to this point after we have last flushed - // the wallpaper, well we really need it to draw again. So - // seems like we need to reload it. Ouch. - updateWallpaper = updateWallpaper || mBackground == null; - if (updateWallpaper) { - updateWallpaperLocked(); - } - - SurfaceHolder sh = getSurfaceHolder(); - final Rect frame = sh.getSurfaceFrame(); - final int dw = frame.width(); - final int dh = frame.height(); - final int availw = dw - mBackgroundWidth; - final int availh = dh - mBackgroundHeight; + final int availw = dw - mBackground.getWidth(); + final int availh = dh - mBackground.getHeight(); int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2); int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2); mOffsetsChanged = false; - if (!force && !mRedrawNeeded - && xPixels == mLastXTranslation && yPixels == mLastYTranslation) { + mRedrawNeeded = false; + if (surfaceDimensionsChanged) { + mLastSurfaceWidth = dw; + mLastSurfaceHeight = dh; + } + mLastXTranslation = xPixels; + mLastYTranslation = yPixels; + if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) { if (DEBUG) { Log.d(TAG, "Suppressed drawFrame since the image has not " + "actually moved an integral number of pixels."); } return; } - mRedrawNeeded = false; - mLastXTranslation = xPixels; - mLastYTranslation = yPixels; if (DEBUG) { - Log.d(TAG, "drawFrameUnlocked(" + force + "): mBackgroundWxH=" + mBackgroundWidth + "x" - + mBackgroundHeight + " SurfaceFrame=" + frame.toShortString() - + " X,YOffset=" + mXOffset + "," + mYOffset); + Log.d(TAG, "Redrawing wallpaper"); } if (mIsHwAccelerated) { if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) { @@ -370,9 +397,10 @@ public class ImageWallpaper extends WallpaperService { } - void updateWallpaperLocked() { + private void updateWallpaperLocked() { Throwable exception = null; try { + mWallpaperManager.forgetLoadedWallpaper(); // force reload mBackground = mWallpaperManager.getBitmap(); } catch (RuntimeException e) { exception = e; @@ -393,9 +421,6 @@ public class ImageWallpaper extends WallpaperService { Log.w(TAG, "Unable reset to default wallpaper!", ex); } } - - mBackgroundWidth = mBackground != null ? mBackground.getWidth() : 0; - mBackgroundHeight = mBackground != null ? mBackground.getHeight() : 0; } private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int x, int y) { @@ -409,7 +434,8 @@ public class ImageWallpaper extends WallpaperService { c.translate(x, y); if (w < 0 || h < 0) { c.save(Canvas.CLIP_SAVE_FLAG); - c.clipRect(0, 0, mBackgroundWidth, mBackgroundHeight, Op.DIFFERENCE); + c.clipRect(0, 0, mBackground.getWidth(), mBackground.getHeight(), + Op.DIFFERENCE); c.drawColor(0xff000000); c.restore(); } @@ -425,11 +451,10 @@ public class ImageWallpaper extends WallpaperService { private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left, int top) { if (!initGL(sh)) return false; - final float right = left + mBackgroundWidth; - final float bottom = top + mBackgroundHeight; + final float right = left + mBackground.getWidth(); + final float bottom = top + mBackground.getHeight(); final Rect frame = sh.getSurfaceFrame(); - final Matrix4f ortho = new Matrix4f(); ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f); @@ -437,7 +462,7 @@ public class ImageWallpaper extends WallpaperService { final int texture = loadTexture(mBackground); final int program = buildProgram(sSimpleVS, sSimpleFS); - + final int attribPosition = glGetAttribLocation(program, "position"); final int attribTexCoords = glGetAttribLocation(program, "texCoords"); final int uniformTexture = glGetUniformLocation(program, "texture"); @@ -460,7 +485,7 @@ public class ImageWallpaper extends WallpaperService { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); } - + // drawQuad triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, @@ -471,12 +496,12 @@ public class ImageWallpaper extends WallpaperService { TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - + if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { throw new RuntimeException("Cannot swap buffers"); } checkEglError(); - + finishGL(); return true; diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java index 57d2ed3..9f0bcf5 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java @@ -185,6 +185,16 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener final Activity activity = (Activity) RecentsPanelView.this.getContext(); final SystemUIApplication app = (SystemUIApplication) activity.getApplication(); if (app.isWaitingForWindowAnimationStart()) { + if (mItemToAnimateInWhenWindowAnimationIsFinished != null) { + for (View v : + new View[] { holder.iconView, holder.labelView, holder.calloutLine }) { + if (v != null) { + v.setAlpha(1f); + v.setTranslationX(0f); + v.setTranslationY(0f); + } + } + } mItemToAnimateInWhenWindowAnimationIsFinished = holder; final int translation = -getResources().getDimensionPixelSize( R.dimen.status_bar_recents_app_icon_translate_distance); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index c832fb8..248a516 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -21,6 +21,8 @@ import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.util.Slog; +import android.view.MotionEvent; import android.view.View; import com.android.systemui.R; @@ -31,11 +33,18 @@ public class NotificationPanelView extends PanelView { Drawable mHandleBar; float mHandleBarHeight; View mHandleView; + int mFingers; + PhoneStatusBar mStatusBar; + boolean mOkToFlip; public NotificationPanelView(Context context, AttributeSet attrs) { super(context, attrs); } + public void setStatusBar(PhoneStatusBar bar) { + mStatusBar = bar; + } + @Override protected void onFinishInflate() { super.onFinishInflate(); @@ -79,4 +88,35 @@ public class NotificationPanelView extends PanelView { mHandleBar.draw(canvas); canvas.translate(0, -off); } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (PhoneStatusBar.SETTINGS_DRAG_SHORTCUT && mStatusBar.mHasFlipSettings) { + switch (event.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + mOkToFlip = getExpandedHeight() == 0; + break; + case MotionEvent.ACTION_POINTER_DOWN: + if (mOkToFlip) { + float miny = event.getY(0); + float maxy = miny; + for (int i=1; i<event.getPointerCount(); i++) { + final float y = event.getY(i); + if (y < miny) miny = y; + if (y > maxy) maxy = y; + } + if (maxy - miny < mHandleBarHeight) { + if (getMeasuredHeight() < mHandleBarHeight) { + mStatusBar.switchToSettings(); + } else { + mStatusBar.flipToSettings(); + } + mOkToFlip = false; + } + } + break; + } + } + return mHandleView.dispatchTouchEvent(event); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index d0fc340..c9a137c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -102,7 +102,7 @@ public class PanelBar extends FrameLayout { startOpeningPanel(panel); } final boolean result = mTouchingPanel != null - ? mTouchingPanel.getHandle().dispatchTouchEvent(event) + ? mTouchingPanel.onTouchEvent(event) : true; return result; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index 7eb84e1..6184e30 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -98,7 +98,7 @@ public class PanelView extends FrameLayout { if (mPeekAnimator == null) { mPeekAnimator = ObjectAnimator.ofFloat(this, "expandedHeight", mPeekHeight) - .setDuration(300); + .setDuration(250); } mPeekAnimator.start(); } @@ -206,7 +206,7 @@ public class PanelView extends FrameLayout { mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity); - mPeekHeight = res.getDimension(R.dimen.close_handle_height) + mPeekHeight = res.getDimension(R.dimen.peek_height) + getPaddingBottom() // our window might have a dropshadow - (mHandleView == null ? 0 : mHandleView.getPaddingTop()); // the handle might have a topshadow } @@ -250,6 +250,7 @@ public class PanelView extends FrameLayout { case MotionEvent.ACTION_DOWN: mTracking = true; mHandleView.setPressed(true); + postInvalidate(); // catch the press state change mInitialTouchY = y; mVelocityTracker = VelocityTracker.obtain(); trackMovement(event); @@ -283,6 +284,7 @@ public class PanelView extends FrameLayout { mFinalTouchY = y; mTracking = false; mHandleView.setPressed(false); + postInvalidate(); // catch the press state change mBar.onTrackingStopped(PanelView.this); trackMovement(event); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 75a2598..1c4dff8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -20,6 +20,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; +import android.animation.TimeInterpolator; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.Notification; @@ -61,6 +62,7 @@ import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; +import android.view.ViewPropertyAnimator; import android.view.ViewStub; import android.view.WindowManager; import android.view.animation.AccelerateInterpolator; @@ -108,6 +110,8 @@ public class PhoneStatusBar extends BaseStatusBar { public static final boolean ENABLE_NOTIFICATION_PANEL_CLING = false; + public static final boolean SETTINGS_DRAG_SHORTCUT = true; + // additional instrumentation for testing purposes; intended to be left on during development public static final boolean CHATTY = DEBUG; @@ -178,7 +182,7 @@ public class PhoneStatusBar extends BaseStatusBar { View mMoreIcon; // expanded notifications - PanelView mNotificationPanel; // the sliding/resizing panel within the notification window + NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window ScrollView mScrollView; View mExpandedContents; int mNotificationPanelGravity; @@ -188,13 +192,18 @@ public class PhoneStatusBar extends BaseStatusBar { TextView mNotificationPanelDebugText; // settings - boolean mHasSettingsPanel; + QuickSettings mQS; + boolean mHasSettingsPanel, mHasFlipSettings; SettingsPanelView mSettingsPanel; + View mFlipSettingsView; + QuickSettingsContainerView mSettingsContainer; int mSettingsPanelGravity; // top bar + View mNotificationPanelHeader; + View mDateTimeView; View mClearButton; - ImageView mSettingsButton; + ImageView mSettingsButton, mNotificationButton; // carrier/wifi label private TextView mCarrierLabel; @@ -290,8 +299,12 @@ public class PhoneStatusBar extends BaseStatusBar { if (MULTIUSER_DEBUG) Slog.d(TAG, String.format("User setup changed: " + "selfChange=%s userSetup=%s mUserSetup=%s", selfChange, userSetup, mUserSetup)); - if (mSettingsPanel != null) + if (mSettingsButton != null && !mHasSettingsPanel) { + mSettingsButton.setVisibility(userSetup ? View.VISIBLE : View.INVISIBLE); + } + if (mSettingsPanel != null) { mSettingsPanel.setEnabled(userSetup); + } if (userSetup != mUserSetup) { mUserSetup = userSetup; if (!mUserSetup && mStatusBarView != null) @@ -352,13 +365,10 @@ public class PhoneStatusBar extends BaseStatusBar { PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder); mStatusBarView.setPanelHolder(holder); - mNotificationPanel = (PanelView) mStatusBarWindow.findViewById(R.id.notification_panel); + mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(R.id.notification_panel); + mNotificationPanel.setStatusBar(this); mNotificationPanelIsFullScreenWidth = (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT); - mNotificationPanel.setSystemUiVisibility( - View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | - View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS | - View.STATUS_BAR_DISABLE_CLOCK); // make the header non-responsive to clicks mNotificationPanel.findViewById(R.id.header).setOnTouchListener( @@ -415,6 +425,8 @@ public class PhoneStatusBar extends BaseStatusBar { mPile.setLongPressListener(getNotificationLongClicker()); mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout); + mNotificationPanelHeader = mStatusBarWindow.findViewById(R.id.header); + mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button); mClearButton.setOnClickListener(mClearButtonListener); mClearButton.setAlpha(0f); @@ -423,6 +435,13 @@ public class PhoneStatusBar extends BaseStatusBar { mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date); mHasSettingsPanel = res.getBoolean(R.bool.config_hasSettingsPanel); + mHasFlipSettings = res.getBoolean(R.bool.config_hasFlipSettingsPanel); + + mDateTimeView = mNotificationPanelHeader.findViewById(R.id.datetime); + if (mHasFlipSettings) { + mDateTimeView.setOnClickListener(mClockClickListener); + mDateTimeView.setEnabled(true); + } mSettingsButton = (ImageView) mStatusBarWindow.findViewById(R.id.settings_button); if (mSettingsButton != null) { @@ -442,9 +461,21 @@ public class PhoneStatusBar extends BaseStatusBar { mSettingsButton.setImageResource(R.drawable.ic_notify_settings); } } - + if (mHasFlipSettings) { + mNotificationButton = (ImageView) mStatusBarWindow.findViewById(R.id.notification_button); + if (mNotificationButton != null) { + mNotificationButton.setOnClickListener(mNotificationButtonListener); + } + } + mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll); mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns + if (!mNotificationPanelIsFullScreenWidth) { + mScrollView.setSystemUiVisibility( + View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | + View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS | + View.STATUS_BAR_DISABLE_CLOCK); + } mTicker = new MyTicker(context, mStatusBarView); @@ -472,6 +503,8 @@ public class PhoneStatusBar extends BaseStatusBar { mEmergencyCallLabel = (TextView)mStatusBarWindow.findViewById(R.id.emergency_calls_only); if (mEmergencyCallLabel != null) { mNetworkController.addEmergencyLabelView(mEmergencyCallLabel); + mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { }}); mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, @@ -505,28 +538,52 @@ public class PhoneStatusBar extends BaseStatusBar { // Quick Settings (where available, some restrictions apply) if (mHasSettingsPanel) { - final View settings_stub - = mStatusBarWindow.findViewById(R.id.quick_settings_stub); - - if (settings_stub != null) { - mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate(); + // first, figure out where quick settings should be inflated + final View settings_stub; + if (mHasFlipSettings) { + // a version of quick settings that flips around behind the notifications + settings_stub = mStatusBarWindow.findViewById(R.id.flip_settings_stub); + if (settings_stub != null) { + mFlipSettingsView = ((ViewStub)settings_stub).inflate(); + mFlipSettingsView.setVisibility(View.GONE); + mFlipSettingsView.setVerticalScrollBarEnabled(false); + } } else { - mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel); + // full quick settings panel + settings_stub = mStatusBarWindow.findViewById(R.id.quick_settings_stub); + if (settings_stub != null) { + mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate(); + } else { + mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel); + } + + if (mSettingsPanel != null) { + if (!ActivityManager.isHighEndGfx()) { + mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor( + R.color.notification_panel_solid_background))); + } + } } - if (mSettingsPanel != null) { - mSettingsPanel.setBar(mStatusBarView); - mSettingsPanel.setService(this); - mSettingsPanel.setup(mNetworkController, mBluetoothController, mBatteryController, - mLocationController); - mSettingsPanel.setSystemUiVisibility( - View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER - | View.STATUS_BAR_DISABLE_SYSTEM_INFO); - - if (!ActivityManager.isHighEndGfx()) { - mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor( - R.color.notification_panel_solid_background))); + // wherever you find it, Quick Settings needs a container to survive + mSettingsContainer = (QuickSettingsContainerView) + mStatusBarWindow.findViewById(R.id.quick_settings_container); + if (mSettingsContainer != null) { + mQS = new QuickSettings(mContext, mSettingsContainer); + if (!mNotificationPanelIsFullScreenWidth) { + mSettingsContainer.setSystemUiVisibility( + View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER + | View.STATUS_BAR_DISABLE_SYSTEM_INFO); + } + if (mSettingsPanel != null) { + mSettingsPanel.setQuickSettings(mQS); } + mQS.setService(this); + mQS.setBar(mStatusBarView); + mQS.setup(mNetworkController, mBluetoothController, mBatteryController, + mLocationController); + } else { + mQS = null; // fly away, be free } } @@ -984,7 +1041,8 @@ public class PhoneStatusBar extends BaseStatusBar { final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null; final boolean makeVisible = !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly()) - && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight); + && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight) + && mScrollView.getVisibility() == View.VISIBLE; if (force || mCarrierLabelVisible != makeVisible) { mCarrierLabelVisible = makeVisible; @@ -1024,7 +1082,13 @@ public class PhoneStatusBar extends BaseStatusBar { + " any=" + any + " clearable=" + clearable); } - if (mClearButton.isShown()) { + if (mHasFlipSettings + && mFlipSettingsView != null + && mFlipSettingsView.getVisibility() == View.VISIBLE + && mScrollView.getVisibility() != View.VISIBLE) { + // the flip settings panel is unequivocally showing; we should not be shown + mClearButton.setVisibility(View.INVISIBLE); + } else if (mClearButton.isShown()) { if (clearable != (mClearButton.getAlpha() == 1.0f)) { ObjectAnimator clearAnimation = ObjectAnimator.ofFloat( mClearButton, "alpha", clearable ? 1.0f : 0.0f).setDuration(250); @@ -1225,6 +1289,10 @@ public class PhoneStatusBar extends BaseStatusBar { } } + public Handler getHandler() { + return mHandler; + } + View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { // Because 'v' is a ViewGroup, all its children will be (un)selected @@ -1293,6 +1361,53 @@ public class PhoneStatusBar extends BaseStatusBar { mStatusBarView.collapseAllPanels(true); } + public ViewPropertyAnimator setVisibilityWhenDone( + final ViewPropertyAnimator a, final View v, final int vis) { + a.setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + v.setVisibility(vis); + a.setListener(null); // oneshot + } + }); + return a; + } + + public Animator setVisibilityWhenDone( + final Animator a, final View v, final int vis) { + a.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + v.setVisibility(vis); + } + }); + return a; + } + + public Animator interpolator(TimeInterpolator ti, Animator a) { + a.setInterpolator(ti); + return a; + } + + public Animator startDelay(int d, Animator a) { + a.setStartDelay(d); + return a; + } + + public Animator start(Animator a) { + a.start(); + return a; + } + + final TimeInterpolator mAccelerateInterpolator = new AccelerateInterpolator(); + final TimeInterpolator mDecelerateInterpolator = new DecelerateInterpolator(); + final int FLIP_DURATION_OUT = 125; + final int FLIP_DURATION_IN = 225; + final int FLIP_DURATION = (FLIP_DURATION_IN + FLIP_DURATION_OUT); + + Animator mScrollViewAnim, mFlipSettingsViewAnim, mNotificationButtonAnim, + mSettingsButtonAnim, mClearButtonAnim; + @Override public void animateExpandNotificationsPanel() { if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible); @@ -1301,10 +1416,53 @@ public class PhoneStatusBar extends BaseStatusBar { } mNotificationPanel.expand(); + if (mHasFlipSettings && mScrollView.getVisibility() != View.VISIBLE) { + flipToNotifications(); + } if (false) postStartTracing(); } + public void flipToNotifications() { + if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel(); + if (mScrollViewAnim != null) mScrollViewAnim.cancel(); + if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel(); + if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel(); + if (mClearButtonAnim != null) mClearButtonAnim.cancel(); + + mScrollView.setVisibility(View.VISIBLE); + mScrollViewAnim = start( + startDelay(FLIP_DURATION_OUT, + interpolator(mDecelerateInterpolator, + ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f, 1f) + .setDuration(FLIP_DURATION_IN) + ))); + mFlipSettingsViewAnim = start( + setVisibilityWhenDone( + interpolator(mAccelerateInterpolator, + ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f, 0f) + ) + .setDuration(FLIP_DURATION_OUT), + mFlipSettingsView, View.INVISIBLE)); + mNotificationButtonAnim = start( + setVisibilityWhenDone( + ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f) + .setDuration(FLIP_DURATION), + mNotificationButton, View.INVISIBLE)); + mSettingsButton.setVisibility(View.VISIBLE); + mSettingsButtonAnim = start( + ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f) + .setDuration(FLIP_DURATION)); + mClearButton.setVisibility(View.VISIBLE); + mClearButton.setAlpha(0f); + setAreThereNotifications(); // this will show/hide the button as necessary + mNotificationPanel.postDelayed(new Runnable() { + public void run() { + updateCarrierLabelVisibility(false); + } + }, FLIP_DURATION - 150); + } + @Override public void animateExpandSettingsPanel() { if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible); @@ -1312,15 +1470,90 @@ public class PhoneStatusBar extends BaseStatusBar { return; } - if (mSettingsPanel != null) mSettingsPanel.expand(); + if (mHasFlipSettings) { + mNotificationPanel.expand(); + if (mFlipSettingsView.getVisibility() != View.VISIBLE) { + flipToSettings(); + } + } else if (mSettingsPanel != null) { + mSettingsPanel.expand(); + } if (false) postStartTracing(); } + public void switchToSettings() { + mFlipSettingsView.setScaleX(1f); + mFlipSettingsView.setVisibility(View.VISIBLE); + mSettingsButton.setVisibility(View.GONE); + mScrollView.setVisibility(View.GONE); + mScrollView.setScaleX(0f); + mNotificationButton.setVisibility(View.VISIBLE); + mNotificationButton.setAlpha(1f); + mClearButton.setVisibility(View.GONE); + } + + public void flipToSettings() { + if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel(); + if (mScrollViewAnim != null) mScrollViewAnim.cancel(); + if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel(); + if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel(); + if (mClearButtonAnim != null) mClearButtonAnim.cancel(); + + mFlipSettingsView.setVisibility(View.VISIBLE); + mFlipSettingsView.setScaleX(0f); + mFlipSettingsViewAnim = start( + startDelay(FLIP_DURATION_OUT, + interpolator(mDecelerateInterpolator, + ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f, 1f) + .setDuration(FLIP_DURATION_IN) + ))); + mScrollViewAnim = start( + setVisibilityWhenDone( + interpolator(mAccelerateInterpolator, + ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f) + ) + .setDuration(FLIP_DURATION_OUT), + mScrollView, View.INVISIBLE)); + mSettingsButtonAnim = start( + setVisibilityWhenDone( + ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f) + .setDuration(FLIP_DURATION), + mScrollView, View.INVISIBLE)); + mNotificationButton.setVisibility(View.VISIBLE); + mNotificationButtonAnim = start( + ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f) + .setDuration(FLIP_DURATION)); + mClearButtonAnim = start( + setVisibilityWhenDone( + ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f) + .setDuration(FLIP_DURATION), + mClearButton, View.INVISIBLE)); + mNotificationPanel.postDelayed(new Runnable() { + public void run() { + updateCarrierLabelVisibility(false); + } + }, FLIP_DURATION - 150); + } + + public void flipPanels() { + if (mHasFlipSettings) { + if (mFlipSettingsView.getVisibility() != View.VISIBLE) { + flipToSettings(); + } else { + flipToNotifications(); + } + } + } + public void animateCollapseQuickSettings() { mStatusBarView.collapseAllPanels(true); } + void makeExpandedInvisibleSoon() { + mHandler.postDelayed(new Runnable() { public void run() { makeExpandedInvisible(); }}, 50); + } + void makeExpandedInvisible() { if (SPEW) Slog.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible + " mExpandedVisible=" + mExpandedVisible); @@ -1332,6 +1565,18 @@ public class PhoneStatusBar extends BaseStatusBar { // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868) mStatusBarView.collapseAllPanels(/*animate=*/ false); + if (mHasFlipSettings) { + // reset things to their proper state + mScrollView.setScaleX(1f); + mScrollView.setVisibility(View.VISIBLE); + mSettingsButton.setAlpha(1f); + mSettingsButton.setVisibility(View.VISIBLE); + mNotificationPanel.setVisibility(View.GONE); + mFlipSettingsView.setVisibility(View.GONE); + mNotificationButton.setVisibility(View.GONE); + setAreThereNotifications(); // show the clear button + } + mExpandedVisible = false; mPile.setLayoutTransitionsEnabled(false); if (mNavigationBarView != null) @@ -1622,7 +1867,7 @@ public class PhoneStatusBar extends BaseStatusBar { mCommandQueue.setNavigationIconHints( altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT) : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT)); - if (mSettingsPanel != null) mSettingsPanel.setImeWindowStatus(vis > 0); + if (mQS != null) mQS.setImeWindowStatus(vis > 0); } @Override @@ -1942,24 +2187,42 @@ public class PhoneStatusBar extends BaseStatusBar { } }; + public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) { + if (onlyProvisioned && !isDeviceProvisioned()) return; + try { + // Dismiss the lock screen when Settings starts. + ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); + } catch (RemoteException e) { + } + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); + animateCollapsePanels(); + } + private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() { public void onClick(View v) { if (mHasSettingsPanel) { animateExpandSettingsPanel(); } else { - try { - // Dismiss the lock screen when Settings starts. - ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); - } catch (RemoteException e) { - } - Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); - animateCollapsePanels(); + startActivityDismissingKeyguard( + new Intent(android.provider.Settings.ACTION_SETTINGS), true); } } }; + private View.OnClickListener mClockClickListener = new View.OnClickListener() { + public void onClick(View v) { + startActivityDismissingKeyguard( + new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone + } + }; + + private View.OnClickListener mNotificationButtonListener = new View.OnClickListener() { + public void onClick(View v) { + animateExpandNotificationsPanel(); + } + }; + private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { Slog.v(TAG, "onReceive: " + intent); @@ -2050,7 +2313,7 @@ public class PhoneStatusBar extends BaseStatusBar { } // Update the QuickSettings container - if (mSettingsPanel != null) mSettingsPanel.updateResources(); + if (mQS != null) mQS.updateResources(); loadDimens(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 3c2f0e6..af6a149 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -154,7 +154,8 @@ public class PhoneStatusBarView extends PanelBar { @Override public void onAllPanelsCollapsed() { super.onAllPanelsCollapsed(); - mBar.makeExpandedInvisible(); + // give animations time to settle + mBar.makeExpandedInvisibleSoon(); mFadingPanel = null; mLastFullyOpenedPanel = null; } @@ -191,14 +192,34 @@ public class PhoneStatusBarView extends PanelBar { if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx()) { if (mShouldFade) { frac = mPanelExpandedFractionSum; // don't judge me - // woo, special effects - final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2.2f)))); - // attenuate background color alpha by k - final int color = (int) ((mScrimColor >>> 24) * k) << 24 | (mScrimColor & 0xFFFFFF); - mBar.mStatusBarWindow.setBackgroundColor(color); + // let's start this 20% of the way down the screen + frac = frac * 1.2f - 0.2f; + if (frac <= 0) { + mBar.mStatusBarWindow.setBackgroundColor(0); + } else { + // woo, special effects + final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f)))); + // attenuate background color alpha by k + final int color = (int) ((mScrimColor >>> 24) * k) << 24 | (mScrimColor & 0xFFFFFF); + mBar.mStatusBarWindow.setBackgroundColor(color); + } } } + // fade out the panel as it gets buried into the status bar to avoid overdrawing the + // status bar on the last frame of a close animation + final int H = mBar.getStatusBarHeight(); + final float ph = panel.getExpandedHeight() + panel.getPaddingBottom(); + float alpha = 1f; + if (ph < 2*H) { + if (ph < H) alpha = 0f; + else alpha = (ph - H) / H; + alpha = alpha * alpha; // get there faster + } + if (panel.getAlpha() != alpha) { + panel.setAlpha(alpha); + } + mBar.updateCarrierLabelVisibility(false); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java index faf20e2..58e3a57 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java @@ -88,7 +88,7 @@ class QuickSettings { private Context mContext; private PanelBar mBar; private QuickSettingsModel mModel; - private QuickSettingsContainerView mContainerView; + private ViewGroup mContainerView; private DisplayManager mDisplayManager; private WifiDisplayStatus mWifiDisplayStatus; @@ -145,6 +145,7 @@ class QuickSettings { IntentFilter filter = new IntentFilter(); filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED); filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); + filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); filter.addAction(Intent.ACTION_USER_SWITCHED); mContext.registerReceiver(mReceiver, filter); @@ -321,7 +322,31 @@ class QuickSettings { parent.addView(userTile); mDynamicSpannedTiles.add(userTile); + // Brightness + QuickSettingsTileView brightnessTile = (QuickSettingsTileView) + inflater.inflate(R.layout.quick_settings_tile, parent, false); + brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater); + brightnessTile.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mBar.collapseAllPanels(true); + showBrightnessDialog(); + } + }); + mModel.addBrightnessTile(brightnessTile, new QuickSettingsModel.RefreshCallback() { + @Override + public void refreshView(QuickSettingsTileView view, State state) { + TextView tv = (TextView) view.findViewById(R.id.brightness_textview); + tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0); + tv.setText(state.label); + dismissBrightnessDialog(mBrightnessDialogShortTimeout); + } + }); + parent.addView(brightnessTile); + mDynamicSpannedTiles.add(brightnessTile); + // Time tile + /* QuickSettingsTileView timeTile = (QuickSettingsTileView) inflater.inflate(R.layout.quick_settings_tile, parent, false); timeTile.setContent(R.layout.quick_settings_tile_time, inflater); @@ -338,6 +363,7 @@ class QuickSettings { }); parent.addView(timeTile); mDynamicSpannedTiles.add(timeTile); + */ // Settings tile QuickSettingsTileView settingsTile = (QuickSettingsTileView) @@ -549,27 +575,6 @@ class QuickSettings { parent.addView(bluetoothTile); } - // Brightness - QuickSettingsTileView brightnessTile = (QuickSettingsTileView) - inflater.inflate(R.layout.quick_settings_tile, parent, false); - brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater); - brightnessTile.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mBar.collapseAllPanels(true); - showBrightnessDialog(); - } - }); - mModel.addBrightnessTile(brightnessTile, new QuickSettingsModel.RefreshCallback() { - @Override - public void refreshView(QuickSettingsTileView view, State state) { - TextView tv = (TextView) view.findViewById(R.id.brightness_textview); - tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0); - tv.setText(state.label); - dismissBrightnessDialog(mBrightnessDialogShortTimeout); - } - }); - parent.addView(brightnessTile); } private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) { @@ -717,6 +722,7 @@ class QuickSettings { for (QuickSettingsTileView v : mDynamicSpannedTiles) { v.setColumnSpan(span); } + ((QuickSettingsContainerView)mContainerView).updateResources(); mContainerView.requestLayout(); // Reset the dialog @@ -849,6 +855,11 @@ class QuickSettings { DisplayManager.EXTRA_WIFI_DISPLAY_STATUS); mWifiDisplayStatus = status; applyWifiDisplayStatus(); + } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { + int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, + BluetoothAdapter.ERROR); + mBluetoothState.enabled = (state == BluetoothAdapter.STATE_ON); + applyBluetoothStatus(); } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { int status = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java index 4e10fa3..a58eb22 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java @@ -53,7 +53,6 @@ public class SettingsPanelView extends PanelView { super.onFinishInflate(); mQSContainer = (QuickSettingsContainerView) findViewById(R.id.quick_settings_container); - mQS = new QuickSettings(getContext(), mQSContainer); Resources resources = getContext().getResources(); mHandleBar = resources.getDrawable(R.drawable.status_bar_close); @@ -62,6 +61,10 @@ public class SettingsPanelView extends PanelView { setContentDescription(resources.getString(R.string.accessibility_desc_quick_settings)); } + + public void setQuickSettings(QuickSettings qs) { + mQS = qs; + } @Override public void setBar(PanelBar panelBar) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 0176f42..89c70e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -42,6 +42,7 @@ public class StatusBarWindowView extends FrameLayout private ExpandHelper mExpandHelper; private NotificationRowLayout latestItems; private NotificationPanelView mNotificationPanel; + private ScrollView mScrollView; PhoneStatusBar mService; @@ -55,13 +56,13 @@ public class StatusBarWindowView extends FrameLayout protected void onAttachedToWindow () { super.onAttachedToWindow(); latestItems = (NotificationRowLayout) findViewById(R.id.latestItems); - ScrollView scroller = (ScrollView) findViewById(R.id.scroll); + mScrollView = (ScrollView) findViewById(R.id.scroll); mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel); int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height); int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height); mExpandHelper = new ExpandHelper(mContext, latestItems, minHeight, maxHeight); mExpandHelper.setEventSource(this); - mExpandHelper.setScrollView(scroller); + mExpandHelper.setScrollView(mScrollView); } @Override @@ -80,7 +81,7 @@ public class StatusBarWindowView extends FrameLayout @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean intercept = false; - if (mNotificationPanel.isFullyExpanded()) { + if (mNotificationPanel.isFullyExpanded() && mScrollView.getVisibility() == View.VISIBLE) { intercept = mExpandHelper.onInterceptTouchEvent(ev); } if (!intercept) { diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java index 9ea47f9..c215f1b 100644 --- a/policy/src/com/android/internal/policy/impl/GlobalActions.java +++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java @@ -290,7 +290,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac } }); AlertDialog dialog = builder.create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); + dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); dialog.show(); } @@ -339,7 +339,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac return mAdapter.getItem(position).onLongPress(); } }); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); + dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); dialog.setOnDismissListener(this); @@ -390,11 +390,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac refreshSilentMode(); mAirplaneModeOn.updateState(mAirplaneState); mAdapter.notifyDataSetChanged(); - if (mKeyguardShowing) { - mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); - } else { - mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); - } + mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); if (SHOW_SILENT_TOGGLE) { IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); mContext.registerReceiver(mRingerModeReceiver, filter); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 72cb1dd..41d67bc 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -2867,8 +2867,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { mDecor = generateDecor(); mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); mDecor.setIsRootNamespace(true); - mDecor.setLayoutDirection( - getContext().getResources().getConfiguration().getLayoutDirection()); if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) { mDecor.postOnAnimation(mInvalidatePanelMenuRunnable); } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index e8af0a5..24ce9bc 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -299,6 +299,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mCarDockRotation; int mDeskDockRotation; int mHdmiRotation; + boolean mHdmiRotationLock; int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE; int mUserRotation = Surface.ROTATION_0; @@ -1035,11 +1036,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { mCanHideNavigationBar = false; } + // For demo purposes, allow the rotation of the HDMI display to be controlled. + // By default, HDMI locks rotation to landscape. if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) { mHdmiRotation = mPortraitRotation; } else { mHdmiRotation = mLandscapeRotation; } + mHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", true); } public void updateSettings() { @@ -1473,16 +1477,24 @@ public class PhoneWindowManager implements WindowManagerPolicy { return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation); } + @Override public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) { return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD; } + @Override public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) { - return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR - && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR - && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER - && attrs.type != WindowManager.LayoutParams.TYPE_DREAM - && attrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND; + switch (attrs.type) { + case TYPE_STATUS_BAR: + case TYPE_NAVIGATION_BAR: + case TYPE_WALLPAPER: + case TYPE_DREAM: + case TYPE_UNIVERSE_BACKGROUND: + case TYPE_KEYGUARD: + return false; + default: + return true; + } } /** {@inheritDoc} */ @@ -3865,7 +3877,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // enable 180 degree rotation while docked. preferredRotation = mDeskDockEnablesAccelerometer ? sensorRotation : mDeskDockRotation; - } else if (mHdmiPlugged) { + } else if (mHdmiPlugged && mHdmiRotationLock) { // Ignore sensor when plugged into HDMI. // Note that the dock orientation overrides the HDMI orientation. preferredRotation = mHdmiRotation; @@ -4530,5 +4542,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { pw.print(" mSeascapeRotation="); pw.println(mSeascapeRotation); pw.print(prefix); pw.print("mPortraitRotation="); pw.print(mPortraitRotation); pw.print(" mUpsideDownRotation="); pw.println(mUpsideDownRotation); + pw.print(prefix); pw.print("mHdmiRotation="); pw.print(mHdmiRotation); + pw.print(" mHdmiRotationLock="); pw.println(mHdmiRotationLock); } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java index 78fdda3..04ab871 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java @@ -75,7 +75,7 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu public void onDetachedFromWindow() { if (DEBUG) Log.d(TAG, "onDetachedFromWindow()"); if (mBiometricUnlock != null) { - mBiometricUnlock.stopAndShowBackup(); + mBiometricUnlock.stop(); } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index ebc54b3..b86e5b8 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -611,6 +611,7 @@ public class KeyguardHostView extends KeyguardViewBase { int layoutId = getLayoutIdFor(securityMode); if (view == null && layoutId != 0) { final LayoutInflater inflater = LayoutInflater.from(mContext); + if (DEBUG) Log.v(TAG, "inflating id = " + layoutId); View v = inflater.inflate(layoutId, this, false); mSecurityViewContainer.addView(v); updateSecurityView(v); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java index 0ad2404..b66c883 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java @@ -43,7 +43,7 @@ import com.android.internal.widget.LockPatternUtils; /** * Manages creating, showing, hiding and resetting the keyguard. Calls back - * via {@link com.android.internal.policy.impl.KeyguardViewCallback} to poke + * via {@link KeyguardViewMediator.ViewMediatorCallback} to poke * the wake lock and report that the keyguard is done, which is in turn, * reported to this class by the current {@link KeyguardViewBase}. */ @@ -233,6 +233,7 @@ public class KeyguardViewManager { if (mScreenOn) { mKeyguardView.show(); + mKeyguardView.requestFocus(); } } @@ -314,22 +315,25 @@ public class KeyguardViewManager { // Caller should wait for this window to be shown before turning // on the screen. - if (mKeyguardHost.getVisibility() == View.VISIBLE) { - // Keyguard may be in the process of being shown, but not yet - // updated with the window manager... give it a chance to do so. - mKeyguardHost.post(new Runnable() { - public void run() { - if (mKeyguardHost.getVisibility() == View.VISIBLE) { - showListener.onShown(mKeyguardHost.getWindowToken()); - } else { - showListener.onShown(null); + if (showListener != null) { + if (mKeyguardHost.getVisibility() == View.VISIBLE) { + // Keyguard may be in the process of being shown, but not yet + // updated with the window manager... give it a chance to do so. + mKeyguardHost.post(new Runnable() { + @Override + public void run() { + if (mKeyguardHost.getVisibility() == View.VISIBLE) { + showListener.onShown(mKeyguardHost.getWindowToken()); + } else { + showListener.onShown(null); + } } - } - }); - } else { - showListener.onShown(null); + }); + } else { + showListener.onShown(null); + } } - } else { + } else if (showListener != null) { showListener.onShown(null); } } @@ -356,10 +360,9 @@ public class KeyguardViewManager { if (mKeyguardView != null) { mKeyguardView.wakeWhenReadyTq(keyCode); return true; - } else { - Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq"); - return false; } + Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq"); + return false; } /** @@ -382,6 +385,7 @@ public class KeyguardViewManager { final KeyguardViewBase lastView = mKeyguardView; mKeyguardView = null; mKeyguardHost.postDelayed(new Runnable() { + @Override public void run() { synchronized (KeyguardViewManager.this) { lastView.cleanUp(); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java index 92f9dfd..ceb0325 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java @@ -629,9 +629,7 @@ public class KeyguardViewMediator { mScreenOn = true; cancelDoKeyguardLaterLocked(); if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence); - if (showListener != null) { - notifyScreenOnLocked(showListener); - } + notifyScreenOnLocked(showListener); } maybeSendUserPresentBroadcast(); } @@ -1365,7 +1363,7 @@ public class KeyguardViewMediator { /** * Handle message sent by {@link #verifyUnlock} - * @see #RESET + * @see #VERIFY_UNLOCK */ private void handleVerifyUnlock() { synchronized (KeyguardViewMediator.this) { diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index e7e4f87..06d37dc 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -98,21 +98,19 @@ class AppWidgetService extends IAppWidgetService.Stub IntentFilter userFilter = new IntentFilter(); userFilter.addAction(Intent.ACTION_USER_REMOVED); + userFilter.addAction(Intent.ACTION_USER_STOPPING); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)); + if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { + onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); + } else if (Intent.ACTION_USER_STOPPING.equals(intent.getAction())) { + onUserStopping(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); + } } }, userFilter); - - IntentFilter userStopFilter = new IntentFilter(); - userStopFilter.addAction(Intent.ACTION_USER_STOPPED); - mContext.registerReceiverAsUser(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - onUserStopped(getSendingUserId()); - } - }, UserHandle.ALL, userFilter, null, null); } /** @@ -203,7 +201,7 @@ class AppWidgetService extends IAppWidgetService.Stub synchronized (mAppWidgetServices) { AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); mAppWidgetServices.remove(userId); - + if (impl == null) { AppWidgetServiceImpl.getSettingsFile(userId).delete(); } else { @@ -212,7 +210,15 @@ class AppWidgetService extends IAppWidgetService.Stub } } - public void onUserStopped(int userId) { + public void onUserStopping(int userId) { + if (userId < 1) return; + synchronized (mAppWidgetServices) { + AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); + if (impl != null) { + mAppWidgetServices.remove(userId); + impl.onUserStopping(); + } + } } private AppWidgetServiceImpl getImplForUser(int userId) { @@ -324,11 +330,11 @@ class AppWidgetService extends IAppWidgetService.Stub String action = intent.getAction(); // Slog.d(TAG, "received " + action); if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { - int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); + int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); if (userId >= 0) { getImplForUser(userId).sendInitialBroadcasts(); } else { - Slog.w(TAG, "Not user handle supplied in " + intent); + Slog.w(TAG, "Incorrect user handle supplied in " + intent); } } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { for (int i = 0; i < mAppWidgetServices.size(); i++) { diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index 9fea6f3..6a313a0 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -1778,13 +1778,16 @@ class AppWidgetServiceImpl { return new AtomicFile(settingsFile); } - void onUserRemoved() { + void onUserStopping() { // prune the ones we don't want to keep int N = mInstalledProviders.size(); for (int i = N - 1; i >= 0; i--) { Provider p = mInstalledProviders.get(i); cancelBroadcasts(p); } + } + + void onUserRemoved() { getSettingsFile(mUserId).delete(); } diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 9f01eca..f241c80 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -1474,6 +1474,7 @@ class BackupManagerService extends IBackupManager.Stub { if (MORE_DEBUG) Slog.v(TAG, " removing participant " + packageName); removeEverBackedUp(packageName); set.remove(packageName); + mPendingBackups.remove(packageName); } } @@ -1625,6 +1626,7 @@ class BackupManagerService extends IBackupManager.Stub { } catch (InterruptedException e) { // just bail if (DEBUG) Slog.w(TAG, "Interrupted: " + e); + mActivityManager.clearPendingBackup(); return null; } } @@ -1632,6 +1634,7 @@ class BackupManagerService extends IBackupManager.Stub { // if we timed out with no connect, abort and move on if (mConnecting == true) { Slog.w(TAG, "Timeout waiting for agent " + app); + mActivityManager.clearPendingBackup(); return null; } if (DEBUG) Slog.i(TAG, "got agent " + mConnectedAgent); diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags index 840e006..0fe66fc 100644 --- a/services/java/com/android/server/EventLogTags.logtags +++ b/services/java/com/android/server/EventLogTags.logtags @@ -52,12 +52,12 @@ option java_package com.android.server # NotificationManagerService.java # --------------------------- # when a NotificationManager.notify is called -2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(notification|3) +2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3) # when someone tries to cancel a notification, the notification manager sometimes # calls this with flags too -2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(required_flags|1),(forbidden_flags|1) +2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1) # when someone tries to cancel all of the notifications for a particular package -2752 notification_cancel_all (pkg|3),(required_flags|1),(forbidden_flags|1) +2752 notification_cancel_all (pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1) # --------------------------- diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 6948927..37dee19 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -23,8 +23,11 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; +import android.content.pm.Signature; import android.content.res.Resources; import android.database.ContentObserver; import android.location.Address; @@ -90,10 +93,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run private static final String WAKELOCK_KEY = TAG; private static final String THREAD_NAME = TAG; - private static final String ACCESS_FINE_LOCATION = - android.Manifest.permission.ACCESS_FINE_LOCATION; - private static final String ACCESS_COARSE_LOCATION = - android.Manifest.permission.ACCESS_COARSE_LOCATION; + // Location resolution level: no location data whatsoever + private static final int RESOLUTION_LEVEL_NONE = 0; + // Location resolution level: coarse location data only + private static final int RESOLUTION_LEVEL_COARSE = 1; + // Location resolution level: fine location data + private static final int RESOLUTION_LEVEL_FINE = 2; + private static final String ACCESS_MOCK_LOCATION = android.Manifest.permission.ACCESS_MOCK_LOCATION; private static final String ACCESS_LOCATION_EXTRA_COMMANDS = @@ -246,6 +252,74 @@ public class LocationManagerService extends ILocationManager.Stub implements Run updateProvidersLocked(); } + private void ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs) { + PackageManager pm = mContext.getPackageManager(); + String systemPackageName = mContext.getPackageName(); + ArrayList<HashSet<Signature>> sigSets = ServiceWatcher.getSignatureSets(mContext, pkgs); + + List<ResolveInfo> rInfos = pm.queryIntentServicesAsUser( + new Intent(FUSED_LOCATION_SERVICE_ACTION), + PackageManager.GET_META_DATA, mCurrentUserId); + for (ResolveInfo rInfo : rInfos) { + String packageName = rInfo.serviceInfo.packageName; + + // Check that the signature is in the list of supported sigs. If it's not in + // this list the standard provider binding logic won't bind to it. + try { + PackageInfo pInfo; + pInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); + if (!ServiceWatcher.isSignatureMatch(pInfo.signatures, sigSets)) { + Log.w(TAG, packageName + " resolves service " + FUSED_LOCATION_SERVICE_ACTION + + ", but has wrong signature, ignoring"); + continue; + } + } catch (NameNotFoundException e) { + Log.e(TAG, "missing package: " + packageName); + continue; + } + + // Get the version info + if (rInfo.serviceInfo.metaData == null) { + Log.w(TAG, "Found fused provider without metadata: " + packageName); + continue; + } + + int version = rInfo.serviceInfo.metaData.getInt( + ServiceWatcher.EXTRA_SERVICE_VERSION, -1); + if (version == 0) { + // This should be the fallback fused location provider. + + // Make sure it's in the system partition. + if ((rInfo.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { + if (D) Log.d(TAG, "Fallback candidate not in /system: " + packageName); + continue; + } + + // Check that the fallback is signed the same as the OS + // as a proxy for coreApp="true" + if (pm.checkSignatures(systemPackageName, packageName) + != PackageManager.SIGNATURE_MATCH) { + if (D) Log.d(TAG, "Fallback candidate not signed the same as system: " + + packageName); + continue; + } + + // Found a valid fallback. + if (D) Log.d(TAG, "Found fallback provider: " + packageName); + return; + } else { + if (D) Log.d(TAG, "Fallback candidate not version 0: " + packageName); + } + } + + throw new IllegalStateException("Unable to find a fused location provider that is in the " + + "system partition with version 0 and signed with the platform certificate. " + + "Such a package is needed to provide a default fused location provider in the " + + "event that no other fused location provider has been installed or is currently " + + "available. For example, coreOnly boot mode when decrypting the data " + + "partition. The fallback must also be marked coreApp=\"true\" in the manifest"); + } + private void loadProvidersLocked() { // create a passive location provider, which is always enabled PassiveProvider passiveProvider = new PassiveProvider(this); @@ -275,14 +349,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run */ Resources resources = mContext.getResources(); ArrayList<String> providerPackageNames = new ArrayList<String>(); - String[] pkgs1 = resources.getStringArray( + String[] pkgs = resources.getStringArray( com.android.internal.R.array.config_locationProviderPackageNames); - String[] pkgs2 = resources.getStringArray( - com.android.internal.R.array.config_overlay_locationProviderPackageNames); - if (D) Log.d(TAG, "built-in location providers: " + Arrays.toString(pkgs1)); - if (D) Log.d(TAG, "overlay location providers: " + Arrays.toString(pkgs2)); - if (pkgs1 != null) providerPackageNames.addAll(Arrays.asList(pkgs1)); - if (pkgs2 != null) providerPackageNames.addAll(Arrays.asList(pkgs2)); + if (D) Log.d(TAG, "certificates for location providers pulled from: " + + Arrays.toString(pkgs)); + if (pkgs != null) providerPackageNames.addAll(Arrays.asList(pkgs)); + + ensureFallbackFusedProviderPresentLocked(providerPackageNames); // bind to network provider LocationProviderProxy networkProvider = LocationProviderProxy.createAndBind( @@ -347,7 +420,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run final int mUid; // uid of receiver final int mPid; // pid of receiver final String mPackageName; // package name of receiver - final String mPermission; // best permission that receiver has + final int mAllowedResolutionLevel; // resolution level allowed to receiver final ILocationListener mListener; final PendingIntent mPendingIntent; @@ -366,7 +439,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } else { mKey = intent; } - mPermission = checkPermission(); + mAllowedResolutionLevel = getAllowedResolutionLevel(pid, uid); mUid = uid; mPid = pid; mPackageName = packageName; @@ -440,7 +513,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run // synchronize to ensure incrementPendingBroadcastsLocked() // is called before decrementPendingBroadcasts() mPendingIntent.send(mContext, 0, statusChanged, this, mLocationHandler, - mPermission); + getResolutionPermission(mAllowedResolutionLevel)); // call this after broadcasting so we do not increment // if we throw an exeption. incrementPendingBroadcastsLocked(); @@ -474,7 +547,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run // synchronize to ensure incrementPendingBroadcastsLocked() // is called before decrementPendingBroadcasts() mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler, - mPermission); + getResolutionPermission(mAllowedResolutionLevel)); // call this after broadcasting so we do not increment // if we throw an exeption. incrementPendingBroadcastsLocked(); @@ -512,7 +585,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run // synchronize to ensure incrementPendingBroadcastsLocked() // is called before decrementPendingBroadcasts() mPendingIntent.send(mContext, 0, providerIntent, this, mLocationHandler, - mPermission); + getResolutionPermission(mAllowedResolutionLevel)); // call this after broadcasting so we do not increment // if we throw an exeption. incrementPendingBroadcastsLocked(); @@ -609,51 +682,76 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } /** - * Returns the best permission available to the caller. + * Returns the permission string associated with the specified resolution level. + * + * @param resolutionLevel the resolution level + * @return the permission string */ - private String getBestCallingPermission() { - if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) == - PackageManager.PERMISSION_GRANTED) { - return ACCESS_FINE_LOCATION; - } else if (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) == - PackageManager.PERMISSION_GRANTED) { - return ACCESS_COARSE_LOCATION; + private String getResolutionPermission(int resolutionLevel) { + switch (resolutionLevel) { + case RESOLUTION_LEVEL_FINE: + return android.Manifest.permission.ACCESS_FINE_LOCATION; + case RESOLUTION_LEVEL_COARSE: + return android.Manifest.permission.ACCESS_COARSE_LOCATION; + default: + return null; } - return null; } /** - * Throw SecurityException if caller has neither COARSE or FINE. - * Otherwise, return the best permission. + * Returns the resolution level allowed to the given PID/UID pair. + * + * @param pid the PID + * @param uid the UID + * @return resolution level allowed to the pid/uid pair */ - private String checkPermission() { - String perm = getBestCallingPermission(); - if (perm == null) { - throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" + - " ACCESS_FINE_LOCATION permission"); + private int getAllowedResolutionLevel(int pid, int uid) { + if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, + pid, uid) == PackageManager.PERMISSION_GRANTED) { + return RESOLUTION_LEVEL_FINE; + } else if (mContext.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, + pid, uid) == PackageManager.PERMISSION_GRANTED) { + return RESOLUTION_LEVEL_COARSE; + } else { + return RESOLUTION_LEVEL_NONE; } - return perm; } /** - * Throw SecurityException if caller lacks permission to use Geofences. + * Returns the resolution level allowed to the caller + * + * @return resolution level allowed to caller */ - private void checkGeofencePermission() { - if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) != - PackageManager.PERMISSION_GRANTED) { + private int getCallerAllowedResolutionLevel() { + return getAllowedResolutionLevel(Binder.getCallingPid(), Binder.getCallingUid()); + } + + /** + * Throw SecurityException if specified resolution level is insufficient to use geofences. + * + * @param allowedResolutionLevel resolution level allowed to caller + */ + private void checkResolutionLevelIsSufficientForGeofenceUse(int allowedResolutionLevel) { + if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { throw new SecurityException("Geofence usage requires ACCESS_FINE_LOCATION permission"); } } - private String getMinimumPermissionForProvider(String provider) { + /** + * Return the minimum resolution level required to use the specified location provider. + * + * @param provider the name of the location provider + * @return minimum resolution level required for provider + */ + private int getMinimumResolutionLevelForProviderUse(String provider) { if (LocationManager.GPS_PROVIDER.equals(provider) || LocationManager.PASSIVE_PROVIDER.equals(provider)) { // gps and passive providers require FINE permission - return ACCESS_FINE_LOCATION; + return RESOLUTION_LEVEL_FINE; } else if (LocationManager.NETWORK_PROVIDER.equals(provider) || LocationManager.FUSED_PROVIDER.equals(provider)) { // network and fused providers are ok with COARSE or FINE - return ACCESS_COARSE_LOCATION; + return RESOLUTION_LEVEL_COARSE; } else { // mock providers LocationProviderInterface lp = mMockProviders.get(provider); @@ -662,41 +760,38 @@ public class LocationManagerService extends ILocationManager.Stub implements Run if (properties != null) { if (properties.mRequiresSatellite) { // provider requiring satellites require FINE permission - return ACCESS_FINE_LOCATION; + return RESOLUTION_LEVEL_FINE; } else if (properties.mRequiresNetwork || properties.mRequiresCell) { // provider requiring network and or cell require COARSE or FINE - return ACCESS_COARSE_LOCATION; + return RESOLUTION_LEVEL_COARSE; } } } } - - return null; + return RESOLUTION_LEVEL_FINE; // if in doubt, require FINE } - private boolean isPermissionSufficient(String perm, String minPerm) { - if (ACCESS_FINE_LOCATION.equals(minPerm)) { - return ACCESS_FINE_LOCATION.equals(perm); - } else if (ACCESS_COARSE_LOCATION.equals(minPerm)) { - return ACCESS_FINE_LOCATION.equals(perm) || - ACCESS_COARSE_LOCATION.equals(perm); - } else { - return false; - } - } - - private void checkPermissionForProvider(String perm, String provider) { - String minPerm = getMinimumPermissionForProvider(provider); - if (!isPermissionSufficient(perm, minPerm)) { - if (ACCESS_FINE_LOCATION.equals(minPerm)) { - throw new SecurityException("Location provider \"" + provider + - "\" requires ACCESS_FINE_LOCATION permission."); - } else if (ACCESS_COARSE_LOCATION.equals(minPerm)) { - throw new SecurityException("Location provider \"" + provider + - "\" requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission."); - } else { - throw new SecurityException("Insufficient permission for location provider \"" + - provider + "\"."); + /** + * Throw SecurityException if specified resolution level is insufficient to use the named + * location provider. + * + * @param allowedResolutionLevel resolution level allowed to caller + * @param providerName the name of the location provider + */ + private void checkResolutionLevelIsSufficientForProviderUse(int allowedResolutionLevel, + String providerName) { + int requiredResolutionLevel = getMinimumResolutionLevelForProviderUse(providerName); + if (allowedResolutionLevel < requiredResolutionLevel) { + switch (requiredResolutionLevel) { + case RESOLUTION_LEVEL_FINE: + throw new SecurityException("\"" + providerName + "\" location provider " + + "requires ACCESS_FINE_LOCATION permission."); + case RESOLUTION_LEVEL_COARSE: + throw new SecurityException("\"" + providerName + "\" location provider " + + "requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission."); + default: + throw new SecurityException("Insufficient permission for \"" + providerName + + "\" location provider."); } } } @@ -731,8 +826,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run */ @Override public List<String> getProviders(Criteria criteria, boolean enabledOnly) { + int allowedResolutionLevel = getCallerAllowedResolutionLevel(); ArrayList<String> out; - String perm = getBestCallingPermission(); int callingUserId = UserHandle.getCallingUserId(); long identity = Binder.clearCallingIdentity(); try { @@ -743,7 +838,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run if (LocationManager.FUSED_PROVIDER.equals(name)) { continue; } - if (isPermissionSufficient(perm, getMinimumPermissionForProvider(name))) { + if (allowedResolutionLevel >= getMinimumResolutionLevelForProviderUse(name)) { if (enabledOnly && !isAllowedBySettingsLocked(name, callingUserId)) { continue; } @@ -803,8 +898,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run @Override public boolean providerMeetsCriteria(String provider, Criteria criteria) { - checkPermission(); - LocationProviderInterface p = mProvidersByName.get(provider); if (p == null) { throw new IllegalArgumentException("provider=" + provider); @@ -1010,33 +1103,41 @@ public class LocationManagerService extends ILocationManager.Stub implements Run return receiver; } - private String checkPermissionAndRequest(LocationRequest request) { - String perm = getBestCallingPermission(); - String provider = request.getProvider(); - checkPermissionForProvider(perm, provider); - - if (ACCESS_COARSE_LOCATION.equals(perm)) { - switch (request.getQuality()) { + /** + * Creates a LocationRequest based upon the supplied LocationRequest that to meets resolution + * and consistency requirements. + * + * @param request the LocationRequest from which to create a sanitized version + * @param shouldBeCoarse whether the sanitized version should be held to coarse resolution + * constraints + * @param fastestCoarseIntervalMS minimum interval allowed for coarse resolution + * @return a version of request that meets the given resolution and consistency requirements + * @hide + */ + private LocationRequest createSanitizedRequest(LocationRequest request, int resolutionLevel) { + LocationRequest sanitizedRequest = new LocationRequest(request); + if (resolutionLevel < RESOLUTION_LEVEL_FINE) { + switch (sanitizedRequest.getQuality()) { case LocationRequest.ACCURACY_FINE: - request.setQuality(LocationRequest.ACCURACY_BLOCK); + sanitizedRequest.setQuality(LocationRequest.ACCURACY_BLOCK); break; case LocationRequest.POWER_HIGH: - request.setQuality(LocationRequest.POWER_LOW); + sanitizedRequest.setQuality(LocationRequest.POWER_LOW); break; } // throttle - if (request.getInterval() < LocationFudger.FASTEST_INTERVAL_MS) { - request.setInterval(LocationFudger.FASTEST_INTERVAL_MS); + if (sanitizedRequest.getInterval() < LocationFudger.FASTEST_INTERVAL_MS) { + sanitizedRequest.setInterval(LocationFudger.FASTEST_INTERVAL_MS); } - if (request.getFastestInterval() < LocationFudger.FASTEST_INTERVAL_MS) { - request.setFastestInterval(LocationFudger.FASTEST_INTERVAL_MS); + if (sanitizedRequest.getFastestInterval() < LocationFudger.FASTEST_INTERVAL_MS) { + sanitizedRequest.setFastestInterval(LocationFudger.FASTEST_INTERVAL_MS); } } // make getFastestInterval() the minimum of interval and fastest interval - if (request.getFastestInterval() > request.getInterval()) { + if (sanitizedRequest.getFastestInterval() > sanitizedRequest.getInterval()) { request.setFastestInterval(request.getInterval()); } - return perm; + return sanitizedRequest; } private void checkPackageName(String packageName) { @@ -1079,7 +1180,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run PendingIntent intent, String packageName) { if (request == null) request = DEFAULT_LOCATION_REQUEST; checkPackageName(packageName); - checkPermissionAndRequest(request); + int allowedResolutionLevel = getCallerAllowedResolutionLevel(); + checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, + request.getProvider()); + LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); @@ -1089,7 +1193,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - requestLocationUpdatesLocked(request, recevier, pid, uid, packageName); + requestLocationUpdatesLocked(sanitizedRequest, recevier, pid, uid, packageName); } } finally { Binder.restoreCallingIdentity(identity); @@ -1132,7 +1236,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run public void removeUpdates(ILocationListener listener, PendingIntent intent, String packageName) { checkPackageName(packageName); - checkPermission(); + final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); Receiver receiver = checkListenerOrIntent(listener, intent, pid, uid, packageName); @@ -1188,8 +1292,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run public Location getLastLocation(LocationRequest request, String packageName) { if (D) Log.d(TAG, "getLastLocation: " + request); if (request == null) request = DEFAULT_LOCATION_REQUEST; - String perm = checkPermissionAndRequest(request); + int allowedResolutionLevel = getCallerAllowedResolutionLevel(); checkPackageName(packageName); + checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, + request.getProvider()); + // no need to sanitize this request, as only the provider name is used long identity = Binder.clearCallingIdentity(); try { @@ -1213,13 +1320,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run if (location == null) { return null; } - if (ACCESS_FINE_LOCATION.equals(perm)) { - return location; - } else { + if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); if (noGPSLocation != null) { return mLocationFudger.getOrCreate(noGPSLocation); } + } else { + return location; } } return null; @@ -1232,18 +1339,21 @@ public class LocationManagerService extends ILocationManager.Stub implements Run public void requestGeofence(LocationRequest request, Geofence geofence, PendingIntent intent, String packageName) { if (request == null) request = DEFAULT_LOCATION_REQUEST; - checkGeofencePermission(); - checkPermissionAndRequest(request); + int allowedResolutionLevel = getCallerAllowedResolutionLevel(); + checkResolutionLevelIsSufficientForGeofenceUse(allowedResolutionLevel); checkPendingIntent(intent); checkPackageName(packageName); + checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, + request.getProvider()); + LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel); - if (D) Log.d(TAG, "requestGeofence: " + request + " " + geofence + " " + intent); + if (D) Log.d(TAG, "requestGeofence: " + sanitizedRequest + " " + geofence + " " + intent); // geo-fence manager uses the public location API, need to clear identity int uid = Binder.getCallingUid(); long identity = Binder.clearCallingIdentity(); try { - mGeofenceManager.addFence(request, geofence, intent, uid, packageName); + mGeofenceManager.addFence(sanitizedRequest, geofence, intent, uid, packageName); } finally { Binder.restoreCallingIdentity(identity); } @@ -1251,7 +1361,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run @Override public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) { - checkGeofencePermission(); + checkResolutionLevelIsSufficientForGeofenceUse(getCallerAllowedResolutionLevel()); checkPendingIntent(intent); checkPackageName(packageName); @@ -1272,10 +1382,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run if (mGpsStatusProvider == null) { return false; } - if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); - } + checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), + LocationManager.GPS_PROVIDER); try { mGpsStatusProvider.addGpsStatusListener(listener); @@ -1303,8 +1411,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run // throw NullPointerException to remain compatible with previous implementation throw new NullPointerException(); } + checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), + provider); - checkPermission(); // and check for ACCESS_LOCATION_EXTRA_COMMANDS if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS) != PackageManager.PERMISSION_GRANTED)) { @@ -1340,7 +1449,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run */ @Override public ProviderProperties getProviderProperties(String provider) { - checkPermissionForProvider(getBestCallingPermission(), provider); + if (mProvidersByName.get(provider) == null) { + return null; + } + + checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), + provider); LocationProviderInterface p; synchronized (mLock) { @@ -1353,7 +1467,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run @Override public boolean isProviderEnabled(String provider) { - checkPermissionForProvider(getBestCallingPermission(), provider); + checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), + provider); if (LocationManager.FUSED_PROVIDER.equals(provider)) return false; long identity = Binder.clearCallingIdentity(); @@ -1518,10 +1633,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } Location notifyLocation = null; - if (ACCESS_FINE_LOCATION.equals(receiver.mPermission)) { - notifyLocation = lastLocation; // use fine location + if (receiver.mAllowedResolutionLevel < RESOLUTION_LEVEL_FINE) { + notifyLocation = coarseLocation; // use coarse location } else { - notifyLocation = coarseLocation; // use coarse location if available + notifyLocation = lastLocation; // use fine location } if (notifyLocation != null) { Location lastLoc = r.mLastFixBroadcast; diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index 09a606e..4a54efe 100755 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -916,7 +916,7 @@ public class NotificationManagerService extends INotificationManager.Stub // behalf of the download manager without affecting other apps. if (!pkg.equals("com.android.providers.downloads") || Log.isLoggable("DownloadManager", Log.VERBOSE)) { - EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag, + EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag, userId, notification.toString()); } @@ -1207,7 +1207,7 @@ public class NotificationManagerService extends INotificationManager.Stub */ private void cancelNotification(String pkg, String tag, int id, int mustHaveFlags, int mustNotHaveFlags, boolean sendDelete, int userId) { - EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, + EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId, mustHaveFlags, mustNotHaveFlags); synchronized (mNotificationList) { @@ -1231,20 +1231,34 @@ public class NotificationManagerService extends INotificationManager.Stub } /** + * Determine whether the userId applies to the notification in question, either because + * they match exactly, or one of them is USER_ALL (which is treated as a wildcard). + */ + private boolean notificationMatchesUserId(NotificationRecord r, int userId) { + return + // looking for USER_ALL notifications? match everything + userId == UserHandle.USER_ALL + // a notification sent to USER_ALL matches any query + || r.userId == UserHandle.USER_ALL + // an exact user match + || r.userId == userId; + } + + /** * Cancels all notifications from a given package that have all of the * {@code mustHaveFlags}. */ boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags, int mustNotHaveFlags, boolean doit, int userId) { - EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, mustHaveFlags, - mustNotHaveFlags); + EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, userId, + mustHaveFlags, mustNotHaveFlags); synchronized (mNotificationList) { final int N = mNotificationList.size(); boolean canceledSomething = false; for (int i = N-1; i >= 0; --i) { NotificationRecord r = mNotificationList.get(i); - if (userId != UserHandle.USER_ALL && r.userId != userId) { + if (!notificationMatchesUserId(r, userId)) { continue; } if ((r.notification.flags & mustHaveFlags) != mustHaveFlags) { @@ -1322,7 +1336,7 @@ public class NotificationManagerService extends INotificationManager.Stub for (int i=N-1; i>=0; i--) { NotificationRecord r = mNotificationList.get(i); - if (r.userId != userId) { + if (!notificationMatchesUserId(r, userId)) { continue; } @@ -1376,7 +1390,7 @@ public class NotificationManagerService extends INotificationManager.Stub final int len = list.size(); for (int i=0; i<len; i++) { NotificationRecord r = list.get(i); - if (r.userId != userId || r.id != id) { + if (!notificationMatchesUserId(r, userId) || r.id != id) { continue; } if (tag == null) { diff --git a/services/java/com/android/server/ServiceWatcher.java b/services/java/com/android/server/ServiceWatcher.java index 5598b0a..2e7c6d1 100644 --- a/services/java/com/android/server/ServiceWatcher.java +++ b/services/java/com/android/server/ServiceWatcher.java @@ -43,7 +43,7 @@ import java.util.List; */ public class ServiceWatcher implements ServiceConnection { private static final boolean D = false; - private static final String EXTRA_VERSION = "version"; + public static final String EXTRA_SERVICE_VERSION = "serviceVersion"; private final String mTag; private final Context mContext; @@ -58,9 +58,27 @@ public class ServiceWatcher implements ServiceConnection { // all fields below synchronized on mLock private IBinder mBinder; // connected service private String mPackageName; // current best package - private int mVersion; // current best version + private int mVersion = Integer.MIN_VALUE; // current best version private int mCurrentUserId; + public static ArrayList<HashSet<Signature>> getSignatureSets(Context context, + List<String> initialPackageNames) { + PackageManager pm = context.getPackageManager(); + ArrayList<HashSet<Signature>> sigSets = new ArrayList<HashSet<Signature>>(); + for (int i = 0, size = initialPackageNames.size(); i < size; i++) { + String pkg = initialPackageNames.get(i); + try { + HashSet<Signature> set = new HashSet<Signature>(); + Signature[] sigs = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures; + set.addAll(Arrays.asList(sigs)); + sigSets.add(set); + } catch (NameNotFoundException e) { + Log.w("ServiceWatcher", pkg + " not found"); + } + } + return sigSets; + } + public ServiceWatcher(Context context, String logTag, String action, List<String> initialPackageNames, Runnable newServiceWork, Handler handler, int userId) { mContext = context; @@ -71,20 +89,7 @@ public class ServiceWatcher implements ServiceConnection { mHandler = handler; mCurrentUserId = userId; - mSignatureSets = new ArrayList<HashSet<Signature>>(); - for (int i=0; i < initialPackageNames.size(); i++) { - String pkg = initialPackageNames.get(i); - HashSet<Signature> set = new HashSet<Signature>(); - try { - Signature[] sigs = - mPm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures; - set.addAll(Arrays.asList(sigs)); - mSignatureSets.add(set); - } catch (NameNotFoundException e) { - Log.w(logTag, pkg + " not found"); - } - } - + mSignatureSets = getSignatureSets(context, initialPackageNames); } public boolean start() { @@ -132,15 +137,16 @@ public class ServiceWatcher implements ServiceConnection { // check version int version = 0; if (rInfo.serviceInfo.metaData != null) { - version = rInfo.serviceInfo.metaData.getInt(EXTRA_VERSION, 0); + version = rInfo.serviceInfo.metaData.getInt(EXTRA_SERVICE_VERSION, 0); } + if (version > mVersion) { bestVersion = version; bestPackage = packageName; } } - if (D) Log.d(mTag, String.format("bindBestPackage %s found %d, %s", + if (D) Log.d(mTag, String.format("bindBestPackage for %s : %s found %d, %s", mAction, (justCheckThisPackage == null ? "" : "(" + justCheckThisPackage + ") "), rInfos.size(), (bestPackage == null ? "no new best package" : "new best packge: " + bestPackage))); @@ -174,7 +180,8 @@ public class ServiceWatcher implements ServiceConnection { | Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_NOT_VISIBLE, mCurrentUserId); } - private boolean isSignatureMatch(Signature[] signatures) { + public static boolean isSignatureMatch(Signature[] signatures, + List<HashSet<Signature>> sigSets) { if (signatures == null) return false; // build hashset of input to test against @@ -184,7 +191,7 @@ public class ServiceWatcher implements ServiceConnection { } // test input against each of the signature sets - for (HashSet<Signature> referenceSet : mSignatureSets) { + for (HashSet<Signature> referenceSet : sigSets) { if (referenceSet.equals(inputSet)) { return true; } @@ -192,6 +199,10 @@ public class ServiceWatcher implements ServiceConnection { return false; } + private boolean isSignatureMatch(Signature[] signatures) { + return isSignatureMatch(signatures, mSignatureSets); + } + private final PackageMonitor mPackageMonitor = new PackageMonitor() { /** * Called when package has been reinstalled diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java index e0f3814..a02fc8d 100644 --- a/services/java/com/android/server/WallpaperManagerService.java +++ b/services/java/com/android/server/WallpaperManagerService.java @@ -458,15 +458,21 @@ class WallpaperManagerService extends IWallpaperManager.Stub { IntentFilter userFilter = new IntentFilter(); userFilter.addAction(Intent.ACTION_USER_REMOVED); + userFilter.addAction(Intent.ACTION_USER_STOPPING); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_USER_REMOVED.equals(action)) { - removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); + onRemoveUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); + } else if (Intent.ACTION_USER_STOPPING.equals(action)) { + onStoppingUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); } } }, userFilter); + try { ActivityManagerNative.getDefault().registerUserSwitchObserver( new IUserSwitchObserver.Stub() { @@ -491,13 +497,24 @@ class WallpaperManagerService extends IWallpaperManager.Stub { } } - void removeUser(int userId) { + void onStoppingUser(int userId) { + if (userId < 1) return; synchronized (mLock) { WallpaperData wallpaper = mWallpaperMap.get(userId); if (wallpaper != null) { - wallpaper.wallpaperObserver.stopWatching(); + if (wallpaper.wallpaperObserver != null) { + wallpaper.wallpaperObserver.stopWatching(); + wallpaper.wallpaperObserver = null; + } mWallpaperMap.remove(userId); } + } + } + + void onRemoveUser(int userId) { + if (userId < 1) return; + synchronized (mLock) { + onStoppingUser(userId); File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER); wallpaperFile.delete(); File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO); diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java index c8931f4..0f04b44 100644 --- a/services/java/com/android/server/accessibility/ScreenMagnifier.java +++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java @@ -38,7 +38,9 @@ import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemClock; import android.provider.Settings; +import android.text.TextUtils; import android.util.Property; import android.util.Slog; import android.view.Display; @@ -70,6 +72,7 @@ import com.android.internal.os.SomeArgs; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Locale; /** * This class handles the screen magnification when accessibility is enabled. @@ -662,12 +665,33 @@ public final class ScreenMagnifier implements EventStreamTransformation { while (mDelayedEventQueue != null) { MotionEventInfo info = mDelayedEventQueue; mDelayedEventQueue = info.mNext; - ScreenMagnifier.this.onMotionEvent(info.mEvent, info.mRawEvent, - info.mPolicyFlags); + final long offset = SystemClock.uptimeMillis() - info.mCachedTimeMillis; + MotionEvent event = obtainEventWithOffsetTimeAndDownTime(info.mEvent, offset); + MotionEvent rawEvent = obtainEventWithOffsetTimeAndDownTime(info.mRawEvent, offset); + ScreenMagnifier.this.onMotionEvent(event, rawEvent, info.mPolicyFlags); + event.recycle(); + rawEvent.recycle(); info.recycle(); } } + private MotionEvent obtainEventWithOffsetTimeAndDownTime(MotionEvent event, long offset) { + final int pointerCount = event.getPointerCount(); + PointerCoords[] coords = getTempPointerCoordsWithMinSize(pointerCount); + PointerProperties[] properties = getTempPointerPropertiesWithMinSize(pointerCount); + for (int i = 0; i < pointerCount; i++) { + event.getPointerCoords(i, coords[i]); + event.getPointerProperties(i, properties[i]); + } + final long downTime = event.getDownTime() + offset; + final long eventTime = event.getEventTime() + offset; + return MotionEvent.obtain(downTime, eventTime, + event.getAction(), pointerCount, properties, coords, + event.getMetaState(), event.getButtonState(), + 1.0f, 1.0f, event.getDeviceId(), event.getEdgeFlags(), + event.getSource(), event.getFlags()); + } + private void clearDelayedMotionEvents() { while (mDelayedEventQueue != null) { MotionEventInfo info = mDelayedEventQueue; @@ -746,6 +770,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { public MotionEvent mEvent; public MotionEvent mRawEvent; public int mPolicyFlags; + public long mCachedTimeMillis; public static MotionEventInfo obtain(MotionEvent event, MotionEvent rawEvent, int policyFlags) { @@ -770,6 +795,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { mEvent = MotionEvent.obtain(event); mRawEvent = MotionEvent.obtain(rawEvent); mPolicyFlags = policyFlags; + mCachedTimeMillis = SystemClock.uptimeMillis(); } public void recycle() { @@ -793,6 +819,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { mRawEvent.recycle(); mRawEvent = null; mPolicyFlags = 0; + mCachedTimeMillis = 0; } } @@ -850,6 +877,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { private static final int MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED = 3; private static final int MESSAGE_ON_WINDOW_TRANSITION = 4; private static final int MESSAGE_ON_ROTATION_CHANGED = 5; + private static final int MESSAGE_ON_WINDOW_LAYERS_CHANGED = 6; private final Handler mHandler = new MyHandler(); @@ -880,24 +908,8 @@ public final class ScreenMagnifier implements EventStreamTransformation { mDisplayContentChangeListener = new IDisplayContentChangeListener.Stub() { @Override public void onWindowTransition(int displayId, int transition, WindowInfo info) { - Message message = mHandler.obtainMessage(MESSAGE_ON_WINDOW_TRANSITION, - transition, 0, WindowInfo.obtain(info)); - // TODO: This makes me quite unhappy but for the time being the - // least risky fix for cases where the keyguard is removed but - // the windows it force hides are not made visible yet. Hence, - // we would compute the magnified frame before we have a stable - // state. One more reason to move the magnified frame computation - // in the window manager! - if (info.type == WindowManager.LayoutParams.TYPE_KEYGUARD - || info.type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG - && (transition == WindowManagerPolicy.TRANSIT_EXIT - || transition == WindowManagerPolicy.TRANSIT_HIDE)) { - final long delay = (long) (2 * mLongAnimationDuration - * mWindowAnimationScale); - mHandler.sendMessageDelayed(message, delay); - } else { - message.sendToTarget(); - } + mHandler.obtainMessage(MESSAGE_ON_WINDOW_TRANSITION, + transition, 0, WindowInfo.obtain(info)).sendToTarget(); } @Override @@ -917,6 +929,11 @@ public final class ScreenMagnifier implements EventStreamTransformation { mHandler.obtainMessage(MESSAGE_ON_ROTATION_CHANGED, rotation, 0) .sendToTarget(); } + + @Override + public void onWindowLayersChanged(int displayId) throws RemoteException { + mHandler.sendEmptyMessage(MESSAGE_ON_WINDOW_LAYERS_CHANGED); + } }; try { @@ -985,45 +1002,44 @@ public final class ScreenMagnifier implements EventStreamTransformation { mViewport.recomputeBounds(mMagnificationController.isMagnifying()); } break; } - } else { - switch (transition) { - case WindowManagerPolicy.TRANSIT_ENTER: - case WindowManagerPolicy.TRANSIT_SHOW: { - if (!magnifying || !isScreenMagnificationAutoUpdateEnabled(mContext)) { - break; - } - final int type = info.type; - switch (type) { - // TODO: Are these all the windows we want to make - // visible when they appear on the screen? - // Do we need to take some of them out? - case WindowManager.LayoutParams.TYPE_APPLICATION: - case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL: - case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA: - case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL: - case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG: - case WindowManager.LayoutParams.TYPE_SEARCH_BAR: - case WindowManager.LayoutParams.TYPE_PHONE: - case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT: - case WindowManager.LayoutParams.TYPE_TOAST: - case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY: - case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE: - case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG: - case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG: - case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR: - case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY: - case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL: - case WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY: { - Rect magnifiedRegionBounds = mMagnificationController - .getMagnifiedRegionBounds(); - Rect touchableRegion = info.touchableRegion; - if (!magnifiedRegionBounds.intersect(touchableRegion)) { - ensureRectangleInMagnifiedRegionBounds( - magnifiedRegionBounds, touchableRegion); - } - } break; - } break; + } + switch (transition) { + case WindowManagerPolicy.TRANSIT_ENTER: + case WindowManagerPolicy.TRANSIT_SHOW: { + if (!magnifying || !isScreenMagnificationAutoUpdateEnabled(mContext)) { + break; } + final int type = info.type; + switch (type) { + // TODO: Are these all the windows we want to make + // visible when they appear on the screen? + // Do we need to take some of them out? + case WindowManager.LayoutParams.TYPE_APPLICATION: + case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL: + case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA: + case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL: + case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG: + case WindowManager.LayoutParams.TYPE_SEARCH_BAR: + case WindowManager.LayoutParams.TYPE_PHONE: + case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT: + case WindowManager.LayoutParams.TYPE_TOAST: + case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY: + case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE: + case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG: + case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG: + case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR: + case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY: + case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL: + case WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY: { + Rect magnifiedRegionBounds = mMagnificationController + .getMagnifiedRegionBounds(); + Rect touchableRegion = info.touchableRegion; + if (!magnifiedRegionBounds.intersect(touchableRegion)) { + ensureRectangleInMagnifiedRegionBounds( + magnifiedRegionBounds, touchableRegion); + } + } break; + } break; } } } finally { @@ -1052,7 +1068,12 @@ public final class ScreenMagnifier implements EventStreamTransformation { final float scrollX; final float scrollY; if (rectangle.width() > magnifiedRegionBounds.width()) { - scrollX = rectangle.left - magnifiedRegionBounds.left; + final int direction = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()); + if (direction == View.LAYOUT_DIRECTION_LTR) { + scrollX = rectangle.left - magnifiedRegionBounds.left; + } else { + scrollX = rectangle.right - magnifiedRegionBounds.right; + } } else if (rectangle.left < magnifiedRegionBounds.left) { scrollX = rectangle.left - magnifiedRegionBounds.left; } else if (rectangle.right > magnifiedRegionBounds.right) { @@ -1192,6 +1213,9 @@ public final class ScreenMagnifier implements EventStreamTransformation { final int rotation = message.arg1; handleOnRotationChanged(rotation); } break; + case MESSAGE_ON_WINDOW_LAYERS_CHANGED: { + mViewport.recomputeBounds(mMagnificationController.isMagnifying()); + } break; default: { throw new IllegalArgumentException("Unknown message: " + action); } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 7132e1e..1737876 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -11119,8 +11119,8 @@ public final class ActivityManagerService extends ActivityManagerNative // instantiated. The backup agent will invoke backupAgentCreated() on the // activity manager to announce its creation. public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { - if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); - enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); + if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); + enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); synchronized(this) { // !!! TODO: currently no check here that we're already bound @@ -11181,6 +11181,17 @@ public final class ActivityManagerService extends ActivityManagerNative return true; } + @Override + public void clearPendingBackup() { + if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); + enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); + + synchronized (this) { + mBackupTarget = null; + mBackupAppName = null; + } + } + // A backup agent has just come up public void backupAgentCreated(String agentPackageName, IBinder agent) { if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName @@ -11217,32 +11228,34 @@ public final class ActivityManagerService extends ActivityManagerNative } synchronized(this) { - if (mBackupAppName == null) { - Slog.w(TAG, "Unbinding backup agent with no active backup"); - return; - } - - if (!mBackupAppName.equals(appInfo.packageName)) { - Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); - return; - } + try { + if (mBackupAppName == null) { + Slog.w(TAG, "Unbinding backup agent with no active backup"); + return; + } - ProcessRecord proc = mBackupTarget.app; - mBackupTarget = null; - mBackupAppName = null; + if (!mBackupAppName.equals(appInfo.packageName)) { + Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); + return; + } - // Not backing this app up any more; reset its OOM adjustment - updateOomAdjLocked(proc); + // Not backing this app up any more; reset its OOM adjustment + final ProcessRecord proc = mBackupTarget.app; + updateOomAdjLocked(proc); - // If the app crashed during backup, 'thread' will be null here - if (proc.thread != null) { - try { - proc.thread.scheduleDestroyBackupAgent(appInfo, - compatibilityInfoForPackageLocked(appInfo)); - } catch (Exception e) { - Slog.e(TAG, "Exception when unbinding backup agent:"); - e.printStackTrace(); + // If the app crashed during backup, 'thread' will be null here + if (proc.thread != null) { + try { + proc.thread.scheduleDestroyBackupAgent(appInfo, + compatibilityInfoForPackageLocked(appInfo)); + } catch (Exception e) { + Slog.e(TAG, "Exception when unbinding backup agent:"); + e.printStackTrace(); + } } + } finally { + mBackupTarget = null; + mBackupAppName = null; } } } diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java index b4dab86..e76bf44 100644 --- a/services/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/java/com/android/server/display/DisplayDeviceInfo.java @@ -17,6 +17,7 @@ package com.android.server.display; import android.util.DisplayMetrics; +import android.view.Surface; import libcore.util.Objects; @@ -31,11 +32,21 @@ final class DisplayDeviceInfo { public static final int FLAG_DEFAULT_DISPLAY = 1 << 0; /** - * Flag: Indicates that this display device can rotate to show contents in a - * different orientation. Otherwise the rotation is assumed to be fixed in the - * natural orientation and the display manager should transform the content to fit. + * Flag: Indicates that the orientation of this display device is coupled to the + * rotation of its associated logical display. + * <p> + * This flag should be applied to the default display to indicate that the user + * physically rotates the display when content is presented in a different orientation. + * The display manager will apply a coordinate transformation assuming that the + * physical orientation of the display matches the logical orientation of its content. + * </p><p> + * The flag should not be set when the display device is mounted in a fixed orientation + * such as on a desk. The display manager will apply a coordinate transformation + * such as a scale and translation to letterbox or pillarbox format under the + * assumption that the physical orientation of the display is invariant. + * </p> */ - public static final int FLAG_SUPPORTS_ROTATION = 1 << 1; + public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1; /** * Flag: Indicates that this display device has secure video output, such as HDCP. @@ -116,6 +127,17 @@ final class DisplayDeviceInfo { */ public int touch; + /** + * The additional rotation to apply to all content presented on the display device + * relative to its physical coordinate system. Default is {@link Surface#ROTATION_0}. + * <p> + * This field can be used to compensate for the fact that the display has been + * physically rotated relative to its natural orientation such as an HDMI monitor + * that has been mounted sideways to appear to be portrait rather than landscape. + * </p> + */ + public int rotation = Surface.ROTATION_0; + public void setAssumedDensityForExternalDisplay(int width, int height) { densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; // Technically, these values should be smaller than the apparent density @@ -139,7 +161,8 @@ final class DisplayDeviceInfo { && xDpi == other.xDpi && yDpi == other.yDpi && flags == other.flags - && touch == other.touch; + && touch == other.touch + && rotation == other.rotation; } @Override @@ -157,14 +180,18 @@ final class DisplayDeviceInfo { yDpi = other.yDpi; flags = other.flags; touch = other.touch; + rotation = other.rotation; } // For debugging purposes @Override public String toString() { - return "DisplayDeviceInfo{\"" + name + "\": " + width + " x " + height + ", " + refreshRate + " fps, " + return "DisplayDeviceInfo{\"" + name + "\": " + width + " x " + height + ", " + + refreshRate + " fps, " + "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi" - + ", touch " + touchToString(touch) + flagsToString(flags) + "}"; + + ", touch " + touchToString(touch) + flagsToString(flags) + + ", rotation " + rotation + + "}"; } private static String touchToString(int touch) { @@ -185,8 +212,8 @@ final class DisplayDeviceInfo { if ((flags & FLAG_DEFAULT_DISPLAY) != 0) { msg.append(", FLAG_DEFAULT_DISPLAY"); } - if ((flags & FLAG_SUPPORTS_ROTATION) != 0) { - msg.append(", FLAG_SUPPORTS_ROTATION"); + if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) { + msg.append(", FLAG_ROTATES_WITH_CONTENT"); } if ((flags & FLAG_SECURE) != 0) { msg.append(", FLAG_SECURE"); diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java index 0a42528..e58a0a5 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -127,6 +127,13 @@ public final class DisplayManagerService extends IDisplayManager.Stub { // services should be started. This option may disable certain display adapters. public boolean mOnlyCore; + // True if the display manager service should pretend there is only one display + // and only tell applications about the existence of the default logical display. + // The display manager can still mirror content to secondary displays but applications + // cannot present unique content on those displays. + // Used for demonstration purposes only. + private final boolean mSingleDisplayDemoMode; + // All callback records indexed by calling process id. public final SparseArray<CallbackRecord> mCallbacks = new SparseArray<CallbackRecord>(); @@ -182,6 +189,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { mHandler = new DisplayManagerHandler(mainHandler.getLooper()); mUiHandler = uiHandler; mDisplayAdapterListener = new DisplayAdapterListener(); + mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false); mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER); } @@ -305,6 +313,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub { DisplayDevice device = mDisplayDevices.get(i); device.blankLocked(); } + + scheduleTraversalLocked(false); } } } @@ -322,6 +332,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub { DisplayDevice device = mDisplayDevices.get(i); device.unblankLocked(); } + + scheduleTraversalLocked(false); } } } @@ -627,6 +639,12 @@ public final class DisplayManagerService extends IDisplayManager.Stub { isDefault = false; } + if (!isDefault && mSingleDisplayDemoMode) { + Slog.i(TAG, "Not creating a logical display for a secondary display " + + " because single display demo mode is enabled: " + deviceInfo); + return; + } + final int displayId = assignDisplayIdLocked(isDefault); final int layerStack = assignLayerStackLocked(displayId); @@ -755,7 +773,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub { + device.getDisplayDeviceInfoLocked()); return; } else { - display.configureDisplayInTransactionLocked(device); + boolean isBlanked = (mAllDisplayBlankStateFromPowerManager + == DISPLAY_BLANK_STATE_BLANKED); + display.configureDisplayInTransactionLocked(device, isBlanked); } // Update the viewports if needed. @@ -851,6 +871,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId); pw.println(" mDefaultViewport=" + mDefaultViewport); pw.println(" mExternalTouchViewport=" + mExternalTouchViewport); + pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.increaseIndent(); diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java index d780006..fe38d7f 100644 --- a/services/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/java/com/android/server/display/LocalDisplayAdapter.java @@ -20,6 +20,7 @@ import android.content.Context; import android.os.Handler; import android.os.IBinder; import android.os.Looper; +import android.os.SystemProperties; import android.util.SparseArray; import android.view.DisplayEventReceiver; import android.view.Surface; @@ -135,7 +136,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { mInfo.name = getContext().getResources().getString( com.android.internal.R.string.display_manager_built_in_display_name); mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY - | DisplayDeviceInfo.FLAG_SUPPORTS_ROTATION; + | DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT; mInfo.densityDpi = (int)(mPhys.density * 160 + 0.5f); mInfo.xDpi = mPhys.xDpi; mInfo.yDpi = mPhys.yDpi; @@ -145,6 +146,12 @@ final class LocalDisplayAdapter extends DisplayAdapter { com.android.internal.R.string.display_manager_hdmi_display_name); mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL; mInfo.setAssumedDensityForExternalDisplay(mPhys.width, mPhys.height); + + // For demonstration purposes, allow rotation of the external display. + // In the future we might allow the user to configure this directly. + if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) { + mInfo.rotation = Surface.ROTATION_270; + } } } return mInfo; diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java index c4b749c..aa7ea82 100644 --- a/services/java/com/android/server/display/LogicalDisplay.java +++ b/services/java/com/android/server/display/LogicalDisplay.java @@ -55,6 +55,10 @@ import libcore.util.Objects; final class LogicalDisplay { private final DisplayInfo mBaseDisplayInfo = new DisplayInfo(); + // The layer stack we use when the display has been blanked to prevent any + // of its content from appearing. + private static final int BLANK_LAYER_STACK = -1; + private final int mDisplayId; private final int mLayerStack; private DisplayInfo mOverrideDisplayInfo; // set by the window manager @@ -217,13 +221,15 @@ final class LogicalDisplay { * where the display is being mirrored. * * @param device The display device to modify. + * @param isBlanked True if the device is being blanked. */ - public void configureDisplayInTransactionLocked(DisplayDevice device) { + public void configureDisplayInTransactionLocked(DisplayDevice device, + boolean isBlanked) { final DisplayInfo displayInfo = getDisplayInfoLocked(); final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked(); // Set the layer stack. - device.setLayerStackInTransactionLocked(mLayerStack); + device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack); // Set the viewport. // This is the area of the logical display that we intend to show on the @@ -235,10 +241,13 @@ final class LogicalDisplay { // is rotated when the contents of the logical display are rendered. int orientation = Surface.ROTATION_0; if (device == mPrimaryDisplayDevice - && (displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_ROTATION) != 0) { + && (displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) { orientation = displayInfo.rotation; } + // Apply the physical rotation of the display device itself. + orientation = (orientation + displayDeviceInfo.rotation) % 4; + // Set the frame. // The frame specifies the rotated physical coordinates into which the viewport // is mapped. We need to take care to preserve the aspect ratio of the viewport. diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java index c441b02..66eac88 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/java/com/android/server/display/WifiDisplayAdapter.java @@ -16,17 +16,28 @@ package com.android.server.display; +import com.android.internal.R; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.WifiDisplay; import android.hardware.display.WifiDisplayStatus; import android.media.RemoteDisplay; import android.os.Handler; import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.UserHandle; +import android.provider.Settings; import android.util.Slog; import android.view.Surface; @@ -52,8 +63,18 @@ final class WifiDisplayAdapter extends DisplayAdapter { private static final boolean DEBUG = false; + private static final int MSG_SEND_STATUS_CHANGE_BROADCAST = 1; + private static final int MSG_UPDATE_NOTIFICATION = 2; + + private static final String ACTION_DISCONNECT = "android.server.display.wfd.DISCONNECT"; + + private final WifiDisplayHandler mHandler; private final PersistentDataStore mPersistentDataStore; private final boolean mSupportsProtectedBuffers; + private final NotificationManager mNotificationManager; + + private final PendingIntent mSettingsPendingIntent; + private final PendingIntent mDisconnectPendingIntent; private WifiDisplayController mDisplayController; private WifiDisplayDevice mDisplayDevice; @@ -67,14 +88,32 @@ final class WifiDisplayAdapter extends DisplayAdapter { private WifiDisplay[] mRememberedDisplays = WifiDisplay.EMPTY_ARRAY; private boolean mPendingStatusChangeBroadcast; + private boolean mPendingNotificationUpdate; public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, Context context, Handler handler, Listener listener, PersistentDataStore persistentDataStore) { super(syncRoot, context, handler, listener, TAG); + mHandler = new WifiDisplayHandler(handler.getLooper()); mPersistentDataStore = persistentDataStore; mSupportsProtectedBuffers = context.getResources().getBoolean( com.android.internal.R.bool.config_wifiDisplaySupportsProtectedBuffers); + mNotificationManager = (NotificationManager)context.getSystemService( + Context.NOTIFICATION_SERVICE); + + Intent settingsIntent = new Intent(Settings.ACTION_WIFI_DISPLAY_SETTINGS); + settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + mSettingsPendingIntent = PendingIntent.getActivityAsUser( + context, 0, settingsIntent, 0, null, UserHandle.CURRENT); + + Intent disconnectIntent = new Intent(ACTION_DISCONNECT); + mDisconnectPendingIntent = PendingIntent.getBroadcastAsUser( + context, 0, disconnectIntent, 0, UserHandle.CURRENT); + + context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, + new IntentFilter(ACTION_DISCONNECT), null, mHandler); } @Override @@ -89,6 +128,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { pw.println("mAvailableDisplays=" + Arrays.toString(mAvailableDisplays)); pw.println("mRememberedDisplays=" + Arrays.toString(mRememberedDisplays)); pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast); + pw.println("mPendingNotificationUpdate=" + mPendingNotificationUpdate); pw.println("mSupportsProtectedBuffers=" + mSupportsProtectedBuffers); // Try to dump the controller state. @@ -266,6 +306,8 @@ final class WifiDisplayAdapter extends DisplayAdapter { mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height, refreshRate, deviceFlags, surface); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED); + + scheduleUpdateNotificationLocked(); } private void handleDisconnectLocked() { @@ -273,6 +315,8 @@ final class WifiDisplayAdapter extends DisplayAdapter { mDisplayDevice.clearSurfaceLocked(); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED); mDisplayDevice = null; + + scheduleUpdateNotificationLocked(); } } @@ -280,28 +324,81 @@ final class WifiDisplayAdapter extends DisplayAdapter { mCurrentStatus = null; if (!mPendingStatusChangeBroadcast) { mPendingStatusChangeBroadcast = true; - getHandler().post(mStatusChangeBroadcast); + mHandler.sendEmptyMessage(MSG_SEND_STATUS_CHANGE_BROADCAST); } } - private final Runnable mStatusChangeBroadcast = new Runnable() { - @Override - public void run() { - final Intent intent; - synchronized (getSyncRoot()) { - if (!mPendingStatusChangeBroadcast) { - return; - } + private void scheduleUpdateNotificationLocked() { + if (!mPendingNotificationUpdate) { + mPendingNotificationUpdate = true; + mHandler.sendEmptyMessage(MSG_UPDATE_NOTIFICATION); + } + } + + // Runs on the handler. + private void handleSendStatusChangeBroadcast() { + final Intent intent; + synchronized (getSyncRoot()) { + if (!mPendingStatusChangeBroadcast) { + return; + } + + mPendingStatusChangeBroadcast = false; + intent = new Intent(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + intent.putExtra(DisplayManager.EXTRA_WIFI_DISPLAY_STATUS, + getWifiDisplayStatusLocked()); + } - mPendingStatusChangeBroadcast = false; - intent = new Intent(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - intent.putExtra(DisplayManager.EXTRA_WIFI_DISPLAY_STATUS, - getWifiDisplayStatusLocked()); + // Send protected broadcast about wifi display status to registered receivers. + getContext().sendBroadcastAsUser(intent, UserHandle.ALL); + } + + // Runs on the handler. + private void handleUpdateNotification() { + final boolean isConnected; + synchronized (getSyncRoot()) { + if (!mPendingNotificationUpdate) { + return; } - // Send protected broadcast about wifi display status to registered receivers. - getContext().sendBroadcast(intent); + mPendingNotificationUpdate = false; + isConnected = (mDisplayDevice != null); + } + + mNotificationManager.cancelAsUser(null, + R.string.wifi_display_notification_title, UserHandle.ALL); + + if (isConnected) { + Context context = getContext(); + + Resources r = context.getResources(); + Notification notification = new Notification.Builder(context) + .setContentTitle(r.getString( + R.string.wifi_display_notification_title)) + .setContentText(r.getString( + R.string.wifi_display_notification_message)) + .setContentIntent(mSettingsPendingIntent) + .setSmallIcon(R.drawable.ic_notify_wifidisplay) + .setOngoing(true) + .addAction(android.R.drawable.ic_menu_close_clear_cancel, + r.getString(R.string.wifi_display_notification_disconnect), + mDisconnectPendingIntent) + .build(); + mNotificationManager.notifyAsUser(null, + R.string.wifi_display_notification_title, + notification, UserHandle.ALL); + } + } + + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(ACTION_DISCONNECT)) { + synchronized (getSyncRoot()) { + requestDisconnectLocked(); + } + } } }; @@ -454,4 +551,23 @@ final class WifiDisplayAdapter extends DisplayAdapter { return mInfo; } } + + private final class WifiDisplayHandler extends Handler { + public WifiDisplayHandler(Looper looper) { + super(looper, null, true /*async*/); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_SEND_STATUS_CHANGE_BROADCAST: + handleSendStatusChangeBroadcast(); + break; + + case MSG_UPDATE_NOTIFICATION: + handleUpdateNotification(); + break; + } + } + } } diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java index 4f9375a..072dd33 100644 --- a/services/java/com/android/server/pm/UserManagerService.java +++ b/services/java/com/android/server/pm/UserManagerService.java @@ -62,6 +62,8 @@ public class UserManagerService extends IUserManager.Stub { private static final String LOG_TAG = "UserManagerService"; + private static final boolean DBG = false; + private static final String TAG_NAME = "name"; private static final String ATTR_FLAGS = "flags"; private static final String ATTR_ICON_PATH = "icon"; @@ -97,6 +99,9 @@ public class UserManagerService extends IUserManager.Stub { private int[] mUserIds; private boolean mGuestEnabled; private int mNextSerialNumber; + // This resets on a reboot. Otherwise it keeps incrementing so that user ids are + // not reused in quick succession + private int mNextUserId = MIN_USER_ID; private static UserManagerService sInstance; @@ -149,7 +154,7 @@ public class UserManagerService extends IUserManager.Stub { -1, -1); mUserListFile = new File(mUsersDir, USER_LIST_FILENAME); readUserListLocked(); - // Prune out any partially created users. + // Prune out any partially created/partially removed users. ArrayList<UserInfo> partials = new ArrayList<UserInfo>(); for (int i = 0; i < mUsers.size(); i++) { UserInfo ui = mUsers.valueAt(i); @@ -199,7 +204,8 @@ public class UserManagerService extends IUserManager.Stub { */ private UserInfo getUserInfoLocked(int userId) { UserInfo ui = mUsers.get(userId); - if (ui != null && ui.partial) { + // If it is partial and not in the process of being removed, return as unknown user. + if (ui != null && ui.partial && !mRemovingUserIds.contains(userId)) { Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId); return null; } @@ -459,7 +465,7 @@ public class UserManagerService extends IUserManager.Stub { private void fallbackToSingleUserLocked() { // Create the primary user UserInfo primary = new UserInfo(0, "Primary", null, - UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); + UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED); mUsers.put(0, primary); mNextSerialNumber = MIN_USER_ID; updateUserIdsLocked(); @@ -668,6 +674,7 @@ public class UserManagerService extends IUserManager.Stub { long now = System.currentTimeMillis(); userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0; userInfo.partial = true; + Environment.getUserSystemDirectory(userInfo.id).mkdirs(); mUsers.put(userId, userInfo); writeUserListLocked(); writeUserLocked(userInfo); @@ -703,8 +710,13 @@ public class UserManagerService extends IUserManager.Stub { return false; } mRemovingUserIds.add(userHandle); + // Set this to a partially created user, so that the user will be purged + // on next startup, in case the runtime stops now before stopping and + // removing the user completely. + user.partial = true; + writeUserLocked(user); } - + if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle); int res; try { res = ActivityManagerNative.getDefault().stopUser(userHandle, @@ -725,12 +737,13 @@ public class UserManagerService extends IUserManager.Stub { } void finishRemoveUser(int userHandle) { + if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userHandle); synchronized (mInstallLock) { synchronized (mPackagesLock) { removeUserStateLocked(userHandle); } } - + if (DBG) Slog.i(LOG_TAG, "Removed user " + userHandle + ", sending broadcast"); // Let other services shutdown any activity long ident = Binder.clearCallingIdentity(); try { @@ -799,10 +812,11 @@ public class UserManagerService extends IUserManager.Stub { num++; } } - int[] newUsers = new int[num]; + final int[] newUsers = new int[num]; + int n = 0; for (int i = 0; i < mUsers.size(); i++) { if (!mUsers.valueAt(i).partial) { - newUsers[i] = mUsers.keyAt(i); + newUsers[n++] = mUsers.keyAt(i); } } mUserIds = newUsers; @@ -835,13 +849,14 @@ public class UserManagerService extends IUserManager.Stub { */ private int getNextAvailableIdLocked() { synchronized (mPackagesLock) { - int i = MIN_USER_ID; + int i = mNextUserId; while (i < Integer.MAX_VALUE) { if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.contains(i)) { break; } i++; } + mNextUserId = i + 1; return i; } } diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java index 4e692a2..b94bceb 100644 --- a/services/java/com/android/server/power/PowerManagerService.java +++ b/services/java/com/android/server/power/PowerManagerService.java @@ -107,6 +107,8 @@ public final class PowerManagerService extends IPowerManager.Stub private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9; // Dirty bit: screen on blocker state became held or unheld private static final int DIRTY_SCREEN_ON_BLOCKER_RELEASED = 1 << 10; + // Dirty bit: dock state changed + private static final int DIRTY_DOCK_STATE = 1 << 11; // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp(). // The screen should be off or in the process of being turned off by the display controller. @@ -269,6 +271,9 @@ public final class PowerManagerService extends IPowerManager.Stub // draining faster than it is charging and the user activity timeout has expired. private int mBatteryLevelWhenDreamStarted; + // The current dock state. + private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; + // True if the device should wake up when plugged or unplugged. private boolean mWakeUpWhenPluggedOrUnpluggedConfig; @@ -281,6 +286,9 @@ public final class PowerManagerService extends IPowerManager.Stub // True if dreams should be activated on sleep. private boolean mDreamsActivateOnSleepSetting; + // True if dreams should be activated on dock. + private boolean mDreamsActivateOnDockSetting; + // The screen off timeout setting value in milliseconds. private int mScreenOffTimeoutSetting; @@ -440,6 +448,10 @@ public final class PowerManagerService extends IPowerManager.Stub filter.addAction(Intent.ACTION_USER_SWITCHED); mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler); + filter = new IntentFilter(); + filter.addAction(Intent.ACTION_DOCK_EVENT); + mContext.registerReceiver(new DockReceiver(), filter, null, mHandler); + // Register for settings changes. final ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(Settings.Secure.getUriFor( @@ -448,6 +460,9 @@ public final class PowerManagerService extends IPowerManager.Stub resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP), false, mSettingsObserver, UserHandle.USER_ALL); + resolver.registerContentObserver(Settings.Secure.getUriFor( + Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK), + false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_OFF_TIMEOUT), false, mSettingsObserver, UserHandle.USER_ALL); @@ -487,6 +502,9 @@ public final class PowerManagerService extends IPowerManager.Stub mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 0, UserHandle.USER_CURRENT) != 0); + mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver, + Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 0, + UserHandle.USER_CURRENT) != 0); mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT, UserHandle.USER_CURRENT); @@ -1339,13 +1357,14 @@ public final class PowerManagerService extends IPowerManager.Stub private boolean updateWakefulnessLocked(int dirty) { boolean changed = false; if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED - | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE)) != 0) { + | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE + | DIRTY_DOCK_STATE)) != 0) { if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) { if (DEBUG_SPEW) { Slog.d(TAG, "updateWakefulnessLocked: Bed time..."); } final long time = SystemClock.uptimeMillis(); - if (mDreamsActivateOnSleepSetting) { + if (shouldNapAtBedTimeLocked()) { changed = napNoUpdateLocked(time); } else { changed = goToSleepNoUpdateLocked(time, @@ -1357,6 +1376,16 @@ public final class PowerManagerService extends IPowerManager.Stub } /** + * Returns true if the device should automatically nap and start dreaming when the user + * activity timeout has expired and it's bedtime. + */ + private boolean shouldNapAtBedTimeLocked() { + return mDreamsActivateOnSleepSetting + || (mDreamsActivateOnDockSetting + && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED); + } + + /** * Returns true if the device should go to sleep now. * Also used when exiting a dream to determine whether we should go back * to being fully awake or else go to sleep for good. @@ -2124,6 +2153,7 @@ public final class PowerManagerService extends IPowerManager.Stub pw.println(" mPlugType=" + mPlugType); pw.println(" mBatteryLevel=" + mBatteryLevel); pw.println(" mBatteryLevelWhenDreamStarted=" + mBatteryLevelWhenDreamStarted); + pw.println(" mDockState=" + mDockState); pw.println(" mStayOn=" + mStayOn); pw.println(" mProximityPositive=" + mProximityPositive); pw.println(" mBootCompleted=" + mBootCompleted); @@ -2149,6 +2179,7 @@ public final class PowerManagerService extends IPowerManager.Stub pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig); pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting); pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting); + pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting); pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting); pw.println(" mMaximumScreenOffTimeoutFromDeviceAdmin=" + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced=" @@ -2267,6 +2298,21 @@ public final class PowerManagerService extends IPowerManager.Stub } } + private final class DockReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + synchronized (mLock) { + int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, + Intent.EXTRA_DOCK_STATE_UNDOCKED); + if (mDockState != dockState) { + mDockState = dockState; + mDirty |= DIRTY_DOCK_STATE; + updatePowerStateLocked(); + } + } + } + } + private final class SettingsObserver extends ContentObserver { public SettingsObserver(Handler handler) { super(handler); diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 77d815b..e74b6db 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -265,7 +265,7 @@ public class WindowManagerService extends IWindowManager.Stub static final int DEFAULT_FADE_IN_OUT_DURATION = 400; /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */ - static final int WINDOW_FREEZE_TIMEOUT_DURATION = 3000; + static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000; /** * If true, the window manager will do its own custom freezing and general @@ -2420,6 +2420,7 @@ public class WindowManagerService extends IWindowManager.Stub final WindowList windows = win.getWindowList(); windows.remove(win); mPendingRemove.remove(win); + mResizingWindows.remove(win); mWindowsChanged = true; if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win); @@ -2823,16 +2824,9 @@ public class WindowManagerService extends IWindowManager.Stub "Relayout window turning screen on: " + win); win.mTurnOnScreen = true; } - int diff = 0; - if (win.mConfiguration != mCurConfiguration - && (win.mConfiguration == null - || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) { - win.mConfiguration = mCurConfiguration; - if (DEBUG_CONFIGURATION) { - Slog.i(TAG, "Window " + win + " visible with new config: " - + win.mConfiguration + " / 0x" - + Integer.toHexString(diff)); - } + if (win.isConfigChanged()) { + if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win + + " visible with new config: " + win.mConfiguration); outConfig.setTo(mCurConfiguration); } } @@ -6576,6 +6570,36 @@ public class WindowManagerService extends IWindowManager.Stub } } + private void scheduleNotifyWindowLayersChangedIfNeededLocked(DisplayContent displayContent) { + if (displayContent.mDisplayContentChangeListeners != null + && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) { + mH.obtainMessage(H.NOTIFY_WINDOW_LAYERS_CHANGED, displayContent) .sendToTarget(); + } + } + + private void handleNotifyWindowLayersChanged(DisplayContent displayContent) { + RemoteCallbackList<IDisplayContentChangeListener> callbacks = null; + synchronized (mWindowMap) { + callbacks = displayContent.mDisplayContentChangeListeners; + if (callbacks == null) { + return; + } + } + try { + final int watcherCount = callbacks.beginBroadcast(); + for (int i = 0; i < watcherCount; i++) { + try { + callbacks.getBroadcastItem(i).onWindowLayersChanged( + displayContent.getDisplayId()); + } catch (RemoteException re) { + /* ignore */ + } + } + } finally { + callbacks.finishBroadcast(); + } + } + public void addWindowChangeListener(WindowChangeListener listener) { synchronized(mWindowMap) { mWindowChangeListeners.add(listener); @@ -7222,12 +7246,13 @@ public class WindowManagerService extends IWindowManager.Stub public static final int NOTIFY_ROTATION_CHANGED = 28; public static final int NOTIFY_WINDOW_TRANSITION = 29; public static final int NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 30; + public static final int NOTIFY_WINDOW_LAYERS_CHANGED = 31; - public static final int DO_DISPLAY_ADDED = 31; - public static final int DO_DISPLAY_REMOVED = 32; - public static final int DO_DISPLAY_CHANGED = 33; + public static final int DO_DISPLAY_ADDED = 32; + public static final int DO_DISPLAY_REMOVED = 33; + public static final int DO_DISPLAY_CHANGED = 34; - public static final int CLIENT_FREEZE_TIMEOUT = 34; + public static final int CLIENT_FREEZE_TIMEOUT = 35; public static final int ANIMATOR_WHAT_OFFSET = 100000; public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1; @@ -7699,6 +7724,12 @@ public class WindowManagerService extends IWindowManager.Stub break; } + case NOTIFY_WINDOW_LAYERS_CHANGED: { + DisplayContent displayContent = (DisplayContent) msg.obj; + handleNotifyWindowLayersChanged(displayContent); + break; + } + case DO_DISPLAY_ADDED: synchronized (mWindowMap) { handleDisplayAddedLocked(msg.arg1); @@ -8075,6 +8106,8 @@ public class WindowManagerService extends IWindowManager.Stub Slog.v(TAG, "Assigning layers", here); } + boolean anyLayerChanged = false; + for (i=0; i<N; i++) { final WindowState w = windows.get(i); final WindowStateAnimator winAnimator = w.mWinAnimator; @@ -8090,6 +8123,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (w.mLayer != oldLayer) { layerChanged = true; + anyLayerChanged = true; } oldLayer = winAnimator.mAnimLayer; if (w.mTargetAppToken != null) { @@ -8108,6 +8142,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (winAnimator.mAnimLayer != oldLayer) { layerChanged = true; + anyLayerChanged = true; } if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) { // Force an animation pass just to update the mDimAnimator layer. @@ -8122,10 +8157,22 @@ public class WindowManagerService extends IWindowManager.Stub //System.out.println( // "Assigned layer " + curLayer + " to " + w.mClient.asBinder()); } + + if (anyLayerChanged) { + scheduleNotifyWindowLayersChangedIfNeededLocked(getDefaultDisplayContentLocked()); + } } - private boolean mInLayout = false; private final void performLayoutAndPlaceSurfacesLocked() { + do { + mTraversalScheduled = false; + performLayoutAndPlaceSurfacesLockedLoop(); + mH.removeMessages(H.DO_TRAVERSAL); + } while (mTraversalScheduled); + } + + private boolean mInLayout = false; + private final void performLayoutAndPlaceSurfacesLockedLoop() { if (mInLayout) { if (DEBUG) { throw new RuntimeException("Recursive call!"); @@ -8260,7 +8307,7 @@ public class WindowManagerService extends IWindowManager.Stub Slog.v(TAG, "1ST PASS " + win + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame + " mLayoutAttached=" + win.mLayoutAttached - + " screen changed=" + win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE)); + + " screen changed=" + win.isConfigChanged()); final AppWindowToken atoken = win.mAppToken; if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + win.mViewVisibility + " mRelayoutCalled=" @@ -8282,7 +8329,7 @@ public class WindowManagerService extends IWindowManager.Stub // windows, since that means "perform layout as normal, // just don't display"). if (!gone || !win.mHaveFrame || win.mLayoutNeeded - || win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE) + || win.isConfigChanged() || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) { if (!win.mLayoutAttached) { if (initial) { diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index feb29b1..c195f45 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -1038,18 +1038,26 @@ final class WindowState implements WindowManagerPolicy.WindowState { } boolean isHiddenFromUserLocked() { - // Save some cycles by not calling getDisplayInfo unless it is an application - // window intended for all users. - if (mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW - && mAppToken != null && mAppToken.showWhenLocked) { - final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo(); - if (isFullscreen(displayInfo.appWidth, displayInfo.appHeight)) { + // Attached windows are evaluated based on the window that they are attached to. + WindowState win = this; + while (win.mAttachedWindow != null) { + win = win.mAttachedWindow; + } + if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW + && win.mAppToken != null && win.mAppToken.showWhenLocked) { + // Save some cycles by not calling getDisplayInfo unless it is an application + // window intended for all users. + final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo(); + if (win.mFrame.left <= 0 && win.mFrame.top <= 0 + && win.mFrame.right >= displayInfo.appWidth + && win.mFrame.bottom >= displayInfo.appHeight) { // Is a fullscreen window, like the clock alarm. Show to everyone. return false; } } - return mShowToOwnerOnly && UserHandle.getUserId(mOwnerUid) != mService.mCurrentUserId; + return win.mShowToOwnerOnly + && UserHandle.getUserId(win.mOwnerUid) != mService.mCurrentUserId; } private static void applyInsets(Region outRegion, Rect frame, Rect inset) { diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 4cb409d..9118aea 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -33,6 +33,15 @@ <meta-data android:name="android.graphics.renderThread" android:value="true" /> <activity + android:name="MipMapActivity" + android:label="_MipMap"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="PathOffsetActivity" android:label="_PathOffset"> <intent-filter> diff --git a/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg Binary files differnew file mode 100644 index 0000000..7f047b1 --- /dev/null +++ b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java index 8cc2246..854dd69 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java @@ -68,9 +68,16 @@ public class BitmapMeshActivity extends Activity { super.onDraw(canvas); canvas.drawARGB(255, 255, 255, 255); + canvas.translate(100, 100); canvas.drawBitmapMesh(mBitmap1, 3, 3, mVertices, 0, null, 0, null); + canvas.save(); + canvas.translate(0, 400); + canvas.clipRect(0.0f, 0.0f, 80.0f, 80.0f); + canvas.drawBitmapMesh(mBitmap1, 3, 3, mVertices, 0, null, 0, null); + canvas.restore(); + canvas.translate(400, 0); canvas.drawBitmapMesh(mBitmap1, 3, 3, mVertices, 0, mColors, 0, null); } diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java new file mode 100644 index 0000000..1034649 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010 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.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.os.Bundle; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.ScaleAnimation; +import android.widget.FrameLayout; + +@SuppressWarnings({"UnusedDeclaration"}) +public class MipMapActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final BitmapsView view = new BitmapsView(this); + setContentView(view); + } + + static class BitmapsView extends View { + private Paint mBitmapPaint; + private final Bitmap mBitmap1; + private final Bitmap mBitmap2; + + BitmapsView(Context c) { + super(c); + + mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo); + mBitmap2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo); + + mBitmap1.setHasMipMap(true); + + mBitmapPaint = new Paint(); + mBitmapPaint.setFilterBitmap(true); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + canvas.save(); + canvas.scale(0.3f, 0.3f); + canvas.drawBitmap(mBitmap1, 0, 0, mBitmapPaint); + canvas.restore(); + + canvas.save(); + canvas.translate(mBitmap1.getWidth() * 0.3f + 96.0f, 0.0f); + canvas.scale(0.3f, 0.3f); + canvas.drawBitmap(mBitmap2, 0, 0, mBitmapPaint); + canvas.restore(); + } + } +} diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png Binary files differnew file mode 100644 index 0000000..84e6bc8 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back_default.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back_default.png Binary files differdeleted file mode 100644 index ac5a97b..0000000 --- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back_default.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png Binary files differnew file mode 100644 index 0000000..38e4f45 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home_default.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home_default.png Binary files differdeleted file mode 100644 index a90dc9b..0000000 --- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home_default.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png Binary files differnew file mode 100644 index 0000000..bf9f300 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent_default.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent_default.png Binary files differdeleted file mode 100644 index cb3c433..0000000 --- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent_default.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png Binary files differnew file mode 100644 index 0000000..a00bc5b --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back_default.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back_default.png Binary files differdeleted file mode 100644 index 5ab09f0..0000000 --- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back_default.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png Binary files differnew file mode 100644 index 0000000..dc3183b --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home_default.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home_default.png Binary files differdeleted file mode 100644 index 62ca427..0000000 --- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home_default.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png Binary files differnew file mode 100644 index 0000000..b07f611 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent_default.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent_default.png Binary files differdeleted file mode 100644 index ff698fb..0000000 --- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent_default.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml index c5acddb..599ca08 100644 --- a/tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml +++ b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml @@ -1,5 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1"/> <ImageView android:layout_height="wrap_content" android:layout_width="wrap_content"/> @@ -13,12 +17,4 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1"/> - <ImageView - android:layout_height="wrap_content" - android:layout_width="wrap_content"/> - <ImageView - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:layout_marginLeft="3dip" - android:layout_marginRight="15dip"/> </merge> diff --git a/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml index d3c492e..d3c492e 100644 --- a/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml +++ b/tools/layoutlib/bridge/resources/bars/status_bar.xml diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png Binary files differnew file mode 100644 index 0000000..bd60cd6 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back_default.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back_default.png Binary files differdeleted file mode 100644 index 4cb305d..0000000 --- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back_default.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png Binary files differnew file mode 100644 index 0000000..c5bc5c9 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home_default.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home_default.png Binary files differdeleted file mode 100644 index 31d35c8..0000000 --- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home_default.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png Binary files differnew file mode 100644 index 0000000..f621d9c --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent_default.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent_default.png Binary files differdeleted file mode 100644 index f0cc341..0000000 --- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent_default.png +++ /dev/null diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index daf520b..bf8658e 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -210,7 +210,8 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { Capability.PLAY_ANIMATION, Capability.ANIMATED_VIEW_MANIPULATION, Capability.ADAPTER_BINDING, - Capability.EXTENDED_VIEWINFO); + Capability.EXTENDED_VIEWINFO, + Capability.FIXED_SCALABLE_NINE_PATCH); BridgeAssetManager.initSystem(); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java index 62c886b..ea9d8d9 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java @@ -60,11 +60,15 @@ abstract class CustomBar extends LinearLayout { protected abstract TextView getStyleableTextView(); - protected CustomBar(Context context, Density density, String layoutPath, String name) - throws XmlPullParserException { + protected CustomBar(Context context, Density density, int orientation, String layoutPath, + String name) throws XmlPullParserException { super(context); - setOrientation(LinearLayout.HORIZONTAL); - setGravity(Gravity.CENTER_VERTICAL); + setOrientation(orientation); + if (orientation == LinearLayout.HORIZONTAL) { + setGravity(Gravity.CENTER_VERTICAL); + } else { + setGravity(Gravity.CENTER_HORIZONTAL); + } LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java index 68f5aba..226649d 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java @@ -21,6 +21,7 @@ import com.android.resources.Density; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; +import android.widget.LinearLayout; import android.widget.TextView; public class FakeActionBar extends CustomBar { @@ -29,7 +30,7 @@ public class FakeActionBar extends CustomBar { public FakeActionBar(Context context, Density density, String label, String icon) throws XmlPullParserException { - super(context, density, "/bars/action_bar.xml", "action_bar.xml"); + super(context, density, LinearLayout.HORIZONTAL, "/bars/action_bar.xml", "action_bar.xml"); // Cannot access the inside items through id because no R.id values have been // created for them. diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java index 456ddb4..cc90d6b 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java @@ -17,34 +17,34 @@ package com.android.layoutlib.bridge.bars; import com.android.resources.Density; -import com.android.resources.ResourceType; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LevelListDrawable; +import android.widget.LinearLayout; import android.widget.TextView; -public class TabletSystemBar extends CustomBar { +public class NavigationBar extends CustomBar { - public TabletSystemBar(Context context, Density density) throws XmlPullParserException { - super(context, density, "/bars/tablet_system_bar.xml", "tablet_system_bar.xml"); + public NavigationBar(Context context, Density density, int orientation) throws XmlPullParserException { + super(context, density, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml"); setBackgroundColor(0xFF000000); // Cannot access the inside items through id because no R.id values have been // created for them. // We do know the order though. - loadIcon(0, "ic_sysbar_back_default.png", density); - loadIcon(1, "ic_sysbar_home_default.png", density); - loadIcon(2, "ic_sysbar_recent_default.png", density); - // 3 is the spacer - loadIcon(4, "stat_sys_wifi_signal_4_fully.png", density); - Drawable drawable = loadIcon(5, ResourceType.DRAWABLE, "stat_sys_battery_charge"); - if (drawable instanceof LevelListDrawable) { - ((LevelListDrawable) drawable).setLevel(100); + // 0 is a spacer. + int back = 1; + int recent = 3; + if (orientation == LinearLayout.VERTICAL) { + back = 3; + recent = 1; } + + loadIcon(back, "ic_sysbar_back.png", density); + loadIcon(2, "ic_sysbar_home.png", density); + loadIcon(recent, "ic_sysbar_recent.png", density); } @Override diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java index 7521011..5c08412 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java @@ -25,12 +25,13 @@ import android.content.Context; import android.graphics.drawable.Drawable; import android.graphics.drawable.LevelListDrawable; import android.view.Gravity; +import android.widget.LinearLayout; import android.widget.TextView; -public class PhoneSystemBar extends CustomBar { +public class StatusBar extends CustomBar { - public PhoneSystemBar(Context context, Density density) throws XmlPullParserException { - super(context, density, "/bars/phone_system_bar.xml", "phone_system_bar.xml"); + public StatusBar(Context context, Density density) throws XmlPullParserException { + super(context, density, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml"); // FIXME: use FILL_H? setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java index 5f5ebc4..c27859f 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java @@ -21,6 +21,7 @@ import com.android.resources.Density; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; +import android.widget.LinearLayout; import android.widget.TextView; public class TitleBar extends CustomBar { @@ -29,7 +30,7 @@ public class TitleBar extends CustomBar { public TitleBar(Context context, Density density, String label) throws XmlPullParserException { - super(context, density, "/bars/title_bar.xml", "title_bar.xml"); + super(context, density, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml"); // Cannot access the inside items through id because no R.id values have been // created for them. diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java index a235ec3..803849f 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java @@ -21,9 +21,12 @@ import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; /** @@ -38,14 +41,21 @@ public class ParserFactory { public static XmlPullParser create(File f) throws XmlPullParserException, FileNotFoundException { - KXmlParser parser = instantiateParser(f.getName()); - parser.setInput(new FileInputStream(f), ENCODING); - return parser; + InputStream stream = new FileInputStream(f); + return create(stream, f.getName(), f.length()); } public static XmlPullParser create(InputStream stream, String name) + throws XmlPullParserException { + return create(stream, name, -1); + } + + private static XmlPullParser create(InputStream stream, String name, long size) throws XmlPullParserException { KXmlParser parser = instantiateParser(name); + + stream = readAndClose(stream, name, size); + parser.setInput(stream, ENCODING); return parser; } @@ -61,6 +71,61 @@ public class ParserFactory { return parser; } + private static InputStream readAndClose(InputStream stream, String name, long size) + throws XmlPullParserException { + // just a sanity check. It's doubtful we'll have such big files! + if (size > Integer.MAX_VALUE) { + throw new XmlPullParserException("File " + name + " is too big to be parsed"); + } + int intSize = (int) size; + + // create a buffered reader to facilitate reading. + BufferedInputStream bufferedStream = new BufferedInputStream(stream); + try { + int avail; + if (intSize != -1) { + avail = intSize; + } else { + // get the size to read. + avail = bufferedStream.available(); + } + + // create the initial buffer and read it. + byte[] buffer = new byte[avail]; + int read = stream.read(buffer); + + // this is the easy case. + if (read == intSize) { + return new ByteArrayInputStream(buffer); + } + + // check if there is more to read (read() does not necessarily read all that + // available() returned!) + while ((avail = bufferedStream.available()) > 0) { + if (read + avail > buffer.length) { + // just allocate what is needed. We're mostly reading small files + // so it shouldn't be too problematic. + byte[] moreBuffer = new byte[read + avail]; + System.arraycopy(buffer, 0, moreBuffer, 0, read); + buffer = moreBuffer; + } + + read += stream.read(buffer, read, avail); + } + + // return a new stream encapsulating this buffer. + return new ByteArrayInputStream(buffer); + + } catch (IOException e) { + throw new XmlPullParserException("Failed to read " + name, null, e); + } finally { + try { + bufferedStream.close(); + } catch (IOException e) { + } + } + } + private static class CustomParser extends KXmlParser { private final String mName; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java index de65fd4..f109e39 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java @@ -20,11 +20,12 @@ import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTE import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT; import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; +import com.android.ide.common.rendering.api.HardwareConfig; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.RenderParams; import com.android.ide.common.rendering.api.RenderResources; -import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider; +import com.android.ide.common.rendering.api.Result; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.resources.Density; @@ -98,19 +99,22 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso return result; } + HardwareConfig hardwareConfig = mParams.getHardwareConfig(); + // setup the display Metrics. DisplayMetrics metrics = new DisplayMetrics(); - metrics.densityDpi = metrics.noncompatDensityDpi = mParams.getDensity().getDpiValue(); + metrics.densityDpi = metrics.noncompatDensityDpi = + hardwareConfig.getDensity().getDpiValue(); metrics.density = metrics.noncompatDensity = metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT; metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density; - metrics.widthPixels = metrics.noncompatWidthPixels = mParams.getScreenWidth(); - metrics.heightPixels = metrics.noncompatHeightPixels = mParams.getScreenHeight(); - metrics.xdpi = metrics.noncompatXdpi = mParams.getXdpi(); - metrics.ydpi = metrics.noncompatYdpi = mParams.getYdpi(); + metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth(); + metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight(); + metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi(); + metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi(); RenderResources resources = mParams.getResources(); @@ -305,7 +309,9 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso private Configuration getConfiguration() { Configuration config = new Configuration(); - ScreenSize screenSize = mParams.getConfigScreenSize(); + HardwareConfig hardwareConfig = mParams.getHardwareConfig(); + + ScreenSize screenSize = hardwareConfig.getScreenSize(); if (screenSize != null) { switch (screenSize) { case SMALL: @@ -323,13 +329,13 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso } } - Density density = mParams.getDensity(); + Density density = hardwareConfig.getDensity(); if (density == null) { density = Density.MEDIUM; } - config.screenWidthDp = mParams.getScreenWidth() / density.getDpiValue(); - config.screenHeightDp = mParams.getScreenHeight() / density.getDpiValue(); + config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue(); + config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue(); if (config.screenHeightDp < config.screenWidthDp) { config.smallestScreenWidthDp = config.screenHeightDp; } else { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java index 8133210..b677131 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java @@ -19,6 +19,7 @@ package com.android.layoutlib.bridge.impl; import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; import com.android.ide.common.rendering.api.DrawableParams; +import com.android.ide.common.rendering.api.HardwareConfig; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.Result.Status; @@ -59,6 +60,7 @@ public class RenderDrawable extends RenderAction<DrawableParams> { try { // get the drawable resource value DrawableParams params = getParams(); + HardwareConfig hardwareConfig = params.getHardwareConfig(); ResourceValue drawableResource = params.getDrawable(); // resolve it @@ -75,15 +77,15 @@ public class RenderDrawable extends RenderAction<DrawableParams> { // get the actual Drawable object to draw Drawable d = ResourceHelper.getDrawable(drawableResource, context); - content.setBackgroundDrawable(d); + content.setBackground(d); // set the AttachInfo on the root view. AttachInfo_Accessor.setAttachInfo(content); // measure - int w = params.getScreenWidth(); - int h = params.getScreenHeight(); + int w = hardwareConfig.getScreenWidth(); + int h = hardwareConfig.getScreenHeight(); int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY); int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY); content.measure(w_spec, h_spec); @@ -99,11 +101,11 @@ public class RenderDrawable extends RenderAction<DrawableParams> { // create an Android bitmap around the BufferedImage Bitmap bitmap = Bitmap_Delegate.createBitmap(image, - true /*isMutable*/, params.getDensity()); + true /*isMutable*/, hardwareConfig.getDensity()); // create a Canvas around the Android bitmap Canvas canvas = new Canvas(bitmap); - canvas.setDensity(params.getDensity().getDpiValue()); + canvas.setDensity(hardwareConfig.getDensity().getDpiValue()); // and draw content.draw(canvas); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index cc0f077..c14af4a 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -24,6 +24,7 @@ import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; import com.android.ide.common.rendering.api.AdapterBinding; +import com.android.ide.common.rendering.api.HardwareConfig; import com.android.ide.common.rendering.api.IAnimationListener; import com.android.ide.common.rendering.api.ILayoutPullParser; import com.android.ide.common.rendering.api.IProjectCallback; @@ -43,13 +44,13 @@ import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; import com.android.layoutlib.bridge.bars.FakeActionBar; -import com.android.layoutlib.bridge.bars.PhoneSystemBar; -import com.android.layoutlib.bridge.bars.TabletSystemBar; +import com.android.layoutlib.bridge.bars.NavigationBar; +import com.android.layoutlib.bridge.bars.StatusBar; import com.android.layoutlib.bridge.bars.TitleBar; import com.android.layoutlib.bridge.impl.binding.FakeAdapter; import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; import com.android.resources.ResourceType; -import com.android.resources.ScreenSize; +import com.android.resources.ScreenOrientation; import com.android.util.Pair; import org.xmlpull.v1.XmlPullParserException; @@ -68,8 +69,8 @@ import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.AttachInfo_Accessor; import android.view.BridgeInflater; -import android.view.IWindowManagerImpl; import android.view.IWindowManager; +import android.view.IWindowManagerImpl; import android.view.Surface; import android.view.View; import android.view.View.MeasureSpec; @@ -124,7 +125,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { private boolean mWindowIsFloating; private int mStatusBarSize; - private int mSystemBarSize; + private int mNavigationBarSize; + private int mNavigationBarOrientation = LinearLayout.HORIZONTAL; private int mTitleBarSize; private int mActionBarSize; @@ -187,7 +189,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { findBackground(resources); findStatusBar(resources, metrics); findActionBar(resources, metrics); - findSystemBar(resources, metrics); + findNavigationBar(resources, metrics); // FIXME: find those out, and possibly add them to the render params boolean hasSystemNavBar = true; @@ -221,19 +223,57 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { try { SessionParams params = getParams(); + HardwareConfig hardwareConfig = params.getHardwareConfig(); BridgeContext context = getContext(); + // the view group that receives the window background. ViewGroup backgroundView = null; if (mWindowIsFloating || params.isForceNoDecor()) { backgroundView = mViewRoot = mContentRoot = new FrameLayout(context); } else { + if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) { + /* + * This is a special case where the navigation bar is on the right. + +-------------------------------------------------+---+ + | Status bar (always) | | + +-------------------------------------------------+ | + | (Layout with background drawable) | | + | +---------------------------------------------+ | | + | | Title/Action bar (optional) | | | + | +---------------------------------------------+ | | + | | Content, vertical extending | | | + | | | | | + | +---------------------------------------------+ | | + +-------------------------------------------------+---+ + + So we create a horizontal layout, with the nav bar on the right, + and the left part is the normal layout below without the nav bar at + the bottom + */ + LinearLayout topLayout = new LinearLayout(context); + mViewRoot = topLayout; + topLayout.setOrientation(LinearLayout.HORIZONTAL); + + try { + NavigationBar navigationBar = new NavigationBar(context, + hardwareConfig.getDensity(), LinearLayout.VERTICAL); + navigationBar.setLayoutParams( + new LinearLayout.LayoutParams( + mNavigationBarSize, + LayoutParams.MATCH_PARENT)); + topLayout.addView(navigationBar); + } catch (XmlPullParserException e) { + + } + } + /* * we're creating the following layout * +-------------------------------------------------+ - | System bar (only in phone UI) | + | Status bar (always) | +-------------------------------------------------+ | (Layout with background drawable) | | +---------------------------------------------+ | @@ -243,20 +283,31 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { | | | | | +---------------------------------------------+ | +-------------------------------------------------+ - | System bar (only in tablet UI) | + | Navigation bar for soft buttons, maybe see above| +-------------------------------------------------+ */ LinearLayout topLayout = new LinearLayout(context); - mViewRoot = topLayout; topLayout.setOrientation(LinearLayout.VERTICAL); + // if we don't already have a view root this is it + if (mViewRoot == null) { + mViewRoot = topLayout; + } else { + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( + LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); + layoutParams.weight = 1; + topLayout.setLayoutParams(layoutParams); + + // this is the case of soft buttons + vertical bar. + // this top layout is the first layout in the horizontal layout. see above) + mViewRoot.addView(topLayout, 0); + } if (mStatusBarSize > 0) { // system bar try { - PhoneSystemBar systemBar = new PhoneSystemBar(context, - params.getDensity()); + StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity()); systemBar.setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, mStatusBarSize)); @@ -280,7 +331,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (mActionBarSize > 0) { try { FakeActionBar actionBar = new FakeActionBar(context, - params.getDensity(), + hardwareConfig.getDensity(), params.getAppLabel(), params.getAppIcon()); actionBar.setLayoutParams( new LinearLayout.LayoutParams( @@ -292,7 +343,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } else if (mTitleBarSize > 0) { try { TitleBar titleBar = new TitleBar(context, - params.getDensity(), params.getAppLabel()); + hardwareConfig.getDensity(), params.getAppLabel()); titleBar.setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, mTitleBarSize)); @@ -310,15 +361,16 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { mContentRoot.setLayoutParams(layoutParams); backgroundLayout.addView(mContentRoot); - if (mSystemBarSize > 0) { + if (mNavigationBarOrientation == LinearLayout.HORIZONTAL && + mNavigationBarSize > 0) { // system bar try { - TabletSystemBar systemBar = new TabletSystemBar(context, - params.getDensity()); - systemBar.setLayoutParams( + NavigationBar navigationBar = new NavigationBar(context, + hardwareConfig.getDensity(), LinearLayout.HORIZONTAL); + navigationBar.setLayoutParams( new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, mSystemBarSize)); - topLayout.addView(systemBar); + LayoutParams.MATCH_PARENT, mNavigationBarSize)); + topLayout.addView(navigationBar); } catch (XmlPullParserException e) { } @@ -346,7 +398,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // get the background drawable if (mWindowBackground != null && backgroundView != null) { Drawable d = ResourceHelper.getDrawable(mWindowBackground, context); - backgroundView.setBackgroundDrawable(d); + backgroundView.setBackground(d); } return SUCCESS.createResult(); @@ -389,13 +441,14 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } RenderingMode renderingMode = params.getRenderingMode(); + HardwareConfig hardwareConfig = params.getHardwareConfig(); // only do the screen measure when needed. boolean newRenderSize = false; if (mMeasuredScreenWidth == -1) { newRenderSize = true; - mMeasuredScreenWidth = params.getScreenWidth(); - mMeasuredScreenHeight = params.getScreenHeight(); + mMeasuredScreenWidth = hardwareConfig.getScreenWidth(); + mMeasuredScreenHeight = hardwareConfig.getScreenHeight(); if (renderingMode != RenderingMode.NORMAL) { int widthMeasureSpecMode = renderingMode.isHorizExpand() ? @@ -495,11 +548,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // create an Android bitmap around the BufferedImage Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, - true /*isMutable*/, params.getDensity()); + true /*isMutable*/, hardwareConfig.getDensity()); // create a Canvas around the Android bitmap mCanvas = new Canvas(bitmap); - mCanvas.setDensity(params.getDensity().getDpiValue()); + mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue()); } if (freshRender && newImage == false) { @@ -972,30 +1025,28 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } } - private boolean isTabletUi() { - return getParams().getConfigScreenSize() == ScreenSize.XLARGE; + private boolean hasSoftwareButtons() { + return getParams().getHardwareConfig().hasSoftwareButtons(); } private void findStatusBar(RenderResources resources, DisplayMetrics metrics) { - if (isTabletUi() == false) { - boolean windowFullscreen = getBooleanThemeValue(resources, - "windowFullscreen", false /*defaultValue*/); + boolean windowFullscreen = getBooleanThemeValue(resources, + "windowFullscreen", false /*defaultValue*/); - if (windowFullscreen == false && mWindowIsFloating == false) { - // default value - mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT; + if (windowFullscreen == false && mWindowIsFloating == false) { + // default value + mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT; - // get the real value - ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, - "status_bar_height"); + // get the real value + ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, + "status_bar_height"); - if (value != null) { - TypedValue typedValue = ResourceHelper.getValue("status_bar_height", - value.getValue(), true /*requireUnit*/); - if (typedValue != null) { - // compute the pixel value based on the display metrics - mStatusBarSize = (int)typedValue.getDimension(metrics); - } + if (value != null) { + TypedValue typedValue = ResourceHelper.getValue("status_bar_height", + value.getValue(), true /*requireUnit*/); + if (typedValue != null) { + // compute the pixel value based on the display metrics + mStatusBarSize = (int)typedValue.getDimension(metrics); } } } @@ -1062,22 +1113,48 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } } - private void findSystemBar(RenderResources resources, DisplayMetrics metrics) { - if (isTabletUi() && mWindowIsFloating == false) { + private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) { + if (hasSoftwareButtons() && mWindowIsFloating == false) { // default value - mSystemBarSize = 48; // ?? + mNavigationBarSize = 48; // ?? + + HardwareConfig hardwareConfig = getParams().getHardwareConfig(); + + boolean barOnBottom = true; + + if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) { + // compute the dp of the screen. + int shortSize = hardwareConfig.getScreenHeight(); + + // compute in dp + int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / hardwareConfig.getDensity().getDpiValue(); + + if (shortSizeDp < 600) { + // 0-599dp: "phone" UI with bar on the side + barOnBottom = false; + } else { + // 600+dp: "tablet" UI with bar on the bottom + barOnBottom = true; + } + } + + if (barOnBottom) { + mNavigationBarOrientation = LinearLayout.HORIZONTAL; + } else { + mNavigationBarOrientation = LinearLayout.VERTICAL; + } // get the real value ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, - "status_bar_height"); + barOnBottom ? "navigation_bar_height" : "navigation_bar_width"); if (value != null) { - TypedValue typedValue = ResourceHelper.getValue("status_bar_height", + TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height", value.getValue(), true /*requireUnit*/); if (typedValue != null) { // compute the pixel value based on the display metrics - mSystemBarSize = (int)typedValue.getDimension(metrics); + mNavigationBarSize = (int)typedValue.getDimension(metrics); } } } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index e913d10..b871cdc 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1983,7 +1983,9 @@ public class WifiManager { protected void finalize() throws Throwable { try { - mHandler.getLooper().quit(); + if (mHandler != null && mHandler.getLooper() != null) { + mHandler.getLooper().quit(); + } } finally { super.finalize(); } diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java index 93ab4a4..0b0d738 100644 --- a/wifi/java/android/net/wifi/WifiMonitor.java +++ b/wifi/java/android/net/wifi/WifiMonitor.java @@ -178,6 +178,7 @@ public class WifiMonitor { private static final String P2P_GO_NEG_SUCCESS_STR = "P2P-GO-NEG-SUCCESS"; + /* P2P-GO-NEG-FAILURE status=x */ private static final String P2P_GO_NEG_FAILURE_STR = "P2P-GO-NEG-FAILURE"; private static final String P2P_GROUP_FORMATION_SUCCESS_STR = @@ -566,6 +567,26 @@ public class WifiMonitor { WifiManager.ERROR, 0)); } + /* <event> status=<err> and the special case of <event> reason=FREQ_CONFLICT */ + private P2pStatus p2pError(String dataString) { + P2pStatus err = P2pStatus.UNKNOWN; + String[] tokens = dataString.split(" "); + if (tokens.length < 2) return err; + String[] nameValue = tokens[1].split("="); + if (nameValue.length != 2) return err; + + /* Handle the special case of reason=FREQ+CONFLICT */ + if (nameValue[1].equals("FREQ_CONFLICT")) { + return P2pStatus.NO_COMMON_CHANNEL; + } + try { + err = P2pStatus.valueOf(Integer.parseInt(nameValue[1])); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + return err; + } + /** * Handle p2p events */ @@ -582,11 +603,11 @@ public class WifiMonitor { } else if (dataString.startsWith(P2P_GO_NEG_SUCCESS_STR)) { mStateMachine.sendMessage(P2P_GO_NEGOTIATION_SUCCESS_EVENT); } else if (dataString.startsWith(P2P_GO_NEG_FAILURE_STR)) { - mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT); + mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT, p2pError(dataString)); } else if (dataString.startsWith(P2P_GROUP_FORMATION_SUCCESS_STR)) { mStateMachine.sendMessage(P2P_GROUP_FORMATION_SUCCESS_EVENT); } else if (dataString.startsWith(P2P_GROUP_FORMATION_FAILURE_STR)) { - mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT); + mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT, p2pError(dataString)); } else if (dataString.startsWith(P2P_GROUP_STARTED_STR)) { mStateMachine.sendMessage(P2P_GROUP_STARTED_EVENT, new WifiP2pGroup(dataString)); } else if (dataString.startsWith(P2P_GROUP_REMOVED_STR)) { @@ -595,17 +616,7 @@ public class WifiMonitor { mStateMachine.sendMessage(P2P_INVITATION_RECEIVED_EVENT, new WifiP2pGroup(dataString)); } else if (dataString.startsWith(P2P_INVITATION_RESULT_STR)) { - String[] tokens = dataString.split(" "); - if (tokens.length != 2) return; - String[] nameValue = tokens[1].split("="); - if (nameValue.length != 2) return; - P2pStatus err = P2pStatus.UNKNOWN; - try { - err = P2pStatus.valueOf(Integer.parseInt(nameValue[1])); - } catch (NumberFormatException e) { - e.printStackTrace(); - } - mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, err); + mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, p2pError(dataString)); } else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) { mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT, new WifiP2pProvDiscEvent(dataString)); diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index db539e4..fd76fc8 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -114,6 +114,7 @@ public class WifiStateMachine extends StateMachine { private final boolean mP2pSupported; private final AtomicBoolean mP2pConnected = new AtomicBoolean(false); + private boolean mTemporarilyDisconnectWifi = false; private final String mPrimaryDeviceType; /* Scan results handling */ @@ -358,8 +359,12 @@ public class WifiStateMachine extends StateMachine { static final int CMD_RESET_SUPPLICANT_STATE = BASE + 111; /* P2p commands */ + /* We are ok with no response here since we wont do much with it anyway */ public static final int CMD_ENABLE_P2P = BASE + 131; - public static final int CMD_DISABLE_P2P = BASE + 132; + /* In order to shut down supplicant cleanly, we wait till p2p has + * been disabled */ + public static final int CMD_DISABLE_P2P_REQ = BASE + 132; + public static final int CMD_DISABLE_P2P_RSP = BASE + 133; private static final int CONNECT_MODE = 1; private static final int SCAN_ONLY_MODE = 2; @@ -457,6 +462,11 @@ public class WifiStateMachine extends StateMachine { private State mDriverStartingState = new DriverStartingState(); /* Driver started */ private State mDriverStartedState = new DriverStartedState(); + /* Wait until p2p is disabled + * This is a special state which is entered right after we exit out of DriverStartedState + * before transitioning to another state. + */ + private State mWaitForP2pDisableState = new WaitForP2pDisableState(); /* Driver stopping */ private State mDriverStoppingState = new DriverStoppingState(); /* Driver stopped */ @@ -698,6 +708,7 @@ public class WifiStateMachine extends StateMachine { addState(mDisconnectingState, mConnectModeState); addState(mDisconnectedState, mConnectModeState); addState(mWpsRunningState, mConnectModeState); + addState(mWaitForP2pDisableState, mSupplicantStartedState); addState(mDriverStoppingState, mSupplicantStartedState); addState(mDriverStoppedState, mSupplicantStartedState); addState(mSupplicantStoppingState, mDefaultState); @@ -2017,6 +2028,10 @@ public class WifiStateMachine extends StateMachine { NetworkInfo info = (NetworkInfo) message.obj; mP2pConnected.set(info.isConnected()); break; + case WifiP2pService.DISCONNECT_WIFI_REQUEST: + mTemporarilyDisconnectWifi = (message.arg1 == 1); + replyToMessage(message, WifiP2pService.DISCONNECT_WIFI_RESPONSE); + break; default: loge("Error! unhandled message" + message); break; @@ -2428,7 +2443,11 @@ public class WifiStateMachine extends StateMachine { WifiConfiguration config; switch(message.what) { case CMD_STOP_SUPPLICANT: /* Supplicant stopped by user */ - transitionTo(mSupplicantStoppingState); + if (mP2pSupported) { + transitionTo(mWaitForP2pDisableState); + } else { + transitionTo(mSupplicantStoppingState); + } break; case WifiMonitor.SUP_DISCONNECTION_EVENT: /* Supplicant connection lost */ loge("Connection lost, restart supplicant"); @@ -2438,7 +2457,11 @@ public class WifiStateMachine extends StateMachine { handleNetworkDisconnect(); sendSupplicantConnectionChangedBroadcast(false); mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE); - transitionTo(mDriverLoadedState); + if (mP2pSupported) { + transitionTo(mWaitForP2pDisableState); + } else { + transitionTo(mDriverLoadedState); + } sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS); break; case WifiMonitor.SCAN_RESULTS_EVENT: @@ -2833,8 +2856,12 @@ public class WifiStateMachine extends StateMachine { } mWakeLock.acquire(); mWifiNative.stopDriver(); - transitionTo(mDriverStoppingState); mWakeLock.release(); + if (mP2pSupported) { + transitionTo(mWaitForP2pDisableState); + } else { + transitionTo(mDriverStoppingState); + } break; case CMD_START_PACKET_FILTERING: if (message.arg1 == MULTICAST_V6) { @@ -2880,8 +2907,63 @@ public class WifiStateMachine extends StateMachine { mIsRunning = false; updateBatteryWorkSource(null); mScanResults = new ArrayList<ScanResult>(); + } + } - if (mP2pSupported) mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P); + class WaitForP2pDisableState extends State { + private State mTransitionToState; + @Override + public void enter() { + if (DBG) log(getName() + "\n"); + EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); + switch (getCurrentMessage().what) { + case WifiMonitor.SUP_DISCONNECTION_EVENT: + mTransitionToState = mDriverLoadedState; + break; + case CMD_DELAYED_STOP_DRIVER: + mTransitionToState = mDriverStoppingState; + break; + case CMD_STOP_SUPPLICANT: + mTransitionToState = mSupplicantStoppingState; + break; + default: + mTransitionToState = mDriverStoppingState; + break; + } + mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_REQ); + } + @Override + public boolean processMessage(Message message) { + if (DBG) log(getName() + message.toString() + "\n"); + switch(message.what) { + case WifiStateMachine.CMD_DISABLE_P2P_RSP: + transitionTo(mTransitionToState); + break; + /* Defer wifi start/shut and driver commands */ + case CMD_LOAD_DRIVER: + case CMD_UNLOAD_DRIVER: + case CMD_START_SUPPLICANT: + case CMD_STOP_SUPPLICANT: + case CMD_START_AP: + case CMD_STOP_AP: + case CMD_START_DRIVER: + case CMD_STOP_DRIVER: + case CMD_SET_SCAN_MODE: + case CMD_SET_SCAN_TYPE: + case CMD_SET_COUNTRY_CODE: + case CMD_SET_FREQUENCY_BAND: + case CMD_START_PACKET_FILTERING: + case CMD_STOP_PACKET_FILTERING: + case CMD_START_SCAN: + case CMD_DISCONNECT: + case CMD_REASSOCIATE: + case CMD_RECONNECT: + deferMessage(message); + break; + default: + return NOT_HANDLED; + } + return HANDLED; } } @@ -3030,6 +3112,15 @@ public class WifiStateMachine extends StateMachine { transitionTo(mDisconnectedState); } break; + case WifiP2pService.DISCONNECT_WIFI_REQUEST: + if (message.arg1 == 1) { + mWifiNative.disconnect(); + mTemporarilyDisconnectWifi = true; + } else { + mWifiNative.reconnect(); + mTemporarilyDisconnectWifi = false; + } + break; /* Do a redundant disconnect without transition */ case CMD_DISCONNECT: mWifiNative.disconnect(); @@ -3159,6 +3250,13 @@ public class WifiStateMachine extends StateMachine { mWifiNative.disconnect(); transitionTo(mDisconnectingState); break; + case WifiP2pService.DISCONNECT_WIFI_REQUEST: + if (message.arg1 == 1) { + mWifiNative.disconnect(); + mTemporarilyDisconnectWifi = true; + transitionTo(mDisconnectingState); + } + break; case CMD_SET_SCAN_MODE: if (message.arg1 == SCAN_ONLY_MODE) { sendMessage(CMD_DISCONNECT); @@ -3465,6 +3563,13 @@ public class WifiStateMachine extends StateMachine { if (DBG) log(getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); + // We dont scan frequently if this is a temporary disconnect + // due to p2p + if (mTemporarilyDisconnectWifi) { + mWifiP2pChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_RESPONSE); + return; + } + mFrameworkScanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(), Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS, mDefaultFrameworkScanIntervalMs); @@ -3579,6 +3684,12 @@ public class WifiStateMachine extends StateMachine { sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN, ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs); } + case CMD_RECONNECT: + case CMD_REASSOCIATE: + // Drop a third party reconnect/reassociate if we are + // tempoarily disconnected for p2p + if (mTemporarilyDisconnectWifi) ret = NOT_HANDLED; + break; default: ret = NOT_HANDLED; } diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java index 9c727f9..c8f0712 100644 --- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java +++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java @@ -556,8 +556,8 @@ public class WifiWatchdogStateMachine extends StateMachine { mLinkProperties = (LinkProperties) intent.getParcelableExtra( WifiManager.EXTRA_LINK_PROPERTIES); if (mPoorNetworkDetectionEnabled) { - if (mWifiInfo == null) { - if (DBG) logd("Ignoring link verification, mWifiInfo is NULL"); + if (mWifiInfo == null || mCurrentBssid == null) { + loge("Ignore, wifiinfo " + mWifiInfo +" bssid " + mCurrentBssid); sendLinkStatusNotification(true); } else { transitionTo(mVerifyingLinkState); @@ -726,7 +726,7 @@ public class WifiWatchdogStateMachine extends StateMachine { } private void handleRssiChange() { - if (mCurrentSignalLevel <= LINK_MONITOR_LEVEL_THRESHOLD) { + if (mCurrentSignalLevel <= LINK_MONITOR_LEVEL_THRESHOLD && mCurrentBssid != null) { transitionTo(mLinkMonitoringState); } else { // stay here @@ -920,11 +920,15 @@ public class WifiWatchdogStateMachine extends StateMachine { if (DBG) logd("########################################"); if (isGood) { mWsmChannel.sendMessage(GOOD_LINK_DETECTED); - mCurrentBssid.mLastTimeGood = SystemClock.elapsedRealtime(); - logd("Good link notification is sent"); + if (mCurrentBssid != null) { + mCurrentBssid.mLastTimeGood = SystemClock.elapsedRealtime(); + } + if (DBG) logd("Good link notification is sent"); } else { mWsmChannel.sendMessage(POOR_LINK_DETECTED); - mCurrentBssid.mLastTimePoor = SystemClock.elapsedRealtime(); + if (mCurrentBssid != null) { + mCurrentBssid.mLastTimePoor = SystemClock.elapsedRealtime(); + } logd("Poor link notification is sent"); } } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java index 70baf13..7f32431 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java @@ -134,6 +134,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000; private static int mGroupCreatingTimeoutIndex = 0; + private static final int DISABLE_P2P_WAIT_TIME_MS = 5 * 1000; + private static int mDisableP2pTimeoutIndex = 0; + /* Set a two minute discover timeout to avoid STA scans from being blocked */ private static final int DISCOVER_TIMEOUT_S = 120; @@ -149,9 +152,30 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private static final int PEER_CONNECTION_USER_ACCEPT = BASE + 2; /* User rejected a peer request */ private static final int PEER_CONNECTION_USER_REJECT = BASE + 3; + /* User wants to disconnect wifi in favour of p2p */ + private static final int DROP_WIFI_USER_ACCEPT = BASE + 4; + /* User wants to keep his wifi connection and drop p2p */ + private static final int DROP_WIFI_USER_REJECT = BASE + 5; + /* Delayed message to timeout p2p disable */ + public static final int DISABLE_P2P_TIMED_OUT = BASE + 6; + /* Commands to the WifiStateMachine */ - public static final int P2P_CONNECTION_CHANGED = BASE + 11; + public static final int P2P_CONNECTION_CHANGED = BASE + 11; + + /* These commands are used to tempoarily disconnect wifi when we detect + * a frequency conflict which would make it impossible to have with p2p + * and wifi active at the same time. + * + * If the user chooses to disable wifi tempoarily, we keep wifi disconnected + * until the p2p connection is done and terminated at which point we will + * bring back wifi up + * + * DISCONNECT_WIFI_REQUEST + * msg.arg1 = 1 enables temporary disconnect and 0 disables it. + */ + public static final int DISCONNECT_WIFI_REQUEST = BASE + 12; + public static final int DISCONNECT_WIFI_RESPONSE = BASE + 13; private final boolean mP2pSupported; @@ -172,6 +196,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private NetworkInfo mNetworkInfo; + private boolean mTempoarilyDisconnectedWifi = false; + /* The transaction Id of service discovery request */ private byte mServiceTransactionId = 0; @@ -222,7 +248,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { PREVIOUS_PROTOCOL_ERROR, /* There is no common channels the both devices can use. */ - NO_COMMON_CHANNE, + NO_COMMON_CHANNEL, /* Unknown p2p group. For example, Device A tries to invoke the previous persistent group, * but device B has removed the specified credential already. */ @@ -257,7 +283,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case 6: return PREVIOUS_PROTOCOL_ERROR; case 7: - return NO_COMMON_CHANNE; + return NO_COMMON_CHANNEL; case 8: return UNKNOWN_P2P_GROUP; case 9: @@ -346,6 +372,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { = new UserAuthorizingInvitationState(); private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState(); private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState(); + private FrequencyConflictState mFrequencyConflictState =new FrequencyConflictState(); private GroupCreatedState mGroupCreatedState = new GroupCreatedState(); private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState(); @@ -400,6 +427,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { addState(mUserAuthorizingInvitationState, mGroupCreatingState); addState(mProvisionDiscoveryState, mGroupCreatingState); addState(mGroupNegotiationState, mGroupCreatingState); + addState(mFrequencyConflictState, mGroupCreatingState); addState(mGroupCreatedState, mP2pEnabledState); addState(mUserAuthorizingJoinState, mGroupCreatedState); addState(mOngoingGroupRemovalState, mGroupCreatedState); @@ -551,16 +579,25 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case WifiMonitor.P2P_DEVICE_LOST_EVENT: case WifiMonitor.P2P_FIND_STOPPED_EVENT: case WifiMonitor.P2P_SERV_DISC_RESP_EVENT: - case WifiStateMachine.CMD_ENABLE_P2P: - case WifiStateMachine.CMD_DISABLE_P2P: case PEER_CONNECTION_USER_ACCEPT: case PEER_CONNECTION_USER_REJECT: + case DISCONNECT_WIFI_RESPONSE: + case DROP_WIFI_USER_ACCEPT: + case DROP_WIFI_USER_REJECT: case GROUP_CREATING_TIMED_OUT: + case DISABLE_P2P_TIMED_OUT: case DhcpStateMachine.CMD_PRE_DHCP_ACTION: case DhcpStateMachine.CMD_POST_DHCP_ACTION: case DhcpStateMachine.CMD_ON_QUIT: case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT: break; + case WifiStateMachine.CMD_ENABLE_P2P: + // Enable is lazy and has no response + break; + case WifiStateMachine.CMD_DISABLE_P2P_REQ: + // If we end up handling in default, p2p is not enabled + mWifiChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP); + break; /* unexpected group created, remove */ case WifiMonitor.P2P_GROUP_STARTED_EVENT: mGroup = (WifiP2pGroup) message.obj; @@ -663,6 +700,13 @@ public class WifiP2pService extends IWifiP2pManager.Stub { class P2pDisablingState extends State { @Override + public void enter() { + if (DBG) logd(getName()); + sendMessageDelayed(obtainMessage(DISABLE_P2P_TIMED_OUT, + ++mDisableP2pTimeoutIndex, 0), DISABLE_P2P_WAIT_TIME_MS); + } + + @Override public boolean processMessage(Message message) { if (DBG) logd(getName() + message.toString()); switch (message.what) { @@ -671,14 +715,25 @@ public class WifiP2pService extends IWifiP2pManager.Stub { transitionTo(mP2pDisabledState); break; case WifiStateMachine.CMD_ENABLE_P2P: - case WifiStateMachine.CMD_DISABLE_P2P: + case WifiStateMachine.CMD_DISABLE_P2P_REQ: deferMessage(message); break; + case DISABLE_P2P_TIMED_OUT: + if (mGroupCreatingTimeoutIndex == message.arg1) { + loge("P2p disable timed out"); + transitionTo(mP2pDisabledState); + } + break; default: return NOT_HANDLED; } return HANDLED; } + + @Override + public void exit() { + mWifiChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP); + } } class P2pDisabledState extends State { @@ -702,9 +757,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mWifiMonitor.startMonitoring(); transitionTo(mP2pEnablingState); break; - case WifiStateMachine.CMD_DISABLE_P2P: - //Nothing to do - break; default: return NOT_HANDLED; } @@ -731,7 +783,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { transitionTo(mP2pDisabledState); break; case WifiStateMachine.CMD_ENABLE_P2P: - case WifiStateMachine.CMD_DISABLE_P2P: + case WifiStateMachine.CMD_DISABLE_P2P_REQ: deferMessage(message); break; default: @@ -762,7 +814,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case WifiStateMachine.CMD_ENABLE_P2P: //Nothing to do break; - case WifiStateMachine.CMD_DISABLE_P2P: + case WifiStateMachine.CMD_DISABLE_P2P_REQ: if (mPeers.clear()) sendP2pPeersChangedBroadcast(); if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast(); @@ -1027,20 +1079,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { // remain at this state. } break; - case WifiMonitor.P2P_GROUP_STARTED_EVENT: - mGroup = (WifiP2pGroup) message.obj; - if (DBG) logd(getName() + " group started"); - - if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) { - // This is an invocation case. - mAutonomousGroup = false; - deferMessage(message); - transitionTo(mGroupNegotiationState); - } else { - return NOT_HANDLED; - } - break; - default: + default: return NOT_HANDLED; } return HANDLED; @@ -1074,6 +1113,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub { // mSavedPeerConfig can be empty if (mSavedPeerConfig != null && !mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) { + if (DBG) { + logd("mSavedPeerConfig " + mSavedPeerConfig.deviceAddress + + "device " + device.deviceAddress); + } // Do the regular device lost handling ret = NOT_HANDLED; break; @@ -1269,6 +1312,12 @@ public class WifiP2pService extends IWifiP2pManager.Stub { transitionTo(mGroupCreatedState); break; case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT: + P2pStatus status = (P2pStatus) message.obj; + if (status == P2pStatus.NO_COMMON_CHANNEL) { + transitionTo(mFrequencyConflictState); + break; + } + /* continue with group removal handling */ case WifiMonitor.P2P_GROUP_REMOVED_EVENT: if (DBG) logd(getName() + " go failure"); handleGroupCreationFailure(); @@ -1278,9 +1327,14 @@ public class WifiP2pService extends IWifiP2pManager.Stub { // a group removed event. Flushing things at group formation // failure causes supplicant issues. Ignore right now. case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT: + status = (P2pStatus) message.obj; + if (status == P2pStatus.NO_COMMON_CHANNEL) { + transitionTo(mFrequencyConflictState); + break; + } break; case WifiMonitor.P2P_INVITATION_RESULT_EVENT: - P2pStatus status = (P2pStatus)message.obj; + status = (P2pStatus)message.obj; if (status == P2pStatus.SUCCESS) { // invocation was succeeded. // wait P2P_GROUP_STARTED_EVENT. @@ -1300,6 +1354,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub { handleGroupCreationFailure(); transitionTo(mInactiveState); } + } else if (status == P2pStatus.NO_COMMON_CHANNEL) { + transitionTo(mFrequencyConflictState); } else { handleGroupCreationFailure(); transitionTo(mInactiveState); @@ -1312,7 +1368,90 @@ public class WifiP2pService extends IWifiP2pManager.Stub { } } + class FrequencyConflictState extends State { + private AlertDialog mFrequencyConflictDialog; + @Override + public void enter() { + if (DBG) logd(getName()); + notifyFrequencyConflict(); + } + private void notifyFrequencyConflict() { + logd("Notify frequency conflict"); + Resources r = Resources.getSystem(); + + AlertDialog dialog = new AlertDialog.Builder(mContext) + .setMessage(r.getString(R.string.wifi_p2p_frequency_conflict_message, + getDeviceName(mSavedPeerConfig.deviceAddress))) + .setPositiveButton(r.getString(R.string.dlg_ok), new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + sendMessage(DROP_WIFI_USER_ACCEPT); + } + }) + .setNegativeButton(r.getString(R.string.decline), new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + sendMessage(DROP_WIFI_USER_REJECT); + } + }) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface arg0) { + sendMessage(DROP_WIFI_USER_REJECT); + } + }) + .create(); + + dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); + dialog.show(); + mFrequencyConflictDialog = dialog; + } + + @Override + public boolean processMessage(Message message) { + if (DBG) logd(getName() + message.toString()); + switch (message.what) { + case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT: + case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT: + loge(getName() + "group sucess during freq conflict!"); + break; + case WifiMonitor.P2P_GROUP_STARTED_EVENT: + loge(getName() + "group started after freq conflict, handle anyway"); + deferMessage(message); + transitionTo(mGroupNegotiationState); + break; + case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT: + case WifiMonitor.P2P_GROUP_REMOVED_EVENT: + case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT: + // Ignore failures since we retry again + break; + case DROP_WIFI_USER_REJECT: + // User rejected dropping wifi in favour of p2p + handleGroupCreationFailure(); + transitionTo(mInactiveState); + break; + case DROP_WIFI_USER_ACCEPT: + // User accepted dropping wifi in favour of p2p + mWifiChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_REQUEST, 1); + mTempoarilyDisconnectedWifi = true; + break; + case DISCONNECT_WIFI_RESPONSE: + // Got a response from wifistatemachine, retry p2p + if (DBG) logd(getName() + "Wifi disconnected, retry p2p"); + transitionTo(mInactiveState); + sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig); + break; + default: + return NOT_HANDLED; + } + return HANDLED; + } + + public void exit() { + if (mFrequencyConflictDialog != null) mFrequencyConflictDialog.dismiss(); + } + } class GroupCreatedState extends State { @Override @@ -1421,7 +1560,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { } // Do the regular device lost handling return NOT_HANDLED; - case WifiStateMachine.CMD_DISABLE_P2P: + case WifiStateMachine.CMD_DISABLE_P2P_REQ: sendMessage(WifiP2pManager.REMOVE_GROUP); deferMessage(message); break; @@ -2195,6 +2334,11 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mPeersLostDuringConnection.clear(); mServiceDiscReqId = null; if (changed) sendP2pPeersChangedBroadcast(); + + if (mTempoarilyDisconnectedWifi) { + mWifiChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_REQUEST, 0); + mTempoarilyDisconnectedWifi = false; + } } //State machine initiated requests can have replyTo set to null indicating |
