Merge "Make setter methods on Outline call setEmpty() based on params" into lmp-dev
diff --git a/Android.mk b/Android.mk
index 0d02be7..7dfa6a0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -322,15 +322,17 @@
media/java/android/media/IRemoteVolumeObserver.aidl \
media/java/android/media/IRingtonePlayer.aidl \
media/java/android/media/IVolumeController.aidl \
+ media/java/android/media/browse/IMediaBrowserService.aidl \
+ media/java/android/media/browse/IMediaBrowserServiceCallbacks.aidl \
+ media/java/android/media/projection/IMediaProjection.aidl \
+ media/java/android/media/projection/IMediaProjectionCallback.aidl \
+ media/java/android/media/projection/IMediaProjectionManager.aidl \
media/java/android/media/routing/IMediaRouteService.aidl \
media/java/android/media/routing/IMediaRouteClientCallback.aidl \
media/java/android/media/routing/IMediaRouter.aidl \
media/java/android/media/routing/IMediaRouterDelegate.aidl \
media/java/android/media/routing/IMediaRouterRoutingCallback.aidl \
media/java/android/media/routing/IMediaRouterStateCallback.aidl \
- media/java/android/media/projection/IMediaProjection.aidl \
- media/java/android/media/projection/IMediaProjectionCallback.aidl \
- media/java/android/media/projection/IMediaProjectionManager.aidl \
media/java/android/media/session/IActiveSessionsListener.aidl \
media/java/android/media/session/ISessionController.aidl \
media/java/android/media/session/ISessionControllerCallback.aidl \
@@ -391,76 +393,27 @@
LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_JAVA_LIBRARIES := core-libart conscrypt okhttp core-junit bouncycastle ext
-LOCAL_MODULE := framework-base
+LOCAL_MODULE := framework
+
+LOCAL_DX_FLAGS := --core-library --multi-dex
LOCAL_RMTYPEDEFS := true
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# Make sure that R.java and Manifest.java are built before we build
-# the source for this library.
-framework_res_R_stamp := \
- $(call intermediates-dir-for,APPS,framework-res,,COMMON)/src/R.stamp
-$(full_classes_compiled_jar): $(framework_res_R_stamp)
-
-# Build part 1 of the framework library.
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := framework
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_STATIC_JAVA_LIBRARIES := framework-base
-LOCAL_DX_FLAGS := --core-library
-
-# List of packages to include along with their descendants.
-LOCAL_JAR_PACKAGES := \
- android
-
-# List of packages to exclude along with their descendants.
-# Overrides inclusion.
-LOCAL_JAR_EXCLUDE_PACKAGES := \
- android.bluetooth \
- android.filterfw \
- android.filterpacks \
- android.hardware \
- android.telephony
-
# List of classes and interfaces which should be loaded by the Zygote.
LOCAL_JAVA_RESOURCE_FILES += $(LOCAL_PATH)/preloaded-classes
include $(BUILD_JAVA_LIBRARY)
framework_module := $(LOCAL_INSTALLED_MODULE)
-# Build part 2 of the framework library.
-# ============================================================
-include $(CLEAR_VARS)
+# Make sure that R.java and Manifest.java are built before we build
+# the source for this library.
+framework_res_R_stamp := \
+ $(call intermediates-dir-for,APPS,framework-res,,COMMON)/src/R.stamp
+$(full_classes_compiled_jar): $(framework_res_R_stamp)
-LOCAL_MODULE := framework2
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_STATIC_JAVA_LIBRARIES := framework-base
-LOCAL_DX_FLAGS := --core-library
-
-# List of packages to include along with their descendants.
-LOCAL_JAR_PACKAGES := \
- android.bluetooth \
- android.filterfw \
- android.filterpacks \
- android.hardware \
- android.telephony \
- com \
- javax
-
-include $(BUILD_JAVA_LIBRARY)
-framework2_module := $(LOCAL_INSTALLED_MODULE)
-
-# Make sure that all framework modules are installed when framework is.
-# ============================================================
$(framework_module): | $(dir $(framework_module))framework-res.apk
-$(framework_module): | $(dir $(framework_module))framework2.jar
-framework_built := $(call java-lib-deps,framework framework2)
+framework_built := $(call java-lib-deps,framework)
# Copy AIDL files to be preprocessed and included in the SDK,
# specified relative to the root of the build tree.
@@ -495,6 +448,7 @@
frameworks/base/core/java/android/os/DropBoxManager.aidl \
frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
frameworks/base/core/java/android/os/ParcelUuid.aidl \
+ frameworks/base/core/java/android/os/PersistableBundle.aidl \
frameworks/base/core/java/android/print/PrinterInfo.aidl \
frameworks/base/core/java/android/print/PageRange.aidl \
frameworks/base/core/java/android/print/PrintAttributes.aidl \
@@ -636,7 +590,6 @@
okhttp \
ext \
framework \
- framework2 \
telephony-common \
voip-common
@@ -678,7 +631,7 @@
-overview $(LOCAL_PATH)/core/java/overview.html
framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR:= \
- $(call intermediates-dir-for,JAVA_LIBRARIES,framework-base,,COMMON)
+ $(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON)
framework_docs_LOCAL_ADDITIONAL_JAVA_DIR:= \
$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR) \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2c9ea54..3014e0f 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -210,6 +210,8 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/ims-common_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework2_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/telecomm/java/com/android/internal/telecomm)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework.* $(PRODUCT_OUT)/system/framework2.*)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
diff --git a/api/current.txt b/api/current.txt
index d1a39e7..dab7718 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -380,6 +380,8 @@
field public static final int centerY = 16843171; // 0x10101a3
field public static final int checkBoxPreferenceStyle = 16842895; // 0x101008f
field public static final int checkMark = 16843016; // 0x1010108
+ field public static final int checkMarkTint = 16843949; // 0x10104ad
+ field public static final int checkMarkTintMode = 16843950; // 0x10104ae
field public static final int checkable = 16843237; // 0x10101e5
field public static final int checkableBehavior = 16843232; // 0x10101e0
field public static final int checkboxStyle = 16842860; // 0x101006c
@@ -744,6 +746,7 @@
field public static final int l_resource_pad23 = 16843770; // 0x10103fa
field public static final int l_resource_pad24 = 16843769; // 0x10103f9
field public static final int l_resource_pad25 = 16843768; // 0x10103f8
+ field public static final int l_resource_pad26 = 16843767; // 0x10103f7
field public static final int l_resource_pad3 = 16843790; // 0x101040e
field public static final int l_resource_pad4 = 16843789; // 0x101040d
field public static final int l_resource_pad5 = 16843788; // 0x101040c
@@ -945,6 +948,7 @@
field public static final int popupKeyboard = 16843331; // 0x1010243
field public static final int popupLayout = 16843323; // 0x101023b
field public static final int popupMenuStyle = 16843520; // 0x1010300
+ field public static final int popupTheme = 16843951; // 0x10104af
field public static final int popupWindowStyle = 16842870; // 0x1010076
field public static final int port = 16842793; // 0x1010029
field public static final int positiveButtonText = 16843253; // 0x10101f5
@@ -1304,6 +1308,7 @@
field public static final int toXScale = 16843203; // 0x10101c3
field public static final int toYDelta = 16843209; // 0x10101c9
field public static final int toYScale = 16843205; // 0x10101c5
+ field public static final int toolbarStyle = 16843952; // 0x10104b0
field public static final int top = 16843182; // 0x10101ae
field public static final int topBright = 16842955; // 0x10100cb
field public static final int topDark = 16842951; // 0x10100c7
@@ -1327,7 +1332,6 @@
field public static final int trimPathEnd = 16843813; // 0x1010425
field public static final int trimPathOffset = 16843814; // 0x1010426
field public static final int trimPathStart = 16843812; // 0x1010424
- field public static final int tvInputType = 16843767; // 0x10103f7
field public static final int type = 16843169; // 0x10101a1
field public static final int typeface = 16842902; // 0x1010096
field public static final int uiOptions = 16843672; // 0x1010398
@@ -3818,6 +3822,7 @@
method public void startWatchingMode(java.lang.String, java.lang.String, android.app.AppOpsManager.OnOpChangedListener);
method public void stopWatchingMode(android.app.AppOpsManager.OnOpChangedListener);
field public static final int MODE_ALLOWED = 0; // 0x0
+ field public static final int MODE_DEFAULT = 3; // 0x3
field public static final int MODE_ERRORED = 2; // 0x2
field public static final int MODE_IGNORED = 1; // 0x1
field public static final java.lang.String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -5355,7 +5360,7 @@
method public boolean installCaCert(android.content.ComponentName, byte[]);
method public boolean isActivePasswordSufficient();
method public boolean isAdminActive(android.content.ComponentName);
- method public boolean isApplicationBlocked(android.content.ComponentName, java.lang.String);
+ method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
method public boolean isDeviceOwnerApp(java.lang.String);
method public boolean isLockTaskPermitted(java.lang.String);
method public boolean isMasterVolumeMuted(android.content.ComponentName);
@@ -5365,9 +5370,9 @@
method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
method public boolean resetPassword(java.lang.String, int);
method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
- method public boolean setApplicationBlocked(android.content.ComponentName, java.lang.String, boolean);
+ method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
- method public int setApplicationsBlocked(android.content.ComponentName, android.content.Intent, boolean);
+ method public int setApplicationsHidden(android.content.ComponentName, android.content.Intent, boolean);
method public void setBlockUninstall(android.content.ComponentName, java.lang.String, boolean);
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
@@ -6660,7 +6665,7 @@
public abstract class AbstractRestrictionsProvider extends android.content.BroadcastReceiver {
ctor public AbstractRestrictionsProvider();
method public void onReceive(android.content.Context, android.content.Intent);
- method public abstract void requestPermission(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle);
+ method public abstract void requestPermission(android.content.Context, java.lang.String, java.lang.String, java.lang.String, android.os.PersistableBundle);
}
public abstract class AbstractThreadedSyncAdapter {
@@ -8050,14 +8055,17 @@
public class RestrictionsManager {
method public android.os.Bundle getApplicationRestrictions();
+ method public android.content.Intent getLocalApprovalIntent();
method public java.util.List<android.content.RestrictionEntry> getManifestRestrictions(java.lang.String);
method public boolean hasRestrictionsProvider();
- method public void notifyPermissionResponse(java.lang.String, android.os.Bundle);
- method public void requestPermission(java.lang.String, android.os.Bundle);
- field public static final java.lang.String ACTION_PERMISSION_RESPONSE_RECEIVED = "android.intent.action.PERMISSION_RESPONSE_RECEIVED";
+ method public void notifyPermissionResponse(java.lang.String, android.os.PersistableBundle);
+ method public void requestPermission(java.lang.String, java.lang.String, android.os.PersistableBundle);
+ field public static final java.lang.String ACTION_PERMISSION_RESPONSE_RECEIVED = "android.content.action.PERMISSION_RESPONSE_RECEIVED";
+ field public static final java.lang.String ACTION_REQUEST_LOCAL_APPROVAL = "android.content.action.REQUEST_LOCAL_APPROVAL";
field public static final java.lang.String ACTION_REQUEST_PERMISSION = "android.content.action.REQUEST_PERMISSION";
field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";
field public static final java.lang.String EXTRA_REQUEST_BUNDLE = "android.content.extra.REQUEST_BUNDLE";
+ field public static final java.lang.String EXTRA_REQUEST_ID = "android.content.extra.REQUEST_ID";
field public static final java.lang.String EXTRA_REQUEST_TYPE = "android.content.extra.REQUEST_TYPE";
field public static final java.lang.String EXTRA_RESPONSE_BUNDLE = "android.content.extra.RESPONSE_BUNDLE";
field public static final java.lang.String META_DATA_APP_RESTRICTIONS = "android.content.APP_RESTRICTIONS";
@@ -8070,7 +8078,6 @@
field public static final java.lang.String REQUEST_KEY_NEW_REQUEST = "android.request.new_request";
field public static final java.lang.String REQUEST_KEY_TITLE = "android.request.title";
field public static final java.lang.String REQUEST_TYPE_APPROVAL = "android.request.type.approval";
- field public static final java.lang.String REQUEST_TYPE_LOCAL_APPROVAL = "android.request.type.local_approval";
field public static final java.lang.String RESPONSE_KEY_ERROR_CODE = "android.response.errorcode";
field public static final java.lang.String RESPONSE_KEY_MESSAGE = "android.response.msg";
field public static final java.lang.String RESPONSE_KEY_RESPONSE_TIMESTAMP = "android.response.timestamp";
@@ -8278,7 +8285,6 @@
field public static final int DOCUMENT_LAUNCH_INTO_EXISTING = 1; // 0x1
field public static final int DOCUMENT_LAUNCH_NEVER = 3; // 0x3
field public static final int DOCUMENT_LAUNCH_NONE = 0; // 0x0
- field public static final int DO_NOT_PERSIST = 1; // 0x1
field public static final int FLAG_ALLOW_TASK_REPARENTING = 64; // 0x40
field public static final int FLAG_ALWAYS_RETAIN_TASK_STATE = 8; // 0x8
field public static final int FLAG_AUTO_REMOVE_FROM_RECENTS = 8192; // 0x2000
@@ -8298,6 +8304,7 @@
field public static final int LAUNCH_SINGLE_TASK = 2; // 0x2
field public static final int LAUNCH_SINGLE_TOP = 1; // 0x1
field public static final int PERSIST_ACROSS_REBOOTS = 2; // 0x2
+ field public static final int PERSIST_NEVER = 1; // 0x1
field public static final int PERSIST_ROOT_ONLY = 0; // 0x0
field public static final int SCREEN_ORIENTATION_BEHIND = 3; // 0x3
field public static final int SCREEN_ORIENTATION_FULL_SENSOR = 10; // 0xa
@@ -8873,6 +8880,7 @@
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int FLAG_COSTS_MONEY = 1; // 0x1
field public static final int PROTECTION_DANGEROUS = 1; // 0x1
+ field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10
field public static final int PROTECTION_MASK_BASE = 15; // 0xf
@@ -14972,7 +14980,14 @@
method public final void setInteger(java.lang.String, int);
method public final void setLong(java.lang.String, long);
method public final void setString(java.lang.String, java.lang.String);
+ field public static final java.lang.String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
+ field public static final java.lang.String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
+ field public static final java.lang.String KEY_AAC_DRC_HEAVY_COMPRESSION = "aac-drc-heavy-compression";
+ field public static final java.lang.String KEY_AAC_DRC_TARGET_REFERENCE_LEVEL = "aac-target-ref-level";
+ field public static final java.lang.String KEY_AAC_ENCODED_TARGET_LEVEL = "aac-encoded-target-level";
+ field public static final java.lang.String KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT = "aac-max-output-channel_count";
field public static final java.lang.String KEY_AAC_PROFILE = "aac-profile";
+ field public static final java.lang.String KEY_AAC_SBR_MODE = "aac-sbr-mode";
field public static final java.lang.String KEY_BITRATE_MODE = "bitrate-mode";
field public static final java.lang.String KEY_BIT_RATE = "bitrate";
field public static final java.lang.String KEY_CHANNEL_COUNT = "channel-count";
@@ -15070,7 +15085,7 @@
method public android.media.MediaMetadata.Builder putString(java.lang.String, java.lang.String);
}
- public abstract class MediaMetadataEditor {
+ public abstract deprecated class MediaMetadataEditor {
method public synchronized void addEditableKey(int);
method public abstract void apply();
method public synchronized void clear();
@@ -15540,7 +15555,7 @@
field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
}
- public class RemoteControlClient {
+ public deprecated class RemoteControlClient {
ctor public RemoteControlClient(android.app.PendingIntent);
ctor public RemoteControlClient(android.app.PendingIntent, android.os.Looper);
method public android.media.RemoteControlClient.MetadataEditor editMetadata(boolean);
@@ -15572,7 +15587,7 @@
field public static final int PLAYSTATE_STOPPED = 1; // 0x1
}
- public class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
+ public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
method public synchronized void apply();
field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
}
@@ -15589,7 +15604,7 @@
method public abstract void onPlaybackPositionUpdate(long);
}
- public final class RemoteController {
+ public final deprecated class RemoteController {
ctor public RemoteController(android.content.Context, android.media.RemoteController.OnClientUpdateListener) throws java.lang.IllegalArgumentException;
ctor public RemoteController(android.content.Context, android.media.RemoteController.OnClientUpdateListener, android.os.Looper) throws java.lang.IllegalArgumentException;
method public boolean clearArtworkConfiguration();
@@ -15668,7 +15683,7 @@
}
public class SoundPool {
- ctor public SoundPool(int, int, int);
+ ctor public deprecated SoundPool(int, int, int);
method public final void autoPause();
method public final void autoResume();
method public int load(java.lang.String, int);
@@ -15688,6 +15703,13 @@
method public final boolean unload(int);
}
+ public static class SoundPool.Builder {
+ ctor public SoundPool.Builder();
+ method public android.media.SoundPool build();
+ method public android.media.SoundPool.Builder setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
+ method public android.media.SoundPool.Builder setMaxStreams(int) throws java.lang.IllegalArgumentException;
+ }
+
public static abstract interface SoundPool.OnLoadCompleteListener {
method public abstract void onLoadComplete(android.media.SoundPool, int, int);
}
@@ -16136,6 +16158,85 @@
}
+package android.media.browse {
+
+ public final class MediaBrowser {
+ ctor public MediaBrowser(android.content.Context, android.content.ComponentName, android.media.browse.MediaBrowser.ConnectionCallback, android.os.Bundle);
+ method public void connect();
+ method public void disconnect();
+ method public android.os.Bundle getExtras();
+ method public android.net.Uri getRoot();
+ method public android.media.session.MediaSession.Token getSessionToken();
+ method public boolean isConnected();
+ method public void loadThumbnail(android.net.Uri, int, int, android.media.browse.MediaBrowser.ThumbnailCallback);
+ method public void subscribe(android.net.Uri, android.media.browse.MediaBrowser.SubscriptionCallback);
+ method public void unsubscribe(android.net.Uri);
+ }
+
+ public static class MediaBrowser.ConnectionCallback {
+ ctor public MediaBrowser.ConnectionCallback();
+ method public void onConnected();
+ method public void onConnectionFailed();
+ method public void onConnectionSuspended();
+ }
+
+ public static abstract class MediaBrowser.SubscriptionCallback {
+ ctor public MediaBrowser.SubscriptionCallback();
+ method public void onChildrenLoaded(android.net.Uri, java.util.List<android.media.browse.MediaBrowserItem>);
+ method public void onError(android.net.Uri);
+ }
+
+ public static abstract class MediaBrowser.ThumbnailCallback {
+ ctor public MediaBrowser.ThumbnailCallback();
+ method public void onError(android.net.Uri);
+ method public void onThumbnailLoaded(android.net.Uri, android.graphics.Bitmap);
+ }
+
+ public final class MediaBrowserItem implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.os.Bundle getExtras();
+ method public int getFlags();
+ method public int getIconResId();
+ method public android.net.Uri getIconUri();
+ method public java.lang.CharSequence getSummary();
+ method public java.lang.CharSequence getTitle();
+ method public android.net.Uri getUri();
+ method public boolean isBrowsable();
+ method public boolean isPlayable();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final int FLAG_BROWSABLE = 1; // 0x1
+ field public static final int FLAG_PLAYABLE = 2; // 0x2
+ }
+
+ public static final class MediaBrowserItem.Builder {
+ ctor public MediaBrowserItem.Builder(android.net.Uri, int, java.lang.CharSequence);
+ method public android.media.browse.MediaBrowserItem build();
+ method public android.media.browse.MediaBrowserItem.Builder setExtras(android.os.Bundle);
+ method public android.media.browse.MediaBrowserItem.Builder setIconResId(int);
+ method public android.media.browse.MediaBrowserItem.Builder setIconUri(android.net.Uri);
+ method public android.media.browse.MediaBrowserItem.Builder setSummary(java.lang.CharSequence);
+ }
+
+ public abstract class MediaBrowserService extends android.app.Service {
+ ctor public MediaBrowserService();
+ method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public android.media.session.MediaSession.Token getSessionToken();
+ method public void notifyChildrenChanged(android.net.Uri);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method protected abstract android.media.browse.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
+ method protected abstract android.graphics.Bitmap onGetThumbnail(android.net.Uri, int, int);
+ method protected abstract java.util.List<android.media.browse.MediaBrowserItem> onLoadChildren(android.net.Uri);
+ method public void setSessionToken(android.media.session.MediaSession.Token);
+ field public static final java.lang.String SERVICE_ACTION = "android.media.browse.MediaBrowserService";
+ }
+
+ public static class MediaBrowserService.BrowserRoot {
+ ctor public MediaBrowserService.BrowserRoot(android.net.Uri, android.os.Bundle);
+ }
+
+}
+
package android.media.effect {
public abstract class Effect {
@@ -16671,33 +16772,33 @@
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/channel";
field public static final android.net.Uri CONTENT_URI;
- field public static final int SERVICE_TYPE_AUDIO = 2; // 0x2
- field public static final int SERVICE_TYPE_AUDIO_VIDEO = 1; // 0x1
- field public static final int SERVICE_TYPE_OTHER = 0; // 0x0
- field public static final int TYPE_1SEG = 197632; // 0x30400
- field public static final int TYPE_ATSC_C = 131584; // 0x20200
- field public static final int TYPE_ATSC_M_H = 131840; // 0x20300
- field public static final int TYPE_ATSC_T = 131072; // 0x20000
- field public static final int TYPE_CMMB = 262400; // 0x40100
- field public static final int TYPE_DTMB = 262144; // 0x40000
- field public static final int TYPE_DVB_C = 66048; // 0x10200
- field public static final int TYPE_DVB_C2 = 66049; // 0x10201
- field public static final int TYPE_DVB_H = 66304; // 0x10300
- field public static final int TYPE_DVB_S = 65792; // 0x10100
- field public static final int TYPE_DVB_S2 = 65793; // 0x10101
- field public static final int TYPE_DVB_SH = 66560; // 0x10400
- field public static final int TYPE_DVB_T = 65536; // 0x10000
- field public static final int TYPE_DVB_T2 = 65537; // 0x10001
- field public static final int TYPE_ISDB_C = 197376; // 0x30300
- field public static final int TYPE_ISDB_S = 197120; // 0x30200
- field public static final int TYPE_ISDB_T = 196608; // 0x30000
- field public static final int TYPE_ISDB_TB = 196864; // 0x30100
- field public static final int TYPE_NTSC = 1; // 0x1
- field public static final int TYPE_OTHER = 0; // 0x0
- field public static final int TYPE_PAL = 2; // 0x2
- field public static final int TYPE_SECAM = 3; // 0x3
- field public static final int TYPE_S_DMB = 327936; // 0x50100
- field public static final int TYPE_T_DMB = 327680; // 0x50000
+ field public static final java.lang.String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
+ field public static final java.lang.String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO";
+ field public static final java.lang.String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
+ field public static final java.lang.String TYPE_1SEG = "TYPE_1SEG";
+ field public static final java.lang.String TYPE_ATSC_C = "TYPE_ATSC_C";
+ field public static final java.lang.String TYPE_ATSC_M_H = "TYPE_ATSC_M_H";
+ field public static final java.lang.String TYPE_ATSC_T = "TYPE_ATSC_T";
+ field public static final java.lang.String TYPE_CMMB = "TYPE_CMMB";
+ field public static final java.lang.String TYPE_DTMB = "TYPE_DTMB";
+ field public static final java.lang.String TYPE_DVB_C = "TYPE_DVB_C";
+ field public static final java.lang.String TYPE_DVB_C2 = "TYPE_DVB_C2";
+ field public static final java.lang.String TYPE_DVB_H = "TYPE_DVB_H";
+ field public static final java.lang.String TYPE_DVB_S = "TYPE_DVB_S";
+ field public static final java.lang.String TYPE_DVB_S2 = "TYPE_DVB_S2";
+ field public static final java.lang.String TYPE_DVB_SH = "TYPE_DVB_SH";
+ field public static final java.lang.String TYPE_DVB_T = "TYPE_DVB_T";
+ field public static final java.lang.String TYPE_DVB_T2 = "TYPE_DVB_T2";
+ field public static final java.lang.String TYPE_ISDB_C = "TYPE_ISDB_C";
+ field public static final java.lang.String TYPE_ISDB_S = "TYPE_ISDB_S";
+ field public static final java.lang.String TYPE_ISDB_T = "TYPE_ISDB_T";
+ field public static final java.lang.String TYPE_ISDB_TB = "TYPE_ISDB_TB";
+ field public static final java.lang.String TYPE_NTSC = "TYPE_NTSC";
+ field public static final java.lang.String TYPE_OTHER = "TYPE_OTHER";
+ field public static final java.lang.String TYPE_PAL = "TYPE_PAL";
+ field public static final java.lang.String TYPE_SECAM = "TYPE_SECAM";
+ field public static final java.lang.String TYPE_S_DMB = "TYPE_S_DMB";
+ field public static final java.lang.String TYPE_T_DMB = "TYPE_T_DMB";
field public static final java.lang.String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I";
field public static final java.lang.String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P";
field public static final java.lang.String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P";
@@ -16727,9 +16828,12 @@
field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+ field public static final java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
+ field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+ field public static final java.lang.String COLUMN_SEASON_NUMBER = "season_number";
field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
@@ -16771,17 +16875,16 @@
method public java.lang.CharSequence loadLabel(android.content.Context);
method public void writeToParcel(android.os.Parcel, int);
field public static final java.lang.String EXTRA_INPUT_ID = "inputId";
- field public static final int TYPE_COMPONENT = 6; // 0x6
- field public static final int TYPE_COMPOSITE = 3; // 0x3
- field public static final int TYPE_DISPLAY_PORT = 10; // 0xa
- field public static final int TYPE_DVI = 8; // 0x8
- field public static final int TYPE_HDMI = 9; // 0x9
- field public static final int TYPE_OTHER_HARDWARE = 1; // 0x1
- field public static final int TYPE_SCART = 5; // 0x5
- field public static final int TYPE_SVIDEO = 4; // 0x4
- field public static final int TYPE_TUNER = 2; // 0x2
- field public static final int TYPE_VGA = 7; // 0x7
- field public static final int TYPE_VIRTUAL = 0; // 0x0
+ field public static final int TYPE_COMPONENT = 1004; // 0x3ec
+ field public static final int TYPE_COMPOSITE = 1001; // 0x3e9
+ field public static final int TYPE_DISPLAY_PORT = 1008; // 0x3f0
+ field public static final int TYPE_DVI = 1006; // 0x3ee
+ field public static final int TYPE_HDMI = 1007; // 0x3ef
+ field public static final int TYPE_OTHER = 1000; // 0x3e8
+ field public static final int TYPE_SCART = 1003; // 0x3eb
+ field public static final int TYPE_SVIDEO = 1002; // 0x3ea
+ field public static final int TYPE_TUNER = 0; // 0x0
+ field public static final int TYPE_VGA = 1005; // 0x3ed
}
public final class TvInputManager {
@@ -17356,18 +17459,6 @@
method public android.net.NetworkRequest.Builder setNetworkSpecifier(java.lang.String);
}
- public abstract interface PSKKeyManager {
- method public abstract java.lang.String chooseClientKeyIdentity(java.lang.String, java.net.Socket);
- method public abstract java.lang.String chooseClientKeyIdentity(java.lang.String, javax.net.ssl.SSLEngine);
- method public abstract java.lang.String chooseServerKeyIdentityHint(java.net.Socket);
- method public abstract java.lang.String chooseServerKeyIdentityHint(javax.net.ssl.SSLEngine);
- method public abstract javax.crypto.SecretKey getKey(java.lang.String, java.lang.String, java.net.Socket);
- method public abstract javax.crypto.SecretKey getKey(java.lang.String, java.lang.String, javax.net.ssl.SSLEngine);
- field public static final int MAX_IDENTITY_HINT_LENGTH_BYTES = 128; // 0x80
- field public static final int MAX_IDENTITY_LENGTH_BYTES = 128; // 0x80
- field public static final int MAX_KEY_LENGTH_BYTES = 256; // 0x100
- }
-
public class ParseException extends java.lang.RuntimeException {
field public java.lang.String response;
}
@@ -17394,6 +17485,19 @@
method public void writeToParcel(android.os.Parcel, int);
}
+ public abstract class PskKeyManager {
+ ctor public PskKeyManager();
+ method public java.lang.String chooseClientKeyIdentity(java.lang.String, java.net.Socket);
+ method public java.lang.String chooseClientKeyIdentity(java.lang.String, javax.net.ssl.SSLEngine);
+ method public java.lang.String chooseServerKeyIdentityHint(java.net.Socket);
+ method public java.lang.String chooseServerKeyIdentityHint(javax.net.ssl.SSLEngine);
+ method public javax.crypto.SecretKey getKey(java.lang.String, java.lang.String, java.net.Socket);
+ method public javax.crypto.SecretKey getKey(java.lang.String, java.lang.String, javax.net.ssl.SSLEngine);
+ field public static final int MAX_IDENTITY_HINT_LENGTH_BYTES = 128; // 0x80
+ field public static final int MAX_IDENTITY_LENGTH_BYTES = 128; // 0x80
+ field public static final int MAX_KEY_LENGTH_BYTES = 256; // 0x100
+ }
+
public final class RouteInfo implements android.os.Parcelable {
method public int describeContents();
method public android.net.IpPrefix getDestination();
@@ -27133,14 +27237,19 @@
method public final void cancelNotification(java.lang.String);
method public final void cancelNotifications(java.lang.String[]);
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
+ method public final int getCurrentListenerFlags();
method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
method public android.os.IBinder onBind(android.content.Intent);
method public void onListenerConnected();
+ method public void onListenerFlagsChanged(int);
method public void onNotificationPosted(android.service.notification.StatusBarNotification);
method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap);
method public void onNotificationRemoved(android.service.notification.StatusBarNotification);
method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
+ method public final void requestListenerFlags(int);
+ field public static final int FLAG_DISABLE_HOST_ALERTS = 1; // 0x1
+ field public static final int FLAG_NONE = 0; // 0x0
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
}
@@ -27221,15 +27330,10 @@
package android.service.voice {
public class AlwaysOnHotwordDetector {
- method public int getAvailability();
method public android.content.Intent getManageIntent(int);
method public int getSupportedRecognitionModes();
method public int startRecognition(int);
method public int stopRecognition();
- field public static final int KEYPHRASE_ENROLLED = 2; // 0x2
- field public static final int KEYPHRASE_HARDWARE_UNAVAILABLE = -2; // 0xfffffffe
- field public static final int KEYPHRASE_UNENROLLED = 1; // 0x1
- field public static final int KEYPHRASE_UNSUPPORTED = -1; // 0xffffffff
field public static final int MANAGE_ACTION_ENROLL = 0; // 0x0
field public static final int MANAGE_ACTION_RE_ENROLL = 1; // 0x1
field public static final int MANAGE_ACTION_UN_ENROLL = 2; // 0x2
@@ -27237,21 +27341,28 @@
field public static final int RECOGNITION_FLAG_NONE = 0; // 0x0
field public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 2; // 0x2
field public static final int RECOGNITION_MODE_VOICE_TRIGGER = 1; // 0x1
+ field public static final int STATE_HARDWARE_UNAVAILABLE = -2; // 0xfffffffe
+ field public static final int STATE_INVALID = -3; // 0xfffffffd
+ field public static final int STATE_KEYPHRASE_ENROLLED = 2; // 0x2
+ field public static final int STATE_KEYPHRASE_UNENROLLED = 1; // 0x1
+ field public static final int STATE_KEYPHRASE_UNSUPPORTED = -1; // 0xffffffff
field public static final int STATUS_ERROR = -2147483648; // 0x80000000
field public static final int STATUS_OK = 0; // 0x0
}
public static abstract interface AlwaysOnHotwordDetector.Callback {
+ method public abstract void onAvailabilityChanged(int);
method public abstract void onDetected(byte[]);
method public abstract void onDetectionStopped();
}
public class VoiceInteractionService extends android.app.Service {
ctor public VoiceInteractionService();
- method public final android.service.voice.AlwaysOnHotwordDetector getAlwaysOnHotwordDetector(java.lang.String, java.lang.String, android.service.voice.AlwaysOnHotwordDetector.Callback);
+ method public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(java.lang.String, java.lang.String, android.service.voice.AlwaysOnHotwordDetector.Callback);
method public static boolean isActiveService(android.content.Context, android.content.ComponentName);
method public android.os.IBinder onBind(android.content.Intent);
method public void onReady();
+ method public void onShutdown();
method public void startSession(android.os.Bundle);
field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService";
field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction";
@@ -28602,14 +28713,13 @@
field public static final android.os.Parcelable.Creator CREATOR;
}
- public class RemoteCallVideoClient implements android.os.IBinder.DeathRecipient {
- method public void binderDied();
- method public void handleCallSessionEvent(int) throws android.os.RemoteException;
- method public void handleCameraCapabilitiesChange(android.telecomm.CallCameraCapabilities) throws android.os.RemoteException;
- method public void receiveSessionModifyRequest(android.telecomm.VideoCallProfile) throws android.os.RemoteException;
- method public void receiveSessionModifyResponse(int, android.telecomm.VideoCallProfile, android.telecomm.VideoCallProfile) throws android.os.RemoteException;
- method public void updateCallDataUsage(int) throws android.os.RemoteException;
- method public void updatePeerDimensions(int, int) throws android.os.RemoteException;
+ public class RemoteCallVideoClient {
+ method public void handleCallSessionEvent(int);
+ method public void handleCameraCapabilitiesChange(android.telecomm.CallCameraCapabilities);
+ method public void receiveSessionModifyRequest(android.telecomm.VideoCallProfile);
+ method public void receiveSessionModifyResponse(int, android.telecomm.VideoCallProfile, android.telecomm.VideoCallProfile);
+ method public void updateCallDataUsage(int);
+ method public void updatePeerDimensions(int, int);
}
public class RemoteCallVideoProvider {
@@ -28618,12 +28728,12 @@
method public void sendSessionModifyRequest(android.telecomm.VideoCallProfile);
method public void sendSessionModifyResponse(android.telecomm.VideoCallProfile);
method public void setCallVideoClient(android.telecomm.CallVideoClient);
- method public void setCamera(java.lang.String) throws android.os.RemoteException;
+ method public void setCamera(java.lang.String);
method public void setDeviceOrientation(int);
method public void setDisplaySurface(android.view.Surface);
method public void setPauseImage(java.lang.String);
method public void setPreviewSurface(android.view.Surface);
- method public void setZoom(float) throws android.os.RemoteException;
+ method public void setZoom(float);
}
public final class RemoteConnection {
@@ -28699,6 +28809,7 @@
method public void registerPhoneAccount(android.telecomm.PhoneAccount);
method public void unregisterPhoneAccount(android.telecomm.PhoneAccountHandle);
field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.intent.action.CONNECTION_SERVICE_CONFIGURE";
+ field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecomm.intent.action.SHOW_CALL_SETTINGS";
field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecomm.extra.CALL_BACK_NUMBER";
@@ -28711,6 +28822,7 @@
}
public class VideoCallProfile implements android.os.Parcelable {
+ ctor public VideoCallProfile(int);
ctor public VideoCallProfile(int, int);
method public int describeContents();
method public int getQuality();
@@ -31872,8 +31984,8 @@
method public android.animation.Animator onDisappear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
method public android.animation.Animator onDisappear(android.view.ViewGroup, android.view.View, android.transition.TransitionValues, android.transition.TransitionValues);
method public void setMode(int);
- field public static final int IN = 1; // 0x1
- field public static final int OUT = 2; // 0x2
+ field public static final int MODE_IN = 1; // 0x1
+ field public static final int MODE_OUT = 2; // 0x2
}
public abstract class VisibilityPropagation extends android.transition.TransitionPropagation {
@@ -37620,9 +37732,13 @@
ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int);
ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int, int);
method public android.graphics.drawable.Drawable getCheckMarkDrawable();
+ method public android.content.res.ColorStateList getCheckMarkTint();
+ method public android.graphics.PorterDuff.Mode getCheckMarkTintMode();
method public boolean isChecked();
method public void setCheckMarkDrawable(int);
method public void setCheckMarkDrawable(android.graphics.drawable.Drawable);
+ method public void setCheckMarkTint(android.content.res.ColorStateList);
+ method public void setCheckMarkTintMode(android.graphics.PorterDuff.Mode);
method public void setChecked(boolean);
method public void toggle();
}
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index d6c17ae..faf5622 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -197,13 +197,13 @@
return;
}
- if ("block".equals(op)) {
- runSetBlockedSetting(true);
+ if ("hide".equals(op)) {
+ runSetHiddenSetting(true);
return;
}
- if ("unblock".equals(op)) {
- runSetBlockedSetting(false);
+ if ("unhide".equals(op)) {
+ runSetHiddenSetting(false);
return;
}
@@ -1471,7 +1471,7 @@
}
}
- private void runSetBlockedSetting(boolean state) {
+ private void runSetHiddenSetting(boolean state) {
int userId = 0;
String option = nextOption();
if (option != null && option.equals("--user")) {
@@ -1492,9 +1492,9 @@
return;
}
try {
- mPm.setApplicationBlockedSettingAsUser(pkg, state, userId);
- System.err.println("Package " + pkg + " new blocked state: "
- + mPm.getApplicationBlockedSettingAsUser(pkg, userId));
+ mPm.setApplicationHiddenSettingAsUser(pkg, state, userId);
+ System.err.println("Package " + pkg + " new hidden state: "
+ + mPm.getApplicationHiddenSettingAsUser(pkg, userId));
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
@@ -1751,8 +1751,8 @@
System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
- System.err.println(" pm block [--user USER_ID] PACKAGE_OR_COMPONENT");
- System.err.println(" pm unblock [--user USER_ID] PACKAGE_OR_COMPONENT");
+ System.err.println(" pm hide [--user USER_ID] PACKAGE_OR_COMPONENT");
+ System.err.println(" pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm grant PACKAGE PERMISSION");
System.err.println(" pm revoke PACKAGE PERMISSION");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index fb70098..342155d 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -284,6 +284,17 @@
return true;
}
+ case START_ACTIVITY_FROM_RECENTS_TRANSACTION:
+ {
+ data.enforceInterface(IActivityManager.descriptor);
+ int taskId = data.readInt();
+ Bundle options = data.readInt() == 0 ? null : Bundle.CREATOR.createFromParcel(data);
+ int result = startActivityFromRecents(taskId, options);
+ reply.writeNoException();
+ reply.writeInt(result);
+ return true;
+ }
+
case FINISH_ACTIVITY_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -2482,6 +2493,24 @@
data.recycle();
return result != 0;
}
+ public int startActivityFromRecents(int taskId, Bundle options) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(taskId);
+ if (options == null) {
+ data.writeInt(0);
+ } else {
+ data.writeInt(1);
+ options.writeToParcel(data, 0);
+ }
+ mRemote.transact(START_ACTIVITY_FROM_RECENTS_TRANSACTION, data, reply, 0);
+ reply.readException();
+ int result = reply.readInt();
+ reply.recycle();
+ data.recycle();
+ return result;
+ }
public boolean finishActivity(IBinder token, int resultCode, Intent resultData, boolean finishTask)
throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 990ea85..caadecb 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -94,6 +94,13 @@
*/
public static final int MODE_ERRORED = 2;
+ /**
+ * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
+ * use its default security check. This mode is not normally used; it should only be used
+ * with appop permissions, and callers must explicitly check for it and deal with it.
+ */
+ public static final int MODE_DEFAULT = 3;
+
// when adding one of these:
// - increment _NUM_OP
// - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode
@@ -588,7 +595,7 @@
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
- AppOpsManager.MODE_IGNORED, // OP_GET_USAGE_STATS
+ AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 6a51371..1cb0fd4 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1452,10 +1452,10 @@
}
@Override
- public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
+ public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
UserHandle user) {
try {
- return mPM.setApplicationBlockedSettingAsUser(packageName, blocked,
+ return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
user.getIdentifier());
} catch (RemoteException re) {
// Should never happen!
@@ -1464,9 +1464,9 @@
}
@Override
- public boolean getApplicationBlockedSettingAsUser(String packageName, UserHandle user) {
+ public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
try {
- return mPM.getApplicationBlockedSettingAsUser(packageName, user.getIdentifier());
+ return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
} catch (RemoteException re) {
// Should never happen!
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 8e3323b..175b6a5 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -413,8 +413,7 @@
registerService(CONNECTIVITY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
- return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b),
- ctx.getPackageName());
+ return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
}});
registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
@@ -762,9 +761,16 @@
registerService(PERSISTENT_DATA_BLOCK_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(PERSISTENT_DATA_BLOCK_SERVICE);
- return new PersistentDataBlockManager(
- IPersistentDataBlockService.Stub.asInterface(b));
- }});
+ IPersistentDataBlockService persistentDataBlockService =
+ IPersistentDataBlockService.Stub.asInterface(b);
+ if (persistentDataBlockService != null) {
+ return new PersistentDataBlockManager(persistentDataBlockService);
+ } else {
+ // not supported
+ return null;
+ }
+ }
+ });
registerService(MEDIA_PROJECTION_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index ac29161..cc13a3b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -86,6 +86,7 @@
ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
public boolean startNextMatchingActivity(IBinder callingActivity,
Intent intent, Bundle options) throws RemoteException;
+ public int startActivityFromRecents(int taskId, Bundle options) throws RemoteException;
public boolean finishActivity(IBinder token, int code, Intent data, boolean finishTask)
throws RemoteException;
public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
@@ -756,4 +757,5 @@
int IS_BG_MEDIA_PLAYING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+226;
int MEDIA_RESOURCES_RELEASED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+227;
int NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+228;
+ int START_ACTIVITY_FROM_RECENTS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 229;
}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 5b92538..113c533 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -59,6 +59,8 @@
void cancelNotificationsFromListener(in INotificationListener token, in String[] keys);
ParceledListSlice getActiveNotificationsFromListener(in INotificationListener token);
+ void requestFlagsFromListener(in INotificationListener token, int flags);
+ int getFlagsFromListener(in INotificationListener token);
ZenModeConfig getZenModeConfig();
boolean setZenModeConfig(in ZenModeConfig config);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 5f2262b..efeded5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2523,20 +2523,20 @@
}
/**
- * Called by device or profile owner to block or unblock packages. When a package is blocked it
+ * Called by device or profile owner to hide or unhide packages. When a package is hidden it
* is unavailable for use, but the data and actual package file remain.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
- * @param packageName The name of the package to block or unblock.
- * @param blocked {@code true} if the package should be blocked, {@code false} if it should be
- * unblocked.
- * @return boolean Whether the blocked setting of the package was successfully updated.
+ * @param packageName The name of the package to hide or unhide.
+ * @param hidden {@code true} if the package should be hidden, {@code false} if it should be
+ * unhidden.
+ * @return boolean Whether the hidden setting of the package was successfully updated.
*/
- public boolean setApplicationBlocked(ComponentName admin, String packageName,
- boolean blocked) {
+ public boolean setApplicationHidden(ComponentName admin, String packageName,
+ boolean hidden) {
if (mService != null) {
try {
- return mService.setApplicationBlocked(admin, packageName, blocked);
+ return mService.setApplicationHidden(admin, packageName, hidden);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2545,20 +2545,20 @@
}
/**
- * Called by profile or device owner to block or unblock currently installed packages. This
+ * Called by profile or device owner to hide or unhide currently installed packages. This
* should only be called by a profile or device owner running within a managed profile.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param intent An intent matching the app(s) to be updated. All apps that resolve for this
* intent will be updated in the current profile.
- * @param blocked {@code true} if the packages should be blocked, {@code false} if they should
- * be unblocked.
+ * @param hidden {@code true} if the packages should be hidden, {@code false} if they should
+ * be unhidden.
* @return int The number of activities that matched the intent and were updated.
*/
- public int setApplicationsBlocked(ComponentName admin, Intent intent, boolean blocked) {
+ public int setApplicationsHidden(ComponentName admin, Intent intent, boolean hidden) {
if (mService != null) {
try {
- return mService.setApplicationsBlocked(admin, intent, blocked);
+ return mService.setApplicationsHidden(admin, intent, hidden);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2567,16 +2567,16 @@
}
/**
- * Called by device or profile owner to determine if a package is blocked.
+ * Called by device or profile owner to determine if a package is hidden.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
- * @param packageName The name of the package to retrieve the blocked status of.
- * @return boolean {@code true} if the package is blocked, {@code false} otherwise.
+ * @param packageName The name of the package to retrieve the hidden status of.
+ * @return boolean {@code true} if the package is hidden, {@code false} otherwise.
*/
- public boolean isApplicationBlocked(ComponentName admin, String packageName) {
+ public boolean isApplicationHidden(ComponentName admin, String packageName) {
if (mService != null) {
try {
- return mService.isApplicationBlocked(admin, packageName);
+ return mService.isApplicationHidden(admin, packageName);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 9b1979f..5fc8c5f 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -132,9 +132,9 @@
void addCrossProfileIntentFilter(in ComponentName admin, in IntentFilter filter, int flags);
void clearCrossProfileIntentFilters(in ComponentName admin);
- boolean setApplicationBlocked(in ComponentName admin, in String packageName, boolean blocked);
- int setApplicationsBlocked(in ComponentName admin, in Intent intent, boolean blocked);
- boolean isApplicationBlocked(in ComponentName admin, in String packageName);
+ boolean setApplicationHidden(in ComponentName admin, in String packageName, boolean hidden);
+ int setApplicationsHidden(in ComponentName admin, in Intent intent, boolean hidden);
+ boolean isApplicationHidden(in ComponentName admin, in String packageName);
UserHandle createUser(in ComponentName who, in String name);
UserHandle createAndInitializeUser(in ComponentName who, in String name, in String profileOwnerName, in ComponentName profileOwnerComponent, in Bundle adminExtras);
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index 35ff665..57d2011 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -134,6 +134,7 @@
mLastTimeSaved = stats.mLastTimeSaved;
final int pkgCount = stats.mPackageStats.size();
+ mPackageStats.ensureCapacity(pkgCount);
for (int i = 0; i < pkgCount; i++) {
PackageUsageStats pkgStats = stats.mPackageStats.valueAt(i);
mPackageStats.append(stats.mPackageStats.keyAt(i), new PackageUsageStats(pkgStats));
diff --git a/core/java/android/content/AbstractRestrictionsProvider.java b/core/java/android/content/AbstractRestrictionsProvider.java
index 3272970..2b40870 100644
--- a/core/java/android/content/AbstractRestrictionsProvider.java
+++ b/core/java/android/content/AbstractRestrictionsProvider.java
@@ -17,8 +17,8 @@
package android.content;
import android.app.admin.DevicePolicyManager;
-import android.os.Bundle;
import android.os.IBinder;
+import android.os.PersistableBundle;
/**
* Abstract implementation of a Restrictions Provider BroadcastReceiver. To implement a
@@ -30,7 +30,7 @@
* The function of a Restrictions Provider is to transport permission requests from apps on this
* device to an administrator (most likely on a remote device or computer) and deliver back
* responses. The response should be sent back to the app via
- * {@link RestrictionsManager#notifyPermissionResponse(String, Bundle)}.
+ * {@link RestrictionsManager#notifyPermissionResponse(String, PersistableBundle)}.
*
* @see RestrictionsManager
*/
@@ -59,7 +59,7 @@
* @see RestrictionsManager#REQUEST_KEY_ID
*/
public abstract void requestPermission(Context context,
- String packageName, String requestType, Bundle request);
+ String packageName, String requestType, String requestId, PersistableBundle request);
/**
* Intercept standard Restrictions Provider broadcasts. Implementations
@@ -73,8 +73,10 @@
if (RestrictionsManager.ACTION_REQUEST_PERMISSION.equals(action)) {
String packageName = intent.getStringExtra(RestrictionsManager.EXTRA_PACKAGE_NAME);
String requestType = intent.getStringExtra(RestrictionsManager.EXTRA_REQUEST_TYPE);
- Bundle request = intent.getBundleExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE);
- requestPermission(context, packageName, requestType, request);
+ String requestId = intent.getStringExtra(RestrictionsManager.EXTRA_REQUEST_ID);
+ PersistableBundle request = (PersistableBundle)
+ intent.getParcelableExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE);
+ requestPermission(context, packageName, requestType, requestId, request);
}
}
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index de3b881..87d14b9 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -2153,8 +2153,16 @@
* @param sync the master auto-sync setting that applies to all the providers and accounts
*/
public static void setMasterSyncAutomatically(boolean sync) {
+ setMasterSyncAutomaticallyAsUser(sync, UserHandle.getCallingUserId());
+ }
+
+ /**
+ * @see #setMasterSyncAutomatically(boolean)
+ * @hide
+ */
+ public static void setMasterSyncAutomaticallyAsUser(boolean sync, int userId) {
try {
- getContentService().setMasterSyncAutomatically(sync);
+ getContentService().setMasterSyncAutomaticallyAsUser(sync, userId);
} catch (RemoteException e) {
// exception ignored; if this is thrown then it means the runtime is in the midst of
// being restarted
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index d363ad1..9998f08 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -128,6 +128,7 @@
void setIsSyncable(in Account account, String providerName, int syncable);
void setMasterSyncAutomatically(boolean flag);
+ void setMasterSyncAutomaticallyAsUser(boolean flag, int userId);
boolean getMasterSyncAutomatically();
boolean getMasterSyncAutomaticallyAsUser(int userId);
diff --git a/core/java/android/content/IRestrictionsManager.aidl b/core/java/android/content/IRestrictionsManager.aidl
index b1c0a3a..495ac2e 100644
--- a/core/java/android/content/IRestrictionsManager.aidl
+++ b/core/java/android/content/IRestrictionsManager.aidl
@@ -16,7 +16,9 @@
package android.content;
+import android.content.Intent;
import android.os.Bundle;
+import android.os.PersistableBundle;
/**
* Interface used by the RestrictionsManager
@@ -25,6 +27,8 @@
interface IRestrictionsManager {
Bundle getApplicationRestrictions(in String packageName);
boolean hasRestrictionsProvider();
- void requestPermission(in String packageName, in String requestTemplate, in Bundle requestData);
- void notifyPermissionResponse(in String packageName, in Bundle response);
+ void requestPermission(in String packageName, in String requestType, in String requestId,
+ in PersistableBundle requestData);
+ void notifyPermissionResponse(in String packageName, in PersistableBundle response);
+ Intent getLocalApprovalIntent();
}
diff --git a/core/java/android/content/RestrictionsManager.java b/core/java/android/content/RestrictionsManager.java
index 5ae10cfc..c1226c0 100644
--- a/core/java/android/content/RestrictionsManager.java
+++ b/core/java/android/content/RestrictionsManager.java
@@ -16,6 +16,7 @@
package android.content;
+import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -23,6 +24,7 @@
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.Log;
@@ -51,7 +53,7 @@
* <p>
* The RestrictionsManager forwards the dynamic requests to the active
* Restrictions Provider. The Restrictions Provider can respond back to requests by calling
- * {@link #notifyPermissionResponse(String, Bundle)}, when
+ * {@link #notifyPermissionResponse(String, PersistableBundle)}, when
* a response is received from the administrator of the device or user.
* The response is relayed back to the application via a protected broadcast,
* {@link #ACTION_PERMISSION_RESPONSE_RECEIVED}.
@@ -126,14 +128,15 @@
* {@link #EXTRA_RESPONSE_BUNDLE}.
*/
public static final String ACTION_PERMISSION_RESPONSE_RECEIVED =
- "android.intent.action.PERMISSION_RESPONSE_RECEIVED";
+ "android.content.action.PERMISSION_RESPONSE_RECEIVED";
/**
* Broadcast intent sent to the Restrictions Provider to handle a permission request from
* an app. It will have the following extras: {@link #EXTRA_PACKAGE_NAME},
- * {@link #EXTRA_REQUEST_TYPE} and {@link #EXTRA_REQUEST_BUNDLE}. The Restrictions Provider
- * will handle the request and respond back to the RestrictionsManager, when a response is
- * available, by calling {@link #notifyPermissionResponse}.
+ * {@link #EXTRA_REQUEST_TYPE}, {@link #EXTRA_REQUEST_ID} and {@link #EXTRA_REQUEST_BUNDLE}.
+ * The Restrictions Provider will handle the request and respond back to the
+ * RestrictionsManager, when a response is available, by calling
+ * {@link #notifyPermissionResponse}.
* <p>
* The BroadcastReceiver must require the {@link android.Manifest.permission#BIND_DEVICE_ADMIN}
* permission to ensure that only the system can send the broadcast.
@@ -142,17 +145,45 @@
"android.content.action.REQUEST_PERMISSION";
/**
+ * Activity intent that is optionally implemented by the Restrictions Provider package
+ * to challenge for an administrator PIN or password locally on the device. Apps will
+ * call this intent using {@link Activity#startActivityForResult}. On a successful
+ * response, {@link Activity#onActivityResult} will return a resultCode of
+ * {@link Activity#RESULT_OK}.
+ * <p>
+ * The intent must contain {@link #EXTRA_REQUEST_BUNDLE} as an extra and the bundle must
+ * contain at least {@link #REQUEST_KEY_MESSAGE} for the activity to display.
+ * <p>
+ * @see #getLocalApprovalIntent()
+ */
+ public static final String ACTION_REQUEST_LOCAL_APPROVAL =
+ "android.content.action.REQUEST_LOCAL_APPROVAL";
+
+ /**
* The package name of the application making the request.
+ * <p>
+ * Type: String
*/
public static final String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";
/**
* The request type passed in the {@link #ACTION_REQUEST_PERMISSION} broadcast.
+ * <p>
+ * Type: String
*/
public static final String EXTRA_REQUEST_TYPE = "android.content.extra.REQUEST_TYPE";
/**
+ * The request ID passed in the {@link #ACTION_REQUEST_PERMISSION} broadcast.
+ * <p>
+ * Type: String
+ */
+ public static final String EXTRA_REQUEST_ID = "android.content.extra.REQUEST_ID";
+
+ /**
* The request bundle passed in the {@link #ACTION_REQUEST_PERMISSION} broadcast.
+ * <p>
+ * Type: {@link PersistableBundle}
*/
public static final String EXTRA_REQUEST_BUNDLE = "android.content.extra.REQUEST_BUNDLE";
@@ -163,14 +194,15 @@
* <li>{@link #REQUEST_KEY_ID}: The request ID.</li>
* <li>{@link #RESPONSE_KEY_RESULT}: The response result.</li>
* </ul>
+ * <p>
+ * Type: {@link PersistableBundle}
*/
public static final String EXTRA_RESPONSE_BUNDLE = "android.content.extra.RESPONSE_BUNDLE";
/**
* Request type for a simple question, with a possible title and icon.
* <p>
- * Required keys are
- * {@link #REQUEST_KEY_ID} and {@link #REQUEST_KEY_MESSAGE}.
+ * Required keys are: {@link #REQUEST_KEY_MESSAGE}
* <p>
* Optional keys are
* {@link #REQUEST_KEY_DATA}, {@link #REQUEST_KEY_ICON}, {@link #REQUEST_KEY_TITLE},
@@ -179,22 +211,6 @@
public static final String REQUEST_TYPE_APPROVAL = "android.request.type.approval";
/**
- * Request type for a local password challenge. This is a way for an app to ask
- * the administrator to override an operation that is restricted on the device, such
- * as configuring Wi-Fi access points. It is most useful for situations where there
- * is no network connectivity for a remote administrator's response. The normal user of the
- * device is not expected to know the password. The challenge is meant for the administrator.
- * <p>
- * Required keys are
- * {@link #REQUEST_KEY_ID} and {@link #REQUEST_KEY_MESSAGE}.
- * <p>
- * Optional keys are
- * {@link #REQUEST_KEY_DATA}, {@link #REQUEST_KEY_ICON}, {@link #REQUEST_KEY_TITLE},
- * {@link #REQUEST_KEY_APPROVE_LABEL} and {@link #REQUEST_KEY_DENY_LABEL}.
- */
- public static final String REQUEST_TYPE_LOCAL_APPROVAL = "android.request.type.local_approval";
-
- /**
* Key for request ID contained in the request bundle.
* <p>
* App-generated request ID to identify the specific request when receiving
@@ -240,9 +256,10 @@
* Key for request icon contained in the request bundle.
* <p>
* Optional, shown alongside the request message presented to the administrator
- * who approves the request.
+ * who approves the request. The content must be a compressed image such as a
+ * PNG or JPEG, as a byte array.
* <p>
- * Type: Bitmap
+ * Type: byte[]
*/
public static final String REQUEST_KEY_ICON = "android.request.icon";
@@ -403,7 +420,7 @@
/**
* Called by an application to check if there is an active Restrictions Provider. If
- * there isn't, {@link #requestPermission(String, Bundle)} is not available.
+ * there isn't, {@link #requestPermission(String, String, PersistableBundle)} is not available.
*
* @return whether there is an active Restrictions Provider.
*/
@@ -428,40 +445,54 @@
* Restrictions Provider might understand. For custom types, the type name should be
* namespaced to avoid collisions with predefined types and types specified by
* other Restrictions Providers.
- * @param request A Bundle containing the data corresponding to the specified request
+ * @param requestId A unique id generated by the app that contains sufficient information
+ * to identify the parameters of the request when it receives the id in the response.
+ * @param request A PersistableBundle containing the data corresponding to the specified request
* type. The keys for the data in the bundle depend on the request type.
*
* @throws IllegalArgumentException if any of the required parameters are missing.
*/
- public void requestPermission(String requestType, Bundle request) {
+ public void requestPermission(String requestType, String requestId, PersistableBundle request) {
if (requestType == null) {
throw new NullPointerException("requestType cannot be null");
}
+ if (requestId == null) {
+ throw new NullPointerException("requestId cannot be null");
+ }
if (request == null) {
throw new NullPointerException("request cannot be null");
}
- if (!request.containsKey(REQUEST_KEY_ID)) {
- throw new IllegalArgumentException("REQUEST_KEY_ID must be specified");
- }
try {
if (mService != null) {
- mService.requestPermission(mContext.getPackageName(), requestType, request);
+ mService.requestPermission(mContext.getPackageName(), requestType, requestId,
+ request);
}
} catch (RemoteException re) {
Log.w(TAG, "Couldn't reach service");
}
}
+ public Intent getLocalApprovalIntent() {
+ try {
+ if (mService != null) {
+ return mService.getLocalApprovalIntent();
+ }
+ } catch (RemoteException re) {
+ Log.w(TAG, "Couldn't reach service");
+ }
+ return null;
+ }
+
/**
* Called by the Restrictions Provider to deliver a response to an application.
*
* @param packageName the application to deliver the response to. Cannot be null.
- * @param response the Bundle containing the response status, request ID and other information.
+ * @param response the bundle containing the response status, request ID and other information.
* Cannot be null.
*
* @throws IllegalArgumentException if any of the required parameters are missing.
*/
- public void notifyPermissionResponse(String packageName, Bundle response) {
+ public void notifyPermissionResponse(String packageName, PersistableBundle response) {
if (packageName == null) {
throw new NullPointerException("packageName cannot be null");
}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index bcf1e87..dbf49c5 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -112,7 +112,7 @@
* Constant corresponding to <code>doNotPersist</code> in
* the {@link android.R.attr#persistableMode} attribute.
*/
- public static final int DO_NOT_PERSIST = 1;
+ public static final int PERSIST_NEVER = 1;
/**
* Constant corresponding to <code>persistAcrossReboots</code> in
* the {@link android.R.attr#persistableMode} attribute.
@@ -667,7 +667,7 @@
private String persistableModeToString() {
switch(persistableMode) {
case PERSIST_ROOT_ONLY: return "PERSIST_ROOT_ONLY";
- case DO_NOT_PERSIST: return "DO_NOT_PERSIST";
+ case PERSIST_NEVER: return "PERSIST_NEVER";
case PERSIST_ACROSS_REBOOTS: return "PERSIST_ACROSS_REBOOTS";
default: return "UNKNOWN=" + persistableMode;
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 95bd480..482ad6e 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -334,11 +334,11 @@
public static final int FLAG_FULL_BACKUP_ONLY = 1<<26;
/**
- * Value for {@link #flags}: true if the application is blocked via restrictions and for
+ * Value for {@link #flags}: true if the application is hidden via restrictions and for
* most purposes is considered as not installed.
* {@hide}
*/
- public static final int FLAG_BLOCKED = 1<<27;
+ public static final int FLAG_HIDDEN = 1<<27;
/**
* Value for {@link #flags}: set to <code>true</code> if the application
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index eb46cf0..4b339a1 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -110,6 +110,8 @@
int getFlagsForUid(int uid);
+ String[] getAppOpPermissionPackages(String permissionName);
+
ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags, int userId);
boolean canForwardTo(in Intent intent, String resolvedType, int sourceUserId, int targetUserId);
@@ -428,8 +430,8 @@
/** Reflects current DeviceStorageMonitorService state */
boolean isStorageLow();
- boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked, int userId);
- boolean getApplicationBlockedSettingAsUser(String packageName, int userId);
+ boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId);
+ boolean getApplicationHiddenSettingAsUser(String packageName, int userId);
IPackageInstaller getPackageInstaller();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b4c0219..8b6ae41 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3642,20 +3642,21 @@
public abstract int getApplicationEnabledSetting(String packageName);
/**
- * Puts the package in a blocked state, which is almost like an uninstalled state,
+ * Puts the package in a hidden state, which is almost like an uninstalled state,
* making the package unavailable, but it doesn't remove the data or the actual
- * package file.
+ * package file. Application can be unhidden by either resetting the hidden state
+ * or by installing it, such as with {@link #installExistingPackage(String)}
* @hide
*/
- public abstract boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
+ public abstract boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
UserHandle userHandle);
/**
- * Returns the blocked state of a package.
- * @see #setApplicationBlockedSettingAsUser(String, boolean, UserHandle)
+ * Returns the hidden state of a package.
+ * @see #setApplicationHiddenSettingAsUser(String, boolean, UserHandle)
* @hide
*/
- public abstract boolean getApplicationBlockedSettingAsUser(String packageName,
+ public abstract boolean getApplicationHiddenSettingAsUser(String packageName,
UserHandle userHandle);
/**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 833dc21..9866200 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -382,23 +382,23 @@
}
/**
- * Returns true if the package is installed and not blocked, or if the caller
- * explicitly wanted all uninstalled and blocked packages as well.
+ * Returns true if the package is installed and not hidden, or if the caller
+ * explicitly wanted all uninstalled and hidden packages as well.
*/
- private static boolean checkUseInstalledOrBlocked(int flags, PackageUserState state) {
- return (state.installed && !state.blocked)
+ private static boolean checkUseInstalledOrHidden(int flags, PackageUserState state) {
+ return (state.installed && !state.hidden)
|| (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
}
public static boolean isAvailable(PackageUserState state) {
- return checkUseInstalledOrBlocked(0, state);
+ return checkUseInstalledOrHidden(0, state);
}
public static PackageInfo generatePackageInfo(PackageParser.Package p,
int gids[], int flags, long firstInstallTime, long lastUpdateTime,
HashSet<String> grantedPermissions, PackageUserState state, int userId) {
- if (!checkUseInstalledOrBlocked(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state)) {
return null;
}
PackageInfo pi = new PackageInfo();
@@ -4533,7 +4533,7 @@
return true;
}
}
- if (!state.installed || state.blocked) {
+ if (!state.installed || state.hidden) {
return true;
}
if (state.stopped) {
@@ -4566,10 +4566,10 @@
} else {
ai.flags &= ~ApplicationInfo.FLAG_INSTALLED;
}
- if (state.blocked) {
- ai.flags |= ApplicationInfo.FLAG_BLOCKED;
+ if (state.hidden) {
+ ai.flags |= ApplicationInfo.FLAG_HIDDEN;
} else {
- ai.flags &= ~ApplicationInfo.FLAG_BLOCKED;
+ ai.flags &= ~ApplicationInfo.FLAG_HIDDEN;
}
if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
ai.enabled = true;
@@ -4585,7 +4585,7 @@
public static ApplicationInfo generateApplicationInfo(Package p, int flags,
PackageUserState state, int userId) {
if (p == null) return null;
- if (!checkUseInstalledOrBlocked(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state)) {
return null;
}
if (!copyNeeded(flags, p, state, null, userId)
@@ -4673,7 +4673,7 @@
public static final ActivityInfo generateActivityInfo(Activity a, int flags,
PackageUserState state, int userId) {
if (a == null) return null;
- if (!checkUseInstalledOrBlocked(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state)) {
return null;
}
if (!copyNeeded(flags, a.owner, state, a.metaData, userId)) {
@@ -4714,7 +4714,7 @@
public static final ServiceInfo generateServiceInfo(Service s, int flags,
PackageUserState state, int userId) {
if (s == null) return null;
- if (!checkUseInstalledOrBlocked(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state)) {
return null;
}
if (!copyNeeded(flags, s.owner, state, s.metaData, userId)) {
@@ -4763,7 +4763,7 @@
public static final ProviderInfo generateProviderInfo(Provider p, int flags,
PackageUserState state, int userId) {
if (p == null) return null;
- if (!checkUseInstalledOrBlocked(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state)) {
return null;
}
if (!copyNeeded(flags, p.owner, state, p.metaData, userId)
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index f0d4cb1..4dcad6f 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -28,7 +28,7 @@
public boolean stopped;
public boolean notLaunched;
public boolean installed;
- public boolean blocked; // Is the app restricted by owner / admin
+ public boolean hidden; // Is the app restricted by owner / admin
public int enabled;
public boolean blockUninstall;
@@ -39,7 +39,7 @@
public PackageUserState() {
installed = true;
- blocked = false;
+ hidden = false;
enabled = COMPONENT_ENABLED_STATE_DEFAULT;
}
@@ -48,7 +48,7 @@
stopped = o.stopped;
notLaunched = o.notLaunched;
enabled = o.enabled;
- blocked = o.blocked;
+ hidden = o.hidden;
lastDisableAppCaller = o.lastDisableAppCaller;
disabledComponents = o.disabledComponents != null
? new HashSet<String>(o.disabledComponents) : null;
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 5a63e5f..af574db 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -69,6 +69,13 @@
public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20;
/**
+ * Additional flag for {@link #protectionLevel}, corresponding
+ * to the <code>development</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ */
+ public static final int PROTECTION_FLAG_APPOP = 0x40;
+
+ /**
* Mask for {@link #protectionLevel}: the basic protection type.
*/
public static final int PROTECTION_MASK_BASE = 0xf;
@@ -153,6 +160,9 @@
if ((level&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
protLevel += "|development";
}
+ if ((level&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
+ protLevel += "|appop";
+ }
return protLevel;
}
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index a88e659..f18cb7d 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -16,8 +16,9 @@
package android.hardware.camera2;
-import android.hardware.camera2.CaptureResult.Key;
import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.impl.PublicKey;
+import android.hardware.camera2.impl.SyntheticKey;
import android.hardware.camera2.utils.TypeReference;
import android.util.Rational;
@@ -321,6 +322,7 @@
* @see CaptureRequest#COLOR_CORRECTION_ABERRATION_CORRECTION_MODE
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
*/
+ @PublicKey
public static final Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_CORRECTION_MODES =
new Key<int[]>("android.colorCorrection.availableAberrationCorrectionModes", int[].class);
@@ -332,6 +334,7 @@
* valid anti-banding modes that the application may request
* for this camera device; they must include AUTO.</p>
*/
+ @PublicKey
public static final Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES =
new Key<int[]>("android.control.aeAvailableAntibandingModes", int[].class);
@@ -351,6 +354,7 @@
*
* @see CaptureRequest#CONTROL_AE_MODE
*/
+ @PublicKey
public static final Key<int[]> CONTROL_AE_AVAILABLE_MODES =
new Key<int[]>("android.control.aeAvailableModes", int[].class);
@@ -358,6 +362,7 @@
* <p>List of frame rate ranges supported by the
* auto-exposure (AE) algorithm/hardware</p>
*/
+ @PublicKey
public static final Key<android.util.Range<Integer>[]> CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES =
new Key<android.util.Range<Integer>[]>("android.control.aeAvailableTargetFpsRanges", new TypeReference<android.util.Range<Integer>[]>() {{ }});
@@ -368,6 +373,7 @@
*
* @see CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP
*/
+ @PublicKey
public static final Key<android.util.Range<Integer>> CONTROL_AE_COMPENSATION_RANGE =
new Key<android.util.Range<Integer>>("android.control.aeCompensationRange", new TypeReference<android.util.Range<Integer>>() {{ }});
@@ -375,6 +381,7 @@
* <p>Smallest step by which exposure compensation
* can be changed</p>
*/
+ @PublicKey
public static final Key<Rational> CONTROL_AE_COMPENSATION_STEP =
new Key<Rational>("android.control.aeCompensationStep", Rational.class);
@@ -391,6 +398,7 @@
* @see CaptureRequest#CONTROL_AF_MODE
* @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
*/
+ @PublicKey
public static final Key<int[]> CONTROL_AF_AVAILABLE_MODES =
new Key<int[]>("android.control.afAvailableModes", int[].class);
@@ -410,6 +418,7 @@
* @see CaptureRequest#CONTROL_EFFECT_MODE
* @see CaptureRequest#CONTROL_MODE
*/
+ @PublicKey
public static final Key<int[]> CONTROL_AVAILABLE_EFFECTS =
new Key<int[]>("android.control.availableEffects", int[].class);
@@ -424,6 +433,7 @@
*
* @see CaptureRequest#CONTROL_SCENE_MODE
*/
+ @PublicKey
public static final Key<int[]> CONTROL_AVAILABLE_SCENE_MODES =
new Key<int[]>("android.control.availableSceneModes", int[].class);
@@ -431,6 +441,7 @@
* <p>List of video stabilization modes that can
* be supported</p>
*/
+ @PublicKey
public static final Key<int[]> CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES =
new Key<int[]>("android.control.availableVideoStabilizationModes", int[].class);
@@ -450,6 +461,7 @@
* @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
*/
+ @PublicKey
public static final Key<int[]> CONTROL_AWB_AVAILABLE_MODES =
new Key<int[]>("android.control.awbAvailableModes", int[].class);
@@ -476,6 +488,8 @@
*
* @see CaptureRequest#CONTROL_AE_REGIONS
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<Integer> CONTROL_MAX_REGIONS_AE =
new Key<Integer>("android.control.maxRegionsAe", int.class);
@@ -487,6 +501,8 @@
*
* @see CaptureRequest#CONTROL_AWB_REGIONS
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<Integer> CONTROL_MAX_REGIONS_AWB =
new Key<Integer>("android.control.maxRegionsAwb", int.class);
@@ -498,6 +514,8 @@
*
* @see CaptureRequest#CONTROL_AF_REGIONS
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<Integer> CONTROL_MAX_REGIONS_AF =
new Key<Integer>("android.control.maxRegionsAf", int.class);
@@ -538,6 +556,7 @@
*
* @see CaptureRequest#EDGE_MODE
*/
+ @PublicKey
public static final Key<int[]> EDGE_AVAILABLE_EDGE_MODES =
new Key<int[]>("android.edge.availableEdgeModes", int[].class);
@@ -547,6 +566,7 @@
* <p>If no flash, none of the flash controls do
* anything. All other metadata should return 0.</p>
*/
+ @PublicKey
public static final Key<Boolean> FLASH_INFO_AVAILABLE =
new Key<Boolean>("android.flash.info.available", boolean.class);
@@ -558,6 +578,7 @@
*
* @see CaptureRequest#HOT_PIXEL_MODE
*/
+ @PublicKey
public static final Key<int[]> HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES =
new Key<int[]>("android.hotPixel.availableHotPixelModes", int[].class);
@@ -577,6 +598,7 @@
* <li>All non (0, 0) sizes will have non-zero widths and heights.</li>
* </ul>
*/
+ @PublicKey
public static final Key<android.util.Size[]> JPEG_AVAILABLE_THUMBNAIL_SIZES =
new Key<android.util.Size[]>("android.jpeg.availableThumbnailSizes", android.util.Size[].class);
@@ -588,6 +610,7 @@
* <p>If the camera device supports variable apertures, the aperture value
* in this list will be sorted in ascending order.</p>
*/
+ @PublicKey
public static final Key<float[]> LENS_INFO_AVAILABLE_APERTURES =
new Key<float[]>("android.lens.info.availableApertures", float[].class);
@@ -601,6 +624,7 @@
*
* @see CaptureRequest#LENS_FILTER_DENSITY
*/
+ @PublicKey
public static final Key<float[]> LENS_INFO_AVAILABLE_FILTER_DENSITIES =
new Key<float[]>("android.lens.info.availableFilterDensities", float[].class);
@@ -614,6 +638,7 @@
*
* @see CaptureRequest#LENS_FOCAL_LENGTH
*/
+ @PublicKey
public static final Key<float[]> LENS_INFO_AVAILABLE_FOCAL_LENGTHS =
new Key<float[]>("android.lens.info.availableFocalLengths", float[].class);
@@ -626,6 +651,7 @@
*
* @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
*/
+ @PublicKey
public static final Key<int[]> LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION =
new Key<int[]>("android.lens.info.availableOpticalStabilization", int[].class);
@@ -637,6 +663,7 @@
*
* @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
*/
+ @PublicKey
public static final Key<Float> LENS_INFO_HYPERFOCAL_DISTANCE =
new Key<Float>("android.lens.info.hyperfocalDistance", float.class);
@@ -647,6 +674,7 @@
* 0.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*/
+ @PublicKey
public static final Key<Float> LENS_INFO_MINIMUM_FOCUS_DISTANCE =
new Key<Float>("android.lens.info.minimumFocusDistance", float.class);
@@ -674,6 +702,7 @@
* @see #LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE
* @see #LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED
*/
+ @PublicKey
public static final Key<Integer> LENS_INFO_FOCUS_DISTANCE_CALIBRATION =
new Key<Integer>("android.lens.info.focusDistanceCalibration", int.class);
@@ -683,6 +712,7 @@
* @see #LENS_FACING_FRONT
* @see #LENS_FACING_BACK
*/
+ @PublicKey
public static final Key<Integer> LENS_FACING =
new Key<Integer>("android.lens.facing", int.class);
@@ -693,6 +723,7 @@
*
* @see CaptureRequest#NOISE_REDUCTION_MODE
*/
+ @PublicKey
public static final Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES =
new Key<int[]>("android.noiseReduction.availableNoiseReductionModes", int[].class);
@@ -758,6 +789,8 @@
*
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<Integer> REQUEST_MAX_NUM_OUTPUT_RAW =
new Key<Integer>("android.request.maxNumOutputRaw", int.class);
@@ -784,6 +817,8 @@
*
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<Integer> REQUEST_MAX_NUM_OUTPUT_PROC =
new Key<Integer>("android.request.maxNumOutputProc", int.class);
@@ -804,6 +839,8 @@
*
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<Integer> REQUEST_MAX_NUM_OUTPUT_PROC_STALLING =
new Key<Integer>("android.request.maxNumOutputProcStalling", int.class);
@@ -842,6 +879,7 @@
*
* @see CaptureResult#REQUEST_PIPELINE_DEPTH
*/
+ @PublicKey
public static final Key<Byte> REQUEST_PIPELINE_MAX_DEPTH =
new Key<Byte>("android.request.pipelineMaxDepth", byte.class);
@@ -862,6 +900,7 @@
* partial results.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*/
+ @PublicKey
public static final Key<Integer> REQUEST_PARTIAL_RESULT_COUNT =
new Key<Integer>("android.request.partialResultCount", int.class);
@@ -892,6 +931,7 @@
* @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING
* @see #REQUEST_AVAILABLE_CAPABILITIES_RAW
*/
+ @PublicKey
public static final Key<int[]> REQUEST_AVAILABLE_CAPABILITIES =
new Key<int[]>("android.request.availableCapabilities", int[].class);
@@ -1001,6 +1041,7 @@
* than this ratio allows will be rounded up to the minimum
* allowed size by the camera device.</p>
*/
+ @PublicKey
public static final Key<Float> SCALER_AVAILABLE_MAX_DIGITAL_ZOOM =
new Key<Float>("android.scaler.availableMaxDigitalZoom", float.class);
@@ -1360,6 +1401,8 @@
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<android.hardware.camera2.params.StreamConfigurationMap> SCALER_STREAM_CONFIGURATION_MAP =
new Key<android.hardware.camera2.params.StreamConfigurationMap>("android.scaler.streamConfigurationMap", android.hardware.camera2.params.StreamConfigurationMap.class);
@@ -1382,6 +1425,7 @@
* @see #SCALER_CROPPING_TYPE_CENTER_ONLY
* @see #SCALER_CROPPING_TYPE_FREEFORM
*/
+ @PublicKey
public static final Key<Integer> SCALER_CROPPING_TYPE =
new Key<Integer>("android.scaler.croppingType", int.class);
@@ -1391,6 +1435,7 @@
* <p>It is smaller or equal to
* sensor full pixel array, which could include the black calibration pixels.</p>
*/
+ @PublicKey
public static final Key<android.graphics.Rect> SENSOR_INFO_ACTIVE_ARRAY_SIZE =
new Key<android.graphics.Rect>("android.sensor.info.activeArraySize", android.graphics.Rect.class);
@@ -1403,6 +1448,7 @@
*
* @see CaptureRequest#SENSOR_SENSITIVITY
*/
+ @PublicKey
public static final Key<android.util.Range<Integer>> SENSOR_INFO_SENSITIVITY_RANGE =
new Key<android.util.Range<Integer>>("android.sensor.info.sensitivityRange", new TypeReference<android.util.Range<Integer>>() {{ }});
@@ -1416,6 +1462,7 @@
* @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR
* @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB
*/
+ @PublicKey
public static final Key<Integer> SENSOR_INFO_COLOR_FILTER_ARRANGEMENT =
new Key<Integer>("android.sensor.info.colorFilterArrangement", int.class);
@@ -1429,6 +1476,7 @@
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
*/
+ @PublicKey
public static final Key<android.util.Range<Long>> SENSOR_INFO_EXPOSURE_TIME_RANGE =
new Key<android.util.Range<Long>>("android.sensor.info.exposureTimeRange", new TypeReference<android.util.Range<Long>>() {{ }});
@@ -1449,6 +1497,7 @@
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CaptureRequest#SENSOR_FRAME_DURATION
*/
+ @PublicKey
public static final Key<Long> SENSOR_INFO_MAX_FRAME_DURATION =
new Key<Long>("android.sensor.info.maxFrameDuration", long.class);
@@ -1460,6 +1509,7 @@
*
* @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.util.SizeF> SENSOR_INFO_PHYSICAL_SIZE =
new Key<android.util.SizeF>("android.sensor.info.physicalSize", android.util.SizeF.class);
@@ -1478,6 +1528,7 @@
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE
*/
+ @PublicKey
public static final Key<android.util.Size> SENSOR_INFO_PIXEL_ARRAY_SIZE =
new Key<android.util.Size>("android.sensor.info.pixelArraySize", android.util.Size.class);
@@ -1495,6 +1546,7 @@
*
* @see CameraCharacteristics#SENSOR_BLACK_LEVEL_PATTERN
*/
+ @PublicKey
public static final Key<Integer> SENSOR_INFO_WHITE_LEVEL =
new Key<Integer>("android.sensor.info.whiteLevel", int.class);
@@ -1507,6 +1559,7 @@
* @see #SENSOR_INFO_TIMESTAMP_CALIBRATION_UNCALIBRATED
* @see #SENSOR_INFO_TIMESTAMP_CALIBRATION_CALIBRATED
*/
+ @PublicKey
public static final Key<Integer> SENSOR_INFO_TIMESTAMP_CALIBRATION =
new Key<Integer>("android.sensor.info.timestampCalibration", int.class);
@@ -1549,6 +1602,7 @@
* @see #SENSOR_REFERENCE_ILLUMINANT1_D50
* @see #SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN
*/
+ @PublicKey
public static final Key<Integer> SENSOR_REFERENCE_ILLUMINANT1 =
new Key<Integer>("android.sensor.referenceIlluminant1", int.class);
@@ -1569,6 +1623,7 @@
* @see CameraCharacteristics#SENSOR_FORWARD_MATRIX2
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
*/
+ @PublicKey
public static final Key<Byte> SENSOR_REFERENCE_ILLUMINANT2 =
new Key<Byte>("android.sensor.referenceIlluminant2", byte.class);
@@ -1587,6 +1642,7 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_CALIBRATION_TRANSFORM1 =
new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.calibrationTransform1", android.hardware.camera2.params.ColorSpaceTransform.class);
@@ -1608,6 +1664,7 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_CALIBRATION_TRANSFORM2 =
new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.calibrationTransform2", android.hardware.camera2.params.ColorSpaceTransform.class);
@@ -1630,6 +1687,7 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_COLOR_TRANSFORM1 =
new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.colorTransform1", android.hardware.camera2.params.ColorSpaceTransform.class);
@@ -1654,6 +1712,7 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_COLOR_TRANSFORM2 =
new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.colorTransform2", android.hardware.camera2.params.ColorSpaceTransform.class);
@@ -1674,6 +1733,7 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_FORWARD_MATRIX1 =
new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.forwardMatrix1", android.hardware.camera2.params.ColorSpaceTransform.class);
@@ -1696,6 +1756,7 @@
*
* @see CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.ColorSpaceTransform> SENSOR_FORWARD_MATRIX2 =
new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.sensor.forwardMatrix2", android.hardware.camera2.params.ColorSpaceTransform.class);
@@ -1714,6 +1775,7 @@
* @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
* @see CameraCharacteristics#SENSOR_INFO_WHITE_LEVEL
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.BlackLevelPattern> SENSOR_BLACK_LEVEL_PATTERN =
new Key<android.hardware.camera2.params.BlackLevelPattern>("android.sensor.blackLevelPattern", android.hardware.camera2.params.BlackLevelPattern.class);
@@ -1732,6 +1794,7 @@
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CaptureRequest#SENSOR_SENSITIVITY
*/
+ @PublicKey
public static final Key<Integer> SENSOR_MAX_ANALOG_SENSITIVITY =
new Key<Integer>("android.sensor.maxAnalogSensitivity", int.class);
@@ -1742,6 +1805,7 @@
* direction of rolling shutter readout, which is from top
* to bottom in the sensor's coordinate system</p>
*/
+ @PublicKey
public static final Key<Integer> SENSOR_ORIENTATION =
new Key<Integer>("android.sensor.orientation", int.class);
@@ -1768,6 +1832,7 @@
*
* @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
*/
+ @PublicKey
public static final Key<android.util.Pair<Double,Double>[]> SENSOR_NOISE_PROFILE =
new Key<android.util.Pair<Double,Double>[]>("android.sensor.noiseProfile", new TypeReference<android.util.Pair<Double,Double>[]>() {{ }});
@@ -1778,6 +1843,7 @@
*
* @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
*/
+ @PublicKey
public static final Key<int[]> SENSOR_AVAILABLE_TEST_PATTERN_MODES =
new Key<int[]>("android.sensor.availableTestPatternModes", int[].class);
@@ -1792,6 +1858,7 @@
* android.statistics.faceIds and
* android.statistics.faceLandmarks outputs.</p>
*/
+ @PublicKey
public static final Key<int[]> STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES =
new Key<int[]>("android.statistics.info.availableFaceDetectModes", int[].class);
@@ -1799,6 +1866,7 @@
* <p>The maximum number of simultaneously detectable
* faces.</p>
*/
+ @PublicKey
public static final Key<Integer> STATISTICS_INFO_MAX_FACE_COUNT =
new Key<Integer>("android.statistics.info.maxFaceCount", int.class);
@@ -1811,6 +1879,7 @@
*
* @see CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE
*/
+ @PublicKey
public static final Key<boolean[]> STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES =
new Key<boolean[]>("android.statistics.info.availableHotPixelMapModes", boolean[].class);
@@ -1827,6 +1896,7 @@
*
* @see CaptureRequest#TONEMAP_CURVE
*/
+ @PublicKey
public static final Key<Integer> TONEMAP_MAX_CURVE_POINTS =
new Key<Integer>("android.tonemap.maxCurvePoints", int.class);
@@ -1838,6 +1908,7 @@
*
* @see CaptureRequest#TONEMAP_MODE
*/
+ @PublicKey
public static final Key<int[]> TONEMAP_AVAILABLE_TONE_MAP_MODES =
new Key<int[]>("android.tonemap.availableToneMapModes", int[].class);
@@ -1879,6 +1950,7 @@
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
*/
+ @PublicKey
public static final Key<Integer> INFO_SUPPORTED_HARDWARE_LEVEL =
new Key<Integer>("android.info.supportedHardwareLevel", int.class);
@@ -1917,10 +1989,12 @@
* @see #SYNC_MAX_LATENCY_PER_FRAME_CONTROL
* @see #SYNC_MAX_LATENCY_UNKNOWN
*/
+ @PublicKey
public static final Key<Integer> SYNC_MAX_LATENCY =
new Key<Integer>("android.sync.maxLatency", int.class);
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+
}
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 63130a7..ebbfc63 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -17,6 +17,8 @@
package android.hardware.camera2;
import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.impl.PublicKey;
+import android.hardware.camera2.impl.SyntheticKey;
import android.util.Log;
import java.lang.reflect.Field;
@@ -151,7 +153,7 @@
}
if (instance == null || instance.getProtected(key) != null) {
- if (shouldKeyBeAdded(key, filterTags)) {
+ if (shouldKeyBeAdded(key, field, filterTags)) {
keyList.add(key);
if (VERBOSE) {
@@ -168,7 +170,7 @@
}
@SuppressWarnings("rawtypes")
- private static <TKey> boolean shouldKeyBeAdded(TKey key, int[] filterTags) {
+ private static <TKey> boolean shouldKeyBeAdded(TKey key, Field field, int[] filterTags) {
if (key == null) {
throw new NullPointerException("key must not be null");
}
@@ -189,11 +191,27 @@
throw new IllegalArgumentException("key type must be that of a metadata key");
}
+ if (field.getAnnotation(PublicKey.class) == null) {
+ // Never expose @hide keys up to the API user
+ return false;
+ }
+
// No filtering necessary
if (filterTags == null) {
return true;
}
+ if (field.getAnnotation(SyntheticKey.class) != null) {
+ // This key is synthetic, so calling #getTag will throw IAE
+
+ // TODO: don't just assume all public+synthetic keys are always available
+ return true;
+ }
+
+ /*
+ * Regular key: look up it's native tag and see if it's in filterTags
+ */
+
int keyTag = nativeKey.getTag();
// non-negative result is returned iff the value is in the array
@@ -1189,7 +1207,8 @@
* image while recording video) use case.</p>
* <p>The camera device should take the highest-quality image
* possible (given the other settings) without disrupting the
- * frame rate of video recording. </p>
+ * frame rate of video recording.<br />
+ * </p>
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
*/
public static final int CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 964f4f3..97077e6 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -16,13 +16,13 @@
package android.hardware.camera2;
-import android.hardware.camera2.CameraCharacteristics.Key;
import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.impl.PublicKey;
+import android.hardware.camera2.impl.SyntheticKey;
import android.hardware.camera2.utils.HashCodeHelpers;
import android.hardware.camera2.utils.TypeReference;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Rational;
import android.view.Surface;
import java.util.Collection;
@@ -526,6 +526,7 @@
* @see #COLOR_CORRECTION_MODE_FAST
* @see #COLOR_CORRECTION_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> COLOR_CORRECTION_MODE =
new Key<Integer>("android.colorCorrection.mode", int.class);
@@ -544,6 +545,7 @@
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.ColorSpaceTransform> COLOR_CORRECTION_TRANSFORM =
new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.colorCorrection.transform", android.hardware.camera2.params.ColorSpaceTransform.class);
@@ -560,6 +562,7 @@
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.RggbChannelVector> COLOR_CORRECTION_GAINS =
new Key<android.hardware.camera2.params.RggbChannelVector>("android.colorCorrection.gains", android.hardware.camera2.params.RggbChannelVector.class);
@@ -583,6 +586,7 @@
* @see #COLOR_CORRECTION_ABERRATION_CORRECTION_MODE_FAST
* @see #COLOR_CORRECTION_ABERRATION_CORRECTION_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> COLOR_CORRECTION_ABERRATION_CORRECTION_MODE =
new Key<Integer>("android.colorCorrection.aberrationCorrectionMode", int.class);
@@ -626,6 +630,7 @@
* @see #CONTROL_AE_ANTIBANDING_MODE_60HZ
* @see #CONTROL_AE_ANTIBANDING_MODE_AUTO
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AE_ANTIBANDING_MODE =
new Key<Integer>("android.control.aeAntibandingMode", int.class);
@@ -654,6 +659,7 @@
* @see CaptureRequest#CONTROL_AE_MODE
* @see CaptureResult#CONTROL_AE_STATE
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AE_EXPOSURE_COMPENSATION =
new Key<Integer>("android.control.aeExposureCompensation", int.class);
@@ -680,6 +686,7 @@
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
* @see CaptureRequest#SENSOR_SENSITIVITY
*/
+ @PublicKey
public static final Key<Boolean> CONTROL_AE_LOCK =
new Key<Boolean>("android.control.aeLock", boolean.class);
@@ -717,6 +724,7 @@
* @see #CONTROL_AE_MODE_ON_ALWAYS_FLASH
* @see #CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AE_MODE =
new Key<Integer>("android.control.aeMode", int.class);
@@ -742,6 +750,7 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AE_REGIONS =
new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.aeRegions", android.hardware.camera2.params.MeteringRectangle[].class);
@@ -753,6 +762,7 @@
*
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
*/
+ @PublicKey
public static final Key<android.util.Range<Integer>> CONTROL_AE_TARGET_FPS_RANGE =
new Key<android.util.Range<Integer>>("android.control.aeTargetFpsRange", new TypeReference<android.util.Range<Integer>>() {{ }});
@@ -780,6 +790,7 @@
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_START
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AE_PRECAPTURE_TRIGGER =
new Key<Integer>("android.control.aePrecaptureTrigger", int.class);
@@ -802,6 +813,7 @@
* @see #CONTROL_AF_MODE_CONTINUOUS_PICTURE
* @see #CONTROL_AF_MODE_EDOF
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AF_MODE =
new Key<Integer>("android.control.afMode", int.class);
@@ -827,6 +839,7 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AF_REGIONS =
new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.afRegions", android.hardware.camera2.params.MeteringRectangle[].class);
@@ -849,6 +862,7 @@
* @see #CONTROL_AF_TRIGGER_START
* @see #CONTROL_AF_TRIGGER_CANCEL
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AF_TRIGGER =
new Key<Integer>("android.control.afTrigger", int.class);
@@ -861,6 +875,7 @@
*
* @see CaptureRequest#CONTROL_AWB_MODE
*/
+ @PublicKey
public static final Key<Boolean> CONTROL_AWB_LOCK =
new Key<Boolean>("android.control.awbLock", boolean.class);
@@ -899,6 +914,7 @@
* @see #CONTROL_AWB_MODE_TWILIGHT
* @see #CONTROL_AWB_MODE_SHADE
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AWB_MODE =
new Key<Integer>("android.control.awbMode", int.class);
@@ -924,6 +940,7 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AWB_REGIONS =
new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.awbRegions", android.hardware.camera2.params.MeteringRectangle[].class);
@@ -948,6 +965,7 @@
* @see #CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG
* @see #CONTROL_CAPTURE_INTENT_MANUAL
*/
+ @PublicKey
public static final Key<Integer> CONTROL_CAPTURE_INTENT =
new Key<Integer>("android.control.captureIntent", int.class);
@@ -973,6 +991,7 @@
* @see #CONTROL_EFFECT_MODE_BLACKBOARD
* @see #CONTROL_EFFECT_MODE_AQUA
*/
+ @PublicKey
public static final Key<Integer> CONTROL_EFFECT_MODE =
new Key<Integer>("android.control.effectMode", int.class);
@@ -1001,6 +1020,7 @@
* @see #CONTROL_MODE_USE_SCENE_MODE
* @see #CONTROL_MODE_OFF_KEEP_STATE
*/
+ @PublicKey
public static final Key<Integer> CONTROL_MODE =
new Key<Integer>("android.control.mode", int.class);
@@ -1042,6 +1062,7 @@
* @see #CONTROL_SCENE_MODE_BARCODE
* @see #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO
*/
+ @PublicKey
public static final Key<Integer> CONTROL_SCENE_MODE =
new Key<Integer>("android.control.sceneMode", int.class);
@@ -1066,6 +1087,7 @@
* @see #CONTROL_VIDEO_STABILIZATION_MODE_OFF
* @see #CONTROL_VIDEO_STABILIZATION_MODE_ON
*/
+ @PublicKey
public static final Key<Integer> CONTROL_VIDEO_STABILIZATION_MODE =
new Key<Integer>("android.control.videoStabilizationMode", int.class);
@@ -1086,6 +1108,7 @@
* @see #EDGE_MODE_FAST
* @see #EDGE_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> EDGE_MODE =
new Key<Integer>("android.edge.mode", int.class);
@@ -1113,6 +1136,7 @@
* @see #FLASH_MODE_SINGLE
* @see #FLASH_MODE_TORCH
*/
+ @PublicKey
public static final Key<Integer> FLASH_MODE =
new Key<Integer>("android.flash.mode", int.class);
@@ -1129,12 +1153,15 @@
* @see #HOT_PIXEL_MODE_FAST
* @see #HOT_PIXEL_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> HOT_PIXEL_MODE =
new Key<Integer>("android.hotPixel.mode", int.class);
/**
* <p>A location object to use when generating image GPS metadata.</p>
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<android.location.Location> JPEG_GPS_LOCATION =
new Key<android.location.Location>("android.jpeg.gpsLocation", android.location.Location.class);
@@ -1166,6 +1193,7 @@
* <p>Orientation of JPEG image to
* write</p>
*/
+ @PublicKey
public static final Key<Integer> JPEG_ORIENTATION =
new Key<Integer>("android.jpeg.orientation", int.class);
@@ -1174,6 +1202,7 @@
* image.</p>
* <p>85-95 is typical usage range.</p>
*/
+ @PublicKey
public static final Key<Byte> JPEG_QUALITY =
new Key<Byte>("android.jpeg.quality", byte.class);
@@ -1181,6 +1210,7 @@
* <p>Compression quality of JPEG
* thumbnail.</p>
*/
+ @PublicKey
public static final Key<Byte> JPEG_THUMBNAIL_QUALITY =
new Key<Byte>("android.jpeg.thumbnailQuality", byte.class);
@@ -1197,6 +1227,7 @@
* generate the thumbnail image. The thumbnail image will always have a smaller Field
* Of View (FOV) than the primary image when aspect ratios differ.</p>
*/
+ @PublicKey
public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
new Key<android.util.Size>("android.jpeg.thumbnailSize", android.util.Size.class);
@@ -1226,6 +1257,7 @@
* @see CaptureRequest#SENSOR_FRAME_DURATION
* @see CaptureRequest#SENSOR_SENSITIVITY
*/
+ @PublicKey
public static final Key<Float> LENS_APERTURE =
new Key<Float>("android.lens.aperture", float.class);
@@ -1249,6 +1281,7 @@
* @see CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES
* @see CaptureResult#LENS_STATE
*/
+ @PublicKey
public static final Key<Float> LENS_FILTER_DENSITY =
new Key<Float>("android.lens.filterDensity", float.class);
@@ -1268,6 +1301,7 @@
* @see CaptureRequest#LENS_FOCUS_DISTANCE
* @see CaptureResult#LENS_STATE
*/
+ @PublicKey
public static final Key<Float> LENS_FOCAL_LENGTH =
new Key<Float>("android.lens.focalLength", float.class);
@@ -1285,6 +1319,7 @@
* @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
* @see CaptureResult#LENS_STATE
*/
+ @PublicKey
public static final Key<Float> LENS_FOCUS_DISTANCE =
new Key<Float>("android.lens.focusDistance", float.class);
@@ -1314,6 +1349,7 @@
* @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
* @see #LENS_OPTICAL_STABILIZATION_MODE_ON
*/
+ @PublicKey
public static final Key<Integer> LENS_OPTICAL_STABILIZATION_MODE =
new Key<Integer>("android.lens.opticalStabilizationMode", int.class);
@@ -1334,6 +1370,7 @@
* @see #NOISE_REDUCTION_MODE_FAST
* @see #NOISE_REDUCTION_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> NOISE_REDUCTION_MODE =
new Key<Integer>("android.noiseReduction.mode", int.class);
@@ -1381,6 +1418,7 @@
* @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.graphics.Rect> SCALER_CROP_REGION =
new Key<android.graphics.Rect>("android.scaler.cropRegion", android.graphics.Rect.class);
@@ -1390,6 +1428,7 @@
* <p>If the sensor can't expose this exact duration, it should shorten the
* duration exposed to the nearest possible value (rather than expose longer).</p>
*/
+ @PublicKey
public static final Key<Long> SENSOR_EXPOSURE_TIME =
new Key<Long>("android.sensor.exposureTime", long.class);
@@ -1468,6 +1507,7 @@
*
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
*/
+ @PublicKey
public static final Key<Long> SENSOR_FRAME_DURATION =
new Key<Long>("android.sensor.frameDuration", long.class);
@@ -1487,6 +1527,7 @@
* @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
* @see CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY
*/
+ @PublicKey
public static final Key<Integer> SENSOR_SENSITIVITY =
new Key<Integer>("android.sensor.sensitivity", int.class);
@@ -1503,6 +1544,7 @@
*
* @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
*/
+ @PublicKey
public static final Key<int[]> SENSOR_TEST_PATTERN_DATA =
new Key<int[]>("android.sensor.testPatternData", int[].class);
@@ -1523,6 +1565,7 @@
* @see #SENSOR_TEST_PATTERN_MODE_PN9
* @see #SENSOR_TEST_PATTERN_MODE_CUSTOM1
*/
+ @PublicKey
public static final Key<Integer> SENSOR_TEST_PATTERN_MODE =
new Key<Integer>("android.sensor.testPatternMode", int.class);
@@ -1561,6 +1604,7 @@
* @see #SHADING_MODE_FAST
* @see #SHADING_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> SHADING_MODE =
new Key<Integer>("android.shading.mode", int.class);
@@ -1577,6 +1621,7 @@
* @see #STATISTICS_FACE_DETECT_MODE_SIMPLE
* @see #STATISTICS_FACE_DETECT_MODE_FULL
*/
+ @PublicKey
public static final Key<Integer> STATISTICS_FACE_DETECT_MODE =
new Key<Integer>("android.statistics.faceDetectMode", int.class);
@@ -1589,6 +1634,7 @@
* @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
* @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES
*/
+ @PublicKey
public static final Key<Boolean> STATISTICS_HOT_PIXEL_MAP_MODE =
new Key<Boolean>("android.statistics.hotPixelMapMode", boolean.class);
@@ -1601,6 +1647,7 @@
* @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
* @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
*/
+ @PublicKey
public static final Key<Integer> STATISTICS_LENS_SHADING_MAP_MODE =
new Key<Integer>("android.statistics.lensShadingMapMode", int.class);
@@ -1730,6 +1777,8 @@
* @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
* @see CaptureRequest#TONEMAP_MODE
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<android.hardware.camera2.params.TonemapCurve> TONEMAP_CURVE =
new Key<android.hardware.camera2.params.TonemapCurve>("android.tonemap.curve", android.hardware.camera2.params.TonemapCurve.class);
@@ -1763,6 +1812,7 @@
* @see #TONEMAP_MODE_FAST
* @see #TONEMAP_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> TONEMAP_MODE =
new Key<Integer>("android.tonemap.mode", int.class);
@@ -1821,10 +1871,12 @@
* other request parameters require a black level recalculation
* or reset.</p>
*/
+ @PublicKey
public static final Key<Boolean> BLACK_LEVEL_LOCK =
new Key<Boolean>("android.blackLevel.lock", boolean.class);
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+
}
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 956e64f..c9774ed 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -17,6 +17,8 @@
package android.hardware.camera2;
import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.impl.PublicKey;
+import android.hardware.camera2.impl.SyntheticKey;
import android.hardware.camera2.utils.TypeReference;
import android.util.Log;
import android.util.Rational;
@@ -365,6 +367,7 @@
* @see #COLOR_CORRECTION_MODE_FAST
* @see #COLOR_CORRECTION_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> COLOR_CORRECTION_MODE =
new Key<Integer>("android.colorCorrection.mode", int.class);
@@ -383,6 +386,7 @@
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.ColorSpaceTransform> COLOR_CORRECTION_TRANSFORM =
new Key<android.hardware.camera2.params.ColorSpaceTransform>("android.colorCorrection.transform", android.hardware.camera2.params.ColorSpaceTransform.class);
@@ -399,6 +403,7 @@
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.RggbChannelVector> COLOR_CORRECTION_GAINS =
new Key<android.hardware.camera2.params.RggbChannelVector>("android.colorCorrection.gains", android.hardware.camera2.params.RggbChannelVector.class);
@@ -422,6 +427,7 @@
* @see #COLOR_CORRECTION_ABERRATION_CORRECTION_MODE_FAST
* @see #COLOR_CORRECTION_ABERRATION_CORRECTION_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> COLOR_CORRECTION_ABERRATION_CORRECTION_MODE =
new Key<Integer>("android.colorCorrection.aberrationCorrectionMode", int.class);
@@ -465,6 +471,7 @@
* @see #CONTROL_AE_ANTIBANDING_MODE_60HZ
* @see #CONTROL_AE_ANTIBANDING_MODE_AUTO
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AE_ANTIBANDING_MODE =
new Key<Integer>("android.control.aeAntibandingMode", int.class);
@@ -493,6 +500,7 @@
* @see CaptureRequest#CONTROL_AE_MODE
* @see CaptureResult#CONTROL_AE_STATE
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AE_EXPOSURE_COMPENSATION =
new Key<Integer>("android.control.aeExposureCompensation", int.class);
@@ -519,6 +527,7 @@
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
* @see CaptureRequest#SENSOR_SENSITIVITY
*/
+ @PublicKey
public static final Key<Boolean> CONTROL_AE_LOCK =
new Key<Boolean>("android.control.aeLock", boolean.class);
@@ -556,6 +565,7 @@
* @see #CONTROL_AE_MODE_ON_ALWAYS_FLASH
* @see #CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AE_MODE =
new Key<Integer>("android.control.aeMode", int.class);
@@ -581,6 +591,7 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AE_REGIONS =
new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.aeRegions", android.hardware.camera2.params.MeteringRectangle[].class);
@@ -592,6 +603,7 @@
*
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
*/
+ @PublicKey
public static final Key<android.util.Range<Integer>> CONTROL_AE_TARGET_FPS_RANGE =
new Key<android.util.Range<Integer>>("android.control.aeTargetFpsRange", new TypeReference<android.util.Range<Integer>>() {{ }});
@@ -619,6 +631,7 @@
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_START
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AE_PRECAPTURE_TRIGGER =
new Key<Integer>("android.control.aePrecaptureTrigger", int.class);
@@ -817,6 +830,7 @@
* @see #CONTROL_AE_STATE_FLASH_REQUIRED
* @see #CONTROL_AE_STATE_PRECAPTURE
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AE_STATE =
new Key<Integer>("android.control.aeState", int.class);
@@ -839,6 +853,7 @@
* @see #CONTROL_AF_MODE_CONTINUOUS_PICTURE
* @see #CONTROL_AF_MODE_EDOF
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AF_MODE =
new Key<Integer>("android.control.afMode", int.class);
@@ -864,6 +879,7 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AF_REGIONS =
new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.afRegions", android.hardware.camera2.params.MeteringRectangle[].class);
@@ -886,6 +902,7 @@
* @see #CONTROL_AF_TRIGGER_START
* @see #CONTROL_AF_TRIGGER_CANCEL
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AF_TRIGGER =
new Key<Integer>("android.control.afTrigger", int.class);
@@ -1283,6 +1300,7 @@
* @see #CONTROL_AF_STATE_NOT_FOCUSED_LOCKED
* @see #CONTROL_AF_STATE_PASSIVE_UNFOCUSED
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AF_STATE =
new Key<Integer>("android.control.afState", int.class);
@@ -1295,6 +1313,7 @@
*
* @see CaptureRequest#CONTROL_AWB_MODE
*/
+ @PublicKey
public static final Key<Boolean> CONTROL_AWB_LOCK =
new Key<Boolean>("android.control.awbLock", boolean.class);
@@ -1333,6 +1352,7 @@
* @see #CONTROL_AWB_MODE_TWILIGHT
* @see #CONTROL_AWB_MODE_SHADE
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AWB_MODE =
new Key<Integer>("android.control.awbMode", int.class);
@@ -1358,6 +1378,7 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AWB_REGIONS =
new Key<android.hardware.camera2.params.MeteringRectangle[]>("android.control.awbRegions", android.hardware.camera2.params.MeteringRectangle[].class);
@@ -1382,6 +1403,7 @@
* @see #CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG
* @see #CONTROL_CAPTURE_INTENT_MANUAL
*/
+ @PublicKey
public static final Key<Integer> CONTROL_CAPTURE_INTENT =
new Key<Integer>("android.control.captureIntent", int.class);
@@ -1512,6 +1534,7 @@
* @see #CONTROL_AWB_STATE_CONVERGED
* @see #CONTROL_AWB_STATE_LOCKED
*/
+ @PublicKey
public static final Key<Integer> CONTROL_AWB_STATE =
new Key<Integer>("android.control.awbState", int.class);
@@ -1537,6 +1560,7 @@
* @see #CONTROL_EFFECT_MODE_BLACKBOARD
* @see #CONTROL_EFFECT_MODE_AQUA
*/
+ @PublicKey
public static final Key<Integer> CONTROL_EFFECT_MODE =
new Key<Integer>("android.control.effectMode", int.class);
@@ -1565,6 +1589,7 @@
* @see #CONTROL_MODE_USE_SCENE_MODE
* @see #CONTROL_MODE_OFF_KEEP_STATE
*/
+ @PublicKey
public static final Key<Integer> CONTROL_MODE =
new Key<Integer>("android.control.mode", int.class);
@@ -1606,6 +1631,7 @@
* @see #CONTROL_SCENE_MODE_BARCODE
* @see #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO
*/
+ @PublicKey
public static final Key<Integer> CONTROL_SCENE_MODE =
new Key<Integer>("android.control.sceneMode", int.class);
@@ -1630,6 +1656,7 @@
* @see #CONTROL_VIDEO_STABILIZATION_MODE_OFF
* @see #CONTROL_VIDEO_STABILIZATION_MODE_ON
*/
+ @PublicKey
public static final Key<Integer> CONTROL_VIDEO_STABILIZATION_MODE =
new Key<Integer>("android.control.videoStabilizationMode", int.class);
@@ -1650,6 +1677,7 @@
* @see #EDGE_MODE_FAST
* @see #EDGE_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> EDGE_MODE =
new Key<Integer>("android.edge.mode", int.class);
@@ -1677,6 +1705,7 @@
* @see #FLASH_MODE_SINGLE
* @see #FLASH_MODE_TORCH
*/
+ @PublicKey
public static final Key<Integer> FLASH_MODE =
new Key<Integer>("android.flash.mode", int.class);
@@ -1694,6 +1723,7 @@
* @see #FLASH_STATE_FIRED
* @see #FLASH_STATE_PARTIAL
*/
+ @PublicKey
public static final Key<Integer> FLASH_STATE =
new Key<Integer>("android.flash.state", int.class);
@@ -1710,12 +1740,15 @@
* @see #HOT_PIXEL_MODE_FAST
* @see #HOT_PIXEL_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> HOT_PIXEL_MODE =
new Key<Integer>("android.hotPixel.mode", int.class);
/**
* <p>A location object to use when generating image GPS metadata.</p>
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<android.location.Location> JPEG_GPS_LOCATION =
new Key<android.location.Location>("android.jpeg.gpsLocation", android.location.Location.class);
@@ -1747,6 +1780,7 @@
* <p>Orientation of JPEG image to
* write</p>
*/
+ @PublicKey
public static final Key<Integer> JPEG_ORIENTATION =
new Key<Integer>("android.jpeg.orientation", int.class);
@@ -1755,6 +1789,7 @@
* image.</p>
* <p>85-95 is typical usage range.</p>
*/
+ @PublicKey
public static final Key<Byte> JPEG_QUALITY =
new Key<Byte>("android.jpeg.quality", byte.class);
@@ -1762,6 +1797,7 @@
* <p>Compression quality of JPEG
* thumbnail.</p>
*/
+ @PublicKey
public static final Key<Byte> JPEG_THUMBNAIL_QUALITY =
new Key<Byte>("android.jpeg.thumbnailQuality", byte.class);
@@ -1778,6 +1814,7 @@
* generate the thumbnail image. The thumbnail image will always have a smaller Field
* Of View (FOV) than the primary image when aspect ratios differ.</p>
*/
+ @PublicKey
public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
new Key<android.util.Size>("android.jpeg.thumbnailSize", android.util.Size.class);
@@ -1807,6 +1844,7 @@
* @see CaptureRequest#SENSOR_FRAME_DURATION
* @see CaptureRequest#SENSOR_SENSITIVITY
*/
+ @PublicKey
public static final Key<Float> LENS_APERTURE =
new Key<Float>("android.lens.aperture", float.class);
@@ -1830,6 +1868,7 @@
* @see CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES
* @see CaptureResult#LENS_STATE
*/
+ @PublicKey
public static final Key<Float> LENS_FILTER_DENSITY =
new Key<Float>("android.lens.filterDensity", float.class);
@@ -1849,6 +1888,7 @@
* @see CaptureRequest#LENS_FOCUS_DISTANCE
* @see CaptureResult#LENS_STATE
*/
+ @PublicKey
public static final Key<Float> LENS_FOCAL_LENGTH =
new Key<Float>("android.lens.focalLength", float.class);
@@ -1857,6 +1897,7 @@
* measured from frontmost surface of the lens.</p>
* <p>Should be zero for fixed-focus cameras</p>
*/
+ @PublicKey
public static final Key<Float> LENS_FOCUS_DISTANCE =
new Key<Float>("android.lens.focusDistance", float.class);
@@ -1866,6 +1907,7 @@
* <p>If variable focus not supported, can still report
* fixed depth of field range</p>
*/
+ @PublicKey
public static final Key<android.util.Pair<Float,Float>> LENS_FOCUS_RANGE =
new Key<android.util.Pair<Float,Float>>("android.lens.focusRange", new TypeReference<android.util.Pair<Float,Float>>() {{ }});
@@ -1895,6 +1937,7 @@
* @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
* @see #LENS_OPTICAL_STABILIZATION_MODE_ON
*/
+ @PublicKey
public static final Key<Integer> LENS_OPTICAL_STABILIZATION_MODE =
new Key<Integer>("android.lens.opticalStabilizationMode", int.class);
@@ -1931,6 +1974,7 @@
* @see #LENS_STATE_STATIONARY
* @see #LENS_STATE_MOVING
*/
+ @PublicKey
public static final Key<Integer> LENS_STATE =
new Key<Integer>("android.lens.state", int.class);
@@ -1951,6 +1995,7 @@
* @see #NOISE_REDUCTION_MODE_FAST
* @see #NOISE_REDUCTION_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> NOISE_REDUCTION_MODE =
new Key<Integer>("android.noiseReduction.mode", int.class);
@@ -1982,6 +2027,7 @@
* frameCount value).</p>
* <p>Reset on release()</p>
*/
+ @PublicKey
public static final Key<Integer> REQUEST_FRAME_COUNT =
new Key<Integer>("android.request.frameCount", int.class);
@@ -2005,6 +2051,7 @@
*
* @see CameraCharacteristics#REQUEST_PIPELINE_MAX_DEPTH
*/
+ @PublicKey
public static final Key<Byte> REQUEST_PIPELINE_DEPTH =
new Key<Byte>("android.request.pipelineDepth", byte.class);
@@ -2043,6 +2090,7 @@
* @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.graphics.Rect> SCALER_CROP_REGION =
new Key<android.graphics.Rect>("android.scaler.cropRegion", android.graphics.Rect.class);
@@ -2052,6 +2100,7 @@
* <p>If the sensor can't expose this exact duration, it should shorten the
* duration exposed to the nearest possible value (rather than expose longer).</p>
*/
+ @PublicKey
public static final Key<Long> SENSOR_EXPOSURE_TIME =
new Key<Long>("android.sensor.exposureTime", long.class);
@@ -2130,6 +2179,7 @@
*
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
*/
+ @PublicKey
public static final Key<Long> SENSOR_FRAME_DURATION =
new Key<Long>("android.sensor.frameDuration", long.class);
@@ -2149,6 +2199,7 @@
* @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
* @see CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY
*/
+ @PublicKey
public static final Key<Integer> SENSOR_SENSITIVITY =
new Key<Integer>("android.sensor.sensitivity", int.class);
@@ -2171,6 +2222,7 @@
*
* @see CameraCharacteristics#SENSOR_INFO_TIMESTAMP_CALIBRATION
*/
+ @PublicKey
public static final Key<Long> SENSOR_TIMESTAMP =
new Key<Long>("android.sensor.timestamp", long.class);
@@ -2185,6 +2237,7 @@
* <p>The order of the values is R, G, B; where R is in the lowest index.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*/
+ @PublicKey
public static final Key<Rational[]> SENSOR_NEUTRAL_COLOR_POINT =
new Key<Rational[]>("android.sensor.neutralColorPoint", Rational[].class);
@@ -2222,6 +2275,7 @@
* </ul>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*/
+ @PublicKey
public static final Key<Float> SENSOR_GREEN_SPLIT =
new Key<Float>("android.sensor.greenSplit", float.class);
@@ -2238,6 +2292,7 @@
*
* @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
*/
+ @PublicKey
public static final Key<int[]> SENSOR_TEST_PATTERN_DATA =
new Key<int[]>("android.sensor.testPatternData", int[].class);
@@ -2258,6 +2313,7 @@
* @see #SENSOR_TEST_PATTERN_MODE_PN9
* @see #SENSOR_TEST_PATTERN_MODE_CUSTOM1
*/
+ @PublicKey
public static final Key<Integer> SENSOR_TEST_PATTERN_MODE =
new Key<Integer>("android.sensor.testPatternMode", int.class);
@@ -2272,6 +2328,7 @@
*
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<Long> SENSOR_ROLLING_SHUTTER_SKEW =
new Key<Long>("android.sensor.rollingShutterSkew", long.class);
@@ -2310,6 +2367,7 @@
* @see #SHADING_MODE_FAST
* @see #SHADING_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> SHADING_MODE =
new Key<Integer>("android.shading.mode", int.class);
@@ -2326,6 +2384,7 @@
* @see #STATISTICS_FACE_DETECT_MODE_SIMPLE
* @see #STATISTICS_FACE_DETECT_MODE_FULL
*/
+ @PublicKey
public static final Key<Integer> STATISTICS_FACE_DETECT_MODE =
new Key<Integer>("android.statistics.faceDetectMode", int.class);
@@ -2388,6 +2447,8 @@
*
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<android.hardware.camera2.params.Face[]> STATISTICS_FACES =
new Key<android.hardware.camera2.params.Face[]>("android.statistics.faces", android.hardware.camera2.params.Face[].class);
@@ -2434,6 +2495,7 @@
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
*/
+ @PublicKey
public static final Key<android.hardware.camera2.params.LensShadingMap> STATISTICS_LENS_SHADING_CORRECTION_MAP =
new Key<android.hardware.camera2.params.LensShadingMap>("android.statistics.lensShadingCorrectionMap", android.hardware.camera2.params.LensShadingMap.class);
@@ -2554,6 +2616,7 @@
* @see #STATISTICS_SCENE_FLICKER_50HZ
* @see #STATISTICS_SCENE_FLICKER_60HZ
*/
+ @PublicKey
public static final Key<Integer> STATISTICS_SCENE_FLICKER =
new Key<Integer>("android.statistics.sceneFlicker", int.class);
@@ -2566,6 +2629,7 @@
* @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
* @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES
*/
+ @PublicKey
public static final Key<Boolean> STATISTICS_HOT_PIXEL_MAP_MODE =
new Key<Boolean>("android.statistics.hotPixelMapMode", boolean.class);
@@ -2581,6 +2645,7 @@
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
*/
+ @PublicKey
public static final Key<android.graphics.Point[]> STATISTICS_HOT_PIXEL_MAP =
new Key<android.graphics.Point[]>("android.statistics.hotPixelMap", android.graphics.Point[].class);
@@ -2593,6 +2658,7 @@
* @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
* @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
*/
+ @PublicKey
public static final Key<Integer> STATISTICS_LENS_SHADING_MAP_MODE =
new Key<Integer>("android.statistics.lensShadingMapMode", int.class);
@@ -2722,6 +2788,8 @@
* @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
* @see CaptureRequest#TONEMAP_MODE
*/
+ @PublicKey
+ @SyntheticKey
public static final Key<android.hardware.camera2.params.TonemapCurve> TONEMAP_CURVE =
new Key<android.hardware.camera2.params.TonemapCurve>("android.tonemap.curve", android.hardware.camera2.params.TonemapCurve.class);
@@ -2755,6 +2823,7 @@
* @see #TONEMAP_MODE_FAST
* @see #TONEMAP_MODE_HIGH_QUALITY
*/
+ @PublicKey
public static final Key<Integer> TONEMAP_MODE =
new Key<Integer>("android.tonemap.mode", int.class);
@@ -2784,6 +2853,7 @@
*
* @see CaptureRequest#BLACK_LEVEL_LOCK
*/
+ @PublicKey
public static final Key<Boolean> BLACK_LEVEL_LOCK =
new Key<Boolean>("android.blackLevel.lock", boolean.class);
@@ -2851,4 +2921,5 @@
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+
}
diff --git a/core/java/android/hardware/camera2/impl/ListenerProxies.java b/core/java/android/hardware/camera2/impl/ListenerProxies.java
index 04c43e3..ab9a4d5 100644
--- a/core/java/android/hardware/camera2/impl/ListenerProxies.java
+++ b/core/java/android/hardware/camera2/impl/ListenerProxies.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package android.hardware.camera2.impl;
import android.hardware.camera2.CameraCaptureSession;
diff --git a/core/java/android/hardware/camera2/impl/PublicKey.java b/core/java/android/hardware/camera2/impl/PublicKey.java
new file mode 100644
index 0000000..d894c1f
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/PublicKey.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.camera2.impl;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Denote a static field {@code Key} as being public-visible (in the SDK).
+ *
+ * <p>Keys without this annotated are assumed to be {@code @hide}.</p>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface PublicKey {
+
+}
diff --git a/core/java/android/hardware/camera2/impl/SyntheticKey.java b/core/java/android/hardware/camera2/impl/SyntheticKey.java
new file mode 100644
index 0000000..034a04939
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/SyntheticKey.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.camera2.impl;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Denote a static field {@code Key} as being synthetic (i.e. not having a native
+ * tag one-to-one counterpart).
+ *
+ * <p>Keys without this annotated are assumed to always have a native counter-part.</p>
+ *
+ * <p>In particular a key with a native counter-part will always have it's {@code #getTag}
+ * method succeed.</p>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface SyntheticKey {
+
+}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index 519bbb6..157c159 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -25,6 +25,7 @@
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.params.StreamConfiguration;
import android.hardware.camera2.params.StreamConfigurationDuration;
@@ -444,6 +445,120 @@
m.set(REQUEST_AVAILABLE_CAPABILITIES, capabilities);
/*
+ * request.availableCharacteristicsKeys
+ */
+ {
+ // TODO: check if the underlying key is supported before listing a key as available
+
+ // Note: We only list public keys. Native HALs should list ALL keys regardless of visibility.
+
+ Key<?> availableKeys[] = new Key<?>[] {
+ CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES ,
+ CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES ,
+ CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES ,
+ CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE ,
+ CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP ,
+ CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES ,
+ CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS ,
+ CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES ,
+ CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES ,
+ CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES ,
+ CameraCharacteristics.CONTROL_MAX_REGIONS ,
+ CameraCharacteristics.FLASH_INFO_AVAILABLE ,
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL ,
+ CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES ,
+ CameraCharacteristics.LENS_FACING ,
+ CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS ,
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES ,
+ CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_STREAMS ,
+ CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT ,
+ CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH ,
+ CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM ,
+// CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP ,
+ CameraCharacteristics.SCALER_CROPPING_TYPE ,
+ CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES ,
+ CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE ,
+ CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE ,
+ CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE ,
+ CameraCharacteristics.SENSOR_ORIENTATION ,
+ CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES ,
+ CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT ,
+ CameraCharacteristics.SYNC_MAX_LATENCY ,
+ };
+ m.set(REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, getTagsForKeys(availableKeys));
+ }
+
+ /*
+ * request.availableRequestKeys
+ */
+ {
+ CaptureRequest.Key<?> availableKeys[] = new CaptureRequest.Key<?>[] {
+ CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
+ CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
+ CaptureRequest.CONTROL_AE_LOCK,
+ CaptureRequest.CONTROL_AE_MODE,
+ CaptureRequest.CONTROL_AE_REGIONS,
+ CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
+ CaptureRequest.CONTROL_AF_MODE,
+ CaptureRequest.CONTROL_AF_REGIONS,
+ CaptureRequest.CONTROL_AF_TRIGGER,
+ CaptureRequest.CONTROL_AWB_LOCK,
+ CaptureRequest.CONTROL_AWB_MODE,
+ CaptureRequest.CONTROL_CAPTURE_INTENT,
+ CaptureRequest.CONTROL_EFFECT_MODE,
+ CaptureRequest.CONTROL_MODE,
+ CaptureRequest.CONTROL_SCENE_MODE,
+ CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE,
+ CaptureRequest.FLASH_MODE,
+ CaptureRequest.JPEG_GPS_COORDINATES,
+ CaptureRequest.JPEG_GPS_PROCESSING_METHOD,
+ CaptureRequest.JPEG_GPS_TIMESTAMP,
+ CaptureRequest.JPEG_ORIENTATION,
+ CaptureRequest.JPEG_QUALITY,
+ CaptureRequest.JPEG_THUMBNAIL_QUALITY,
+ CaptureRequest.JPEG_THUMBNAIL_SIZE,
+ CaptureRequest.LENS_FOCAL_LENGTH,
+ CaptureRequest.SCALER_CROP_REGION,
+ CaptureRequest.STATISTICS_FACE_DETECT_MODE,
+ };
+ m.set(REQUEST_AVAILABLE_REQUEST_KEYS, getTagsForKeys(availableKeys));
+ }
+
+ /*
+ * request.availableResultKeys
+ */
+ {
+ CaptureResult.Key<?> availableKeys[] = new CaptureResult.Key<?>[] {
+ CaptureResult.CONTROL_AE_ANTIBANDING_MODE ,
+ CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION ,
+ CaptureResult.CONTROL_AE_LOCK ,
+ CaptureResult.CONTROL_AE_MODE ,
+ CaptureResult.CONTROL_AE_REGIONS ,
+ CaptureResult.CONTROL_AF_MODE ,
+ CaptureResult.CONTROL_AF_REGIONS ,
+ CaptureResult.CONTROL_AF_STATE ,
+ CaptureResult.CONTROL_AWB_MODE ,
+ CaptureResult.CONTROL_AWB_LOCK ,
+ CaptureResult.CONTROL_MODE ,
+ CaptureResult.FLASH_MODE ,
+ CaptureResult.JPEG_GPS_COORDINATES ,
+ CaptureResult.JPEG_GPS_PROCESSING_METHOD ,
+ CaptureResult.JPEG_GPS_TIMESTAMP ,
+ CaptureResult.JPEG_ORIENTATION ,
+ CaptureResult.JPEG_QUALITY ,
+ CaptureResult.JPEG_THUMBNAIL_QUALITY ,
+ CaptureResult.LENS_FOCAL_LENGTH ,
+ CaptureResult.REQUEST_FRAME_COUNT ,
+ CaptureResult.REQUEST_PIPELINE_DEPTH ,
+ CaptureResult.SCALER_CROP_REGION ,
+ CaptureResult.SENSOR_TIMESTAMP ,
+ CaptureResult.STATISTICS_FACE_DETECT_MODE ,
+// CaptureResult.STATISTICS_FACES ,
+ };
+ m.set(REQUEST_AVAILABLE_RESULT_KEYS, getTagsForKeys(availableKeys));
+ }
+
+ /*
* request.maxNumOutputStreams
*/
int[] outputStreams = {
@@ -649,4 +764,34 @@
// TODO: map other request template values
return m;
}
+
+ private static int[] getTagsForKeys(Key<?>[] keys) {
+ int[] tags = new int[keys.length];
+
+ for (int i = 0; i < keys.length; ++i) {
+ tags[i] = keys[i].getNativeKey().getTag();
+ }
+
+ return tags;
+ }
+
+ private static int[] getTagsForKeys(CaptureRequest.Key<?>[] keys) {
+ int[] tags = new int[keys.length];
+
+ for (int i = 0; i < keys.length; ++i) {
+ tags[i] = keys[i].getNativeKey().getTag();
+ }
+
+ return tags;
+ }
+
+ private static int[] getTagsForKeys(CaptureResult.Key<?>[] keys) {
+ int[] tags = new int[keys.length];
+
+ for (int i = 0; i < keys.length; ++i) {
+ tags[i] = keys[i].getNativeKey().getTag();
+ }
+
+ return tags;
+ }
}
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index f2426e5..1b9a0c5 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -471,22 +471,30 @@
private VirtualDisplayCallbacksDelegate mDelegate;
public VirtualDisplayCallbacks(VirtualDisplay.Callbacks callbacks, Handler handler) {
- mDelegate = new VirtualDisplayCallbacksDelegate(callbacks, handler);
+ if (callbacks != null) {
+ mDelegate = new VirtualDisplayCallbacksDelegate(callbacks, handler);
+ }
}
@Override // Binder call
public void onDisplayPaused() {
- mDelegate.sendEmptyMessage(VirtualDisplayCallbacksDelegate.MSG_DISPLAY_PAUSED);
+ if (mDelegate != null) {
+ mDelegate.sendEmptyMessage(VirtualDisplayCallbacksDelegate.MSG_DISPLAY_PAUSED);
+ }
}
@Override // Binder call
public void onDisplayResumed() {
- mDelegate.sendEmptyMessage(VirtualDisplayCallbacksDelegate.MSG_DISPLAY_RESUMED);
+ if (mDelegate != null) {
+ mDelegate.sendEmptyMessage(VirtualDisplayCallbacksDelegate.MSG_DISPLAY_RESUMED);
+ }
}
@Override // Binder call
public void onDisplayStopped() {
- mDelegate.sendEmptyMessage(VirtualDisplayCallbacksDelegate.MSG_DISPLAY_STOPPED);
+ if (mDelegate != null) {
+ mDelegate.sendEmptyMessage(VirtualDisplayCallbacksDelegate.MSG_DISPLAY_STOPPED);
+ }
}
}
@@ -505,9 +513,6 @@
@Override
public void handleMessage(Message msg) {
- if (mCallbacks == null) {
- return;
- }
switch (msg.what) {
case MSG_DISPLAY_PAUSED:
mCallbacks.onDisplayPaused();
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index e58c54d..99af2e7 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -19,6 +19,7 @@
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.PowerManager;
+import android.view.Display;
import android.view.DisplayInfo;
/**
@@ -132,13 +133,19 @@
* have to micro-manage screen off animations, auto-brightness and other effects.
*/
public static final class DisplayPowerRequest {
- public static final int SCREEN_STATE_OFF = 0;
- public static final int SCREEN_STATE_DOZE = 1;
- public static final int SCREEN_STATE_DIM = 2;
- public static final int SCREEN_STATE_BRIGHT = 3;
+ // Policy: Turn screen off as if the user pressed the power button
+ // including playing a screen off animation if applicable.
+ public static final int POLICY_OFF = 0;
+ // Policy: Enable dozing and always-on display functionality.
+ public static final int POLICY_DOZE = 1;
+ // Policy: Make the screen dim when the user activity timeout is
+ // about to expire.
+ public static final int POLICY_DIM = 2;
+ // Policy: Make the screen bright as usual.
+ public static final int POLICY_BRIGHT = 3;
- // The requested minimum screen power state: off, doze, dim or bright.
- public int screenState;
+ // The basic overall policy to apply: off, doze, dim or bright.
+ public int policy;
// If true, the proximity sensor overrides the screen state when an object is
// nearby, turning it off temporarily until the object is moved away.
@@ -169,44 +176,39 @@
// visible to the user.
public boolean blockScreenOn;
+ // Overrides the policy for adjusting screen brightness and state while dozing.
+ public int dozeScreenBrightness;
+ public int dozeScreenState;
+
public DisplayPowerRequest() {
- screenState = SCREEN_STATE_BRIGHT;
+ policy = POLICY_BRIGHT;
useProximitySensor = false;
screenBrightness = PowerManager.BRIGHTNESS_ON;
screenAutoBrightnessAdjustment = 0.0f;
useAutoBrightness = false;
blockScreenOn = false;
+ dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
+ dozeScreenState = Display.STATE_UNKNOWN;
}
public DisplayPowerRequest(DisplayPowerRequest other) {
copyFrom(other);
}
- // Returns true if we want the screen on in any mode, including doze.
- public boolean wantScreenOnAny() {
- return screenState != SCREEN_STATE_OFF;
- }
-
- // Returns true if we want the screen on in a normal mode, excluding doze.
- // This is usually what we want to tell the rest of the system. For compatibility
- // reasons, we pretend the screen is off when dozing.
- public boolean wantScreenOnNormal() {
- return screenState == SCREEN_STATE_DIM || screenState == SCREEN_STATE_BRIGHT;
- }
-
- public boolean wantLightSensorEnabled() {
- // Specifically, we don't want the light sensor while dozing.
- return useAutoBrightness && wantScreenOnNormal();
+ public boolean isBrightOrDim() {
+ return policy == POLICY_BRIGHT || policy == POLICY_DIM;
}
public void copyFrom(DisplayPowerRequest other) {
- screenState = other.screenState;
+ policy = other.policy;
useProximitySensor = other.useProximitySensor;
screenBrightness = other.screenBrightness;
screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment;
useAutoBrightness = other.useAutoBrightness;
blockScreenOn = other.blockScreenOn;
lowPowerMode = other.lowPowerMode;
+ dozeScreenBrightness = other.dozeScreenBrightness;
+ dozeScreenState = other.dozeScreenState;
}
@Override
@@ -217,13 +219,15 @@
public boolean equals(DisplayPowerRequest other) {
return other != null
- && screenState == other.screenState
+ && policy == other.policy
&& useProximitySensor == other.useProximitySensor
&& screenBrightness == other.screenBrightness
&& screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment
&& useAutoBrightness == other.useAutoBrightness
&& blockScreenOn == other.blockScreenOn
- && lowPowerMode == other.lowPowerMode;
+ && lowPowerMode == other.lowPowerMode
+ && dozeScreenBrightness == other.dozeScreenBrightness
+ && dozeScreenState == other.dozeScreenState;
}
@Override
@@ -233,13 +237,30 @@
@Override
public String toString() {
- return "screenState=" + screenState
+ return "policy=" + policyToString(policy)
+ ", useProximitySensor=" + useProximitySensor
+ ", screenBrightness=" + screenBrightness
+ ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment
+ ", useAutoBrightness=" + useAutoBrightness
+ ", blockScreenOn=" + blockScreenOn
- + ", lowPowerMode=" + lowPowerMode;
+ + ", lowPowerMode=" + lowPowerMode
+ + ", dozeScreenBrightness=" + dozeScreenBrightness
+ + ", dozeScreenState=" + Display.stateToString(dozeScreenState);
+ }
+
+ public static String policyToString(int policy) {
+ switch (policy) {
+ case POLICY_OFF:
+ return "OFF";
+ case POLICY_DOZE:
+ return "DOZE";
+ case POLICY_DIM:
+ return "DIM";
+ case POLICY_BRIGHT:
+ return "BRIGHT";
+ default:
+ return Integer.toString(policy);
+ }
}
}
diff --git a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java b/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java
index ae0bda1..acf92f1 100644
--- a/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java
+++ b/core/java/android/hardware/hdmi/HdmiCecDeviceInfo.java
@@ -57,7 +57,13 @@
// Value indicating the device is not an active source.
public static final int DEVICE_INACTIVE = -1;
- // Logical address, phsical address, device type, vendor id and display name
+ /**
+ * Logical address used to indicate the source comes from internal device.
+ * The logical address of TV(0) is used.
+ */
+ public static final int ADDR_INTERNAL = 0;
+
+ // Logical address, physical address, device type, vendor id and display name
// are immutable value.
private final int mLogicalAddress;
private final int mPhysicalAddress;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 8de545e..13364cd 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -543,8 +543,6 @@
private final IConnectivityManager mService;
- private final String mPackageName;
-
private INetworkManagementService mNMService;
/**
@@ -646,23 +644,6 @@
}
/**
- * Checks if the given network type should be exempt from VPN routing rules
- *
- * @hide
- */
- public static boolean isNetworkTypeExempt(int networkType) {
- switch (networkType) {
- case TYPE_MOBILE_MMS:
- case TYPE_MOBILE_SUPL:
- case TYPE_MOBILE_HIPRI:
- case TYPE_MOBILE_IA:
- return true;
- default:
- return false;
- }
- }
-
- /**
* Specifies the preferred network type. When the device has more
* than one type available the preferred network type will be used.
*
@@ -1236,13 +1217,7 @@
* {@link #setProcessDefaultNetwork} and {@link Network#getSocketFactory} api.
*/
public boolean requestRouteToHost(int networkType, int hostAddress) {
- InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
-
- if (inetAddress == null) {
- return false;
- }
-
- return requestRouteToHostAddress(networkType, inetAddress);
+ return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
}
/**
@@ -1260,9 +1235,8 @@
* {@link #setProcessDefaultNetwork} api.
*/
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
- byte[] address = hostAddress.getAddress();
try {
- return mService.requestRouteToHostAddress(networkType, address, mPackageName);
+ return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress());
} catch (RemoteException e) {
return false;
}
@@ -1433,9 +1407,8 @@
/**
* {@hide}
*/
- public ConnectivityManager(IConnectivityManager service, String packageName) {
+ public ConnectivityManager(IConnectivityManager service) {
mService = checkNotNull(service, "missing IConnectivityManager");
- mPackageName = checkNotNull(packageName, "missing package name");
}
/** {@hide} */
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index f61984a..8b12fb8 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -69,9 +69,7 @@
int stopUsingNetworkFeature(int networkType, in String feature);
- boolean requestRouteToHost(int networkType, int hostAddress, String packageName);
-
- boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, String packageName);
+ boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
/** Policy control over specific {@link NetworkStateTracker}. */
void setPolicyDataEnable(int networkType, boolean enabled);
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 9b95305..663aa15 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -36,12 +36,6 @@
private static final String TAG = "NetworkUtils";
- /** Bring the named network interface up. */
- public native static int enableInterface(String interfaceName);
-
- /** Bring the named network interface down. */
- public native static int disableInterface(String interfaceName);
-
/** Setting bit 0 indicates reseting of IPv4 addresses required */
public static final int RESET_IPV4_ADDRESSES = 0x01;
diff --git a/core/java/android/net/PSKKeyManager.java b/core/java/android/net/PskKeyManager.java
similarity index 77%
rename from core/java/android/net/PSKKeyManager.java
rename to core/java/android/net/PskKeyManager.java
index e868c4f..d162282 100644
--- a/core/java/android/net/PSKKeyManager.java
+++ b/core/java/android/net/PskKeyManager.java
@@ -16,6 +16,7 @@
package android.net;
+import com.android.org.conscrypt.PSKKeyManager;
import java.net.Socket;
import javax.crypto.SecretKey;
import javax.net.ssl.SSLEngine;
@@ -40,10 +41,10 @@
*
* <h3>Supporting multiple keys</h3>
*
- * <p>A peer may have multiple keys to choose from. To help choose the right key, during the handshake
- * the server can provide a <em>PSK identity hint</em> to the client, and the client can provide a
- * <em>PSK identity</em> to the server. The contents of these two pieces of information are specific
- * to application-level protocols.</p>
+ * <p>A peer may have multiple keys to choose from. To help choose the right key, during the
+ * handshake the server can provide a <em>PSK identity hint</em> to the client, and the client can
+ * provide a <em>PSK identity</em> to the server. The contents of these two pieces of information
+ * are specific to application-level protocols.</p>
*
* <p><em>NOTE: Both the PSK identity hint and the PSK identity are transmitted in cleartext.
* Moreover, these data are received and processed prior to peer having been authenticated. Thus,
@@ -76,16 +77,20 @@
* {@link #MAX_IDENTITY_LENGTH_BYTES} and {@link #MAX_IDENTITY_HINT_LENGTH_BYTES}).</li>
* </ul></p>
*
+ * <h3>Subclassing</h3>
+ * Subclasses should normally provide their own implementation of {@code getKey} because the default
+ * implementation returns no key, which aborts the handshake.
+ *
* <h3>Example</h3>
* The following example illustrates how to create an {@code SSLContext} which enables the use of
* TLS-PSK in {@code SSLSocket}, {@code SSLServerSocket} and {@code SSLEngine} instances obtained
* from it.
* <pre> {@code
- * PSKKeyManager myPskKeyManager = ...;
+ * PskKeyManager pskKeyManager = ...;
*
* SSLContext sslContext = SSLContext.getInstance("TLS");
* sslContext.init(
- * new KeyManager[] {myPskKeyManager},
+ * new KeyManager[] {pskKeyManager},
* new TrustManager[0], // No TrustManagers needed for TLS-PSK
* null // Use the default source of entropy
* );
@@ -93,7 +98,7 @@
* SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(...);
* }</pre>
*/
-public interface PSKKeyManager extends com.android.org.conscrypt.PSKKeyManager {
+public abstract class PskKeyManager implements PSKKeyManager {
// IMPLEMENTATION DETAILS: This class exists only because the default implemenetation of the
// TLS/SSL JSSE provider (currently Conscrypt) cannot depend on Android framework classes.
// As a result, this framework class simply extends the PSKKeyManager interface from Conscrypt
@@ -103,61 +108,83 @@
/**
* Maximum supported length (in bytes) for PSK identity hint (in modified UTF-8 representation).
*/
- int MAX_IDENTITY_HINT_LENGTH_BYTES =
- com.android.org.conscrypt.PSKKeyManager.MAX_IDENTITY_HINT_LENGTH_BYTES;
+ public static final int MAX_IDENTITY_HINT_LENGTH_BYTES =
+ PSKKeyManager.MAX_IDENTITY_HINT_LENGTH_BYTES;
/** Maximum supported length (in bytes) for PSK identity (in modified UTF-8 representation). */
- int MAX_IDENTITY_LENGTH_BYTES =
- com.android.org.conscrypt.PSKKeyManager.MAX_IDENTITY_LENGTH_BYTES;
+ public static final int MAX_IDENTITY_LENGTH_BYTES = PSKKeyManager.MAX_IDENTITY_LENGTH_BYTES;
/** Maximum supported length (in bytes) for PSK. */
- int MAX_KEY_LENGTH_BYTES = com.android.org.conscrypt.PSKKeyManager.MAX_KEY_LENGTH_BYTES;
+ public static final int MAX_KEY_LENGTH_BYTES = PSKKeyManager.MAX_KEY_LENGTH_BYTES;
/**
* Gets the PSK identity hint to report to the client to help agree on the PSK for the provided
* socket.
*
+ * <p>
+ * The default implementation returns {@code null}.
+ *
* @return PSK identity hint to be provided to the client or {@code null} to provide no hint.
*/
@Override
- String chooseServerKeyIdentityHint(Socket socket);
+ public String chooseServerKeyIdentityHint(Socket socket) {
+ return null;
+ }
/**
* Gets the PSK identity hint to report to the client to help agree on the PSK for the provided
* engine.
*
+ * <p>
+ * The default implementation returns {@code null}.
+ *
* @return PSK identity hint to be provided to the client or {@code null} to provide no hint.
*/
@Override
- String chooseServerKeyIdentityHint(SSLEngine engine);
+ public String chooseServerKeyIdentityHint(SSLEngine engine) {
+ return null;
+ }
/**
* Gets the PSK identity to report to the server to help agree on the PSK for the provided
* socket.
*
+ * <p>
+ * The default implementation returns an empty string.
+ *
* @param identityHint identity hint provided by the server or {@code null} if none provided.
*
* @return PSK identity to provide to the server. {@code null} is permitted but will be
* converted into an empty string.
*/
@Override
- String chooseClientKeyIdentity(String identityHint, Socket socket);
+ public String chooseClientKeyIdentity(String identityHint, Socket socket) {
+ return "";
+ }
/**
* Gets the PSK identity to report to the server to help agree on the PSK for the provided
* engine.
*
+ * <p>
+ * The default implementation returns an empty string.
+ *
* @param identityHint identity hint provided by the server or {@code null} if none provided.
*
* @return PSK identity to provide to the server. {@code null} is permitted but will be
* converted into an empty string.
*/
@Override
- String chooseClientKeyIdentity(String identityHint, SSLEngine engine);
+ public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
+ return "";
+ }
/**
* Gets the PSK to use for the provided socket.
*
+ * <p>
+ * The default implementation returns {@code null}.
+ *
* @param identityHint identity hint provided by the server to help select the key or
* {@code null} if none provided.
* @param identity identity provided by the client to help select the key.
@@ -166,11 +193,16 @@
* the handshake.
*/
@Override
- SecretKey getKey(String identityHint, String identity, Socket socket);
+ public SecretKey getKey(String identityHint, String identity, Socket socket) {
+ return null;
+ }
/**
* Gets the PSK to use for the provided engine.
*
+ * <p>
+ * The default implementation returns {@code null}.
+ *
* @param identityHint identity hint provided by the server to help select the key or
* {@code null} if none provided.
* @param identity identity provided by the client to help select the key.
@@ -179,5 +211,7 @@
* the handshake.
*/
@Override
- SecretKey getKey(String identityHint, String identity, SSLEngine engine);
+ public SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
+ return null;
+ }
}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 207dc4a..c1e6664 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -19,7 +19,6 @@
import android.net.InterfaceConfiguration;
import android.net.INetworkManagementEventObserver;
-import android.net.LinkAddress;
import android.net.NetworkStats;
import android.net.RouteInfo;
import android.net.UidRange;
@@ -313,11 +312,6 @@
*/
void setDnsServersForNetwork(int netId, in String[] servers, String domains);
- /**
- * Flush the DNS cache associated with the specified network.
- */
- void flushNetworkDnsCache(int netId);
-
void setFirewallEnabled(boolean enabled);
boolean isFirewallEnabled();
void setFirewallInterfaceRule(String iface, boolean allow);
@@ -336,17 +330,6 @@
void removeVpnUidRanges(int netId, in UidRange[] ranges);
/**
- * Exempts {@code host} from the routing set up by {@link setMarkedForwardingRoute}
- * All connects to {@code host} will use the global routing table
- */
- void setHostExemption(in LinkAddress host);
-
- /**
- * Clears an exemption set by {@link setHostExemption}
- */
- void clearHostExemption(in LinkAddress host);
-
- /**
* Start the clatd (464xlat) service
*/
void startClatd(String interfaceName);
@@ -402,7 +385,6 @@
void removeInterfaceFromNetwork(String iface, int netId);
void addLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid);
- void removeLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid);
void setDefaultNetId(int netId);
void clearDefaultNetId();
@@ -419,4 +401,7 @@
* Deny UID from calling protect().
*/
void denyProtect(int uid);
+
+ void addInterfaceToLocalNetwork(String iface, in List<RouteInfo> routes);
+ void removeInterfaceFromLocalNetwork(String iface);
}
diff --git a/core/java/android/os/PersistableBundle.aidl b/core/java/android/os/PersistableBundle.aidl
new file mode 100644
index 0000000..5b05873
--- /dev/null
+++ b/core/java/android/os/PersistableBundle.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.os;
+
+parcelable PersistableBundle;
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 92e80a5..dda6d27 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -263,6 +263,12 @@
*/
public static final int BRIGHTNESS_OFF = 0;
+ /**
+ * Brightness value for default policy handling by the system.
+ * @hide
+ */
+ public static final int BRIGHTNESS_DEFAULT = -1;
+
// Note: Be sure to update android.os.BatteryStats and PowerManager.h
// if adding or modifying user activity event constants.
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 08a15eb..14f4a83 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -16,6 +16,8 @@
package android.os;
+import android.view.Display;
+
/**
* Power manager local system service interface.
*
@@ -53,6 +55,17 @@
*/
public abstract void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis);
+ /**
+ * Used by the dream manager to override certain properties while dozing.
+ *
+ * @param screenState The overridden screen state, or {@link Display.STATE_UNKNOWN}
+ * to disable the override.
+ * @param screenBrightness The overridden screen brightness, or
+ * {@link PowerManager#BRIGHTNESS_DEFAULT} to disable the override.
+ */
+ public abstract void setDozeOverrideFromDreamManager(
+ int screenState, int screenBrightness);
+
public abstract boolean getLowPowerModeEnabled();
public abstract void registerLowPowerModeObserver(LowPowerModeListener listener);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bbaf1c1..34d7c80 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3937,30 +3937,12 @@
"accessibility_captioning_font_scale";
/**
- * Setting that specifies whether the quick setting tile for display
- * color inversion is enabled.
- *
- * @hide
- */
- public static final String ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED =
- "accessibility_display_inversion_quick_setting_enabled";
-
- /**
* Setting that specifies whether display color inversion is enabled.
*/
public static final String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED =
"accessibility_display_inversion_enabled";
/**
- * Setting that specifies whether the quick setting tile for display
- * color space adjustment is enabled.
- *
- * @hide
- */
- public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED =
- "accessibility_display_daltonizer_quick_setting_enabled";
-
- /**
* Setting that specifies whether display color space adjustment is
* enabled.
*
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 5fa542a..5cf8aa6 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -27,10 +27,13 @@
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.os.IBinder;
+import android.os.PowerManager;
+import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Slog;
import android.view.ActionMode;
+import android.view.Display;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
@@ -42,6 +45,7 @@
import android.view.WindowManagerGlobal;
import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
+import android.util.MathUtils;
import com.android.internal.policy.PolicyManager;
import com.android.internal.util.DumpUtils;
@@ -133,8 +137,11 @@
* android:exported="true"
* android:icon="@drawable/my_icon"
* android:label="@string/my_dream_label"
- * android:permission="android.permission.BIND_DREAM_SERVICE" >
- * ...
+ * android:permission="android.permission.BIND_DREAM_SERVICE">
+ * <intent-filter>
+ * <action android:name=”android.service.dreams.DreamService” />
+ * <category android:name=”android.intent.category.DEFAULT” />
+ * </intent-filter>
* </service>
* </pre>
*/
@@ -177,6 +184,8 @@
private boolean mDozing;
private boolean mWindowless;
private DozeHardware mDozeHardware;
+ private int mDozeScreenState = Display.STATE_UNKNOWN;
+ private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
private boolean mDebug = false;
@@ -560,7 +569,7 @@
*
* @return True if this dream can doze.
* @see #startDozing
- * @hide experimental
+ * @hide For use by system UI components only.
*/
public boolean canDoze() {
return mCanDoze;
@@ -593,13 +602,19 @@
* </p>
*
* @see #stopDozing
- * @hide experimental
+ * @hide For use by system UI components only.
*/
public void startDozing() {
if (mCanDoze && !mDozing) {
mDozing = true;
+ updateDoze();
+ }
+ }
+
+ private void updateDoze() {
+ if (mDozing) {
try {
- mSandman.startDozing(mWindowToken);
+ mSandman.startDozing(mWindowToken, mDozeScreenState, mDozeScreenBrightness);
} catch (RemoteException ex) {
// system server died
}
@@ -615,7 +630,7 @@
* </p>
*
* @see #startDozing
- * @hide experimental
+ * @hide For use by system UI components only.
*/
public void stopDozing() {
if (mDozing) {
@@ -636,7 +651,7 @@
* @return True if the dream is dozing.
*
* @see #setDozing(boolean)
- * @hide experimental
+ * @hide For use by system UI components only.
*/
public boolean isDozing() {
return mDozing;
@@ -649,7 +664,7 @@
* @return An instance of {@link DozeHardware} or null if this device does not offer
* hardware support for dozing.
*
- * @hide experimental
+ * @hide For use by system UI components only.
*/
public DozeHardware getDozeHardware() {
if (mCanDoze && mDozeHardware == null && mWindowToken != null) {
@@ -666,11 +681,116 @@
}
/**
+ * Gets the screen state to use while dozing.
+ *
+ * @return The screen state to use while dozing, such as {@link Display#STATE_ON},
+ * {@link Display#STATE_DOZE}, {@link Display#STATE_DOZE_SUSPEND},
+ * or {@link Display#STATE_OFF}, or {@link Display#STATE_UNKNOWN} for the default
+ * behavior.
+ *
+ * @see #setDozeScreenState
+ * @hide For use by system UI components only.
+ */
+ public int getDozeScreenState() {
+ return mDozeScreenState;
+ }
+
+ /**
+ * Sets the screen state to use while dozing.
+ * <p>
+ * The value of this property determines the power state of the primary display
+ * once {@link #startDozing} has been called. The default value is
+ * {@link Display#STATE_UNKNOWN} which lets the system decide.
+ * The dream may set a different state before starting to doze and may
+ * perform transitions between states while dozing to conserve power and
+ * achieve various effects.
+ * </p><p>
+ * It is recommended that the state be set to {@link Display#STATE_DOZE_SUSPEND}
+ * once the dream has completely finished drawing and before it releases its wakelock
+ * to allow the display hardware to be fully suspended. While suspended, the
+ * display will preserve its on-screen contents or hand off control to dedicated
+ * doze hardware if the devices supports it. If the doze suspend state is
+ * used, the dream must make sure to set the mode back
+ * to {@link Display#STATE_DOZE} or {@link Display#STATE_ON} before drawing again
+ * since the display updates may be ignored and not seen by the user otherwise.
+ * </p><p>
+ * The set of available display power states and their behavior while dozing is
+ * hardware dependent and may vary across devices. The dream may therefore
+ * need to be modified or configured to correctly support the hardware.
+ * </p>
+ *
+ * @param state The screen state to use while dozing, such as {@link Display#STATE_ON},
+ * {@link Display#STATE_DOZE}, {@link Display#STATE_DOZE_SUSPEND},
+ * or {@link Display#STATE_OFF}, or {@link Display#STATE_UNKNOWN} for the default
+ * behavior.
+ *
+ * @hide For use by system UI components only.
+ */
+ public void setDozeScreenState(int state) {
+ if (mDozeScreenState != state) {
+ mDozeScreenState = state;
+ updateDoze();
+ }
+ }
+
+ /**
+ * Gets the screen brightness to use while dozing.
+ *
+ * @return The screen brightness while dozing as a value between
+ * {@link PowerManager#BRIGHTNESS_OFF} (0) and {@link PowerManager#BRIGHTNESS_ON} (255),
+ * or {@link PowerManager#BRIGHTNESS_DEFAULT} (-1) to ask the system to apply
+ * its default policy based on the screen state.
+ *
+ * @see #setDozeScreenBrightness
+ * @hide For use by system UI components only.
+ */
+ public int getDozeScreenBrightness() {
+ return mDozeScreenBrightness;
+ }
+
+ /**
+ * Sets the screen brightness to use while dozing.
+ * <p>
+ * The value of this property determines the power state of the primary display
+ * once {@link #startDozing} has been called. The default value is
+ * {@link PowerManager#BRIGHTNESS_DEFAULT} which lets the system decide.
+ * The dream may set a different brightness before starting to doze and may adjust
+ * the brightness while dozing to conserve power and achieve various effects.
+ * </p><p>
+ * Note that dream may specify any brightness in the full 0-255 range, including
+ * values that are less than the minimum value for manual screen brightness
+ * adjustments by the user. In particular, the value may be set to 0 which may
+ * turn off the backlight entirely while still leaving the screen on although
+ * this behavior is device dependent and not guaranteed.
+ * </p><p>
+ * The available range of display brightness values and their behavior while dozing is
+ * hardware dependent and may vary across devices. The dream may therefore
+ * need to be modified or configured to correctly support the hardware.
+ * </p>
+ *
+ * @param brightness The screen brightness while dozing as a value between
+ * {@link PowerManager#BRIGHTNESS_OFF} (0) and {@link PowerManager#BRIGHTNESS_ON} (255),
+ * or {@link PowerManager#BRIGHTNESS_DEFAULT} (-1) to ask the system to apply
+ * its default policy based on the screen state.
+ *
+ * @hide For use by system UI components only.
+ */
+ public void setDozeScreenBrightness(int brightness) {
+ if (brightness != PowerManager.BRIGHTNESS_DEFAULT) {
+ brightness = clampAbsoluteBrightness(brightness);
+ }
+ if (mDozeScreenBrightness != brightness) {
+ mDozeScreenBrightness = brightness;
+ updateDoze();
+ }
+ }
+
+ /**
* Called when this Dream is constructed.
*/
@Override
public void onCreate() {
- if (mDebug) Slog.v(TAG, "onCreate() on thread " + Thread.currentThread().getId());
+ if (mDebug) Slog.v(TAG, "onCreate()");
super.onCreate();
}
@@ -844,8 +964,6 @@
return;
}
- if (mDebug) Slog.v(TAG, "Attached on thread " + Thread.currentThread().getId());
-
mWindowToken = windowToken;
mCanDoze = canDoze;
if (mWindowless && !mCanDoze) {
@@ -963,7 +1081,17 @@
if (isScreenBright()) pw.print(" bright");
if (isWindowless()) pw.print(" windowless");
if (isDozing()) pw.print(" dozing");
+ else if (canDoze()) pw.print(" candoze");
pw.println();
+ if (canDoze()) {
+ pw.println(" doze hardware: " + mDozeHardware);
+ pw.println(" doze screen state: " + Display.stateToString(mDozeScreenState));
+ pw.println(" doze screen brightness: " + mDozeScreenBrightness);
+ }
+ }
+
+ private static int clampAbsoluteBrightness(int value) {
+ return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
}
private final class DreamServiceWrapper extends IDreamService.Stub {
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
index 9608a4d..648426c 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -32,7 +32,7 @@
void testDream(in ComponentName componentName);
boolean isDreaming();
void finishSelf(in IBinder token, boolean immediate);
- void startDozing(in IBinder token);
+ void startDozing(in IBinder token, int screenState, int screenBrightness);
void stopDozing(in IBinder token);
IDozeHardware getDozeHardware(in IBinder token);
-}
\ No newline at end of file
+}
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index b3705d8..19a8ef5 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -28,4 +28,5 @@
void onNotificationRemoved(in StatusBarNotification notification,
in NotificationRankingUpdate update);
void onNotificationRankingUpdate(in NotificationRankingUpdate update);
+ void onListenerFlagsChanged(int flags);
}
\ No newline at end of file
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 7d5ff33..1fc64e4 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -53,6 +53,12 @@
private final String TAG = NotificationListenerService.class.getSimpleName()
+ "[" + getClass().getSimpleName() + "]";
+ /** {@link #getCurrentListenerFlags() Listener flags} constant - default state. **/
+ public static final int FLAG_NONE = 0;
+ /** {@link #getCurrentListenerFlags() Listener flags} constant - the primary device UI
+ * should disable notification sound, vibrating and other visual or aural effects. **/
+ public static final int FLAG_DISABLE_HOST_ALERTS = 1;
+
private INotificationListenerWrapper mWrapper = null;
private RankingMap mRankingMap;
@@ -156,6 +162,16 @@
// optional
}
+ /**
+ * Implement this method to be notified when the
+ * {@link #getCurrentListenerFlags() listener flags} change.
+ *
+ * @param flags The current {@link #getCurrentListenerFlags() listener flags}.
+ */
+ public void onListenerFlagsChanged(int flags) {
+ // optional
+ }
+
private final INotificationManager getNotificationInterface() {
if (mNoMan == null) {
mNoMan = INotificationManager.Stub.asInterface(
@@ -279,6 +295,46 @@
}
/**
+ * Gets the set of flags representing current state.
+ *
+ * <p>
+ * The current state may differ from the requested state if the flag represents state
+ * shared across all listeners or a feature the notification host does not support or refuses
+ * to grant.
+ *
+ * @return One or more of the FLAG_ constants.
+ */
+ public final int getCurrentListenerFlags() {
+ if (!isBound()) return FLAG_NONE;
+ try {
+ return getNotificationInterface().getFlagsFromListener(mWrapper);
+ } catch (android.os.RemoteException ex) {
+ Log.v(TAG, "Unable to contact notification manager", ex);
+ return FLAG_NONE;
+ }
+ }
+
+ /**
+ * Sets the desired {@link #getCurrentListenerFlags() listener flags}.
+ *
+ * <p>
+ * This is merely a request, the host may or not choose to take action depending
+ * on other listener requests or other global state.
+ * <p>
+ * Listen for updates using {@link #onListenerFlagsChanged(int)}.
+ *
+ * @param flags One or more of the FLAG_ constants.
+ */
+ public final void requestListenerFlags(int flags) {
+ if (!isBound()) return;
+ try {
+ getNotificationInterface().requestFlagsFromListener(mWrapper, flags);
+ } catch (android.os.RemoteException ex) {
+ Log.v(TAG, "Unable to contact notification manager", ex);
+ }
+ }
+
+ /**
* Returns current ranking information.
*
* <p>
@@ -402,6 +458,14 @@
}
}
}
+ @Override
+ public void onListenerFlagsChanged(int flags) throws RemoteException {
+ try {
+ NotificationListenerService.this.onListenerFlagsChanged(flags);
+ } catch (Throwable t) {
+ Log.w(TAG, "Error running onListenerFlagsChanged", t);
+ }
+ }
}
private void applyUpdate(NotificationRankingUpdate update) {
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index ad30f44..d685cc5 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -27,6 +27,7 @@
import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
@@ -41,26 +42,37 @@
* always-on keyphrase detection APIs.
*/
public class AlwaysOnHotwordDetector {
- //---- States of Keyphrase availability ----//
+ //---- States of Keyphrase availability. Return codes for onAvailabilityChanged() ----//
/**
- * Indicates that the given keyphrase is not available on the system because of the
- * hardware configuration.
+ * Indicates that this hotword detector is no longer valid for any recognition
+ * and should not be used anymore.
*/
- public static final int KEYPHRASE_HARDWARE_UNAVAILABLE = -2;
+ public static final int STATE_INVALID = -3;
/**
- * Indicates that the given keyphrase is not supported.
+ * Indicates that recognition for the given keyphrase is not available on the system
+ * because of the hardware configuration.
*/
- public static final int KEYPHRASE_UNSUPPORTED = -1;
+ public static final int STATE_HARDWARE_UNAVAILABLE = -2;
+ /**
+ * Indicates that recognition for the given keyphrase is not supported.
+ */
+ public static final int STATE_KEYPHRASE_UNSUPPORTED = -1;
/**
* Indicates that the given keyphrase is not enrolled.
*/
- public static final int KEYPHRASE_UNENROLLED = 1;
+ public static final int STATE_KEYPHRASE_UNENROLLED = 1;
/**
- * Indicates that the given keyphrase is currently enrolled but not being actively listened for.
+ * Indicates that the given keyphrase is currently enrolled and it's possible to start
+ * recognition for it.
*/
- public static final int KEYPHRASE_ENROLLED = 2;
+ public static final int STATE_KEYPHRASE_ENROLLED = 2;
- // Keyphrase management actions ----//
+ /**
+ * Indicates that the detector isn't ready currently.
+ */
+ private static final int STATE_NOT_READY = 0;
+
+ // Keyphrase management actions. Used in getManageIntent() ----//
/** Indicates that we need to enroll. */
public static final int MANAGE_ACTION_ENROLL = 0;
/** Indicates that we need to re-enroll. */
@@ -83,7 +95,7 @@
*/
public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 0x1;
- //---- Recognition mode flags ----//
+ //---- Recognition mode flags. Return codes for getSupportedRecognitionModes() ----//
// Must be kept in sync with the related attribute defined as searchKeyphraseRecognitionFlags.
/**
@@ -98,9 +110,12 @@
= SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION;
static final String TAG = "AlwaysOnHotwordDetector";
+ // TODO: Set to false.
+ static final boolean DBG = true;
- private static final int MSG_HOTWORD_DETECTED = 1;
- private static final int MSG_DETECTION_STOPPED = 2;
+ private static final int MSG_STATE_CHANGED = 1;
+ private static final int MSG_HOTWORD_DETECTED = 2;
+ private static final int MSG_DETECTION_STOPPED = 3;
private final String mText;
private final String mLocale;
@@ -109,23 +124,45 @@
* This may be null if this keyphrase isn't supported by the enrollment application.
*/
private final KeyphraseMetadata mKeyphraseMetadata;
- /**
- * The sound model for the keyphrase, derived from the model management service
- * (IVoiceInteractionManagerService). May be null if the keyphrase isn't enrolled yet.
- */
- private final KeyphraseSoundModel mEnrolledSoundModel;
private final KeyphraseEnrollmentInfo mKeyphraseEnrollmentInfo;
private final IVoiceInteractionService mVoiceInteractionService;
private final IVoiceInteractionManagerService mModelManagementService;
private final SoundTriggerListener mInternalCallback;
private final Callback mExternalCallback;
- private final boolean mDisabled;
+ private final Object mLock = new Object();
+ private final Handler mHandler;
+
+ /**
+ * The sound model for the keyphrase, derived from the model management service
+ * (IVoiceInteractionManagerService). May be null if the keyphrase isn't enrolled yet.
+ */
+ private KeyphraseSoundModel mEnrolledSoundModel;
+ private int mAvailability = STATE_NOT_READY;
/**
* Callbacks for always-on hotword detection.
*/
public interface Callback {
/**
+ * Called when the hotword availability changes.
+ * This indicates a change in the availability of recognition for the given keyphrase.
+ * It's called at least once with the initial availability.<p/>
+ *
+ * Availability implies whether the hardware on this system is capable of listening for
+ * the given keyphrase or not. <p/>
+ * If the return code is one of {@link #STATE_HARDWARE_UNAVAILABLE} or
+ * {@link #STATE_KEYPHRASE_UNSUPPORTED},
+ * detection is not possible and no further interaction should be
+ * performed with this detector. <br/>
+ * If it is {@link #STATE_KEYPHRASE_UNENROLLED} the caller may choose to begin
+ * an enrollment flow for the keyphrase. <br/>
+ * and for {@link #STATE_KEYPHRASE_ENROLLED} a recognition can be started as desired. <p/>
+ *
+ * If the return code is {@link #STATE_INVALID}, this detector is stale.
+ * A new detector should be obtained for use in the future.
+ */
+ void onAvailabilityChanged(int status);
+ /**
* Called when the keyphrase is spoken.
*
* @param data Optional trigger audio data, if it was requested during
@@ -156,51 +193,30 @@
mKeyphraseEnrollmentInfo = keyphraseEnrollmentInfo;
mKeyphraseMetadata = mKeyphraseEnrollmentInfo.getKeyphraseMetadata(text, locale);
mExternalCallback = callback;
- mInternalCallback = new SoundTriggerListener(new MyHandler());
+ mHandler = new MyHandler();
+ mInternalCallback = new SoundTriggerListener(mHandler);
mVoiceInteractionService = voiceInteractionService;
mModelManagementService = modelManagementService;
- if (mKeyphraseMetadata != null) {
- mEnrolledSoundModel = internalGetKeyphraseSoundModel(mKeyphraseMetadata.id);
- } else {
- mEnrolledSoundModel = null;
- }
- int initialAvailability = internalGetAvailabilityLocked();
- mDisabled = (initialAvailability == KEYPHRASE_HARDWARE_UNAVAILABLE)
- || (initialAvailability == KEYPHRASE_UNSUPPORTED);
- }
-
- /**
- * Gets the state of always-on hotword detection for the given keyphrase and locale
- * on this system.
- * Availability implies that the hardware on this system is capable of listening for
- * the given keyphrase or not.
- *
- * @return Indicates if always-on hotword detection is available for the given keyphrase.
- * The return code is one of {@link #KEYPHRASE_HARDWARE_UNAVAILABLE},
- * {@link #KEYPHRASE_UNSUPPORTED}, {@link #KEYPHRASE_UNENROLLED} or
- * {@link #KEYPHRASE_ENROLLED}.
- */
- public int getAvailability() {
- synchronized (this) {
- return internalGetAvailabilityLocked();
- }
+ new RefreshAvailabiltyTask().execute();
}
/**
* Gets the recognition modes supported by the associated keyphrase.
*
* @throws UnsupportedOperationException if the keyphrase itself isn't supported.
- * Callers should check the availability by calling {@link #getAvailability()}
- * before calling this method to avoid this exception.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
*/
public int getSupportedRecognitionModes() {
- synchronized (this) {
+ synchronized (mLock) {
return getSupportedRecognitionModesLocked();
}
}
private int getSupportedRecognitionModesLocked() {
- if (mDisabled) {
+ // This method only makes sense if we can actually support a recognition.
+ if (mAvailability != STATE_KEYPHRASE_ENROLLED
+ && mAvailability != STATE_KEYPHRASE_UNENROLLED) {
throw new UnsupportedOperationException(
"Getting supported recognition modes for the keyphrase is not supported");
}
@@ -216,17 +232,18 @@
* {@link #RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO}.
* @return {@link #STATUS_OK} if the call succeeds, an error code otherwise.
* @throws UnsupportedOperationException if the recognition isn't supported.
- * Callers should check the availability by calling {@link #getAvailability()}
- * before calling this method to avoid this exception.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
*/
public int startRecognition(int recognitionFlags) {
- synchronized (this) {
+ synchronized (mLock) {
return startRecognitionLocked(recognitionFlags);
}
}
private int startRecognitionLocked(int recognitionFlags) {
- if (internalGetAvailabilityLocked() != KEYPHRASE_ENROLLED) {
+ // This method only makes sense if we can start a recognition.
+ if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
throw new UnsupportedOperationException(
"Recognition for the given keyphrase is not supported");
}
@@ -257,17 +274,18 @@
*
* @return {@link #STATUS_OK} if the call succeeds, an error code otherwise.
* @throws UnsupportedOperationException if the recognition isn't supported.
- * Callers should check the availability by calling {@link #getAvailability()}
- * before calling this method to avoid this exception.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
*/
public int stopRecognition() {
- synchronized (this) {
+ synchronized (mLock) {
return stopRecognitionLocked();
}
}
- private synchronized int stopRecognitionLocked() {
- if (internalGetAvailabilityLocked() != KEYPHRASE_ENROLLED) {
+ private int stopRecognitionLocked() {
+ // This method only makes sense if we can start a recognition.
+ if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
throw new UnsupportedOperationException(
"Recognition for the given keyphrase is not supported");
}
@@ -294,11 +312,13 @@
* {@link #MANAGE_ACTION_UN_ENROLL}.
* @return An {@link Intent} to manage the given keyphrase.
* @throws UnsupportedOperationException if managing they keyphrase isn't supported.
- * Callers should check the availability by calling {@link #getAvailability()}
- * before calling this method to avoid this exception.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
*/
public Intent getManageIntent(int action) {
- if (mDisabled) {
+ // This method only makes sense if we can actually support a recognition.
+ if (mAvailability != STATE_KEYPHRASE_ENROLLED
+ && mAvailability != STATE_KEYPHRASE_UNENROLLED) {
throw new UnsupportedOperationException(
"Managing the given keyphrase is not supported");
}
@@ -311,55 +331,44 @@
return mKeyphraseEnrollmentInfo.getManageKeyphraseIntent(action, mText, mLocale);
}
- private int internalGetAvailabilityLocked() {
- ModuleProperties dspModuleProperties = null;
- try {
- dspModuleProperties =
- mModelManagementService.getDspModuleProperties(mVoiceInteractionService);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException in getDspProperties!");
+ /**
+ * Invalidates this hotword detector so that any future calls to this result
+ * in an IllegalStateException.
+ *
+ * @hide
+ */
+ void invalidate() {
+ synchronized (mLock) {
+ mAvailability = STATE_INVALID;
+ notifyStateChangedLocked();
}
- // No DSP available
- if (dspModuleProperties == null) {
- return KEYPHRASE_HARDWARE_UNAVAILABLE;
- }
- // No enrollment application supports this keyphrase/locale
- if (mKeyphraseMetadata == null) {
- return KEYPHRASE_UNSUPPORTED;
- }
- // This keyphrase hasn't been enrolled.
- if (mEnrolledSoundModel == null) {
- return KEYPHRASE_UNENROLLED;
- }
- return KEYPHRASE_ENROLLED;
}
/**
- * @return The corresponding {@link KeyphraseSoundModel} or null if none is found.
+ * Reloads the sound models from the service.
+ *
+ * @hide
*/
- private KeyphraseSoundModel internalGetKeyphraseSoundModel(int keyphraseId) {
- List<KeyphraseSoundModel> soundModels;
- try {
- soundModels = mModelManagementService
- .listRegisteredKeyphraseSoundModels(mVoiceInteractionService);
- if (soundModels == null || soundModels.isEmpty()) {
- Slog.i(TAG, "No available sound models for keyphrase ID: " + keyphraseId);
- return null;
+ void onSoundModelsChanged() {
+ synchronized (mLock) {
+ // TODO: This should stop the recognition if it was using an enrolled sound model
+ // that's no longer available.
+ if (mAvailability == STATE_INVALID
+ || mAvailability == STATE_HARDWARE_UNAVAILABLE
+ || mAvailability == STATE_KEYPHRASE_UNSUPPORTED) {
+ Slog.w(TAG, "Received onSoundModelsChanged for an unsupported keyphrase/config");
+ return;
}
- for (KeyphraseSoundModel soundModel : soundModels) {
- if (soundModel.keyphrases == null) {
- continue;
- }
- for (Keyphrase keyphrase : soundModel.keyphrases) {
- if (keyphrase.id == keyphraseId) {
- return soundModel;
- }
- }
- }
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException in listRegisteredKeyphraseSoundModels!");
+
+ // Execute a refresh availability task - which should then notify of a change.
+ new RefreshAvailabiltyTask().execute();
}
- return null;
+ }
+
+ private void notifyStateChangedLocked() {
+ Message message = Message.obtain(mHandler, MSG_STATE_CHANGED);
+ message.arg1 = mAvailability;
+ message.sendToTarget();
}
/** @hide */
@@ -389,6 +398,9 @@
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
+ case MSG_STATE_CHANGED:
+ mExternalCallback.onAvailabilityChanged(msg.arg1);
+ break;
case MSG_HOTWORD_DETECTED:
mExternalCallback.onDetected((byte[]) msg.obj);
break;
@@ -399,4 +411,95 @@
}
}
}
+
+ class RefreshAvailabiltyTask extends AsyncTask<Void, Void, Void> {
+
+ @Override
+ public Void doInBackground(Void... params) {
+ int availability = internalGetInitialAvailability();
+ KeyphraseSoundModel soundModel = null;
+ // Fetch the sound model if the availability is one of the supported ones.
+ if (availability == STATE_NOT_READY
+ || availability == STATE_KEYPHRASE_UNENROLLED
+ || availability == STATE_KEYPHRASE_ENROLLED) {
+ soundModel =
+ internalGetKeyphraseSoundModel(mKeyphraseMetadata.id);
+ if (soundModel == null) {
+ availability = STATE_KEYPHRASE_UNENROLLED;
+ } else {
+ availability = STATE_KEYPHRASE_ENROLLED;
+ }
+ }
+
+ synchronized (mLock) {
+ if (DBG) {
+ Slog.d(TAG, "Hotword availability changed from " + mAvailability
+ + " -> " + availability);
+ }
+ mAvailability = availability;
+ mEnrolledSoundModel = soundModel;
+ notifyStateChangedLocked();
+ }
+ return null;
+ }
+
+ /**
+ * @return The initial availability without checking the enrollment status.
+ */
+ private int internalGetInitialAvailability() {
+ synchronized (mLock) {
+ // This detector has already been invalidated.
+ if (mAvailability == STATE_INVALID) {
+ return STATE_INVALID;
+ }
+ }
+
+ ModuleProperties dspModuleProperties = null;
+ try {
+ dspModuleProperties =
+ mModelManagementService.getDspModuleProperties(mVoiceInteractionService);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "RemoteException in getDspProperties!");
+ }
+ // No DSP available
+ if (dspModuleProperties == null) {
+ return STATE_HARDWARE_UNAVAILABLE;
+ }
+ // No enrollment application supports this keyphrase/locale
+ if (mKeyphraseMetadata == null) {
+ return STATE_KEYPHRASE_UNSUPPORTED;
+ }
+ return STATE_NOT_READY;
+ }
+
+ /**
+ * @return The corresponding {@link KeyphraseSoundModel} or null if none is found.
+ */
+ private KeyphraseSoundModel internalGetKeyphraseSoundModel(int keyphraseId) {
+ List<KeyphraseSoundModel> soundModels;
+ try {
+ soundModels = mModelManagementService
+ .listRegisteredKeyphraseSoundModels(mVoiceInteractionService);
+ if (soundModels == null || soundModels.isEmpty()) {
+ Slog.i(TAG, "No available sound models for keyphrase ID: " + keyphraseId);
+ return null;
+ }
+ for (int i = 0; i < soundModels.size(); i++) {
+ KeyphraseSoundModel soundModel = soundModels.get(i);
+ if (soundModel.keyphrases == null || soundModel.keyphrases.length == 0) {
+ continue;
+ }
+ for (int j = 0; i < soundModel.keyphrases.length; j++) {
+ Keyphrase keyphrase = soundModel.keyphrases[j];
+ if (keyphrase.id == keyphraseId) {
+ return soundModel;
+ }
+ }
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "RemoteException in listRegisteredKeyphraseSoundModels!");
+ }
+ return null;
+ }
+ }
}
diff --git a/core/java/android/service/voice/IVoiceInteractionService.aidl b/core/java/android/service/voice/IVoiceInteractionService.aidl
index c9915a2..e8265a2 100644
--- a/core/java/android/service/voice/IVoiceInteractionService.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionService.aidl
@@ -21,4 +21,6 @@
*/
oneway interface IVoiceInteractionService {
void ready();
+ void soundModelsChanged();
+ void shutdown();
}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 982f43d..82e23c4 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -28,8 +28,8 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
-
import android.provider.Settings;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractionManagerService;
@@ -70,15 +70,27 @@
@Override public void ready() {
mHandler.sendEmptyMessage(MSG_READY);
}
+ @Override public void shutdown() {
+ mHandler.sendEmptyMessage(MSG_SHUTDOWN);
+ }
+ @Override public void soundModelsChanged() {
+ mHandler.sendEmptyMessage(MSG_SOUND_MODELS_CHANGED);
+ }
};
MyHandler mHandler;
IVoiceInteractionManagerService mSystemService;
+ private final Object mLock = new Object();
+
private KeyphraseEnrollmentInfo mKeyphraseEnrollmentInfo;
+ private AlwaysOnHotwordDetector mHotwordDetector;
+
static final int MSG_READY = 1;
+ static final int MSG_SHUTDOWN = 2;
+ static final int MSG_SOUND_MODELS_CHANGED = 3;
class MyHandler extends Handler {
@Override
@@ -87,6 +99,12 @@
case MSG_READY:
onReady();
break;
+ case MSG_SHUTDOWN:
+ onShutdownInternal();
+ break;
+ case MSG_SOUND_MODELS_CHANGED:
+ onSoundModelsChangedInternal();
+ break;
default:
super.handleMessage(msg);
}
@@ -140,9 +158,10 @@
/**
* Called during service initialization to tell you when the system is ready
- * to receive interaction from it. You should generally do initialization here
- * rather than in {@link #onCreate()}. Methods such as {@link #startSession}
- * and {@link #getAlwaysOnHotwordDetector} will not be operational until this point.
+ * to receive interaction from it. You should generally do initialization here
+ * rather than in {@link #onCreate()}. Methods such as {@link #startSession(Bundle)} and
+ * {@link #createAlwaysOnHotwordDetector(String, String, android.service.voice.AlwaysOnHotwordDetector.Callback)}
+ * will not be operational until this point.
*/
public void onReady() {
mSystemService = IVoiceInteractionManagerService.Stub.asInterface(
@@ -150,22 +169,56 @@
mKeyphraseEnrollmentInfo = new KeyphraseEnrollmentInfo(getPackageManager());
}
+ private void onShutdownInternal() {
+ onShutdown();
+ // Stop any active recognitions when shutting down.
+ // This ensures that if implementations forget to stop any active recognition,
+ // It's still guaranteed to have been stopped.
+ // This helps with cases where the voice interaction implementation is changed
+ // by the user.
+ safelyShutdownHotwordDetector();
+ }
+
/**
+ * Called during service de-initialization to tell you when the system is shutting the
+ * service down.
+ */
+ public void onShutdown() {
+ }
+
+ private void onSoundModelsChangedInternal() {
+ synchronized (this) {
+ if (mHotwordDetector != null) {
+ // TODO: Stop recognition if a sound model that was being recognized gets deleted.
+ mHotwordDetector.onSoundModelsChanged();
+ }
+ }
+ }
+
+ /**
+ * Creates an {@link AlwaysOnHotwordDetector} for the given keyphrase and locale.
+ * This instance must be retained and used by the client.
+ * Calling this a second time invalidates the previously created hotword detector
+ * which can no longer be used to manage recognition.
+ *
* @param keyphrase The keyphrase that's being used, for example "Hello Android".
* @param locale The locale for which the enrollment needs to be performed.
* This is a Java locale, for example "en_US".
* @param callback The callback to notify of detection events.
* @return An always-on hotword detector for the given keyphrase and locale.
*/
- public final AlwaysOnHotwordDetector getAlwaysOnHotwordDetector(
+ public final AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(
String keyphrase, String locale, AlwaysOnHotwordDetector.Callback callback) {
if (mSystemService == null) {
throw new IllegalStateException("Not available until onReady() is called");
}
- // TODO: Cache instances and return the same one instead of creating a new interactor
- // for the same keyphrase/locale combination.
- return new AlwaysOnHotwordDetector(keyphrase, locale, callback,
- mKeyphraseEnrollmentInfo, mInterface, mSystemService);
+ synchronized (mLock) {
+ // Allow only one concurrent recognition via the APIs.
+ safelyShutdownHotwordDetector();
+ mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
+ mKeyphraseEnrollmentInfo, mInterface, mSystemService);
+ }
+ return mHotwordDetector;
}
/**
@@ -176,4 +229,18 @@
protected final KeyphraseEnrollmentInfo getKeyphraseEnrollmentInfo() {
return mKeyphraseEnrollmentInfo;
}
+
+ private void safelyShutdownHotwordDetector() {
+ try {
+ synchronized (mLock) {
+ if (mHotwordDetector != null) {
+ mHotwordDetector.stopRecognition();
+ mHotwordDetector.invalidate();
+ mHotwordDetector = null;
+ }
+ }
+ } catch (Exception ex) {
+ // Ignore.
+ }
+ }
}
diff --git a/core/java/android/transition/ChangeBounds.java b/core/java/android/transition/ChangeBounds.java
index 3f5e8e8..1550297 100644
--- a/core/java/android/transition/ChangeBounds.java
+++ b/core/java/android/transition/ChangeBounds.java
@@ -193,7 +193,8 @@
bottomRightAnimator = ObjectAnimator.ofInt(view, "right", "bottom",
bottomRightPath);
}
- Animator anim = mergeAnimators(topLeftAnimator, bottomRightAnimator);
+ Animator anim = TransitionUtils.mergeAnimators(topLeftAnimator,
+ bottomRightAnimator);
if (view.getParent() instanceof ViewGroup) {
final ViewGroup parent = (ViewGroup) view.getParent();
parent.suppressLayout(true);
@@ -256,7 +257,8 @@
clipAnimator = ObjectAnimator.ofObject(view, "clipBounds", sRectEvaluator,
tempStartBounds, tempEndBounds);
}
- Animator anim = mergeAnimators(translationAnimator, clipAnimator);
+ Animator anim = TransitionUtils.mergeAnimators(translationAnimator,
+ clipAnimator);
if (view.getParent() instanceof ViewGroup) {
final ViewGroup parent = (ViewGroup) view.getParent();
parent.suppressLayout(true);
@@ -330,16 +332,4 @@
}
return null;
}
-
- private static Animator mergeAnimators(Animator animator1, Animator animator2) {
- if (animator1 == null) {
- return animator2;
- } else if (animator2 == null) {
- return animator1;
- } else {
- AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(animator1, animator2);
- return animatorSet;
- }
- }
}
diff --git a/core/java/android/transition/ChangeImageTransform.java b/core/java/android/transition/ChangeImageTransform.java
index 12437d7..2b26756 100644
--- a/core/java/android/transition/ChangeImageTransform.java
+++ b/core/java/android/transition/ChangeImageTransform.java
@@ -32,10 +32,12 @@
import java.util.Map;
/**
- * Transitions changes in ImageView {@link ImageView#setScaleType(ImageView.ScaleType)} as
- * well as image scaling due to ImageView size changes. When combined with
- * {@link android.transition.ChangeBounds}, an ImageView that changes size will
- * scale smoothly.
+ * This Transition captures an ImageView's matrix before and after the
+ * scene change and animates it during the transition.
+ *
+ * <p>In combination with ChangeBounds, ChangeImageTransform allows ImageViews
+ * that change size, shape, or {@link android.widget.ImageView.ScaleType} to animate contents
+ * smoothly.</p>
*/
public class ChangeImageTransform extends Transition {
@@ -192,30 +194,8 @@
private ObjectAnimator createMatrixAnimator(final ImageView imageView, Matrix startMatrix,
final Matrix endMatrix) {
- ObjectAnimator animator = ObjectAnimator.ofObject(imageView, ANIMATED_TRANSFORM_PROPERTY,
+ return ObjectAnimator.ofObject(imageView, ANIMATED_TRANSFORM_PROPERTY,
new MatrixEvaluator(), startMatrix, endMatrix);
- /*
- AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
- private Matrix mPausedMatrix;
-
- @Override
- public void onAnimationPause(Animator animation) {
- if (mPausedMatrix == null) {
- mPausedMatrix = new Matrix();
- }
- Matrix imageMatrix = imageView.getImageMatrix();
- mPausedMatrix.set(imageMatrix);
- imageView.animateTransform(endMatrix);
- }
-
- @Override
- public void onAnimationResume(Animator animation) {
- imageView.animateTransform(mPausedMatrix);
- }
- };
- animator.addPauseListener(listener);
- */
- return animator;
}
private static class MatrixEvaluator implements TypeEvaluator<Matrix> {
diff --git a/core/java/android/transition/ChangeScroll.java b/core/java/android/transition/ChangeScroll.java
new file mode 100644
index 0000000..39291bf
--- /dev/null
+++ b/core/java/android/transition/ChangeScroll.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.transition;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.transition.Transition;
+import android.transition.TransitionValues;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * This transition captures the scroll properties of targets before and after
+ * the scene change and animates any changes.
+ *
+ * @hide
+ */
+public class ChangeScroll extends Transition {
+
+ private static final String PROPNAME_SCROLL_X = "android:changeScroll:x";
+ private static final String PROPNAME_SCROLL_Y = "android:changeScroll:y";
+
+ public ChangeScroll() {}
+
+ public ChangeScroll(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ private void captureValues(TransitionValues transitionValues) {
+ transitionValues.values.put(PROPNAME_SCROLL_X, transitionValues.view.getScrollX());
+ transitionValues.values.put(PROPNAME_SCROLL_Y, transitionValues.view.getScrollY());
+ }
+
+ @Override
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return null;
+ }
+ final View view = endValues.view;
+ int startX = (Integer) startValues.values.get(PROPNAME_SCROLL_X);
+ int endX = (Integer) endValues.values.get(PROPNAME_SCROLL_X);
+ int startY = (Integer) startValues.values.get(PROPNAME_SCROLL_Y);
+ int endY = (Integer) endValues.values.get(PROPNAME_SCROLL_Y);
+ Animator scrollXAnimator = null;
+ Animator scrollYAnimator = null;
+ if (startX != endX) {
+ view.setScrollX(startX);
+ scrollXAnimator = ObjectAnimator.ofInt(view, "scrollX", startX, endX);
+ }
+ if (startY != endY) {
+ view.setScrollY(startY);
+ scrollYAnimator = ObjectAnimator.ofInt(view, "scrollY", startY, endY);
+ }
+ return TransitionUtils.mergeAnimators(scrollXAnimator, scrollYAnimator);
+ }
+}
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
index 420c248..1f9d093 100644
--- a/core/java/android/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -69,17 +69,17 @@
* Fading mode used in {@link #Fade(int)} to make the transition
* operate on targets that are appearing. Maybe be combined with
* {@link #OUT} to fade both in and out. Equivalent to
- * {@link Visibility#IN}.
+ * {@link Visibility#MODE_IN}.
*/
- public static final int IN = Visibility.IN;
+ public static final int IN = Visibility.MODE_IN;
/**
* Fading mode used in {@link #Fade(int)} to make the transition
* operate on targets that are disappearing. Maybe be combined with
* {@link #IN} to fade both in and out. Equivalent to
- * {@link Visibility#OUT}.
+ * {@link Visibility#MODE_OUT}.
*/
- public static final int OUT = Visibility.OUT;
+ public static final int OUT = Visibility.MODE_OUT;
/**
* Constructs a Fade transition that will fade targets in and out.
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index 68b0a43..760ffe1 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -159,6 +159,8 @@
transition = new AutoTransition(mContext, attrs);
} else if ("recolor".equals(name)) {
transition = new Recolor(mContext, attrs);
+ } else if ("changeScroll".equals(name)) {
+ transition = new ChangeScroll(mContext, attrs);
} else if ("transitionSet".equals(name)) {
transition = new TransitionSet(mContext, attrs);
} else if ("transition".equals(name)) {
diff --git a/core/java/android/transition/TransitionUtils.java b/core/java/android/transition/TransitionUtils.java
new file mode 100644
index 0000000..931d46a
--- /dev/null
+++ b/core/java/android/transition/TransitionUtils.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+
+/**
+ * Static utility methods for Transitions.
+ *
+ * @hide
+ */
+public class TransitionUtils {
+
+ static Animator mergeAnimators(Animator animator1, Animator animator2) {
+ if (animator1 == null) {
+ return animator2;
+ } else if (animator2 == null) {
+ return animator1;
+ } else {
+ AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.playTogether(animator1, animator2);
+ return animatorSet;
+ }
+ }
+}
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index cf5ea4c..af2016c 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -50,16 +50,16 @@
/**
* Mode used in {@link #setMode(int)} to make the transition
* operate on targets that are appearing. Maybe be combined with
- * {@link #OUT} to target Visibility changes both in and out.
+ * {@link #MODE_OUT} to target Visibility changes both in and out.
*/
- public static final int IN = 0x1;
+ public static final int MODE_IN = 0x1;
/**
* Mode used in {@link #setMode(int)} to make the transition
* operate on targets that are disappearing. Maybe be combined with
- * {@link #IN} to target Visibility changes both in and out.
+ * {@link #MODE_IN} to target Visibility changes both in and out.
*/
- public static final int OUT = 0x2;
+ public static final int MODE_OUT = 0x2;
private static final String[] sTransitionProperties = {
PROPNAME_VISIBILITY,
@@ -76,7 +76,7 @@
ViewGroup endParent;
}
- private int mMode = IN | OUT;
+ private int mMode = MODE_IN | MODE_OUT;
private int mForcedStartVisibility = -1;
private int mForcedEndVisibility = -1;
@@ -98,12 +98,12 @@
* on <code>mode</code>.
*
* @param mode The behavior supported by this transition, a combination of
- * {@link #IN} and {@link #OUT}.
+ * {@link #MODE_IN} and {@link #MODE_OUT}.
* @attr ref android.R.styleable#VisibilityTransition_visibilityMode
*/
public void setMode(int mode) {
- if ((mode & ~(IN | OUT)) != 0) {
- throw new IllegalArgumentException("Only IN and OUT flags are allowed");
+ if ((mode & ~(MODE_IN | MODE_OUT)) != 0) {
+ throw new IllegalArgumentException("Only MODE_IN and MODE_OUT flags are allowed");
}
mMode = mode;
}
@@ -112,7 +112,7 @@
* Returns whether appearing and/or disappearing Views are supported.
*
* Returns whether appearing and/or disappearing Views are supported. A combination of
- * {@link #IN} and {@link #OUT}.
+ * {@link #MODE_IN} and {@link #MODE_OUT}.
* @attr ref android.R.styleable#VisibilityTransition_visibilityMode
*/
public int getMode() {
@@ -276,7 +276,7 @@
public Animator onAppear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
- if ((mMode & IN) != IN || endValues == null) {
+ if ((mMode & MODE_IN) != MODE_IN || endValues == null) {
return null;
}
return onAppear(sceneRoot, endValues.view, startValues, endValues);
@@ -339,7 +339,7 @@
public Animator onDisappear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
- if ((mMode & OUT) != OUT) {
+ if ((mMode & MODE_OUT) != MODE_OUT) {
return null;
}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index b17fa4a..154d227 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -831,4 +831,13 @@
return Integer.toString(state);
}
}
+
+ /**
+ * Returns true if display updates may be suspended while in the specified
+ * display power state.
+ * @hide
+ */
+ public static boolean isSuspendedState(int state) {
+ return state == STATE_OFF || state == STATE_DOZE_SUSPEND;
+ }
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e138345..0079cc9 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5048,8 +5048,17 @@
* View, false otherwise.
*
* @see ViewGroup#FOCUS_BLOCK_DESCENDANTS
+ * @see ViewGroup#getTouchscreenBlocksFocus()
*/
public boolean hasFocusable() {
+ if (!isFocusableInTouchMode()) {
+ for (ViewParent p = mParent; p instanceof ViewGroup; p = p.getParent()) {
+ final ViewGroup g = (ViewGroup) p;
+ if (g.shouldBlockFocusForTouchscreen()) {
+ return false;
+ }
+ }
+ }
return (mViewFlags & VISIBILITY_MASK) == VISIBLE && isFocusable();
}
@@ -7439,11 +7448,12 @@
* @return Whether any ancestor of this view blocks descendant focus.
*/
private boolean hasAncestorThatBlocksDescendantFocus() {
+ final boolean focusableInTouchMode = isFocusableInTouchMode();
ViewParent ancestor = mParent;
while (ancestor instanceof ViewGroup) {
final ViewGroup vgAncestor = (ViewGroup) ancestor;
if (vgAncestor.getDescendantFocusability() == ViewGroup.FOCUS_BLOCK_DESCENDANTS
- || vgAncestor.shouldBlockFocusForTouchscreen()) {
+ || (!focusableInTouchMode && vgAncestor.shouldBlockFocusForTouchscreen())) {
return true;
} else {
ancestor = vgAncestor.getParent();
@@ -15546,7 +15556,8 @@
}
/**
- * This function is called whenever the drawable hotspot changes.
+ * This function is called whenever the view hotspot changes and needs to
+ * be propagated to drawables managed by the view.
* <p>
* Be sure to call through to the superclass when overriding this function.
*
@@ -15888,30 +15899,6 @@
}
/**
- * Applies a tint to the background drawable.
- * <p>
- * Subsequent calls to {@link #setBackground(Drawable)} will automatically
- * mutate the drawable and apply the specified tint and tint mode using
- * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
- *
- * @param tint the tint to apply, may be {@code null} to clear tint
- * @param tintMode the blending mode used to apply the tint, may be
- * {@code null} to clear tint
- *
- * @attr ref android.R.styleable#View_backgroundTint
- * @attr ref android.R.styleable#View_backgroundTintMode
- * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
- */
- private void setBackgroundTint(@Nullable ColorStateList tint,
- @Nullable PorterDuff.Mode tintMode) {
- mBackgroundTint = tint;
- mBackgroundTintMode = tintMode;
- mHasBackgroundTint = true;
-
- applyBackgroundTint();
- }
-
- /**
* Applies a tint to the background drawable. Does not modify the current tint
* mode, which is {@link PorterDuff.Mode#SRC_ATOP} by default.
* <p>
@@ -15922,16 +15909,20 @@
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#View_backgroundTint
- * @see #setBackgroundTint(ColorStateList, PorterDuff.Mode)
+ * @see #getBackgroundTint()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setBackgroundTint(@Nullable ColorStateList tint) {
- setBackgroundTint(tint, mBackgroundTintMode);
+ mBackgroundTint = tint;
+ mHasBackgroundTint = true;
+
+ applyBackgroundTint();
}
/**
* @return the tint applied to the background drawable
* @attr ref android.R.styleable#View_backgroundTint
- * @see #setBackgroundTint(ColorStateList, PorterDuff.Mode)
+ * @see #setBackgroundTint(ColorStateList)
*/
@Nullable
public ColorStateList getBackgroundTint() {
@@ -15946,16 +15937,19 @@
* @param tintMode the blending mode used to apply the tint, may be
* {@code null} to clear tint
* @attr ref android.R.styleable#View_backgroundTintMode
- * @see #setBackgroundTint(ColorStateList)
+ * @see #getBackgroundTintMode()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
- setBackgroundTint(mBackgroundTint, tintMode);
+ mBackgroundTintMode = tintMode;
+
+ applyBackgroundTint();
}
/**
* @return the blending mode used to apply the tint to the background drawable
* @attr ref android.R.styleable#View_backgroundTintMode
- * @see #setBackgroundTint(ColorStateList, PorterDuff.Mode)
+ * @see #setBackgroundTintMode(PorterDuff.Mode)
*/
@Nullable
public PorterDuff.Mode getBackgroundTintMode() {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 04c8b0b..1028a0c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -669,7 +669,7 @@
// shortcut: don't report a new focusable view if we block our descendants from
// getting focus
&& (getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS)
- && !shouldBlockFocusForTouchscreen()
+ && (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen())
// shortcut: don't report a new focusable view if we already are focused
// (and we don't prefer our descendants)
//
@@ -865,6 +865,17 @@
return mFocused;
}
+ View getDeepestFocusedChild() {
+ View v = this;
+ while (v != null) {
+ if (v.isFocused()) {
+ return v;
+ }
+ v = v instanceof ViewGroup ? ((ViewGroup) v).getFocusedChild() : null;
+ }
+ return null;
+ }
+
/**
* Returns true if this view has or contains focus
*
@@ -911,8 +922,7 @@
}
final int descendantFocusability = getDescendantFocusability();
- if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS &&
- !shouldBlockFocusForTouchscreen()) {
+ if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) {
final int count = mChildrenCount;
final View[] children = mChildren;
@@ -936,8 +946,11 @@
final int descendantFocusability = getDescendantFocusability();
- if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS &&
- !shouldBlockFocusForTouchscreen()) {
+ if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) {
+ if (shouldBlockFocusForTouchscreen()) {
+ focusableMode |= FOCUSABLES_TOUCH_MODE;
+ }
+
final int count = mChildrenCount;
final View[] children = mChildren;
@@ -955,7 +968,8 @@
// among the focusable children would be more interesting.
if ((descendantFocusability != FOCUS_AFTER_DESCENDANTS
// No focusable descendants
- || (focusableCount == views.size())) && !shouldBlockFocusForTouchscreen()) {
+ || (focusableCount == views.size())) &&
+ (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen())) {
super.addFocusables(views, direction, focusableMode);
}
}
@@ -971,9 +985,12 @@
if (touchscreenBlocksFocus) {
mGroupFlags |= FLAG_TOUCHSCREEN_BLOCKS_FOCUS;
if (hasFocus()) {
- final View newFocus = focusSearch(FOCUS_FORWARD);
- if (newFocus != null) {
- newFocus.requestFocus();
+ final View focusedChild = getDeepestFocusedChild();
+ if (!focusedChild.isFocusableInTouchMode()) {
+ final View newFocus = focusSearch(FOCUS_FORWARD);
+ if (newFocus != null) {
+ newFocus.requestFocus();
+ }
}
}
} else {
@@ -2485,10 +2502,6 @@
}
int descendantFocusability = getDescendantFocusability();
- if (shouldBlockFocusForTouchscreen()) {
- return false;
- }
-
switch (descendantFocusability) {
case FOCUS_BLOCK_DESCENDANTS:
return super.requestFocus(direction, previouslyFocusedRect);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index d9ad1f1..671aa10 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -468,13 +468,8 @@
// Compute surface insets required to draw at specified Z value.
// TODO: Use real shadow insets for a constant max Z.
- if (view.isHardwareAccelerated()) {
- final int surfaceInset = (int) Math.ceil(view.getZ() * 2);
- attrs.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
- } else {
- // Software accelerated windows can't use insets.
- attrs.surfaceInsets.setEmpty();
- }
+ final int surfaceInset = (int) Math.ceil(view.getZ() * 2);
+ attrs.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
CompatibilityInfo compatibilityInfo = mDisplayAdjustments.getCompatibilityInfo();
mTranslator = compatibilityInfo.getTranslator();
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 7e2d809..be7e0bc 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -92,10 +92,11 @@
final Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb);
setThumb(thumb);
+ mThumbTintMode = Drawable.parseTintMode(a.getInt(
+ R.styleable.SeekBar_thumbTintMode, -1), mThumbTintMode);
+
if (a.hasValue(R.styleable.SeekBar_thumbTint)) {
mThumbTint = a.getColorStateList(R.styleable.SeekBar_thumbTint);
- mThumbTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.SeekBar_thumbTintMode, -1), mThumbTintMode);
mHasThumbTint = true;
applyThumbTint();
@@ -183,30 +184,6 @@
}
/**
- * Applies a tint to the thumb drawable.
- * <p>
- * Subsequent calls to {@link #setThumb(Drawable)} will automatically
- * mutate the drawable and apply the specified tint and tint mode using
- * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
- *
- * @param tint the tint to apply, may be {@code null} to clear tint
- * @param tintMode the blending mode used to apply the tint, may be
- * {@code null} to clear tint
- *
- * @attr ref android.R.styleable#SeekBar_thumbTint
- * @attr ref android.R.styleable#SeekBar_thumbTintMode
- * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
- */
- private void setThumbTint(@Nullable ColorStateList tint,
- @Nullable PorterDuff.Mode tintMode) {
- mThumbTint = tint;
- mThumbTintMode = tintMode;
- mHasThumbTint = true;
-
- applyThumbTint();
- }
-
- /**
* Applies a tint to the thumb drawable. Does not modify the current tint
* mode, which is {@link PorterDuff.Mode#SRC_ATOP} by default.
* <p>
@@ -217,16 +194,20 @@
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#SeekBar_thumbTint
- * @see #setThumbTint(ColorStateList, PorterDuff.Mode)
+ * @see #getThumbTint()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setThumbTint(@Nullable ColorStateList tint) {
- setThumbTint(tint, mThumbTintMode);
+ mThumbTint = tint;
+ mHasThumbTint = true;
+
+ applyThumbTint();
}
/**
* @return the tint applied to the thumb drawable
* @attr ref android.R.styleable#SeekBar_thumbTint
- * @see #setThumbTint(ColorStateList, PorterDuff.Mode)
+ * @see #setThumbTint(ColorStateList)
*/
@Nullable
public ColorStateList getThumbTint() {
@@ -240,17 +221,21 @@
*
* @param tintMode the blending mode used to apply the tint, may be
* {@code null} to clear tint
+ *
* @attr ref android.R.styleable#SeekBar_thumbTintMode
- * @see #setThumbTint(ColorStateList)
+ * @see #getThumbTintMode()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setThumbTintMode(@Nullable PorterDuff.Mode tintMode) {
- setThumbTint(mThumbTint, tintMode);
+ mThumbTintMode = tintMode;
+
+ applyThumbTint();
}
/**
* @return the blending mode used to apply the tint to the thumb drawable
* @attr ref android.R.styleable#SeekBar_thumbTintMode
- * @see #setThumbTint(ColorStateList, PorterDuff.Mode)
+ * @see #setThumbTintMode(PorterDuff.Mode)
*/
@Nullable
public PorterDuff.Mode getThumbTintMode() {
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 4aa2300..791151c 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -18,9 +18,12 @@
import com.android.internal.R;
+import android.annotation.Nullable;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Canvas;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
@@ -41,8 +44,13 @@
*/
public class CheckedTextView extends TextView implements Checkable {
private boolean mChecked;
+
private int mCheckMarkResource;
private Drawable mCheckMarkDrawable;
+ private ColorStateList mCheckMarkTint = null;
+ private PorterDuff.Mode mCheckMarkTintMode = PorterDuff.Mode.SRC_ATOP;
+ private boolean mHasCheckMarkTint = false;
+
private int mBasePadding;
private int mCheckMarkWidth;
private boolean mNeedRequestlayout;
@@ -74,6 +82,16 @@
setCheckMarkDrawable(d);
}
+ mCheckMarkTintMode = Drawable.parseTintMode(a.getInt(
+ R.styleable.CompoundButton_buttonTintMode, -1), mCheckMarkTintMode);
+
+ if (a.hasValue(R.styleable.CompoundButton_buttonTint)) {
+ mCheckMarkTint = a.getColorStateList(R.styleable.CompoundButton_buttonTint);
+ mHasCheckMarkTint = true;
+
+ applyCheckMarkTint();
+ }
+
boolean checked = a.getBoolean(R.styleable.CheckedTextView_checked, false);
setChecked(checked);
@@ -153,6 +171,7 @@
mCheckMarkWidth = d.getIntrinsicWidth();
d.setState(getDrawableState());
+ applyCheckMarkTint();
} else {
mCheckMarkWidth = 0;
}
@@ -163,6 +182,72 @@
resolvePadding();
}
+ /**
+ * Applies a tint to the check mark drawable. Does not modify the
+ * current tint mode, which is {@link PorterDuff.Mode#SRC_ATOP} by default.
+ * <p>
+ * Subsequent calls to {@link #setCheckMarkDrawable(Drawable)} will
+ * automatically mutate the drawable and apply the specified tint and
+ * tint mode using
+ * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#CheckedTextView_checkMarkTint
+ * @see #getCheckMarkTint()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+ */
+ public void setCheckMarkTint(@Nullable ColorStateList tint) {
+ mCheckMarkTint = tint;
+ mHasCheckMarkTint = true;
+
+ applyCheckMarkTint();
+ }
+
+ /**
+ * @return the tint applied to the check mark drawable
+ * @attr ref android.R.styleable#CheckedTextView_checkMarkTint
+ * @see #setCheckMarkTint(ColorStateList)
+ */
+ @Nullable
+ public ColorStateList getCheckMarkTint() {
+ return mCheckMarkTint;
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by
+ * {@link #setCheckMarkTint(ColorStateList)} to the check mark
+ * drawable. The default mode is {@link PorterDuff.Mode#SRC_ATOP}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be
+ * {@code null} to clear tint
+ * @attr ref android.R.styleable#CheckedTextView_checkMarkTintMode
+ * @see #setCheckMarkTint(ColorStateList)
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
+ */
+ public void setCheckMarkTintMode(@Nullable PorterDuff.Mode tintMode) {
+ mCheckMarkTintMode = tintMode;
+
+ applyCheckMarkTint();
+ }
+
+ /**
+ * @return the blending mode used to apply the tint to the check mark drawable
+ * @attr ref android.R.styleable#CheckedTextView_checkMarkTintMode
+ * @see #setCheckMarkTintMode(PorterDuff.Mode)
+ */
+ @Nullable
+ public PorterDuff.Mode getCheckMarkTintMode() {
+ return mCheckMarkTintMode;
+ }
+
+ private void applyCheckMarkTint() {
+ if (mCheckMarkDrawable != null && mHasCheckMarkTint) {
+ mCheckMarkDrawable = mCheckMarkDrawable.mutate();
+ mCheckMarkDrawable.setTint(mCheckMarkTint, mCheckMarkTintMode);
+ }
+ }
+
@RemotableViewMethod
@Override
public void setVisibility(int visibility) {
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 9ba0fe1..a45777e 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -87,10 +87,11 @@
setButtonDrawable(d);
}
+ mButtonTintMode = Drawable.parseTintMode(a.getInt(
+ R.styleable.CompoundButton_buttonTintMode, -1), mButtonTintMode);
+
if (a.hasValue(R.styleable.CompoundButton_buttonTint)) {
mButtonTint = a.getColorStateList(R.styleable.CompoundButton_buttonTint);
- mButtonTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.CompoundButton_buttonTintMode, -1), mButtonTintMode);
mHasButtonTint = true;
applyButtonTint();
@@ -238,52 +239,31 @@
}
/**
- * Applies a tint to the button drawable.
- * <p>
- * Subsequent calls to {@link #setButtonDrawable(Drawable)} will
- * automatically mutate the drawable and apply the specified tint and tint
- * mode using
- * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
- *
- * @param tint the tint to apply, may be {@code null} to clear tint
- * @param tintMode the blending mode used to apply the tint, may be
- * {@code null} to clear tint
- *
- * @attr ref android.R.styleable#CompoundButton_buttonTint
- * @attr ref android.R.styleable#CompoundButton_buttonTintMode
- * @see Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)
- */
- private void setButtonTint(@Nullable ColorStateList tint,
- @Nullable PorterDuff.Mode tintMode) {
- mButtonTint = tint;
- mButtonTintMode = tintMode;
- mHasButtonTint = true;
-
- applyButtonTint();
- }
-
- /**
* Applies a tint to the button drawable. Does not modify the current tint
* mode, which is {@link PorterDuff.Mode#SRC_ATOP} by default.
* <p>
* Subsequent calls to {@link #setButtonDrawable(Drawable)} will
* automatically mutate the drawable and apply the specified tint and tint
* mode using
- * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
+ * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
*
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#CompoundButton_buttonTint
- * @see #setButtonTint(ColorStateList, android.graphics.PorterDuff.Mode)
+ * @see #setButtonTint(ColorStateList)
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setButtonTint(@Nullable ColorStateList tint) {
- setButtonTint(tint, mButtonTintMode);
+ mButtonTint = tint;
+ mHasButtonTint = true;
+
+ applyButtonTint();
}
/**
* @return the tint applied to the button drawable
* @attr ref android.R.styleable#CompoundButton_buttonTint
- * @see #setButtonTint(ColorStateList, PorterDuff.Mode)
+ * @see #setButtonTint(ColorStateList)
*/
@Nullable
public ColorStateList getButtonTint() {
@@ -298,16 +278,19 @@
* @param tintMode the blending mode used to apply the tint, may be
* {@code null} to clear tint
* @attr ref android.R.styleable#CompoundButton_buttonTintMode
- * @see #setButtonTint(ColorStateList)
+ * @see #getButtonTintMode()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setButtonTintMode(@Nullable PorterDuff.Mode tintMode) {
- setButtonTint(mButtonTint, tintMode);
+ mButtonTintMode = tintMode;
+
+ applyButtonTint();
}
/**
* @return the blending mode used to apply the tint to the button drawable
* @attr ref android.R.styleable#CompoundButton_buttonTintMode
- * @see #setButtonTint(ColorStateList, PorterDuff.Mode)
+ * @see #setButtonTintMode(PorterDuff.Mode)
*/
@Nullable
public PorterDuff.Mode getButtonTintMode() {
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 34f333e..81dfcbb 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -127,10 +127,11 @@
setMeasureAllChildren(true);
}
+ mForegroundTintMode = Drawable.parseTintMode(a.getInt(
+ R.styleable.FrameLayout_foregroundTintMode, -1), mForegroundTintMode);
+
if (a.hasValue(R.styleable.FrameLayout_foregroundTint)) {
mForegroundTint = a.getColorStateList(R.styleable.FrameLayout_foregroundTint);
- mForegroundTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.FrameLayout_foregroundTintMode, -1), mForegroundTintMode);
mHasForegroundTint = true;
applyForegroundTint();
@@ -316,11 +317,6 @@
*/
private void setForegroundTint(@Nullable ColorStateList tint,
@Nullable PorterDuff.Mode tintMode) {
- mForegroundTint = tint;
- mForegroundTintMode = tintMode;
- mHasForegroundTint = true;
-
- applyForegroundTint();
}
/**
@@ -334,16 +330,20 @@
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#FrameLayout_foregroundTint
- * @see #setForegroundTint(ColorStateList, PorterDuff.Mode)
+ * @see #getForegroundTint()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setForegroundTint(@Nullable ColorStateList tint) {
- setForegroundTint(tint, mForegroundTintMode);
+ mForegroundTint = tint;
+ mHasForegroundTint = true;
+
+ applyForegroundTint();
}
/**
* @return the tint applied to the foreground drawable
* @attr ref android.R.styleable#FrameLayout_foregroundTint
- * @see #setForegroundTint(ColorStateList, PorterDuff.Mode)
+ * @see #setForegroundTint(ColorStateList)
*/
@Nullable
public ColorStateList getForegroundTint() {
@@ -358,17 +358,20 @@
* @param tintMode the blending mode used to apply the tint, may be
* {@code null} to clear tint
* @attr ref android.R.styleable#FrameLayout_foregroundTintMode
- * @see #setForegroundTint(ColorStateList)
+ * @see #getForegroundTintMode()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setForegroundTintMode(@Nullable PorterDuff.Mode tintMode) {
- setForegroundTint(mForegroundTint, tintMode);
+ mForegroundTintMode = tintMode;
+
+ applyForegroundTint();
}
/**
* @return the blending mode used to apply the tint to the foreground
* drawable
* @attr ref android.R.styleable#FrameLayout_foregroundTintMode
- * @see #setForegroundTint(ColorStateList, PorterDuff.Mode)
+ * @see #setForegroundTintMode(PorterDuff.Mode)
*/
@Nullable
public PorterDuff.Mode getForegroundTintMode() {
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index e97177d..0881f3e 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -168,10 +168,11 @@
setScaleType(sScaleTypeArray[index]);
}
+ mDrawableTintMode = Drawable.parseTintMode(a.getInt(
+ R.styleable.ImageView_tintMode, -1), mDrawableTintMode);
+
if (a.hasValue(R.styleable.ImageView_tint)) {
mDrawableTint = a.getColorStateList(R.styleable.ImageView_tint);
- mDrawableTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.ImageView_tintMode, -1), mDrawableTintMode);
mHasDrawableTint = true;
applyDrawableTint();
@@ -448,30 +449,6 @@
}
/**
- * Applies a tint to the image drawable.
- * <p>
- * Subsequent calls to {@link #setImageDrawable(Drawable)} will automatically
- * mutate the drawable and apply the specified tint and tint mode using
- * {@link Drawable#setTint(ColorStateList, PorterDuff.Mode)}.
- *
- * @param tint the tint to apply, may be {@code null} to clear tint
- * @param tintMode the blending mode used to apply the tint, may be
- * {@code null} to clear tint
- *
- * @attr ref android.R.styleable#ImageView_tint
- * @attr ref android.R.styleable#ImageView_tintMode
- * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
- */
- private void setTint(@Nullable ColorStateList tint,
- @Nullable PorterDuff.Mode tintMode) {
- mDrawableTint = tint;
- mDrawableTintMode = tintMode;
- mHasDrawableTint = true;
-
- applyDrawableTint();
- }
-
- /**
* Applies a tint to the image drawable. Does not modify the current tint
* mode, which is {@link PorterDuff.Mode#SRC_ATOP} by default.
* <p>
@@ -482,16 +459,20 @@
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#ImageView_tint
+ * @see #getTint()
* @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setTint(@Nullable ColorStateList tint) {
- setTint(tint, mDrawableTintMode);
+ mDrawableTint = tint;
+ mHasDrawableTint = true;
+
+ applyDrawableTint();
}
/**
* @return the tint applied to the image drawable
* @attr ref android.R.styleable#ImageView_tint
- * @see #setTint(ColorStateList, PorterDuff.Mode)
+ * @see #setTint(ColorStateList)
*/
@Nullable
public ColorStateList getTint() {
@@ -506,16 +487,19 @@
* @param tintMode the blending mode used to apply the tint, may be
* {@code null} to clear tint
* @attr ref android.R.styleable#ImageView_tintMode
- * @see #setTint(ColorStateList)
+ * @see #getTintMode()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
- setTint(mDrawableTint, tintMode);
+ mDrawableTintMode = tintMode;
+
+ applyDrawableTint();
}
/**
* @return the blending mode used to apply the tint to the image drawable
* @attr ref android.R.styleable#ImageView_tintMode
- * @see #setTint(ColorStateList, PorterDuff.Mode)
+ * @see #setTintMode(PorterDuff.Mode)
*/
@Nullable
public PorterDuff.Mode getTintMode() {
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 394b255..20c1aa4 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -326,48 +326,48 @@
mMirrorForRtl = a.getBoolean(R.styleable.ProgressBar_mirrorForRtl, mMirrorForRtl);
+ mProgressTintMode = Drawable.parseTintMode(a.getInt(
+ R.styleable.ProgressBar_progressBackgroundTintMode, -1), mProgressTintMode);
+
if (a.hasValue(R.styleable.ProgressBar_progressTint)) {
mProgressTint = a.getColorStateList(
R.styleable.ProgressBar_progressTint);
- mProgressTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.ProgressBar_progressBackgroundTintMode, -1),
- mProgressTintMode);
mHasProgressTint = true;
applyProgressLayerTint(R.id.progress, mProgressTint,
mProgressTintMode, true);
}
+ mProgressBackgroundTintMode = Drawable.parseTintMode(a.getInt(
+ R.styleable.ProgressBar_progressTintMode, -1), mProgressBackgroundTintMode);
+
if (a.hasValue(R.styleable.ProgressBar_progressBackgroundTint)) {
mProgressBackgroundTint = a.getColorStateList(
R.styleable.ProgressBar_progressBackgroundTint);
- mProgressBackgroundTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.ProgressBar_progressTintMode, -1),
- mProgressBackgroundTintMode);
mHasProgressBackgroundTint = true;
applyProgressLayerTint(R.id.background, mProgressBackgroundTint,
mProgressBackgroundTintMode, false);
}
+ mSecondaryProgressTintMode = Drawable.parseTintMode(a.getInt(
+ R.styleable.ProgressBar_secondaryProgressTintMode, -1), mSecondaryProgressTintMode);
+
if (a.hasValue(R.styleable.ProgressBar_secondaryProgressTint)) {
mSecondaryProgressTint = a.getColorStateList(
R.styleable.ProgressBar_secondaryProgressTint);
- mSecondaryProgressTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.ProgressBar_secondaryProgressTintMode, -1),
- mSecondaryProgressTintMode);
mHasSecondaryProgressTint = true;
applyProgressLayerTint(R.id.secondaryProgress, mSecondaryProgressTint,
mSecondaryProgressTintMode, false);
}
+ mIndeterminateTintMode = Drawable.parseTintMode(a.getInt(
+ R.styleable.ProgressBar_indeterminateTintMode, -1), mIndeterminateTintMode);
+
if (a.hasValue(R.styleable.ProgressBar_indeterminateTint)) {
mIndeterminateTint = a.getColorStateList(
R.styleable.ProgressBar_indeterminateTint);
- mIndeterminateTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.ProgressBar_indeterminateTintMode, -1),
- mIndeterminateTintMode);
mHasIndeterminateTint = true;
applyIndeterminateTint();
@@ -574,31 +574,6 @@
}
/**
- * Applies a tint to the indeterminate drawable.
- * <p>
- * Subsequent calls to {@link #setVisibilminateDrawable(Drawable)} will
- * automatically mutate the drawable and apply the specified tint and
- * tint mode using
- * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
- *
- * @param tint the tint to apply, may be {@code null} to clear tint
- * @param tintMode the blending mode used to apply the tint, may be
- * {@code null} to clear tint
- *
- * @attr ref android.R.styleable#ProgressBar_indeterminateTint
- * @attr ref android.R.styleable#ProgressBar_indeterminateTintMode
- * @see Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)
- */
- private void setIndeterminateTint(@Nullable ColorStateList tint,
- @Nullable PorterDuff.Mode tintMode) {
- mIndeterminateTint = tint;
- mIndeterminateTintMode = tintMode;
- mHasIndeterminateTint = true;
-
- applyIndeterminateTint();
- }
-
- /**
* Applies a tint to the indeterminate drawable. Does not modify the
* current tint mode, which is {@link PorterDuff.Mode#SRC_ATOP} by default.
* <p>
@@ -610,16 +585,20 @@
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#ProgressBar_indeterminateTint
- * @see #setIndeterminateTint(ColorStateList, PorterDuff.Mode)
+ * @see #getIndeterminateTint()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setIndeterminateTint(@Nullable ColorStateList tint) {
- setIndeterminateTint(tint, mIndeterminateTintMode);
+ mIndeterminateTint = tint;
+ mHasIndeterminateTint = true;
+
+ applyIndeterminateTint();
}
/**
* @return the tint applied to the indeterminate drawable
* @attr ref android.R.styleable#ProgressBar_indeterminateTint
- * @see #setIndeterminateTint(ColorStateList, PorterDuff.Mode)
+ * @see #setIndeterminateTint(ColorStateList)
*/
@Nullable
public ColorStateList getIndeterminateTint() {
@@ -635,15 +614,18 @@
* {@code null} to clear tint
* @attr ref android.R.styleable#ProgressBar_indeterminateTintMode
* @see #setIndeterminateTint(ColorStateList)
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setIndeterminateTintMode(@Nullable PorterDuff.Mode tintMode) {
- setIndeterminateTint(mIndeterminateTint, tintMode);
+ mIndeterminateTintMode = tintMode;
+
+ applyIndeterminateTint();
}
/**
* @return the blending mode used to apply the tint to the indeterminate drawable
* @attr ref android.R.styleable#ProgressBar_indeterminateTintMode
- * @see #setIndeterminateTint(ColorStateList, PorterDuff.Mode)
+ * @see #setIndeterminateTintMode(PorterDuff.Mode)
*/
@Nullable
public PorterDuff.Mode getIndeterminateTintMode() {
@@ -749,36 +731,6 @@
/**
* Applies a tint to the progress indicator, if one exists, or to the
- * entire progress drawable otherwise.
- * <p>
- * The progress indicator should be specified as a layer with
- * id {@link android.R.id#progress} in a {@link LayerDrawable}
- * used as the progress drawable.
- * <p>
- * Subsequent calls to {@link #setProgressDrawable(Drawable)} will
- * automatically mutate the drawable and apply the specified tint and
- * tint mode using
- * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
- *
- * @param tint the tint to apply, may be {@code null} to clear tint
- * @param tintMode the blending mode used to apply the tint, may be
- * {@code null} to clear tint
- *
- * @attr ref android.R.styleable#ProgressBar_progressTint
- * @attr ref android.R.styleable#ProgressBar_progressTintMode
- * @see Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)
- */
- private void setProgressTint(@Nullable ColorStateList tint,
- @Nullable PorterDuff.Mode tintMode) {
- mProgressTint = tint;
- mProgressTintMode = tintMode;
- mHasProgressTint = true;
-
- applyProgressLayerTint(R.id.progress, tint, tintMode, true);
- }
-
- /**
- * Applies a tint to the progress indicator, if one exists, or to the
* entire progress drawable otherwise. Does not modify the current tint
* mode, which is {@link PorterDuff.Mode#SRC_ATOP} by default.
* <p>
@@ -794,16 +746,20 @@
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#ProgressBar_progressTint
- * @see #setProgressTint(ColorStateList)
+ * @see #getProgressTint()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setProgressTint(@Nullable ColorStateList tint) {
- setProgressTint(tint, mProgressTintMode);
+ mProgressTint = tint;
+ mHasProgressTint = true;
+
+ applyProgressLayerTint(R.id.progress, tint, mProgressTintMode, true);
}
/**
* @return the tint applied to the progress drawable
* @attr ref android.R.styleable#ProgressBar_progressTint
- * @see #setProgressTint(ColorStateList, PorterDuff.Mode)
+ * @see #setProgressTint(ColorStateList)
*/
@Nullable
public ColorStateList getProgressTint() {
@@ -818,16 +774,19 @@
* @param tintMode the blending mode used to apply the tint, may be
* {@code null} to clear tint
* @attr ref android.R.styleable#ProgressBar_progressTintMode
- * @see #setProgressTint(ColorStateList)
+ * @see #getProgressTintMode()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setProgressTintMode(@Nullable PorterDuff.Mode tintMode) {
- setProgressTint(mProgressTint, tintMode);
+ mProgressTintMode = tintMode;
+
+ applyProgressLayerTint(R.id.progress, mProgressTint, tintMode, true);
}
/**
* @return the blending mode used to apply the tint to the progress drawable
* @attr ref android.R.styleable#ProgressBar_progressTintMode
- * @see #setProgressTint(ColorStateList, PorterDuff.Mode)
+ * @see #setProgressTintMode(PorterDuff.Mode)
*/
@Nullable
public PorterDuff.Mode getProgressTintMode() {
@@ -835,35 +794,6 @@
}
/**
- * Applies a tint to the progress background, if one exists.
- * <p>
- * The progress background must be specified as a layer with
- * id {@link android.R.id#background} in a {@link LayerDrawable}
- * used as the progress drawable.
- * <p>
- * Subsequent calls to {@link #setProgressDrawable(Drawable)} where the
- * drawable contains a progress background will automatically mutate the
- * drawable and apply the specified tint and tint mode using
- * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
- *
- * @param tint the tint to apply, may be {@code null} to clear tint
- * @param tintMode the blending mode used to apply the tint, may be
- * {@code null} to clear tint
- *
- * @attr ref android.R.styleable#ProgressBar_progressBackgroundTint
- * @attr ref android.R.styleable#ProgressBar_progressBackgroundTintMode
- * @see Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)
- */
- private void setProgressBackgroundTint(@Nullable ColorStateList tint,
- @Nullable PorterDuff.Mode tintMode) {
- mProgressBackgroundTint = tint;
- mProgressBackgroundTintMode = tintMode;
- mHasProgressBackgroundTint = true;
-
- applyProgressLayerTint(R.id.background, tint, tintMode, false);
- }
-
- /**
* Applies a tint to the progress background, if one exists. Does not
* modify the current tint mode, which is
* {@link PorterDuff.Mode#SRC_ATOP} by default.
@@ -880,16 +810,20 @@
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#ProgressBar_progressBackgroundTint
- * @see #setProgressBackgroundTint(ColorStateList, PorterDuff.Mode)
+ * @see #getProgressBackgroundTint()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setProgressBackgroundTint(@Nullable ColorStateList tint) {
- setProgressBackgroundTint(tint, mProgressBackgroundTintMode);
+ mProgressBackgroundTint = tint;
+ mHasProgressBackgroundTint = true;
+
+ applyProgressLayerTint(R.id.background, tint, mProgressBackgroundTintMode, false);
}
/**
* @return the tint applied to the progress background
* @attr ref android.R.styleable#ProgressBar_progressBackgroundTint
- * @see #setProgressBackgroundTint(ColorStateList, PorterDuff.Mode)
+ * @see #setProgressBackgroundTint(ColorStateList)
*/
@Nullable
public ColorStateList getProgressBackgroundTint() {
@@ -905,16 +839,19 @@
* {@code null} to clear tint
* @attr ref android.R.styleable#ProgressBar_progressBackgroundTintMode
* @see #setProgressBackgroundTint(ColorStateList)
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setProgressBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
- setProgressBackgroundTint(mProgressBackgroundTint, tintMode);
+ mProgressBackgroundTintMode = tintMode;
+
+ applyProgressLayerTint(R.id.background, mProgressBackgroundTint, tintMode, false);
}
/**
* @return the blending mode used to apply the tint to the progress
* background
* @attr ref android.R.styleable#ProgressBar_progressBackgroundTintMode
- * @see #setProgressBackgroundTint(ColorStateList, PorterDuff.Mode)
+ * @see #setProgressBackgroundTintMode(PorterDuff.Mode)
*/
@Nullable
public PorterDuff.Mode getProgressBackgroundTintMode() {
@@ -923,35 +860,6 @@
/**
* Applies a tint to the secondary progress indicator, if one exists.
- * <p>
- * The secondary progress indicator must be specified as a layer with
- * id {@link android.R.id#secondaryProgress} in a {@link LayerDrawable}
- * used as the progress drawable.
- * <p>
- * Subsequent calls to {@link #setProgressDrawable(Drawable)} where the
- * drawable contains a secondary progress indicator will automatically
- * mutate the drawable and apply the specified tint and tint mode using
- * {@link Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)}.
- *
- * @param tint the tint to apply, may be {@code null} to clear tint
- * @param tintMode the blending mode used to apply the tint, may be
- * {@code null} to clear tint
- *
- * @attr ref android.R.styleable#ProgressBar_secondaryProgressTint
- * @attr ref android.R.styleable#ProgressBar_secondaryProgressTintMode
- * @see Drawable#setTint(ColorStateList, android.graphics.PorterDuff.Mode)
- */
- private void setSecondaryProgressTint(@Nullable ColorStateList tint,
- @Nullable PorterDuff.Mode tintMode) {
- mSecondaryProgressTint = tint;
- mSecondaryProgressTintMode = tintMode;
- mHasSecondaryProgressTint = true;
-
- applyProgressLayerTint(R.id.secondaryProgress, tint, tintMode, false);
- }
-
- /**
- * Applies a tint to the secondary progress indicator, if one exists.
* Does not modify the current tint mode, which is
* {@link PorterDuff.Mode#SRC_ATOP} by default.
* <p>
@@ -967,16 +875,20 @@
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#ProgressBar_secondaryProgressTint
- * @see #setSecondaryProgressTint(ColorStateList, PorterDuff.Mode)
+ * @see #getSecondaryProgressTint()
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setSecondaryProgressTint(@Nullable ColorStateList tint) {
- setSecondaryProgressTint(tint, mSecondaryProgressTintMode);
+ mSecondaryProgressTint = tint;
+ mHasSecondaryProgressTint = true;
+
+ applyProgressLayerTint(R.id.secondaryProgress, tint, mSecondaryProgressTintMode, false);
}
/**
* @return the tint applied to the secondary progress drawable
* @attr ref android.R.styleable#ProgressBar_secondaryProgressTint
- * @see #setSecondaryProgressTint(ColorStateList, PorterDuff.Mode)
+ * @see #setSecondaryProgressTint(ColorStateList)
*/
@Nullable
public ColorStateList getSecondaryProgressTint() {
@@ -993,16 +905,19 @@
* {@code null} to clear tint
* @attr ref android.R.styleable#ProgressBar_secondaryProgressTintMode
* @see #setSecondaryProgressTint(ColorStateList)
+ * @see Drawable#setTint(ColorStateList, PorterDuff.Mode)
*/
public void setSecondaryProgressTintMode(@Nullable PorterDuff.Mode tintMode) {
- setSecondaryProgressTint(mSecondaryProgressTint, tintMode);
+ mSecondaryProgressTintMode = tintMode;
+
+ applyProgressLayerTint(R.id.secondaryProgress, mSecondaryProgressTint, tintMode, false);
}
/**
* @return the blending mode used to apply the tint to the secondary
* progress drawable
* @attr ref android.R.styleable#ProgressBar_secondaryProgressTintMode
- * @see #setSecondaryProgressTint(ColorStateList, PorterDuff.Mode)
+ * @see #setSecondaryProgressTintMode(PorterDuff.Mode)
*/
@Nullable
public PorterDuff.Mode getSecondaryProgressTintMode() {
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 64d03be..71102e8 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -233,10 +233,11 @@
if (!TextUtils.isEmpty(subtitle)) {
setSubtitle(subtitle);
}
- a.recycle();
- mPopupContext = context;
- mPopupTheme = 0;
+ // Set the default context, since setPopupTheme() may be a no-op.
+ mPopupContext = mContext;
+ setPopupTheme(a.getResourceId(R.styleable.Toolbar_popupTheme, 0));
+ a.recycle();
}
/**
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 901d6e6..d91eb69 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -27,6 +27,10 @@
// be kept in sync with frameworks/native/include/binder/IBatteryStats.h
void noteStartSensor(int uid, int sensor);
void noteStopSensor(int uid, int sensor);
+ void noteStartVideo(int uid);
+ void noteStopVideo(int uid);
+ void noteStartAudio(int uid);
+ void noteStopAudio(int uid);
// Remaining methods are only used in Java.
byte[] getStatistics();
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index fdb305d..e215517 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -17,6 +17,9 @@
package com.android.internal.app;
import android.app.Activity;
+import android.app.usage.PackageUsageStats;
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
import android.os.AsyncTask;
import android.widget.AbsListView;
import android.widget.GridView;
@@ -54,12 +57,13 @@
import android.widget.TextView;
import com.android.internal.widget.ResolverDrawerLayout;
+import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Set;
/**
@@ -69,7 +73,7 @@
*/
public class ResolverActivity extends Activity implements AdapterView.OnItemClickListener {
private static final String TAG = "ResolverActivity";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private int mLaunchedFromUid;
private ResolveListAdapter mAdapter;
@@ -84,6 +88,10 @@
private int mMaxColumns;
private int mLastSelected = ListView.INVALID_POSITION;
+ private UsageStatsManager mUsm;
+ private UsageStats mStats;
+ private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 14;
+
private boolean mRegistered;
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override public void onSomePackagesChanged() {
@@ -170,7 +178,7 @@
protected void onCreate(Bundle savedInstanceState, Intent intent,
CharSequence title, Intent[] initialIntents,
List<ResolveInfo> rList, boolean alwaysUseOption) {
- onCreate(savedInstanceState, intent, title, initialIntents, rList, alwaysUseOption);
+ onCreate(savedInstanceState, intent, title, 0, initialIntents, rList, alwaysUseOption);
}
protected void onCreate(Bundle savedInstanceState, Intent intent,
@@ -185,6 +193,12 @@
mLaunchedFromUid = -1;
}
mPm = getPackageManager();
+ mUsm = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
+
+ final long sinceTime = System.currentTimeMillis() - USAGE_STATS_PERIOD;
+ mStats = mUsm.getRecentStatsSince(sinceTime);
+ Log.d(TAG, "sinceTime=" + sinceTime);
+
mMaxColumns = getResources().getInteger(R.integer.config_maxResolverActivityColumns);
mPackageMonitor.register(this, getMainLooper(), false);
@@ -672,7 +686,7 @@
for (int i=1; i<N; i++) {
ResolveInfo ri = currentResolveList.get(i);
if (DEBUG) Log.v(
- "ResolveListActivity",
+ TAG,
r0.activityInfo.name + "=" +
r0.priority + "/" + r0.isDefault + " vs " +
ri.activityInfo.name + "=" +
@@ -689,8 +703,8 @@
}
}
if (N > 1) {
- ResolveInfo.DisplayNameComparator rComparator =
- new ResolveInfo.DisplayNameComparator(mPm);
+ Comparator<ResolveInfo> rComparator =
+ new ResolverComparator(ResolverActivity.this);
Collections.sort(currentResolveList, rComparator);
}
// First put the initial items at the top.
@@ -703,8 +717,7 @@
ActivityInfo ai = ii.resolveActivityInfo(
getPackageManager(), 0);
if (ai == null) {
- Log.w("ResolverActivity", "No activity found for "
- + ii);
+ Log.w(TAG, "No activity found for " + ii);
continue;
}
ResolveInfo ri = new ResolveInfo();
@@ -939,5 +952,52 @@
mTargetView.setImageDrawable(info.displayIcon);
}
}
+
+ class ResolverComparator implements Comparator<ResolveInfo> {
+ private final Collator mCollator;
+
+ public ResolverComparator(Context context) {
+ mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
+ }
+
+ @Override
+ public int compare(ResolveInfo lhs, ResolveInfo rhs) {
+ // We want to put the one targeted to another user at the end of the dialog.
+ if (lhs.targetUserId != UserHandle.USER_CURRENT) {
+ return 1;
+ }
+ if (lhs.targetUserId != UserHandle.USER_CURRENT) {
+ return -1;
+ }
+
+ if (mStats != null) {
+ final long timeDiff =
+ getPackageTimeSpent(rhs.activityInfo.packageName) -
+ getPackageTimeSpent(lhs.activityInfo.packageName);
+
+ if (timeDiff != 0) {
+ return timeDiff > 0 ? 1 : -1;
+ }
+ }
+
+ CharSequence sa = lhs.loadLabel(mPm);
+ if (sa == null) sa = lhs.activityInfo.name;
+ CharSequence sb = rhs.loadLabel(mPm);
+ if (sb == null) sb = rhs.activityInfo.name;
+
+ return mCollator.compare(sa.toString(), sb.toString());
+ }
+
+ private long getPackageTimeSpent(String packageName) {
+ if (mStats != null) {
+ final PackageUsageStats stats = mStats.getPackage(packageName);
+ if (stats != null) {
+ return stats.getTotalTimeSpent();
+ }
+
+ }
+ return 0;
+ }
+ }
}
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index e1a4909..5da5ae9 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -27,6 +27,8 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -154,6 +156,11 @@
mToolbar.setSubtitleTextAppearance(mToolbar.getContext(), subtitleTextStyle);
}
+ final int popupTheme = a.getResourceId(R.styleable.ActionBar_popupTheme, 0);
+ if (popupTheme != 0) {
+ mToolbar.setPopupTheme(popupTheme);
+ }
+
a.recycle();
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index f65aab5..7b5395b 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -113,6 +113,7 @@
android/graphics/NinePatchImpl.cpp \
android/graphics/NinePatchPeeker.cpp \
android/graphics/Paint.cpp \
+ android/graphics/PaintImpl.cpp \
android/graphics/Path.cpp \
android/graphics/PathMeasure.cpp \
android/graphics/PathEffect.cpp \
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
old mode 100644
new mode 100755
index 53aca3d..70cf9a8
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -1,3 +1,4 @@
+#include "Paint.h"
#include "SkBitmap.h"
#include "SkPixelRef.h"
#include "SkImageEncoder.h"
@@ -676,7 +677,7 @@
jlong srcHandle, jlong paintHandle,
jintArray offsetXY) {
const SkBitmap* src = reinterpret_cast<SkBitmap*>(srcHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const android::Paint* paint = reinterpret_cast<android::Paint*>(paintHandle);
SkIPoint offset;
SkBitmap* dst = new SkBitmap;
JavaPixelAllocator allocator(env);
@@ -845,7 +846,19 @@
const int h = bm0->height();
const size_t size = bm0->width() * bm0->bytesPerPixel();
for (int y = 0; y < h; y++) {
- if (memcmp(bm0->getAddr(0, y), bm1->getAddr(0, y), size) != 0) {
+ // SkBitmap::getAddr(int, int) may return NULL due to unrecognized config
+ // (ex: kRLE_Index8_Config). This will cause memcmp method to crash. Since bm0
+ // and bm1 both have pixel data() (have passed NULL == getPixels() check),
+ // those 2 bitmaps should be valid (only unrecognized), we return JNI_FALSE
+ // to warn user those 2 unrecognized config bitmaps may be different.
+ void *bm0Addr = bm0->getAddr(0, y);
+ void *bm1Addr = bm1->getAddr(0, y);
+
+ if(bm0Addr == NULL || bm1Addr == NULL) {
+ return JNI_FALSE;
+ }
+
+ if (memcmp(bm0Addr, bm1Addr, size) != 0) {
return JNI_FALSE;
}
}
diff --git a/core/jni/android/graphics/Canvas.h b/core/jni/android/graphics/Canvas.h
index fde22ee..317f69d 100644
--- a/core/jni/android/graphics/Canvas.h
+++ b/core/jni/android/graphics/Canvas.h
@@ -25,6 +25,7 @@
// TODO: move this further up the stack so that all interaction with minikin
// happens prior to calling into this interface
+class Paint;
class TypefaceImpl;
class Canvas {
@@ -60,7 +61,7 @@
virtual void restoreToCount(int saveCount) = 0;
virtual int saveLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, SkCanvas::SaveFlags flags) = 0;
+ const Paint* paint, SkCanvas::SaveFlags flags) = 0;
virtual int saveLayerAlpha(float left, float top, float right, float bottom,
int alpha, SkCanvas::SaveFlags flags) = 0;
@@ -90,47 +91,47 @@
// Canvas draw operations
// ----------------------------------------------------------------------------
virtual void drawColor(int color, SkXfermode::Mode mode) = 0;
- virtual void drawPaint(const SkPaint& paint) = 0;
+ virtual void drawPaint(const Paint& paint) = 0;
// Geometry
- virtual void drawPoint(float x, float y, const SkPaint& paint) = 0;
- virtual void drawPoints(const float* points, int count, const SkPaint& paint) = 0;
+ virtual void drawPoint(float x, float y, const Paint& paint) = 0;
+ virtual void drawPoints(const float* points, int count, const Paint& paint) = 0;
virtual void drawLine(float startX, float startY, float stopX, float stopY,
- const SkPaint& paint) = 0;
- virtual void drawLines(const float* points, int count, const SkPaint& paint) = 0;
+ const Paint& paint) = 0;
+ virtual void drawLines(const float* points, int count, const Paint& paint) = 0;
virtual void drawRect(float left, float top, float right, float bottom,
- const SkPaint& paint) = 0;
+ const Paint& paint) = 0;
virtual void drawRoundRect(float left, float top, float right, float bottom,
- float rx, float ry, const SkPaint& paint) = 0;
- virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) = 0;
+ float rx, float ry, const Paint& paint) = 0;
+ virtual void drawCircle(float x, float y, float radius, const Paint& paint) = 0;
virtual void drawOval(float left, float top, float right, float bottom,
- const SkPaint& paint) = 0;
+ const Paint& paint) = 0;
virtual void drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) = 0;
- virtual void drawPath(const SkPath& path, const SkPaint& paint) = 0;
+ float startAngle, float sweepAngle, bool useCenter, const Paint& paint) = 0;
+ virtual void drawPath(const SkPath& path, const Paint& paint) = 0;
virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
const float* verts, const float* tex, const int* colors,
- const uint16_t* indices, int indexCount, const SkPaint& paint) = 0;
+ const uint16_t* indices, int indexCount, const Paint& paint) = 0;
// Bitmap-based
virtual void drawBitmap(const SkBitmap& bitmap, float left, float top,
- const SkPaint* paint) = 0;
+ const Paint* paint) = 0;
virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
- const SkPaint* paint) = 0;
+ const Paint* paint) = 0;
virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint) = 0;
+ float dstRight, float dstBottom, const Paint* paint) = 0;
virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
- const float* vertices, const int* colors, const SkPaint* paint) = 0;
+ const float* vertices, const int* colors, const Paint* paint) = 0;
// Text
virtual void drawText(const uint16_t* text, int start, int count, int contextCount,
- float x, float y, int bidiFlags, const SkPaint& paint,
+ float x, float y, int bidiFlags, const Paint& paint,
TypefaceImpl* typeface) = 0;
virtual void drawPosText(const uint16_t* text, const float* positions, int count,
- int posCount, const SkPaint& paint) = 0;
+ int posCount, const Paint& paint) = 0;
virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
- float hOffset, float vOffset, const SkPaint& paint) = 0;
+ float hOffset, float vOffset, const Paint& paint) = 0;
};
}; // namespace android
diff --git a/core/jni/android/graphics/CanvasProperty.cpp b/core/jni/android/graphics/CanvasProperty.cpp
index cfa9cd8..e63c5fa 100644
--- a/core/jni/android/graphics/CanvasProperty.cpp
+++ b/core/jni/android/graphics/CanvasProperty.cpp
@@ -16,6 +16,7 @@
#include "jni.h"
#include "GraphicsJNI.h"
+#include "Paint.h"
#include <android_runtime/AndroidRuntime.h>
#include <utils/RefBase.h>
@@ -32,7 +33,7 @@
}
static jlong createPaint(JNIEnv* env, jobject clazz, jlong paintPtr) {
- const SkPaint* paint = reinterpret_cast<const SkPaint*>(paintPtr);
+ const Paint* paint = reinterpret_cast<const Paint*>(paintPtr);
return reinterpret_cast<jlong>(new CanvasPropertyPaint(*paint));
}
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 320c259..7c41c2e 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -370,12 +370,12 @@
return c;
}
-SkPaint* GraphicsJNI::getNativePaint(JNIEnv* env, jobject paint) {
+android::Paint* GraphicsJNI::getNativePaint(JNIEnv* env, jobject paint) {
SkASSERT(env);
SkASSERT(paint);
SkASSERT(env->IsInstanceOf(paint, gPaint_class));
jlong paintHandle = env->GetLongField(paint, gPaint_nativeInstanceID);
- SkPaint* p = reinterpret_cast<SkPaint*>(paintHandle);
+ android::Paint* p = reinterpret_cast<android::Paint*>(paintHandle);
SkASSERT(p);
return p;
}
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 28a6edb..dcc97e5 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -12,9 +12,9 @@
class SkBitmapRegionDecoder;
class SkCanvas;
-class SkPaint;
namespace android {
+class Paint;
class TypefaceImpl;
}
@@ -48,7 +48,7 @@
static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
static SkCanvas* getNativeCanvas(JNIEnv*, jobject canvas);
- static SkPaint* getNativePaint(JNIEnv*, jobject paint);
+ static android::Paint* getNativePaint(JNIEnv*, jobject paint);
static android::TypefaceImpl* getNativeTypeface(JNIEnv*, jobject paint);
static SkBitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp
index f02f118..c66437a 100644
--- a/core/jni/android/graphics/MinikinUtils.cpp
+++ b/core/jni/android/graphics/MinikinUtils.cpp
@@ -18,9 +18,9 @@
#include <cutils/log.h>
#include <string>
-#include "SkPaint.h"
#include "SkPathMeasure.h"
#include "minikin/Layout.h"
+#include "Paint.h"
#include "TypefaceImpl.h"
#include "MinikinSkia.h"
@@ -38,7 +38,7 @@
return off + n;
}
-std::string MinikinUtils::setLayoutProperties(Layout* layout, const SkPaint* paint, int bidiFlags,
+std::string MinikinUtils::setLayoutProperties(Layout* layout, const Paint* paint, int bidiFlags,
TypefaceImpl* typeface) {
TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
layout->setFontCollection(resolvedFace->fFontCollection);
@@ -62,12 +62,12 @@
return std::string(css);
}
-float MinikinUtils::xOffsetForTextAlign(SkPaint* paint, const Layout& layout) {
+float MinikinUtils::xOffsetForTextAlign(Paint* paint, const Layout& layout) {
switch (paint->getTextAlign()) {
- case SkPaint::kCenter_Align:
+ case Paint::kCenter_Align:
return layout.getAdvance() * -0.5f;
break;
- case SkPaint::kRight_Align:
+ case Paint::kRight_Align:
return -layout.getAdvance();
break;
default:
@@ -76,13 +76,13 @@
return 0;
}
-float MinikinUtils::hOffsetForTextAlign(SkPaint* paint, const Layout& layout, const SkPath& path) {
+float MinikinUtils::hOffsetForTextAlign(Paint* paint, const Layout& layout, const SkPath& path) {
float align = 0;
switch (paint->getTextAlign()) {
- case SkPaint::kCenter_Align:
+ case Paint::kCenter_Align:
align = -0.5f;
break;
- case SkPaint::kRight_Align:
+ case Paint::kRight_Align:
align = -1;
break;
default:
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index 1663860..0562c3b1 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -16,7 +16,7 @@
/**
* Utilities for making Minikin work, especially from existing objects like
- * SkPaint and so on.
+ * Paint and so on.
**/
// TODO: does this really need to be separate from MinikinSkia?
@@ -24,6 +24,8 @@
#ifndef ANDROID_MINIKIN_UTILS_H
#define ANDROID_MINIKIN_UTILS_H
+#include "Paint.h"
+
namespace android {
// TODO: these should be defined in Minikin's Layout.h
@@ -43,15 +45,15 @@
class MinikinUtils {
public:
- static std::string setLayoutProperties(Layout* layout, const SkPaint* paint, int bidiFlags,
+ static std::string setLayoutProperties(Layout* layout, const Paint* paint, int bidiFlags,
TypefaceImpl* typeface);
- static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout);
+ static float xOffsetForTextAlign(Paint* paint, const Layout& layout);
- static float hOffsetForTextAlign(SkPaint* paint, const Layout& layout, const SkPath& path);
+ static float hOffsetForTextAlign(Paint* paint, const Layout& layout, const SkPath& path);
// f is a functor of type void f(size_t start, size_t end);
template <typename F>
- static void forFontRun(const Layout& layout, SkPaint* paint, F& f) {
+ static void forFontRun(const Layout& layout, Paint* paint, F& f) {
float saveSkewX = paint->getTextSkewX();
bool savefakeBold = paint->isFakeBoldText();
MinikinFont* curFont = NULL;
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index 5f9a9b7..226f83e 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -7,6 +7,7 @@
#include "SkUtils.h"
#include "Utils.h"
#include "CreateJavaOutputStreamAdaptor.h"
+#include "Paint.h"
#include <androidfw/Asset.h>
#include <androidfw/ResourceTypes.h>
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index e82e8a6..cf23771 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -23,6 +23,7 @@
#include <Caches.h>
+#include "Paint.h"
#include "Canvas.h"
#include "SkCanvas.h"
#include "SkRegion.h"
@@ -123,7 +124,7 @@
SkCanvas* canvas = reinterpret_cast<Canvas*>(canvasHandle)->getSkCanvas();
const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
Res_png_9patch* chunk = reinterpret_cast<Res_png_9patch*>(chunkHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
SkASSERT(canvas);
SkASSERT(boundsRectF);
SkASSERT(bitmap);
@@ -142,7 +143,7 @@
SkCanvas* canvas = reinterpret_cast<Canvas*>(canvasHandle)->getSkCanvas();
const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
Res_png_9patch* chunk = reinterpret_cast<Res_png_9patch*>(chunkHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
SkASSERT(canvas);
SkASSERT(boundsRect);
SkASSERT(bitmap);
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 0ad390a..c06f0d2 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -39,6 +39,7 @@
#include <minikin/Layout.h>
#include "MinikinSkia.h"
#include "MinikinUtils.h"
+#include "Paint.h"
#include "TypefaceImpl.h"
// temporary for debugging
@@ -61,47 +62,47 @@
static jclass gFontMetricsInt_class;
static JMetricsID gFontMetricsInt_fieldID;
-static void defaultSettingsForAndroid(SkPaint* paint) {
+static void defaultSettingsForAndroid(Paint* paint) {
// GlyphID encoding is required because we are using Harfbuzz shaping
- paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
paintOpts.setUseFontFallbacks(true);
paint->setPaintOptionsAndroid(paintOpts);
}
-class SkPaintGlue {
+class PaintGlue {
public:
enum MoveOpt {
AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
};
static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
delete obj;
}
static jlong init(JNIEnv* env, jobject clazz) {
- SkPaint* obj = new SkPaint();
+ Paint* obj = new Paint();
defaultSettingsForAndroid(obj);
return reinterpret_cast<jlong>(obj);
}
static jlong initWithPaint(JNIEnv* env, jobject clazz, jlong paintHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- SkPaint* obj = new SkPaint(*paint);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+ Paint* obj = new Paint(*paint);
return reinterpret_cast<jlong>(obj);
}
static void reset(JNIEnv* env, jobject clazz, jlong objHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
obj->reset();
defaultSettingsForAndroid(obj);
}
static void assign(JNIEnv* env, jobject clazz, jlong dstPaintHandle, jlong srcPaintHandle) {
- SkPaint* dst = reinterpret_cast<SkPaint*>(dstPaintHandle);
- const SkPaint* src = reinterpret_cast<SkPaint*>(srcPaintHandle);
+ Paint* dst = reinterpret_cast<Paint*>(dstPaintHandle);
+ const Paint* src = reinterpret_cast<Paint*>(srcPaintHandle);
*dst = *src;
}
@@ -110,10 +111,10 @@
static jint getFlags(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- SkPaint* nativePaint = GraphicsJNI::getNativePaint(env, paint);
+ Paint* nativePaint = GraphicsJNI::getNativePaint(env, paint);
uint32_t result = nativePaint->getFlags();
result &= ~sFilterBitmapFlag; // Filtering no longer stored in this bit. Mask away.
- if (nativePaint->getFilterLevel() != SkPaint::kNone_FilterLevel) {
+ if (nativePaint->getFilterLevel() != Paint::kNone_FilterLevel) {
result |= sFilterBitmapFlag;
}
return static_cast<jint>(result);
@@ -121,11 +122,11 @@
static void setFlags(JNIEnv* env, jobject paint, jint flags) {
NPE_CHECK_RETURN_VOID(env, paint);
- SkPaint* nativePaint = GraphicsJNI::getNativePaint(env, paint);
+ Paint* nativePaint = GraphicsJNI::getNativePaint(env, paint);
// Instead of modifying 0x02, change the filter level.
nativePaint->setFilterLevel(flags & sFilterBitmapFlag
- ? SkPaint::kLow_FilterLevel
- : SkPaint::kNone_FilterLevel);
+ ? Paint::kLow_FilterLevel
+ : Paint::kNone_FilterLevel);
// Don't pass through filter flag, which is no longer stored in paint's flags.
flags &= ~sFilterBitmapFlag;
// Use the existing value for 0x02.
@@ -137,13 +138,13 @@
static jint getHinting(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
return GraphicsJNI::getNativePaint(env, paint)->getHinting()
- == SkPaint::kNo_Hinting ? 0 : 1;
+ == Paint::kNo_Hinting ? 0 : 1;
}
static void setHinting(JNIEnv* env, jobject paint, jint mode) {
NPE_CHECK_RETURN_VOID(env, paint);
GraphicsJNI::getNativePaint(env, paint)->setHinting(
- mode == 0 ? SkPaint::kNo_Hinting : SkPaint::kNormal_Hinting);
+ mode == 0 ? Paint::kNo_Hinting : Paint::kNormal_Hinting);
}
static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
@@ -179,7 +180,7 @@
static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
NPE_CHECK_RETURN_VOID(env, paint);
GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
- filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
+ filterBitmap ? Paint::kLow_FilterLevel : Paint::kNone_FilterLevel);
}
static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
@@ -188,13 +189,13 @@
}
static jint getStyle(JNIEnv* env, jobject clazz,jlong objHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
return static_cast<jint>(obj->getStyle());
}
static void setStyle(JNIEnv* env, jobject clazz, jlong objHandle, jint styleHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
- SkPaint::Style style = static_cast<SkPaint::Style>(styleHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
+ Paint::Style style = static_cast<Paint::Style>(styleHandle);
obj->setStyle(style);
}
@@ -243,83 +244,83 @@
}
static jint getStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
return static_cast<jint>(obj->getStrokeCap());
}
static void setStrokeCap(JNIEnv* env, jobject clazz, jlong objHandle, jint capHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
- SkPaint::Cap cap = static_cast<SkPaint::Cap>(capHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
+ Paint::Cap cap = static_cast<Paint::Cap>(capHandle);
obj->setStrokeCap(cap);
}
static jint getStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
return static_cast<jint>(obj->getStrokeJoin());
}
static void setStrokeJoin(JNIEnv* env, jobject clazz, jlong objHandle, jint joinHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
- SkPaint::Join join = (SkPaint::Join) joinHandle;
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
+ Paint::Join join = (Paint::Join) joinHandle;
obj->setStrokeJoin(join);
}
static jboolean getFillPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong dstHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE;
}
static jlong setShader(JNIEnv* env, jobject clazz, jlong objHandle, jlong shaderHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
return reinterpret_cast<jlong>(obj->setShader(shader));
}
static jlong setColorFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong filterHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint *>(objHandle);
+ Paint* obj = reinterpret_cast<Paint *>(objHandle);
SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(filterHandle);
return reinterpret_cast<jlong>(obj->setColorFilter(filter));
}
static jlong setXfermode(JNIEnv* env, jobject clazz, jlong objHandle, jlong xfermodeHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
SkXfermode* xfermode = reinterpret_cast<SkXfermode*>(xfermodeHandle);
return reinterpret_cast<jlong>(obj->setXfermode(xfermode));
}
static jlong setPathEffect(JNIEnv* env, jobject clazz, jlong objHandle, jlong effectHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
SkPathEffect* effect = reinterpret_cast<SkPathEffect*>(effectHandle);
return reinterpret_cast<jlong>(obj->setPathEffect(effect));
}
static jlong setMaskFilter(JNIEnv* env, jobject clazz, jlong objHandle, jlong maskfilterHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
SkMaskFilter* maskfilter = reinterpret_cast<SkMaskFilter*>(maskfilterHandle);
return reinterpret_cast<jlong>(obj->setMaskFilter(maskfilter));
}
static jlong setTypeface(JNIEnv* env, jobject clazz, jlong objHandle, jlong typefaceHandle) {
- // TODO: in Paint refactoring, set typeface on android Paint, not SkPaint
+ // TODO: in Paint refactoring, set typeface on android Paint, not Paint
return NULL;
}
static jlong setRasterizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong rasterizerHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
SkAutoTUnref<SkRasterizer> rasterizer(GraphicsJNI::refNativeRasterizer(rasterizerHandle));
return reinterpret_cast<jlong>(obj->setRasterizer(rasterizer));
}
static jint getTextAlign(JNIEnv* env, jobject clazz, jlong objHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
return static_cast<jint>(obj->getTextAlign());
}
static void setTextAlign(JNIEnv* env, jobject clazz, jlong objHandle, jint alignHandle) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
- SkPaint::Align align = static_cast<SkPaint::Align>(alignHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
+ Paint::Align align = static_cast<Paint::Align>(alignHandle);
obj->setTextAlign(align);
}
@@ -364,7 +365,7 @@
}
static void setTextLocale(JNIEnv* env, jobject clazz, jlong objHandle, jstring locale) {
- SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
+ Paint* obj = reinterpret_cast<Paint*>(objHandle);
ScopedUtfChars localeChars(env, locale);
char langTag[ULOC_FULLNAME_CAPACITY];
toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
@@ -376,14 +377,14 @@
static jboolean isElegantTextHeight(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- SkPaint* obj = GraphicsJNI::getNativePaint(env, paint);
+ Paint* obj = GraphicsJNI::getNativePaint(env, paint);
SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
return paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant;
}
static void setElegantTextHeight(JNIEnv* env, jobject paint, jboolean aa) {
NPE_CHECK_RETURN_VOID(env, paint);
- SkPaint* obj = GraphicsJNI::getNativePaint(env, paint);
+ Paint* obj = GraphicsJNI::getNativePaint(env, paint);
SkPaintOptionsAndroid::FontVariant variant =
aa ? SkPaintOptionsAndroid::kElegant_Variant :
SkPaintOptionsAndroid::kDefault_Variant;
@@ -422,13 +423,13 @@
GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
}
- static SkScalar getMetricsInternal(JNIEnv* env, jobject jpaint, SkPaint::FontMetrics *metrics) {
+ static SkScalar getMetricsInternal(JNIEnv* env, jobject jpaint, Paint::FontMetrics *metrics) {
const int kElegantTop = 2500;
const int kElegantBottom = -1000;
const int kElegantAscent = 1900;
const int kElegantDescent = -500;
const int kElegantLeading = 0;
- SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+ Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
typeface = TypefaceImpl_resolveDefault(typeface);
FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle);
@@ -456,21 +457,21 @@
static jfloat ascent(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- SkPaint::FontMetrics metrics;
+ Paint::FontMetrics metrics;
getMetricsInternal(env, paint, &metrics);
return SkScalarToFloat(metrics.fAscent);
}
static jfloat descent(JNIEnv* env, jobject paint) {
NPE_CHECK_RETURN_ZERO(env, paint);
- SkPaint::FontMetrics metrics;
+ Paint::FontMetrics metrics;
getMetricsInternal(env, paint, &metrics);
return SkScalarToFloat(metrics.fDescent);
}
static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
NPE_CHECK_RETURN_ZERO(env, paint);
- SkPaint::FontMetrics metrics;
+ Paint::FontMetrics metrics;
SkScalar spacing = getMetricsInternal(env, paint, &metrics);
if (metricsObj) {
@@ -486,7 +487,7 @@
static jint getFontMetricsInt(JNIEnv* env, jobject paint, jobject metricsObj) {
NPE_CHECK_RETURN_ZERO(env, paint);
- SkPaint::FontMetrics metrics;
+ Paint::FontMetrics metrics;
getMetricsInternal(env, paint, &metrics);
int ascent = SkScalarRoundToInt(metrics.fAscent);
@@ -518,7 +519,7 @@
return 0;
}
- SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+ Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
const jchar* textArray = env->GetCharArrayElements(text, NULL);
jfloat result = 0;
@@ -547,7 +548,7 @@
}
const jchar* textArray = env->GetStringChars(text, NULL);
- SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+ Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
jfloat width = 0;
Layout layout;
@@ -570,7 +571,7 @@
}
const jchar* textArray = env->GetStringChars(text, NULL);
- SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+ Paint* paint = GraphicsJNI::getNativePaint(env, jpaint);
jfloat width = 0;
Layout layout;
@@ -583,7 +584,7 @@
return width;
}
- static int dotextwidths(JNIEnv* env, SkPaint* paint, TypefaceImpl* typeface, const jchar text[], int count,
+ static int dotextwidths(JNIEnv* env, Paint* paint, TypefaceImpl* typeface, const jchar text[], int count,
jfloatArray widths, jint bidiFlags) {
NPE_CHECK_RETURN_ZERO(env, paint);
NPE_CHECK_RETURN_ZERO(env, text);
@@ -614,7 +615,7 @@
static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray text,
jint index, jint count, jint bidiFlags, jfloatArray widths) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
const jchar* textArray = env->GetCharArrayElements(text, NULL);
count = dotextwidths(env, paint, typeface, textArray + index, count, widths, bidiFlags);
@@ -625,7 +626,7 @@
static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring text,
jint start, jint end, jint bidiFlags, jfloatArray widths) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
const jchar* textArray = env->GetStringChars(text, NULL);
int count = dotextwidths(env, paint, typeface, textArray + start, end - start, widths, bidiFlags);
@@ -633,7 +634,7 @@
return count;
}
- static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, TypefaceImpl* typeface, const jchar *text,
+ static jfloat doTextRunAdvances(JNIEnv *env, Paint *paint, TypefaceImpl* typeface, const jchar *text,
jint start, jint count, jint contextCount, jboolean isRtl,
jfloatArray advances, jint advancesIndex) {
NPE_CHECK_RETURN_ZERO(env, paint);
@@ -675,7 +676,7 @@
jlong typefaceHandle,
jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
jboolean isRtl, jfloatArray advances, jint advancesIndex) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
jchar* textArray = env->GetCharArrayElements(text, NULL);
jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextIndex,
@@ -688,7 +689,7 @@
jlong typefaceHandle,
jstring text, jint start, jint end, jint contextStart, jint contextEnd, jboolean isRtl,
jfloatArray advances, jint advancesIndex) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
const jchar* textArray = env->GetStringChars(text, NULL);
jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextStart,
@@ -698,7 +699,7 @@
return result;
}
- static jint doTextRunCursor(JNIEnv *env, SkPaint* paint, const jchar *text, jint start,
+ static jint doTextRunCursor(JNIEnv *env, Paint* paint, const jchar *text, jint start,
jint count, jint flags, jint offset, jint opt) {
GraphemeBreak::MoveOpt moveOpt = GraphemeBreak::MoveOpt(opt);
size_t result = GraphemeBreak::getTextRunCursor(text, start, count, offset, moveOpt);
@@ -707,7 +708,7 @@
static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
jint contextStart, jint contextCount, jint dir, jint offset, jint cursorOpt) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
jchar* textArray = env->GetCharArrayElements(text, NULL);
jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, dir,
offset, cursorOpt);
@@ -717,7 +718,7 @@
static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
jint contextStart, jint contextEnd, jint dir, jint offset, jint cursorOpt) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
const jchar* textArray = env->GetStringChars(text, NULL);
jint result = doTextRunCursor(env, paint, textArray, contextStart,
contextEnd - contextStart, dir, offset, cursorOpt);
@@ -727,7 +728,7 @@
class GetTextFunctor {
public:
- GetTextFunctor(const Layout& layout, SkPath* path, jfloat x, jfloat y, SkPaint* paint,
+ GetTextFunctor(const Layout& layout, SkPath* path, jfloat x, jfloat y, Paint* paint,
uint16_t* glyphs, SkPoint* pos)
: layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) {
}
@@ -750,13 +751,13 @@
SkPath* path;
jfloat x;
jfloat y;
- SkPaint* paint;
+ Paint* paint;
uint16_t* glyphs;
SkPoint* pos;
SkPath tmpPath;
};
- static void getTextPath(JNIEnv* env, SkPaint* paint, TypefaceImpl* typeface, const jchar* text,
+ static void getTextPath(JNIEnv* env, Paint* paint, TypefaceImpl* typeface, const jchar* text,
jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) {
Layout layout;
std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
@@ -766,9 +767,9 @@
SkPoint* pos = new SkPoint[nGlyphs];
x += MinikinUtils::xOffsetForTextAlign(paint, layout);
- SkPaint::Align align = paint->getTextAlign();
- paint->setTextAlign(SkPaint::kLeft_Align);
- paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ Paint::Align align = paint->getTextAlign();
+ paint->setTextAlign(Paint::kLeft_Align);
+ paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
GetTextFunctor f(layout, path, x, y, paint, glyphs, pos);
MinikinUtils::forFontRun(layout, paint, f);
paint->setTextAlign(align);
@@ -779,7 +780,7 @@
static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle,
jlong typefaceHandle, jint bidiFlags,
jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
const jchar* textArray = env->GetCharArrayElements(text, NULL);
@@ -790,7 +791,7 @@
static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle,
jlong typefaceHandle, jint bidiFlags,
jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
const jchar* textArray = env->GetStringChars(text, NULL);
@@ -800,7 +801,7 @@
static void setShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle, jfloat radius,
jfloat dx, jfloat dy, jint color) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
if (radius <= 0) {
paint->setLooper(NULL);
}
@@ -811,13 +812,13 @@
}
static jboolean hasShadowLayer(JNIEnv* env, jobject clazz, jlong paintHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
return paint->getLooper() && paint->getLooper()->asABlurShadow(NULL);
}
- static int breakText(JNIEnv* env, const SkPaint& paint, TypefaceImpl* typeface, const jchar text[],
+ static int breakText(JNIEnv* env, const Paint& paint, TypefaceImpl* typeface, const jchar text[],
int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured,
- SkPaint::TextBufferDirection textBufferDirection) {
+ Paint::TextBufferDirection textBufferDirection) {
size_t measuredCount = 0;
float measured = 0;
@@ -826,7 +827,7 @@
layout.doLayout(text, 0, count, count, css);
float* advances = new float[count];
layout.getAdvances(advances);
- const bool forwardScan = (textBufferDirection == SkPaint::kForward_TextBufferDirection);
+ const bool forwardScan = (textBufferDirection == Paint::kForward_TextBufferDirection);
for (int i = 0; i < count; i++) {
// traverse in the given direction
int index = forwardScan ? i : (count - i - 1);
@@ -854,16 +855,16 @@
jint index, jint count, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
NPE_CHECK_RETURN_ZERO(env, jtext);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
- SkPaint::TextBufferDirection tbd;
+ Paint::TextBufferDirection tbd;
if (count < 0) {
- tbd = SkPaint::kBackward_TextBufferDirection;
+ tbd = Paint::kBackward_TextBufferDirection;
count = -count;
}
else {
- tbd = SkPaint::kForward_TextBufferDirection;
+ tbd = Paint::kForward_TextBufferDirection;
}
if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
@@ -883,12 +884,12 @@
jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
NPE_CHECK_RETURN_ZERO(env, jtext);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
- SkPaint::TextBufferDirection tbd = forwards ?
- SkPaint::kForward_TextBufferDirection :
- SkPaint::kBackward_TextBufferDirection;
+ Paint::TextBufferDirection tbd = forwards ?
+ Paint::kForward_TextBufferDirection :
+ Paint::kBackward_TextBufferDirection;
int count = env->GetStringLength(jtext);
const jchar* text = env->GetStringChars(jtext, NULL);
@@ -898,7 +899,7 @@
}
static void doTextBounds(JNIEnv* env, const jchar* text, int count, jobject bounds,
- const SkPaint& paint, TypefaceImpl* typeface, jint bidiFlags) {
+ const Paint& paint, TypefaceImpl* typeface, jint bidiFlags) {
SkRect r;
SkIRect ir;
@@ -917,7 +918,7 @@
static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle,
jstring text, jint start, jint end, jint bidiFlags, jobject bounds) {
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);;
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);;
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
const jchar* textArray = env->GetStringChars(text, NULL);
doTextBounds(env, textArray + start, end - start, bounds, *paint, typeface, bidiFlags);
@@ -926,7 +927,7 @@
static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle,
jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) {
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
const jchar* textArray = env->GetCharArrayElements(text, NULL);
doTextBounds(env, textArray + index, count, bounds, *paint, typeface, bidiFlags);
@@ -937,83 +938,83 @@
};
static JNINativeMethod methods[] = {
- {"finalizer", "(J)V", (void*) SkPaintGlue::finalizer},
- {"native_init","()J", (void*) SkPaintGlue::init},
- {"native_initWithPaint","(J)J", (void*) SkPaintGlue::initWithPaint},
- {"native_reset","(J)V", (void*) SkPaintGlue::reset},
- {"native_set","(JJ)V", (void*) SkPaintGlue::assign},
- {"getFlags","()I", (void*) SkPaintGlue::getFlags},
- {"setFlags","(I)V", (void*) SkPaintGlue::setFlags},
- {"getHinting","()I", (void*) SkPaintGlue::getHinting},
- {"setHinting","(I)V", (void*) SkPaintGlue::setHinting},
- {"setAntiAlias","(Z)V", (void*) SkPaintGlue::setAntiAlias},
- {"setSubpixelText","(Z)V", (void*) SkPaintGlue::setSubpixelText},
- {"setLinearText","(Z)V", (void*) SkPaintGlue::setLinearText},
- {"setUnderlineText","(Z)V", (void*) SkPaintGlue::setUnderlineText},
- {"setStrikeThruText","(Z)V", (void*) SkPaintGlue::setStrikeThruText},
- {"setFakeBoldText","(Z)V", (void*) SkPaintGlue::setFakeBoldText},
- {"setFilterBitmap","(Z)V", (void*) SkPaintGlue::setFilterBitmap},
- {"setDither","(Z)V", (void*) SkPaintGlue::setDither},
- {"native_getStyle","(J)I", (void*) SkPaintGlue::getStyle},
- {"native_setStyle","(JI)V", (void*) SkPaintGlue::setStyle},
- {"getColor","()I", (void*) SkPaintGlue::getColor},
- {"setColor","(I)V", (void*) SkPaintGlue::setColor},
- {"getAlpha","()I", (void*) SkPaintGlue::getAlpha},
- {"setAlpha","(I)V", (void*) SkPaintGlue::setAlpha},
- {"getStrokeWidth","()F", (void*) SkPaintGlue::getStrokeWidth},
- {"setStrokeWidth","(F)V", (void*) SkPaintGlue::setStrokeWidth},
- {"getStrokeMiter","()F", (void*) SkPaintGlue::getStrokeMiter},
- {"setStrokeMiter","(F)V", (void*) SkPaintGlue::setStrokeMiter},
- {"native_getStrokeCap","(J)I", (void*) SkPaintGlue::getStrokeCap},
- {"native_setStrokeCap","(JI)V", (void*) SkPaintGlue::setStrokeCap},
- {"native_getStrokeJoin","(J)I", (void*) SkPaintGlue::getStrokeJoin},
- {"native_setStrokeJoin","(JI)V", (void*) SkPaintGlue::setStrokeJoin},
- {"native_getFillPath","(JJJ)Z", (void*) SkPaintGlue::getFillPath},
- {"native_setShader","(JJ)J", (void*) SkPaintGlue::setShader},
- {"native_setColorFilter","(JJ)J", (void*) SkPaintGlue::setColorFilter},
- {"native_setXfermode","(JJ)J", (void*) SkPaintGlue::setXfermode},
- {"native_setPathEffect","(JJ)J", (void*) SkPaintGlue::setPathEffect},
- {"native_setMaskFilter","(JJ)J", (void*) SkPaintGlue::setMaskFilter},
- {"native_setTypeface","(JJ)J", (void*) SkPaintGlue::setTypeface},
- {"native_setRasterizer","(JJ)J", (void*) SkPaintGlue::setRasterizer},
- {"native_getTextAlign","(J)I", (void*) SkPaintGlue::getTextAlign},
- {"native_setTextAlign","(JI)V", (void*) SkPaintGlue::setTextAlign},
- {"native_setTextLocale","(JLjava/lang/String;)V", (void*) SkPaintGlue::setTextLocale},
- {"isElegantTextHeight","()Z", (void*) SkPaintGlue::isElegantTextHeight},
- {"setElegantTextHeight","(Z)V", (void*) SkPaintGlue::setElegantTextHeight},
- {"getTextSize","()F", (void*) SkPaintGlue::getTextSize},
- {"setTextSize","(F)V", (void*) SkPaintGlue::setTextSize},
- {"getTextScaleX","()F", (void*) SkPaintGlue::getTextScaleX},
- {"setTextScaleX","(F)V", (void*) SkPaintGlue::setTextScaleX},
- {"getTextSkewX","()F", (void*) SkPaintGlue::getTextSkewX},
- {"setTextSkewX","(F)V", (void*) SkPaintGlue::setTextSkewX},
- {"ascent","()F", (void*) SkPaintGlue::ascent},
- {"descent","()F", (void*) SkPaintGlue::descent},
- {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)SkPaintGlue::getFontMetrics},
- {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)SkPaintGlue::getFontMetricsInt},
- {"native_measureText","([CIII)F", (void*) SkPaintGlue::measureText_CIII},
- {"native_measureText","(Ljava/lang/String;I)F", (void*) SkPaintGlue::measureText_StringI},
- {"native_measureText","(Ljava/lang/String;III)F", (void*) SkPaintGlue::measureText_StringIII},
- {"native_breakText","(JJ[CIIFI[F)I", (void*) SkPaintGlue::breakTextC},
- {"native_breakText","(JJLjava/lang/String;ZFI[F)I", (void*) SkPaintGlue::breakTextS},
- {"native_getTextWidths","(JJ[CIII[F)I", (void*) SkPaintGlue::getTextWidths___CIII_F},
- {"native_getTextWidths","(JJLjava/lang/String;III[F)I", (void*) SkPaintGlue::getTextWidths__StringIII_F},
+ {"finalizer", "(J)V", (void*) PaintGlue::finalizer},
+ {"native_init","()J", (void*) PaintGlue::init},
+ {"native_initWithPaint","(J)J", (void*) PaintGlue::initWithPaint},
+ {"native_reset","(J)V", (void*) PaintGlue::reset},
+ {"native_set","(JJ)V", (void*) PaintGlue::assign},
+ {"getFlags","()I", (void*) PaintGlue::getFlags},
+ {"setFlags","(I)V", (void*) PaintGlue::setFlags},
+ {"getHinting","()I", (void*) PaintGlue::getHinting},
+ {"setHinting","(I)V", (void*) PaintGlue::setHinting},
+ {"setAntiAlias","(Z)V", (void*) PaintGlue::setAntiAlias},
+ {"setSubpixelText","(Z)V", (void*) PaintGlue::setSubpixelText},
+ {"setLinearText","(Z)V", (void*) PaintGlue::setLinearText},
+ {"setUnderlineText","(Z)V", (void*) PaintGlue::setUnderlineText},
+ {"setStrikeThruText","(Z)V", (void*) PaintGlue::setStrikeThruText},
+ {"setFakeBoldText","(Z)V", (void*) PaintGlue::setFakeBoldText},
+ {"setFilterBitmap","(Z)V", (void*) PaintGlue::setFilterBitmap},
+ {"setDither","(Z)V", (void*) PaintGlue::setDither},
+ {"native_getStyle","(J)I", (void*) PaintGlue::getStyle},
+ {"native_setStyle","(JI)V", (void*) PaintGlue::setStyle},
+ {"getColor","()I", (void*) PaintGlue::getColor},
+ {"setColor","(I)V", (void*) PaintGlue::setColor},
+ {"getAlpha","()I", (void*) PaintGlue::getAlpha},
+ {"setAlpha","(I)V", (void*) PaintGlue::setAlpha},
+ {"getStrokeWidth","()F", (void*) PaintGlue::getStrokeWidth},
+ {"setStrokeWidth","(F)V", (void*) PaintGlue::setStrokeWidth},
+ {"getStrokeMiter","()F", (void*) PaintGlue::getStrokeMiter},
+ {"setStrokeMiter","(F)V", (void*) PaintGlue::setStrokeMiter},
+ {"native_getStrokeCap","(J)I", (void*) PaintGlue::getStrokeCap},
+ {"native_setStrokeCap","(JI)V", (void*) PaintGlue::setStrokeCap},
+ {"native_getStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin},
+ {"native_setStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin},
+ {"native_getFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath},
+ {"native_setShader","(JJ)J", (void*) PaintGlue::setShader},
+ {"native_setColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter},
+ {"native_setXfermode","(JJ)J", (void*) PaintGlue::setXfermode},
+ {"native_setPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect},
+ {"native_setMaskFilter","(JJ)J", (void*) PaintGlue::setMaskFilter},
+ {"native_setTypeface","(JJ)J", (void*) PaintGlue::setTypeface},
+ {"native_setRasterizer","(JJ)J", (void*) PaintGlue::setRasterizer},
+ {"native_getTextAlign","(J)I", (void*) PaintGlue::getTextAlign},
+ {"native_setTextAlign","(JI)V", (void*) PaintGlue::setTextAlign},
+ {"native_setTextLocale","(JLjava/lang/String;)V", (void*) PaintGlue::setTextLocale},
+ {"isElegantTextHeight","()Z", (void*) PaintGlue::isElegantTextHeight},
+ {"setElegantTextHeight","(Z)V", (void*) PaintGlue::setElegantTextHeight},
+ {"getTextSize","()F", (void*) PaintGlue::getTextSize},
+ {"setTextSize","(F)V", (void*) PaintGlue::setTextSize},
+ {"getTextScaleX","()F", (void*) PaintGlue::getTextScaleX},
+ {"setTextScaleX","(F)V", (void*) PaintGlue::setTextScaleX},
+ {"getTextSkewX","()F", (void*) PaintGlue::getTextSkewX},
+ {"setTextSkewX","(F)V", (void*) PaintGlue::setTextSkewX},
+ {"ascent","()F", (void*) PaintGlue::ascent},
+ {"descent","()F", (void*) PaintGlue::descent},
+ {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)PaintGlue::getFontMetrics},
+ {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)PaintGlue::getFontMetricsInt},
+ {"native_measureText","([CIII)F", (void*) PaintGlue::measureText_CIII},
+ {"native_measureText","(Ljava/lang/String;I)F", (void*) PaintGlue::measureText_StringI},
+ {"native_measureText","(Ljava/lang/String;III)F", (void*) PaintGlue::measureText_StringIII},
+ {"native_breakText","(JJ[CIIFI[F)I", (void*) PaintGlue::breakTextC},
+ {"native_breakText","(JJLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS},
+ {"native_getTextWidths","(JJ[CIII[F)I", (void*) PaintGlue::getTextWidths___CIII_F},
+ {"native_getTextWidths","(JJLjava/lang/String;III[F)I", (void*) PaintGlue::getTextWidths__StringIII_F},
{"native_getTextRunAdvances","(JJ[CIIIIZ[FI)F",
- (void*) SkPaintGlue::getTextRunAdvances___CIIIIZ_FI},
+ (void*) PaintGlue::getTextRunAdvances___CIIIIZ_FI},
{"native_getTextRunAdvances","(JJLjava/lang/String;IIIIZ[FI)F",
- (void*) SkPaintGlue::getTextRunAdvances__StringIIIIZ_FI},
+ (void*) PaintGlue::getTextRunAdvances__StringIIIIZ_FI},
- {"native_getTextRunCursor", "(J[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C},
+ {"native_getTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C},
{"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I",
- (void*) SkPaintGlue::getTextRunCursor__String},
- {"native_getTextPath","(JJI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C},
- {"native_getTextPath","(JJILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String},
+ (void*) PaintGlue::getTextRunCursor__String},
+ {"native_getTextPath","(JJI[CIIFFJ)V", (void*) PaintGlue::getTextPath___C},
+ {"native_getTextPath","(JJILjava/lang/String;IIFFJ)V", (void*) PaintGlue::getTextPath__String},
{"nativeGetStringBounds", "(JJLjava/lang/String;IIILandroid/graphics/Rect;)V",
- (void*) SkPaintGlue::getStringBounds },
+ (void*) PaintGlue::getStringBounds },
{"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V",
- (void*) SkPaintGlue::getCharArrayBounds },
- {"native_setShadowLayer", "(JFFFI)V", (void*)SkPaintGlue::setShadowLayer},
- {"native_hasShadowLayer", "(J)Z", (void*)SkPaintGlue::hasShadowLayer}
+ (void*) PaintGlue::getCharArrayBounds },
+ {"native_setShadowLayer", "(JFFFI)V", (void*)PaintGlue::setShadowLayer},
+ {"native_hasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer}
};
static jfieldID req_fieldID(jfieldID id) {
diff --git a/core/jni/android/graphics/Paint.h b/core/jni/android/graphics/Paint.h
new file mode 100644
index 0000000..239b217
--- /dev/null
+++ b/core/jni/android/graphics/Paint.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_GRAPHICS_PAINT_H
+#define ANDROID_GRAPHICS_PAINT_H
+
+#include <SkPaint.h>
+
+namespace android {
+
+class Paint : public SkPaint {
+public:
+ Paint();
+ Paint(const Paint& paint);
+ ~Paint();
+
+ Paint& operator=(const Paint& other);
+
+ friend bool operator==(const Paint& a, const Paint& b);
+ friend bool operator!=(const Paint& a, const Paint& b) {
+ return !(a == b);
+ }
+
+private:
+};
+
+} // namespace android
+
+#endif // ANDROID_GRAPHICS_PAINT_H
diff --git a/core/jni/android/graphics/PaintImpl.cpp b/core/jni/android/graphics/PaintImpl.cpp
new file mode 100644
index 0000000..6baae76
--- /dev/null
+++ b/core/jni/android/graphics/PaintImpl.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Paint.h"
+#include <SkPaint.h>
+
+#define LOG_TAG "Paint"
+#include <cutils/log.h>
+
+namespace android {
+
+Paint::Paint() : SkPaint() {
+}
+
+Paint::Paint(const Paint& paint) : SkPaint(paint) {
+}
+
+Paint::~Paint() {
+}
+
+Paint& Paint::operator=(const Paint& other) {
+ SkPaint::operator=(other);
+ return *this;
+}
+
+bool operator==(const Paint& a, const Paint& b) {
+ return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b);
+}
+
+}
diff --git a/core/jni/android/graphics/Rasterizer.cpp b/core/jni/android/graphics/Rasterizer.cpp
index a05d19b..2b1aca1 100644
--- a/core/jni/android/graphics/Rasterizer.cpp
+++ b/core/jni/android/graphics/Rasterizer.cpp
@@ -22,6 +22,7 @@
#include "jni.h"
#include "GraphicsJNI.h"
+#include "Paint.h"
#include "SkLayerRasterizer.h"
#include <android_runtime/AndroidRuntime.h>
@@ -79,7 +80,7 @@
static void addLayer(JNIEnv* env, jobject, jlong layerHandle, jlong paintHandle, jfloat dx, jfloat dy) {
NativeLayerRasterizer* nr = reinterpret_cast<NativeLayerRasterizer *>(layerHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint *>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint *>(paintHandle);
SkASSERT(nr);
SkASSERT(paint);
nr->fBuilder.addLayer(*paint, dx, dy);
diff --git a/core/jni/android/graphics/SkiaCanvas.cpp b/core/jni/android/graphics/SkiaCanvas.cpp
index a4e0d28..f87033b 100644
--- a/core/jni/android/graphics/SkiaCanvas.cpp
+++ b/core/jni/android/graphics/SkiaCanvas.cpp
@@ -34,6 +34,7 @@
#include "MinikinSkia.h"
#include "MinikinUtils.h"
+#include "Paint.h"
#include "TypefaceImpl.h"
#include "unicode/ubidi.h"
@@ -68,7 +69,7 @@
virtual void restoreToCount(int saveCount);
virtual int saveLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, SkCanvas::SaveFlags flags);
+ const Paint* paint, SkCanvas::SaveFlags flags);
virtual int saveLayerAlpha(float left, float top, float right, float bottom,
int alpha, SkCanvas::SaveFlags flags);
@@ -90,39 +91,39 @@
virtual void setDrawFilter(SkDrawFilter* drawFilter);
virtual void drawColor(int color, SkXfermode::Mode mode);
- virtual void drawPaint(const SkPaint& paint);
+ virtual void drawPaint(const Paint& paint);
- virtual void drawPoint(float x, float y, const SkPaint& paint);
- virtual void drawPoints(const float* points, int count, const SkPaint& paint);
+ virtual void drawPoint(float x, float y, const Paint& paint);
+ virtual void drawPoints(const float* points, int count, const Paint& paint);
virtual void drawLine(float startX, float startY, float stopX, float stopY,
- const SkPaint& paint);
- virtual void drawLines(const float* points, int count, const SkPaint& paint);
- virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint);
+ const Paint& paint);
+ virtual void drawLines(const float* points, int count, const Paint& paint);
+ virtual void drawRect(float left, float top, float right, float bottom, const Paint& paint);
virtual void drawRoundRect(float left, float top, float right, float bottom,
- float rx, float ry, const SkPaint& paint);
- virtual void drawCircle(float x, float y, float radius, const SkPaint& paint);
- virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint);
+ float rx, float ry, const Paint& paint);
+ virtual void drawCircle(float x, float y, float radius, const Paint& paint);
+ virtual void drawOval(float left, float top, float right, float bottom, const Paint& paint);
virtual void drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint);
- virtual void drawPath(const SkPath& path, const SkPaint& paint);
+ float startAngle, float sweepAngle, bool useCenter, const Paint& paint);
+ virtual void drawPath(const SkPath& path, const Paint& paint);
virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
const float* verts, const float* tex, const int* colors,
- const uint16_t* indices, int indexCount, const SkPaint& paint);
+ const uint16_t* indices, int indexCount, const Paint& paint);
- virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint);
- virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint);
+ virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const Paint* paint);
+ virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, const Paint* paint);
virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint);
+ float dstRight, float dstBottom, const Paint* paint);
virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
- const float* vertices, const int* colors, const SkPaint* paint);
+ const float* vertices, const int* colors, const Paint* paint);
virtual void drawText(const uint16_t* text, int start, int count, int contextCount,
- float x, float y, int bidiFlags, const SkPaint& paint, TypefaceImpl* typeface);
+ float x, float y, int bidiFlags, const Paint& paint, TypefaceImpl* typeface);
virtual void drawPosText(const uint16_t* text, const float* positions, int count,
- int posCount, const SkPaint& paint);
+ int posCount, const Paint& paint);
virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
- float hOffset, float vOffset, const SkPaint& paint);
+ float hOffset, float vOffset, const Paint& paint);
private:
struct SaveRec {
@@ -134,9 +135,9 @@
void saveClipsForFrame(SkTArray<SkClipStack::Element>& clips, int frameSaveCount);
void applyClips(const SkTArray<SkClipStack::Element>& clips);
- void drawPoints(const float* points, int count, const SkPaint& paint,
+ void drawPoints(const float* points, int count, const Paint& paint,
SkCanvas::PointMode mode);
- void drawTextDecorations(float x, float y, float length, const SkPaint& paint);
+ void drawTextDecorations(float x, float y, float length, const Paint& paint);
SkAutoTUnref<SkCanvas> mCanvas;
SkAutoTDelete<SkDeque> mSaveStack; // lazily allocated, tracks partial saves.
@@ -284,7 +285,7 @@
}
int SkiaCanvas::saveLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, SkCanvas::SaveFlags flags) {
+ const Paint* paint, SkCanvas::SaveFlags flags) {
SkRect bounds = SkRect::MakeLTRB(left, top, right, bottom);
int count = mCanvas->saveLayer(&bounds, paint, flags | SkCanvas::kMatrixClip_SaveFlag);
recordPartialSave(flags);
@@ -466,7 +467,7 @@
mCanvas->drawColor(color, mode);
}
-void SkiaCanvas::drawPaint(const SkPaint& paint) {
+void SkiaCanvas::drawPaint(const Paint& paint) {
mCanvas->drawPaint(paint);
}
@@ -474,7 +475,7 @@
// Canvas draw operations: Geometry
// ----------------------------------------------------------------------------
-void SkiaCanvas::drawPoints(const float* points, int count, const SkPaint& paint,
+void SkiaCanvas::drawPoints(const float* points, int count, const Paint& paint,
SkCanvas::PointMode mode) {
// convert the floats into SkPoints
count >>= 1; // now it is the number of points
@@ -488,57 +489,57 @@
}
-void SkiaCanvas::drawPoint(float x, float y, const SkPaint& paint) {
+void SkiaCanvas::drawPoint(float x, float y, const Paint& paint) {
mCanvas->drawPoint(x, y, paint);
}
-void SkiaCanvas::drawPoints(const float* points, int count, const SkPaint& paint) {
+void SkiaCanvas::drawPoints(const float* points, int count, const Paint& paint) {
this->drawPoints(points, count, paint, SkCanvas::kPoints_PointMode);
}
void SkiaCanvas::drawLine(float startX, float startY, float stopX, float stopY,
- const SkPaint& paint) {
+ const Paint& paint) {
mCanvas->drawLine(startX, startY, stopX, stopY, paint);
}
-void SkiaCanvas::drawLines(const float* points, int count, const SkPaint& paint) {
+void SkiaCanvas::drawLines(const float* points, int count, const Paint& paint) {
this->drawPoints(points, count, paint, SkCanvas::kLines_PointMode);
}
void SkiaCanvas::drawRect(float left, float top, float right, float bottom,
- const SkPaint& paint) {
+ const Paint& paint) {
mCanvas->drawRectCoords(left, top, right, bottom, paint);
}
void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom,
- float rx, float ry, const SkPaint& paint) {
+ float rx, float ry, const Paint& paint) {
SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
mCanvas->drawRoundRect(rect, rx, ry, paint);
}
-void SkiaCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
+void SkiaCanvas::drawCircle(float x, float y, float radius, const Paint& paint) {
mCanvas->drawCircle(x, y, radius, paint);
}
-void SkiaCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) {
+void SkiaCanvas::drawOval(float left, float top, float right, float bottom, const Paint& paint) {
SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
mCanvas->drawOval(oval, paint);
}
void SkiaCanvas::drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
+ float startAngle, float sweepAngle, bool useCenter, const Paint& paint) {
SkRect arc = SkRect::MakeLTRB(left, top, right, bottom);
mCanvas->drawArc(arc, startAngle, sweepAngle, useCenter, paint);
}
-void SkiaCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
+void SkiaCanvas::drawPath(const SkPath& path, const Paint& paint) {
mCanvas->drawPath(path, paint);
}
void SkiaCanvas::drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
const float* verts, const float* texs, const int* colors,
- const uint16_t* indices, int indexCount, const SkPaint& paint) {
+ const uint16_t* indices, int indexCount, const Paint& paint) {
#ifndef SK_SCALAR_IS_FLOAT
SkDEBUGFAIL("SkScalar must be a float for these conversions to be valid");
#endif
@@ -551,24 +552,24 @@
// Canvas draw operations: Bitmaps
// ----------------------------------------------------------------------------
-void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint) {
+void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top, const Paint* paint) {
mCanvas->drawBitmap(bitmap, left, top, paint);
}
-void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) {
+void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, const Paint* paint) {
mCanvas->drawBitmapMatrix(bitmap, matrix, paint);
}
void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint) {
+ float dstRight, float dstBottom, const Paint* paint) {
SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
mCanvas->drawBitmapRectToRect(bitmap, &srcRect, dstRect, paint);
}
void SkiaCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
- const float* vertices, const int* colors, const SkPaint* paint) {
+ const float* vertices, const int* colors, const Paint* paint) {
const int ptCount = (meshWidth + 1) * (meshHeight + 1);
const int indexCount = meshWidth * meshHeight * 6;
@@ -650,7 +651,7 @@
#endif
// cons-up a shader for the bitmap
- SkPaint tmpPaint;
+ Paint tmpPaint;
if (paint) {
tmpPaint = *paint;
}
@@ -670,7 +671,7 @@
class DrawTextFunctor {
public:
- DrawTextFunctor(const Layout& layout, SkCanvas* canvas, float x, float y, SkPaint* paint,
+ DrawTextFunctor(const Layout& layout, SkCanvas* canvas, float x, float y, Paint* paint,
uint16_t* glyphs, SkPoint* pos)
: layout(layout), canvas(canvas), x(x), y(y), paint(paint), glyphs(glyphs),
pos(pos) { }
@@ -688,13 +689,13 @@
SkCanvas* canvas;
float x;
float y;
- SkPaint* paint;
+ Paint* paint;
uint16_t* glyphs;
SkPoint* pos;
};
void SkiaCanvas::drawText(const uint16_t* text, int start, int count, int contextCount,
- float x, float y, int bidiFlags, const SkPaint& paint, TypefaceImpl* typeface) {
+ float x, float y, int bidiFlags, const Paint& paint, TypefaceImpl* typeface) {
Layout layout;
std::string css = MinikinUtils::setLayoutProperties(&layout, &paint, bidiFlags, typeface);
layout.doLayout(text, start, count, contextCount, css);
@@ -703,10 +704,10 @@
uint16_t* glyphs = new uint16_t[nGlyphs];
SkPoint* pos = new SkPoint[nGlyphs];
- SkPaint paintCopy(paint);
+ Paint paintCopy(paint);
x += MinikinUtils::xOffsetForTextAlign(&paintCopy, layout);
- paintCopy.setTextAlign(SkPaint::kLeft_Align);
- paintCopy.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ paintCopy.setTextAlign(Paint::kLeft_Align);
+ paintCopy.setTextEncoding(Paint::kGlyphID_TextEncoding);
DrawTextFunctor f(layout, mCanvas, x, y, &paintCopy, glyphs, pos);
MinikinUtils::forFontRun(layout, &paintCopy, f);
@@ -721,27 +722,27 @@
#define kStdUnderline_Offset (1.0f / 9.0f)
#define kStdUnderline_Thickness (1.0f / 18.0f)
-void SkiaCanvas::drawTextDecorations(float x, float y, float length, const SkPaint& paint) {
+void SkiaCanvas::drawTextDecorations(float x, float y, float length, const Paint& paint) {
uint32_t flags;
SkDrawFilter* drawFilter = mCanvas->getDrawFilter();
if (drawFilter) {
- SkPaint paintCopy(paint);
+ Paint paintCopy(paint);
drawFilter->filter(&paintCopy, SkDrawFilter::kText_Type);
flags = paintCopy.getFlags();
} else {
flags = paint.getFlags();
}
- if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
+ if (flags & (Paint::kUnderlineText_Flag | Paint::kStrikeThruText_Flag)) {
SkScalar left = x;
SkScalar right = x + length;
float textSize = paint.getTextSize();
float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f);
- if (flags & SkPaint::kUnderlineText_Flag) {
+ if (flags & Paint::kUnderlineText_Flag) {
SkScalar top = y + textSize * kStdUnderline_Offset - 0.5f * strokeWidth;
SkScalar bottom = y + textSize * kStdUnderline_Offset + 0.5f * strokeWidth;
mCanvas->drawRectCoords(left, top, right, bottom, paint);
}
- if (flags & SkPaint::kStrikeThruText_Flag) {
+ if (flags & Paint::kStrikeThruText_Flag) {
SkScalar top = y + textSize * kStdStrikeThru_Offset - 0.5f * strokeWidth;
SkScalar bottom = y + textSize * kStdStrikeThru_Offset + 0.5f * strokeWidth;
mCanvas->drawRectCoords(left, top, right, bottom, paint);
@@ -750,7 +751,7 @@
}
void SkiaCanvas::drawPosText(const uint16_t* text, const float* positions, int count, int posCount,
- const SkPaint& paint) {
+ const Paint& paint) {
SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
int indx;
for (indx = 0; indx < posCount; indx++) {
@@ -758,15 +759,15 @@
posPtr[indx].fY = positions[(indx << 1) + 1];
}
- SkPaint paintCopy(paint);
- paintCopy.setTextEncoding(SkPaint::kUTF16_TextEncoding);
+ Paint paintCopy(paint);
+ paintCopy.setTextEncoding(Paint::kUTF16_TextEncoding);
mCanvas->drawPosText(text, count, posPtr, paintCopy);
delete[] posPtr;
}
void SkiaCanvas::drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
- float hOffset, float vOffset, const SkPaint& paint) {
+ float hOffset, float vOffset, const Paint& paint) {
mCanvas->drawTextOnPathHV(glyphs, count, path, hOffset, vOffset, paint);
}
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 46eccdd..377e71c 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -21,6 +21,7 @@
#include "Canvas.h"
#include "SkGraphics.h"
#include "SkPorterDuff.h"
+#include "Paint.h"
#include "TypefaceImpl.h"
#include <minikin/Layout.h>
@@ -76,7 +77,7 @@
static jint saveLayer(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t,
jfloat r, jfloat b, jlong paintHandle, jint flagsHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
return static_cast<jint>(get_canvas(canvasHandle)->saveLayer(l, t, r, b, paint, flags));
}
@@ -191,13 +192,13 @@
}
static void drawPaint(JNIEnv* env, jobject, jlong canvasHandle, jlong paintHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawPaint(*paint);
}
static void drawPoint(JNIEnv*, jobject, jlong canvasHandle, jfloat x, jfloat y,
jlong paintHandle) {
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawPoint(x, y, *paint);
}
@@ -213,13 +214,13 @@
return;
}
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawPoints(floats + offset, count, *paint);
}
static void drawLine(JNIEnv* env, jobject, jlong canvasHandle, jfloat startX, jfloat startY,
jfloat stopX, jfloat stopY, jlong paintHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawLine(startX, startY, stopX, stopY, *paint);
}
@@ -235,38 +236,38 @@
return;
}
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawLines(floats + offset, count, *paint);
}
static void drawRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
jfloat right, jfloat bottom, jlong paintHandle) {
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawRect(left, top, right, bottom, *paint);
}
static void drawRoundRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
jfloat right, jfloat bottom, jfloat rx, jfloat ry, jlong paintHandle) {
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawRoundRect(left, top, right, bottom, rx, ry, *paint);
}
static void drawCircle(JNIEnv* env, jobject, jlong canvasHandle, jfloat cx, jfloat cy,
jfloat radius, jlong paintHandle) {
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawCircle(cx, cy, radius, *paint);
}
static void drawOval(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
jfloat right, jfloat bottom, jlong paintHandle) {
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawOval(left, top, right, bottom, *paint);
}
static void drawArc(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle,
jboolean useCenter, jlong paintHandle) {
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawArc(left, top, right, bottom, startAngle, sweepAngle,
useCenter, *paint);
}
@@ -274,7 +275,7 @@
static void drawPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
jlong paintHandle) {
const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawPath(*path, *paint);
}
@@ -303,7 +304,7 @@
}
SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawVertices(mode, vertexCount, verts, texs, colors,
indices, indexCount, *paint);
}
@@ -313,15 +314,15 @@
jint screenDensity, jint bitmapDensity) {
Canvas* canvas = get_canvas(canvasHandle);
const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
if (canvasDensity == bitmapDensity || canvasDensity == 0 || bitmapDensity == 0) {
if (screenDensity != 0 && screenDensity != bitmapDensity) {
- SkPaint filteredPaint;
+ Paint filteredPaint;
if (paint) {
filteredPaint = *paint;
}
- filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
+ filteredPaint.setFilterLevel(Paint::kLow_FilterLevel);
canvas->drawBitmap(*bitmap, left, top, &filteredPaint);
} else {
canvas->drawBitmap(*bitmap, left, top, paint);
@@ -332,11 +333,11 @@
canvas->translate(left, top);
canvas->scale(scale, scale);
- SkPaint filteredPaint;
+ Paint filteredPaint;
if (paint) {
filteredPaint = *paint;
}
- filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
+ filteredPaint.setFilterLevel(Paint::kLow_FilterLevel);
canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
canvas->restore();
@@ -347,7 +348,7 @@
jlong matrixHandle, jlong paintHandle) {
const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawBitmap(*bitmap, *matrix, paint);
}
@@ -357,14 +358,14 @@
jlong paintHandle, jint screenDensity, jint bitmapDensity) {
Canvas* canvas = get_canvas(canvasHandle);
const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
if (screenDensity != 0 && screenDensity != bitmapDensity) {
- SkPaint filteredPaint;
+ Paint filteredPaint;
if (paint) {
filteredPaint = *paint;
}
- filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
+ filteredPaint.setFilterLevel(Paint::kLow_FilterLevel);
canvas->drawBitmap(*bitmap, srcLeft, srcTop, srcRight, srcBottom,
dstLeft, dstTop, dstRight, dstBottom, &filteredPaint);
} else {
@@ -391,7 +392,7 @@
return;
}
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawBitmap(bitmap, x, y, paint);
}
@@ -403,7 +404,7 @@
AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount);
const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawBitmapMesh(*bitmap, meshWidth, meshHeight,
vertA.ptr(), colorA.ptr(), paint);
}
@@ -411,7 +412,7 @@
static void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
jint index, jint count, jfloat x, jfloat y, jint bidiFlags,
jlong paintHandle, jlong typefaceHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
jchar* jchars = env->GetCharArrayElements(text, NULL);
get_canvas(canvasHandle)->drawText(jchars + index, 0, count, count, x, y,
@@ -422,7 +423,7 @@
static void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
jint start, jint end, jfloat x, jfloat y, jint bidiFlags,
jlong paintHandle, jlong typefaceHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
const int count = end - start;
const jchar* jchars = env->GetStringChars(text, NULL);
@@ -434,7 +435,7 @@
static void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index,
jint count, jint contextIndex, jint contextCount, jfloat x, jfloat y,
jboolean isRtl, jlong paintHandle, jlong typefaceHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
const int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
@@ -448,7 +449,7 @@
jint start, jint end, jint contextStart, jint contextEnd,
jfloat x, jfloat y, jboolean isRtl, jlong paintHandle,
jlong typefaceHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
@@ -462,7 +463,7 @@
static void drawPosTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
jint index, jint count, jfloatArray pos, jlong paintHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
jchar* jchars = text ? env->GetCharArrayElements(text, NULL) : NULL;
float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
@@ -480,7 +481,7 @@
static void drawPosTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
jfloatArray pos, jlong paintHandle) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
const jchar* jchars = text ? env->GetStringChars(text, NULL) : NULL;
int byteLength = text ? env->GetStringLength(text) : 0;
float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
@@ -499,7 +500,7 @@
class DrawTextOnPathFunctor {
public:
DrawTextOnPathFunctor(const Layout& layout, Canvas* canvas, float hOffset,
- float vOffset, const SkPaint& paint, const SkPath& path)
+ float vOffset, const Paint& paint, const SkPath& path)
: layout(layout), canvas(canvas), hOffset(hOffset), vOffset(vOffset),
paint(paint), path(path) {
}
@@ -517,14 +518,14 @@
Canvas* canvas;
float hOffset;
float vOffset;
- const SkPaint& paint;
+ const Paint& paint;
const SkPath& path;
};
static void drawTextOnPath(Canvas* canvas, const uint16_t* text, int count, int bidiFlags,
const SkPath& path, float hOffset, float vOffset,
- const SkPaint& paint, TypefaceImpl* typeface) {
- SkPaint paintCopy(paint);
+ const Paint& paint, TypefaceImpl* typeface) {
+ Paint paintCopy(paint);
Layout layout;
std::string css = MinikinUtils::setLayoutProperties(&layout, &paintCopy, bidiFlags, typeface);
layout.doLayout(text, 0, count, count, css);
@@ -533,7 +534,7 @@
// Set align to left for drawing, as we don't want individual
// glyphs centered or right-aligned; the offset above takes
// care of all alignment.
- paintCopy.setTextAlign(SkPaint::kLeft_Align);
+ paintCopy.setTextAlign(Paint::kLeft_Align);
DrawTextOnPathFunctor f(layout, canvas, hOffset, vOffset, paintCopy, path);
MinikinUtils::forFontRun(layout, &paintCopy, f);
@@ -544,7 +545,7 @@
jfloat vOffset, jint bidiFlags, jlong paintHandle,
jlong typefaceHandle) {
SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
jchar* jchars = env->GetCharArrayElements(text, NULL);
@@ -559,7 +560,7 @@
jlong pathHandle, jfloat hOffset, jfloat vOffset,
jint bidiFlags, jlong paintHandle, jlong typefaceHandle) {
SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
const jchar* jchars = env->GetStringChars(text, NULL);
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 760ed45..32cf286 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -79,26 +79,6 @@
jmethodID setVendorInfo;
} dhcpResultsFieldIds;
-static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
-{
- int result;
-
- const char *nameStr = env->GetStringUTFChars(ifname, NULL);
- result = ::ifc_enable(nameStr);
- env->ReleaseStringUTFChars(ifname, nameStr);
- return (jint)result;
-}
-
-static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
-{
- int result;
-
- const char *nameStr = env->GetStringUTFChars(ifname, NULL);
- result = ::ifc_disable(nameStr);
- env->ReleaseStringUTFChars(ifname, nameStr);
- return (jint)result;
-}
-
static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
jstring ifname, jint mask)
{
@@ -280,9 +260,6 @@
*/
static JNINativeMethod gNetworkUtilMethods[] = {
/* name, signature, funcPtr */
-
- { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
- { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
{ "resetConnections", "(Ljava/lang/String;I)I", (void *)android_net_utils_resetConnections },
{ "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcp },
{ "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcpRenew },
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 8641e73..0a259aa 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -32,7 +32,6 @@
#include <SkCanvas.h>
#include <SkImageInfo.h>
#include <SkMatrix.h>
-#include <SkPaint.h>
#include <SkPorterDuff.h>
#include <SkRegion.h>
#include <SkScalerContext.h>
@@ -43,6 +42,7 @@
#include <Rect.h>
#include <RenderNode.h>
#include <CanvasProperty.h>
+#include <Paint.h>
#include <minikin/Layout.h>
#include "MinikinSkia.h"
@@ -203,14 +203,14 @@
jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
jlong paintPtr, jint saveFlags) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
}
static jint android_view_GLES20Canvas_saveLayerClip(JNIEnv* env, jobject clazz,
jlong rendererPtr, jlong paintPtr, jint saveFlags) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
paint, saveFlags);
@@ -349,7 +349,7 @@
JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawBitmap(bitmap, left, top, paint);
}
@@ -362,7 +362,7 @@
JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
dstLeft, dstTop, dstRight, dstBottom, paint);
}
@@ -376,7 +376,7 @@
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawBitmap(bitmap, *matrix, paint);
}
@@ -400,7 +400,7 @@
}
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawBitmapData(bitmap, left, top, paint);
// Note - bitmap isn't deleted as DisplayListRenderer owns it now
@@ -418,7 +418,7 @@
jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint);
if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0);
@@ -434,7 +434,7 @@
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
}
@@ -449,7 +449,7 @@
jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawRect(left, top, right, bottom, paint);
}
@@ -457,14 +457,14 @@
jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
jfloat rx, jfloat ry, jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
}
static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawCircle(x, y, radius, paint);
}
@@ -482,7 +482,7 @@
jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawOval(left, top, right, bottom, paint);
}
@@ -490,7 +490,7 @@
jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
}
@@ -498,8 +498,8 @@
jlong rendererPtr, jlong regionPtr, jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
- if (paint->getStyle() != SkPaint::kFill_Style ||
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
+ if (paint->getStyle() != Paint::kFill_Style ||
(paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) {
SkRegion::Iterator it(*region);
while (!it.done()) {
@@ -528,7 +528,7 @@
jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
jfloat* storage = env->GetFloatArrayElements(points, NULL);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawPoints(storage + offset, count, paint);
env->ReleaseFloatArrayElements(points, storage, 0);
}
@@ -537,7 +537,7 @@
jlong rendererPtr, jlong pathPtr, jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawPath(path, paint);
}
@@ -545,7 +545,7 @@
jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
jfloat* storage = env->GetFloatArrayElements(points, NULL);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
renderer->drawLines(storage + offset, count, paint);
env->ReleaseFloatArrayElements(points, storage, 0);
}
@@ -573,7 +573,7 @@
class RenderTextFunctor {
public:
RenderTextFunctor(const Layout& layout, DisplayListRenderer* renderer, jfloat x, jfloat y,
- SkPaint* paint, uint16_t* glyphs, float* pos, float totalAdvance,
+ Paint* paint, uint16_t* glyphs, float* pos, float totalAdvance,
uirenderer::Rect& bounds)
: layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs),
pos(pos), totalAdvance(totalAdvance), bounds(bounds) { }
@@ -593,7 +593,7 @@
DisplayListRenderer* renderer;
jfloat x;
jfloat y;
- SkPaint* paint;
+ Paint* paint;
uint16_t* glyphs;
float* pos;
float totalAdvance;
@@ -601,7 +601,7 @@
};
static void renderTextLayout(DisplayListRenderer* renderer, Layout* layout,
- jfloat x, jfloat y, SkPaint* paint) {
+ jfloat x, jfloat y, Paint* paint) {
size_t nGlyphs = layout->nGlyphs();
float* pos = new float[nGlyphs * 2];
uint16_t* glyphs = new uint16_t[nGlyphs];
@@ -618,7 +618,7 @@
}
static void renderText(DisplayListRenderer* renderer, const jchar* text, int count,
- jfloat x, jfloat y, int bidiFlags, SkPaint* paint, TypefaceImpl* typeface) {
+ jfloat x, jfloat y, int bidiFlags, Paint* paint, TypefaceImpl* typeface) {
Layout layout;
std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
layout.doLayout(text, 0, count, count, css);
@@ -629,7 +629,7 @@
class RenderTextOnPathFunctor {
public:
RenderTextOnPathFunctor(const Layout& layout, DisplayListRenderer* renderer, float hOffset,
- float vOffset, SkPaint* paint, SkPath* path)
+ float vOffset, Paint* paint, SkPath* path)
: layout(layout), renderer(renderer), hOffset(hOffset), vOffset(vOffset),
paint(paint), path(path) {
}
@@ -647,19 +647,19 @@
DisplayListRenderer* renderer;
float hOffset;
float vOffset;
- SkPaint* paint;
+ Paint* paint;
SkPath* path;
};
static void renderTextOnPath(DisplayListRenderer* renderer, const jchar* text, int count,
- SkPath* path, jfloat hOffset, jfloat vOffset, int bidiFlags, SkPaint* paint,
+ SkPath* path, jfloat hOffset, jfloat vOffset, int bidiFlags, Paint* paint,
TypefaceImpl* typeface) {
Layout layout;
std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
layout.doLayout(text, 0, count, count, css);
hOffset += MinikinUtils::hOffsetForTextAlign(paint, layout, *path);
- SkPaint::Align align = paint->getTextAlign();
- paint->setTextAlign(SkPaint::kLeft_Align);
+ Paint::Align align = paint->getTextAlign();
+ paint->setTextAlign(Paint::kLeft_Align);
RenderTextOnPathFunctor f(layout, renderer, hOffset, vOffset, paint, path);
MinikinUtils::forFontRun(layout, paint, f);
@@ -668,7 +668,7 @@
static void renderTextRun(DisplayListRenderer* renderer, const jchar* text,
jint start, jint count, jint contextCount, jfloat x, jfloat y,
- int bidiFlags, SkPaint* paint, TypefaceImpl* typeface) {
+ int bidiFlags, Paint* paint, TypefaceImpl* typeface) {
Layout layout;
std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
layout.doLayout(text, start, count, contextCount, css);
@@ -681,7 +681,7 @@
jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
jchar* textArray = env->GetCharArrayElements(text, NULL);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
renderText(renderer, textArray + index, count, x, y, bidiFlags, paint, typeface);
@@ -693,7 +693,7 @@
jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
const jchar* textArray = env->GetStringChars(text, NULL);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
renderText(renderer, textArray + start, end - start, x, y, bidiFlags, paint, typeface);
@@ -707,7 +707,7 @@
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
jchar* textArray = env->GetCharArrayElements(text, NULL);
SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
renderTextOnPath(renderer, textArray + index, count, path,
@@ -722,7 +722,7 @@
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
const jchar* textArray = env->GetStringChars(text, NULL);
SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
renderTextOnPath(renderer, textArray + start, end - start, path,
@@ -736,7 +736,7 @@
jlong paintPtr, jlong typefacePtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
jchar* textArray = env->GetCharArrayElements(text, NULL);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
@@ -753,7 +753,7 @@
const jchar* textArray = env->GetStringChars(text, NULL);
jint count = end - start;
jint contextCount = contextEnd - contextStart;
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index 50edb76..aa674de 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -25,10 +25,10 @@
#include <gui/GLConsumer.h>
+#include <Paint.h>
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkMatrix.h>
-#include <SkPaint.h>
#include <SkXfermode.h>
#include <DeferredLayerUpdater.h>
@@ -56,7 +56,7 @@
jlong layerUpdaterPtr, jlong paintPtr) {
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
if (layer) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
layer->setPaint(paint);
}
}
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 7245447..1f3909a 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -26,6 +26,7 @@
#include <Animator.h>
#include <DisplayListRenderer.h>
#include <RenderNode.h>
+#include <Paint.h>
namespace android {
@@ -95,7 +96,7 @@
static jboolean android_view_RenderNode_setLayerPaint(JNIEnv* env,
jobject clazz, jlong renderNodePtr, jlong paintPtr) {
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+ Paint* paint = reinterpret_cast<Paint*>(paintPtr);
return SET_AND_DIRTY(mutateLayerProperties().setFromPaint, paint, RenderNode::GENERIC);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index fc55116..30629ad 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -894,7 +894,7 @@
android:label="@string/permlab_nfc" />
<!-- @SystemApi Allows an internal user to use privileged ConnectivityManager APIs.
- @hide -->
+ @hide -->
<permission android:name="android.permission.CONNECTIVITY_INTERNAL"
android:permissionGroup="android.permission-group.NETWORK"
android:protectionLevel="signature|system" />
@@ -905,10 +905,10 @@
android:protectionLevel="signature|system" />
<!-- @SystemApi Allows access to the loop radio (Android@Home mesh network) device.
- @hide -->
+ @hide -->
<permission android:name="android.permission.LOOP_RADIO"
- android:permissionGroup="android.permission-group.NETWORK"
- android:protectionLevel="signature|system" />
+ android:permissionGroup="android.permission-group.NETWORK"
+ android:protectionLevel="signature|system" />
<!-- Allows sending and receiving handover transfer status from Wifi and Bluetooth
@hide
@@ -1364,6 +1364,14 @@
android:label="@string/permlab_getTasks"
android:description="@string/permdesc_getTasks" />
+ <!-- Allows an application to start a task from a ActivityManager#RecentTaskInfo.
+ @hide -->
+ <permission android:name="android.permission.START_TASKS_FROM_RECENTS"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signature|system"
+ android:label="@string/permlab_startTasksFromRecents"
+ android:description="@string/permdesc_startTasksFromRecents" />
+
<!-- @SystemApi @hide Allows an application to call APIs that allow it to do interactions
across the users on the device, using singleton services and
user-targeted broadcasts. This permission is not available to
@@ -2461,14 +2469,15 @@
<permission android:name="android.permission.PACKAGE_USAGE_STATS"
android:label="@string/permlab_pkgUsageStats"
android:description="@string/permdesc_pkgUsageStats"
- android:protectionLevel="signature|system" />
+ android:protectionLevel="signature|system|development|appop" />
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<!-- @SystemApi Allows an application to collect battery statistics -->
<permission android:name="android.permission.BATTERY_STATS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:label="@string/permlab_batteryStats"
android:description="@string/permdesc_batteryStats"
- android:protectionLevel="signature|system" />
+ android:protectionLevel="signature|system|development" />
<!-- @SystemApi Allows an application to control the backup and restore process.
<p>Not for use by third-party applications.
@@ -2796,12 +2805,12 @@
android:icon="@drawable/ic_launcher_android"
android:supportsRtl="true">
<activity android:name="com.android.internal.app.ChooserActivity"
- android:theme="@style/Theme.Holo.Dialog.Alert"
+ android:theme="@style/Theme.DeviceDefault.Resolver"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
- android:multiprocess="true"
android:documentLaunchMode="never"
- android:relinquishTaskIdentity="true">
+ android:relinquishTaskIdentity="true"
+ android:process=":ui">
<intent-filter>
<action android:name="android.intent.action.CHOOSER" />
<category android:name="android.intent.category.DEFAULT" />
@@ -2847,7 +2856,7 @@
<activity android:name="android.accounts.ChooseAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Holo.Dialog"
+ android:theme="@android:style/Theme.Material.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
@@ -2855,14 +2864,14 @@
<activity android:name="android.accounts.ChooseTypeAndAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Holo.Dialog"
+ android:theme="@android:style/Theme.Material.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
<activity android:name="android.accounts.ChooseAccountTypeActivity"
android:excludeFromRecents="true"
- android:theme="@android:style/Theme.Holo.Dialog"
+ android:theme="@android:style/Theme.Material.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
@@ -2870,14 +2879,14 @@
<activity android:name="android.accounts.CantAddAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Holo.Dialog.NoActionBar"
+ android:theme="@android:style/Theme.Material.Dialog.NoActionBar"
android:process=":ui">
</activity>
<activity android:name="android.accounts.GrantCredentialsPermissionActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Holo.DialogWhenLarge"
+ android:theme="@android:style/Theme.Material.DialogWhenLarge"
android:process=":ui">
</activity>
diff --git a/core/res/res/drawable-hdpi/spinner_mtrl_am_alpha.9.png b/core/res/res/drawable-hdpi/spinner_mtrl_am_alpha.9.png
index de5819d..de7ac29 100644
--- a/core/res/res/drawable-hdpi/spinner_mtrl_am_alpha.9.png
+++ b/core/res/res/drawable-hdpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-hdpi/textfield_activated_mtrl_alpha.9.png
index 7c77a45..b9a81be 100644
--- a/core/res/res/drawable-hdpi/textfield_activated_mtrl_alpha.9.png
+++ b/core/res/res/drawable-hdpi/textfield_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-hdpi/textfield_default_mtrl_alpha.9.png
index bc6da21..3682629 100644
--- a/core/res/res/drawable-hdpi/textfield_default_mtrl_alpha.9.png
+++ b/core/res/res/drawable-hdpi/textfield_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_mtrl_am_alpha.9.png b/core/res/res/drawable-mdpi/spinner_mtrl_am_alpha.9.png
index f151bfb..bbf5928 100644
--- a/core/res/res/drawable-mdpi/spinner_mtrl_am_alpha.9.png
+++ b/core/res/res/drawable-mdpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-mdpi/textfield_activated_mtrl_alpha.9.png
index 7a72295..f3d06fe 100644
--- a/core/res/res/drawable-mdpi/textfield_activated_mtrl_alpha.9.png
+++ b/core/res/res/drawable-mdpi/textfield_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-mdpi/textfield_default_mtrl_alpha.9.png
index 483931f..f0e7db8 100644
--- a/core/res/res/drawable-mdpi/textfield_default_mtrl_alpha.9.png
+++ b/core/res/res/drawable-mdpi/textfield_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_mtrl_am_alpha.9.png b/core/res/res/drawable-xhdpi/spinner_mtrl_am_alpha.9.png
index c868ed1..d4bd169 100644
--- a/core/res/res/drawable-xhdpi/spinner_mtrl_am_alpha.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-xhdpi/textfield_activated_mtrl_alpha.9.png
index 16c376a..7174b67 100644
--- a/core/res/res/drawable-xhdpi/textfield_activated_mtrl_alpha.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-xhdpi/textfield_default_mtrl_alpha.9.png
index e3bd904..46dad22 100644
--- a/core/res/res/drawable-xhdpi/textfield_default_mtrl_alpha.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_mtrl_am_alpha.9.png b/core/res/res/drawable-xxhdpi/spinner_mtrl_am_alpha.9.png
index 7cb1486..2e7bc12 100644
--- a/core/res/res/drawable-xxhdpi/spinner_mtrl_am_alpha.9.png
+++ b/core/res/res/drawable-xxhdpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_activated_mtrl_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_activated_mtrl_alpha.9.png
index a22f352..661d5f0 100644
--- a/core/res/res/drawable-xxhdpi/textfield_activated_mtrl_alpha.9.png
+++ b/core/res/res/drawable-xxhdpi/textfield_activated_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_default_mtrl_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_default_mtrl_alpha.9.png
index b0504e0..d7696c3 100644
--- a/core/res/res/drawable-xxhdpi/textfield_default_mtrl_alpha.9.png
+++ b/core/res/res/drawable-xxhdpi/textfield_default_mtrl_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/spinner_mtrl_am_alpha.9.png b/core/res/res/drawable-xxxhdpi/spinner_mtrl_am_alpha.9.png
index 2ae7234..1086e9d 100644
--- a/core/res/res/drawable-xxxhdpi/spinner_mtrl_am_alpha.9.png
+++ b/core/res/res/drawable-xxxhdpi/spinner_mtrl_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable/edit_text_material.xml b/core/res/res/drawable/edit_text_material.xml
index 86cec8f..eaf5e45 100644
--- a/core/res/res/drawable/edit_text_material.xml
+++ b/core/res/res/drawable/edit_text_material.xml
@@ -14,20 +14,25 @@
limitations under the License.
-->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="?attr/colorControlActivated">
- <item>
- <selector>
- <item android:state_enabled="false">
- <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
- android:tint="?attr/colorControlNormal"
- android:alpha="?attr/disabledAlpha" />
- </item>
- <item>
- <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
- android:tint="?attr/colorControlNormal" />
- </item>
- </selector>
- </item>
- <item android:id="@+id/mask" android:drawable="@drawable/textfield_activated_mtrl_alpha" />
-</ripple>
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetLeft="@dimen/control_inset_material"
+ android:insetTop="@dimen/control_inset_material"
+ android:insetBottom="@dimen/control_inset_material"
+ android:insetRight="@dimen/control_inset_material">
+ <ripple android:color="?attr/colorControlActivated">
+ <item>
+ <selector>
+ <item android:state_enabled="false">
+ <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
+ android:tint="?attr/colorControlNormal"
+ android:alpha="?attr/disabledAlpha" />
+ </item>
+ <item>
+ <nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
+ android:tint="?attr/colorControlNormal" />
+ </item>
+ </selector>
+ </item>
+ <item android:id="@+id/mask" android:drawable="@drawable/textfield_activated_mtrl_alpha" />
+ </ripple>
+</inset>
diff --git a/core/res/res/drawable/switch_thumb_material_anim.xml b/core/res/res/drawable/switch_thumb_material_anim.xml
index e7baa2c..67e460a 100644
--- a/core/res/res/drawable/switch_thumb_material_anim.xml
+++ b/core/res/res/drawable/switch_thumb_material_anim.xml
@@ -14,41 +14,62 @@
limitations under the License.
-->
-<animated-selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
- <item android:state_enabled="false" android:state_checked="true">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_014" android:gravity="center" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" />
+<animated-selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:constantSize="true">
+ <item
+ android:state_enabled="false"
+ android:state_checked="true">
+ <bitmap
+ android:src="@drawable/btn_switch_to_on_mtrl_014"
+ android:gravity="center"
+ android:tint="?attr/colorControlActivated"
+ android:alpha="?attr/disabledAlpha" />
</item>
<item android:state_enabled="false">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_000" android:gravity="center" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" />
+ <bitmap
+ android:src="@drawable/btn_switch_to_on_mtrl_000"
+ android:gravity="center"
+ android:tint="?attr/colorControlNormal"
+ android:alpha="?attr/disabledAlpha" />
</item>
- <item android:state_checked="true" android:id="@+id/on">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_014" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <item
+ android:state_checked="true"
+ android:id="@+id/on">
+ <bitmap
+ android:src="@drawable/btn_switch_to_on_mtrl_014"
+ android:gravity="center"
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:id="@+id/off">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_000" android:gravity="center" android:tint="?attr/colorControlNormal" />
+ <bitmap
+ android:src="@drawable/btn_switch_to_on_mtrl_000"
+ android:gravity="center"
+ android:tint="?attr/colorControlNormal" />
</item>
- <transition android:fromId="@+id/off" android:toId="@+id/on">
+ <transition
+ android:fromId="@+id/off"
+ android:toId="@+id/on">
<animation-list>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_000" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_on_mtrl_000" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_001" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_on_mtrl_001" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_002" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_on_mtrl_002" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_003" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_on_mtrl_003" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_004" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_on_mtrl_004" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_005" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_on_mtrl_005" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_on_mtrl_006" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_on_mtrl_006" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
<bitmap android:src="@drawable/btn_switch_to_on_mtrl_007" android:gravity="center" android:tint="?attr/colorControlActivated" />
@@ -100,28 +121,28 @@
<bitmap android:src="@drawable/btn_switch_to_off_mtrl_006" android:gravity="center" android:tint="?attr/colorControlActivated" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_off_mtrl_007" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_off_mtrl_007" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_off_mtrl_008" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_off_mtrl_008" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_off_mtrl_009" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_off_mtrl_009" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_off_mtrl_010" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_off_mtrl_010" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_off_mtrl_011" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_off_mtrl_011" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_off_mtrl_012" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_off_mtrl_012" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_off_mtrl_013" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_off_mtrl_013" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
<item android:duration="15">
- <bitmap android:src="@drawable/btn_switch_to_off_mtrl_014" android:gravity="center" android:tint="?attr/colorControlActivated" />
+ <bitmap android:src="@drawable/btn_switch_to_off_mtrl_014" android:gravity="center" android:tint="?attr/colorControlNormal" />
</item>
</animation-list>
</transition>
diff --git a/core/res/res/layout/resolve_list_item.xml b/core/res/res/layout/resolve_list_item.xml
index 75b0c3d..7aa9a72 100644
--- a/core/res/res/layout/resolve_list_item.xml
+++ b/core/res/res/layout/resolve_list_item.xml
@@ -43,6 +43,7 @@
<!-- Activity name -->
<TextView android:id="@android:id/text1"
android:textAppearance="?android:attr/textAppearanceSmall"
+ android:fontFamily="sans-serif-condensed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
@@ -51,6 +52,7 @@
<!-- Extended activity info to distinguish between duplicate activity names -->
<TextView android:id="@android:id/text2"
android:textAppearance="?android:attr/textAppearanceSmall"
+ android:fontFamily="sans-serif-condensed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index 5acb588..b3a3478 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -35,6 +35,7 @@
android:layout_alignParentTop="true"
style="?attr/actionBarStyle"
android:transitionName="android:action_bar"
+ android:touchscreenBlocksFocus="true"
android:gravity="top">
<com.android.internal.widget.ActionBarView
android:id="@+id/action_bar"
@@ -53,5 +54,6 @@
android:layout_height="wrap_content"
style="?attr/actionBarSplitStyle"
android:visibility="gone"
+ android:touchscreenBlocksFocus="true"
android:gravity="center"/>
</com.android.internal.widget.ActionBarOverlayLayout>
diff --git a/core/res/res/layout/screen_toolbar.xml b/core/res/res/layout/screen_toolbar.xml
index 56815f8..039e89f 100644
--- a/core/res/res/layout/screen_toolbar.xml
+++ b/core/res/res/layout/screen_toolbar.xml
@@ -35,6 +35,7 @@
android:layout_alignParentTop="true"
style="?attr/actionBarStyle"
android:transitionName="android:action_bar"
+ android:touchscreenBlocksFocus="true"
android:gravity="top">
<Toolbar
android:id="@+id/action_bar"
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 55b79e8..2077543 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1386,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"للسماح لأحد التطبيقات بالالتزام بخدمة الوكيل المعتمد."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"التفاعل مع نظام التحديث والاسترداد"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"للسماح للتطبيق بالتفاعل مع نظام الاسترداد وتحديثات النظام."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"إنشاء جلسات عرض وسائط"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"للسماح لأحد التطبيقات بإنشاء جلسات عرض وسائط. ويُمكن لهذه الجلسات تمكين التطبيقات من التقاط محتويات مصورة وأخرى صوتية. ولا حاجة إليها مع التطبيقات العادية."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"المس مرتين للتحكم في التكبير/التصغير"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"تعذرت إضافة أداة."</string>
<string name="ime_action_go" msgid="8320845651737369027">"تنفيذ"</string>
@@ -1514,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"تعديل"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"تحذير استخدام البيانات"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"المس لعرض الاستخدام والإعدادات."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2-3 غيغابايت من البيانات المعطلة"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4 غيغابايت من البيانات المعطلة"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"البيانات الخلوية معطلة"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"بيانات Wi-Fi معطلة"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"تم بلوغ الحد المعين"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"تم تجاوز حد بيانات شبكات 2G-3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"تم تجاوز حد بيانات 4G"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"تم تجاوز حد البيانات الخلوية"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"تم تجاوز حد بيانات شبكة Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> فوق الحد المعين."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"تم تقييد بيانات الخلفية"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 437f764..b87db9b 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Разрешава на приложението да променя историята или отметките на браузъра, съхранени на телефона ви. Това може да му позволи да изтрива или променя данните на браузъра. Забележка: Възможно е браузъри на трети страни или други приложения с възможности за сърфиране в мрежата да не могат да наложат ограниченията на разрешението."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"навиване на будилника"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Разрешава на приложението да навие инсталирано приложение будилник. Някои будилници може да не изпълнят тази функция."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"запис на гласови съобщения"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Разрешава на приложението да променя и премахва съобщения от входящата ви гласова поща."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"добавяне на гласова поща"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Разрешава на приложението да добавя съобщения към входящата ви гласова поща."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"четене на гласовата поща"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Разрешава на приложението да чете гласовите ви съобщения."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"промяна на разрешенията за местоположение в браузъра"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Разрешава на приложението да променя разрешенията на браузъра за местоположение. Злонамерените приложения могат да използват това, за да изпращат информация за местоположението до произволни уебсайтове."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"проверка на пакетите"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 7decead..81fee3a 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1748,7 +1748,7 @@
<string name="lock_to_app_toast_locked" msgid="4229650395479263497">"আপনি অ্যাপ-এ-লক করুন মোডে রয়েছেন৷"</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"অ্যাপ-এ-লক ব্যবহার করতে চান?"</string>
<string name="lock_to_app_description" msgid="2800403592608529611">"লক-টু-অ্যাপ কোনো একক অ্যাপ্লিকেশানে প্রদর্শন লক করে।\n \nএটি থেকে বেরিয়ে যেতে ‘সাম্প্রতিকগুলি’ বোতাম স্পর্শ করে ধরে রাখুন।"</string>
- <string name="lock_to_app_negative" msgid="2259143719362732728">"না, ধন্যবাদ"</string>
+ <string name="lock_to_app_negative" msgid="2259143719362732728">"না, থাক"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"চালু করুন"</string>
<string name="lock_to_app_start" msgid="3074665051586318340">"অ্যাপ্লিকেশানে লক করা আছে"</string>
<string name="lock_to_app_exit" msgid="8967089657201849300">"আর অ্যাপ্লিকেশানে লক করা নেই"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index e8d3ecd..7e69339 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permet que l\'aplicació modifiqui l\'historial del navegador o els marcadors del telèfon. Això pot permetre que l\'aplicació esborri o modifiqui les dades del navegador. Nota: És possible que aquest permís no s\'apliqui a navegadors de tercers o a altres aplicacions amb capacitats de navegació web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"configuració d\'una alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permet que l\'aplicació defineixi una alarma en una aplicació de despertador instal·lada. És possible que algunes aplicacions de despertador no incorporin aquesta funció."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"modificar correus de veu"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Permet que l\'aplicació modifiqui i suprimeixi missatges de la safata d\'entrada de la bústia de veu."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"afegeix bústia de veu"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permet que l\'aplicació afegeixi missatges a la safata d\'entrada de la bústia de veu."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"accedir a la bústia de veu"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Permet que l\'aplicació accedeixi als correus de veu."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Modifica els permisos d\'ubicació geogràfica del navegador"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permet que l\'aplicació modifiqui els permisos d\'ubicació geogràfica del navegador. Les aplicacions malicioses poden utilitzar-ho per enviar la informació d\'ubicació a llocs web arbitraris."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"verifica paquets"</string>
@@ -1745,7 +1741,7 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> suprimit"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string>
<string name="lock_to_app_toast" msgid="2126866321272822564">"Estàs en mode de bloqueig d\'aplicació. Per sortir-ne, toca i mantén premut el botó Recents."</string>
- <string name="lock_to_app_toast_locked" msgid="4229650395479263497">"Estàs en el mode de bloqueig d\'aplicació."</string>
+ <string name="lock_to_app_toast_locked" msgid="4229650395479263497">"Estàs en el mode de Bloqueig d\'aplicació."</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"Vols fer servir la funció Bloqueig d\'aplicació?"</string>
<string name="lock_to_app_description" msgid="2800403592608529611">"Amb Bloqueig d\'aplicació es bloqueja la pantalla en una única aplicació.\n\nPer sortir-ne, toca i mantén premut el botó Recents."</string>
<string name="lock_to_app_negative" msgid="2259143719362732728">"NO, GRÀCIES"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 3d56653..01c2cef 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Umožňuje aplikaci upravit historii prohlížeče nebo záložky uložené v telefonu. Aplikace s tímto oprávněním může vymazat či pozměnit data prohlížeče. Poznámka: Pro prohlížeče třetí strany a jiné aplikace umožňující procházení webu toto oprávnění platit nemusí."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"nastavení budíku"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Umožňuje aplikaci nastavit budík v nainstalované aplikaci budík. Některé aplikace budík tuto funkci nemusí obsahovat."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"zápis do hlasové schránky"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Povoluje aplikaci upravit a odebrat zprávy z hlasové schránky."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"přidat hlasovou zprávu"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Umožňuje aplikaci přidávat zprávy do hlasové schránky."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"čtení hlasových zpráv"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Povoluje aplikaci číst hlasové zprávy."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"změna oprávnění prohlížeče poskytovat informace o zeměpisné poloze"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Umožňuje aplikaci upravit oprávnění funkce geolokace v prohlížeči. Škodlivé aplikace toho mohou využít k odeslání údajů o poloze na libovolné webové stránky."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"ověřit balíčky"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Umožňuje aplikaci vázat se na službu zástupce důvěryhodnosti."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Interakce se systémem aktualizací a obnovení"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Umožňuje aplikaci interakci se systémem obnovení a s aktualizacemi systému."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Vytváření relací promítání médií"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Umožňuje aplikaci vytvářet relace promítání médií. Tyto relace mohou aplikacím umožnit zaznamenávat obsah obrazu a zvuku. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dvojitým dotykem můžete ovládat přiblížení"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget nelze přidat."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Přejít"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Upravit"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Upozornění na využití dat"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Informace o využití a nastavení"</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"Data 2G a 3G jsou vypnuta"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"Data 4G jsou vypnuta"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Mobilní data jsou vypnuta"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Data Wi-Fi jsou vypnuta"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Bylo dosaženo limitu"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Překročili jste limit dat 2G–3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Překročili jste limit dat 4G."</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Dosažen limit mobilních dat"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Datový limit Wi-Fi byl překročen"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> nad stanoveným limitem."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Přenos dat na pozadí je omezen"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 299e516..95bd92f 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Tillader, at appen kan ændre browserens historik eller de bogmærker, der er gemt på din telefon. Dette kan give appen tilladelse til at slette eller ændre browserdata. Bemærk! Denne tilladelse håndhæves muligvis ikke af tredjepartsbrowsere eller andre applikationer med websøgningsfunktioner."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"indstille en alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Tillader, at appen kan indstille en alarm i en installeret alarmapp. Nogle alarmapps har muligvis ikke denne funktion."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"skriv talebeskeder"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Tillader, at appen ændrer og fjerner beskeder fra indbakken for din telefonsvarer."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"tilføje telefonsvarer"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Tillader, at appen kan tilføje beskeder på din telefonsvarer."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"læs talebeskeder"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Tillader, at appen læser dine talebeskeder."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"skifte tilladelser til geografisk placering i Browser"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Tillader, at appen kan ændre browserens tilladelser angående geografisk placering. Ondsindede apps kan benytte dette til at sende oplysninger om placering til vilkårlige websites."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"bekræft pakker"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index db4ed5d..b373ecd 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Telefon zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"Wecker stellen"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Ermöglicht der App, einen Alarm in einer installierten Wecker-App einzurichten. Einige Wecker-Apps implementieren diese Funktion möglicherweise nicht."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"Mailboxnachrichten ändern und entfernen"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Ermöglicht dieser App, Nachrichten im Posteingang Ihrer Mailbox zu ändern und zu entfernen"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"Mailbox-Nachrichten hinzufügen"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ermöglicht der App, Nachrichten zu Ihrem Mailbox-Posteingang hinzuzufügen"</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"Mailboxnachrichten abrufen"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Ermöglicht der App das Abrufen Ihrer Mailboxnachrichten"</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Geolokalisierungsberechtigungen des Browsers ändern"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Ermöglicht der App, die Geolokalisierungsberechtigungen des Browsers zu ändern. Schädliche Apps können so Standortinformationen an beliebige Websites senden."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"Pakete überprüfen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 5a69269..d3447b4 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Επιτρέπει στην εφαρμογή την τροποποίηση του ιστορικού του προγράμματος περιήγησης ή των σελιδοδεικτών που έχουν αποθηκευτεί στο τηλέφωνό σας. Αυτό μπορεί να δίνει τη δυνατότητα στην εφαρμογή να διαγράφει ή να τροποποιεί δεδομένα του προγράμματος περιήγησης. Σημείωση: αυτή η άδεια ίσως να μην μπορεί να εφαρμοστεί από τρίτα προγράμματα περιήγησης ή άλλες εφαρμογές με δυνατότητες περιήγησης ιστού."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ρύθμιση ξυπνητηριού"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Επιτρέπει στην εφαρμογή τη ρύθμιση μιας ειδοποίησης σε μια εγκατεστημένη εφαρμογή ξυπνητηριού. Ορισμένες εφαρμογές ξυπνητηριού ενδέχεται να μην μπορούν να ενσωματώσουν αυτήν τη λειτουργία."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"εγγραφή μηνυμάτων στον τηλεφωνητή"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Επιτρέπει στην εφαρμογή να τροποποιεί και να καταργεί τα μηνύματα από τα Εισερχόμενα του τηλεφωνητή σας."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"προσθήκη τηλεφωνητή"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Επιτρέπει στην εφαρμογή να προσθέτει μηνύματα στα εισερχόμενα του αυτόματου τηλεφωνητή σας."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"ανάγνωση μηνυμάτων στον τηλεφωνητή"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Επιτρέπει στην εφαρμογή να διαβάζει τα μηνύματα στον τηλεφωνητή σας."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"τροποποίηση δικαιωμάτων γεωγραφικής θέσης του Προγράμματος περιήγησης"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Επιτρέπει στην εφαρμογή την τροποποίηση των αδειών γεωτοποθεσίας του Προγράμματος περιήγησης. Τυχόν κακόβουλες εφαρμογές ενδέχεται να το χρησιμοποιήσουν για να επιτρέψουν την αποστολή πληροφοριών τοποθεσίας σε αυθαίρετους ιστότοπους."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"επαλήθευση πακέτων"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 33aaf80..0405f7c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite que la aplicación modifique el historial o los marcadores del navegador almacenados en el teléfono. La aplicación puede utilizar este permiso para borrar o modificar datos del navegador. Nota: este permiso no pueden utilizarlo navegadores externos ni otras aplicaciones que tengan funciones de navegación por Internet."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"establecer una alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que la aplicación establezca una alarma en una aplicación de reloj instalada. Es posible que algunas aplicaciones de reloj no incluyan esta función."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"editar los mensajes de voz"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Permite que la aplicación modifique y elimine mensajes de la bandeja de entrada del buzón de voz."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"añadir buzón de voz"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite que la aplicación añada mensajes a la bandeja de entrada del buzón de voz."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"consultar los mensajes de voz"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Permite que la aplicación consulte tus mensajes de voz."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modificar los permisos de ubicación geográfica del navegador"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite que la aplicación modifique los permisos de ubicación geográfica del navegador. Las aplicaciones malintencionadas pueden usar este permiso para autorizar el envío de información sobre la ubicación a sitios web arbitrarios."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"verificar paquetes"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index faf51bb..9c740c2 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Võimaldab rakendusel muuta telefoni salvestatud brauseri ajalugu või järjehoidjaid. See võimaldab rakendusel kustutada või muuta brauseri andmeid. Märkus: see luba ei pruugi jõustuda kolmanda osapoole brauserites või teistes veebisirvimisvõimega rakendustes."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"määrake äratus"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Võimaldab rakendusel seada installitud äratuskellarakenduses äratuse. Mõned äratuskellarakendused ei pruugi seda funktsiooni juurutada."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"kõneposti sõnumite kirjutamine"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Lubab rakendusel muuta ja kustutada kõneposti postkasti sõnumeid."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"lisa kõneposti"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Võimaldab rakendusel lisada sõnumeid teie kõneposti postkasti."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"kõneposti sõnumite lugemine"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Lubab rakendusel lugeda teie kõneposti sõnumeid."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Brauseri geolokatsiooniõiguste muutmine"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Võimaldab rakendusel muuta brauseri geolokatsiooniõigusi. Pahatahtlikud rakendused võivad seda kasutada asukohateabe saatmise lubamiseks suvalistele veebisaitidele."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"pakettide kinnitamine"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Lubab rakendusel ennast siduda usaldusväärse agendi teenusega."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Suhtlemine värskenduse ja taastesüsteemiga"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Lubab rakendusel suhelda taastesüsteemi ja süsteemivärskendustega."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Meediumi projitseerimise seansi loomine"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Lubab rakendusel luua meediumi projitsiooni seanssi. Need seansid võivad annda rakendustele võimaluse hõivata kuva- ja helisisu. Ei ole kunagi vajalik tavaliste rakenduste puhul."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Suumi juhtimiseks puudutage kaks korda"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Vidinat ei saanud lisada."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Mine"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Muuda"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Andmete kasutamise hoiatus"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Kasutuse/sätete vaat. puudutage."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G–3G andmeside on väljalülitatud"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G andmeside on väljalülitatud"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Mob. andmeside väljalülitatud"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"WiFi andmeside väljalülitatud"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Limiit on täis"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G andmemahupiirang ületatud"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G andmemahupiirang ületatud"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Mob. andmeside limiit ületatud"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"WiFi-andmete piir on ületatud"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> üle määratud piirmäära."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Taustandmed on piiratud"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 67962fe..2bf1850 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Arakatzailearen historia edo telefonoan gordetako laster-markak aldatzeko baimena ematen die aplikazioei. Horrela, aplikazioak agian arakatzaile-datuak ezabatu edo aldatu ahal izango ditu. Oharra: baimen hori hirugarrenen arakatzaileek edo sarea arakatzeko gaitasuna eskaintzen duten bestelako aplikazioek aplika dezakete."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"alarmak ezartzea"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Instalatutako alarma batean alarmak ezartzea baimentzen die aplikazioei. Alarma-aplikazio batzuek agian ez dute eginbide hori inplementatuko."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"Idatzi ahots-mezuak"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Erantzungailuko sarrera-ontziko mezuak aldatzea eta kentzea baimentzen die aplikazioei."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"gehitu erantzungailua"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Erantzungailuko sarrera-ontzian mezuak gehitzea baimentzen die aplikazioei."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"Irakurri ahots-mezuak"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Erantzungailuko mezuak irakurtzea baimentzen die aplikazioei."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Aldatu arakatzailearen geokokapenaren baimenak"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Arakatzailearen geokokapenaren baimenak aldatzea baimentzen die aplikazioei. Aplikazio gaiztoek hori erabil dezakete kokapenari buruzko informazioa haiek hautatutako web-orrietara bidaltzeko."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"Egiaztatu paketeak"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index e38baed..596daa8 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"به برنامه اجازه میدهد سابقه مرورگر یا نشانکهای ذخیره شده در تلفن شما را اصلاح کند. این ویژگی ممکن است به برنامه اجازه دهد دادههای مرورگر را حذف یا اصلاح کند. توجه: این مجوز ممکن است توسط مرورگرهای شخص ثالث یا سایر برنامههای دارای قابلیت مرور وب قابل اجرا نباشد."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"تنظیم یک هشدار"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"به برنامه اجازه میدهد تا هشداری را در برنامه ساعت زنگدار نصب شده تنظیم کند. برخی از برنامههای ساعت زنگدار نمیتوانند این ویژگی را اعمال کنند."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"نوشتن پستهای صوتی"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"به برنامه اجازه میدهد پیامها را از صندوق ورودی پست صوتی شما تغییر داده و حذف کند."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"افزودن پست صوتی"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"به برنامه اجازه میدهد تا پیامها را به صندوق دریافت پست صوتی شما اضافه کند."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"خواندن پست صوتی"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"به برنامه اجازه میدهد پستهای صوتیتان را بخواند."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"تغییر مجوزهای مکان جغرافیایی مرورگر"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"به برنامه اجازه میدهد تا مجوزهای جغرافیایی مرورگر را تغییر دهد. برنامههای مخرب میتوانند از آن استفاده کنند تا اطلاعات موقعیت مکانی را به سایتهای وب کتابخانه بفرستند."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"تأیید بستهها"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"به یک برنامه کاربردی برای اتصال به یک سرویس trust agent اجازه میدهد."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"تعامل با سیستم بهروزرسانی و بازیابی"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"به یک برنامه کاربردی اجازه میدهد با سیستم بازیابی و بهروزرسانیهای سیستم تعامل داشته باشد."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"ایجاد جلسات فرستادن رسانه"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"به برنامه اجازه میدهد جلسههای فرستادن رسانه ایجاد کند. این جلسات میتوانند به برنامه این توانایی را بدهند که نمایشگر و محتوای صوتی را ضبط کند. هرگز نباید برای برنامههای عادی مورد نیاز باشد."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"دوبار لمس کنید تا بزرگنمایی کنترل شود"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"افزودن ابزارک انجام نشد."</string>
<string name="ime_action_go" msgid="8320845651737369027">"برو"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"ویرایش"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"هشدار میزان استفاده از داده"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"برای مشاهده کاربرد و تنظیمات لمس کنید."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"داده 2G-3G خاموش است"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"داده 4G خاموش است"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"داده شبکه سلولی خاموش است"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"داده Wi-Fi خاموش است"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"به حد مجاز رسیدهاید"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"اطلاعات 2G-3G بیش از حد مجاز است"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"بیش از حد مجاز 4G است"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"از حد مجاز شبکه سلولی فراتر رفتید"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"از محدوده مجاز دادههای Wi-Fi بیشتر شد"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> از حد تعیین شده بیشتر شد."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"داده پسزمینه محدود شد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 4644c50..07a4c6e 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1390,10 +1390,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Antaa sovelluksen sitoutua luotettavaan tahoon."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Vuorovaikutus päivitys- ja palautusjärjestelmän kanssa"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Sallii sovelluksen vuorovaikutuksen palautusjärjestelmän ja järjestelmäpäivitysten kanssa."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Medialähetysistuntojen luominen"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Antaa sovelluksen luoda medialähetysistuntoja. Nämä istunnot antavat sovellusten tallentaa näyttö- ja äänisisältöä. Ei tavallisten sovellusten käyttöön."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Ohjaa zoomausta napauttamalla kahdesti"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widgetin lisääminen epäonnistui."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Siirry"</string>
@@ -1518,20 +1516,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Muokkaa"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Tiedonsiirtovaroitus"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Näytä käyttö ja aset. koskettam."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G–3G-tiedonsiirto ei käytössä"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G-tiedonsiirto ei käytössä"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Mobiilitiedonsiirto ei käytössä"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Wi-Fi-tiedonsiirto ei käytössä"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Raja saavutettu"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G-tiedonsiirtoraja ylitetty"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G-tiedonsiirtoraja ylitetty"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Mobiilitiedonsiirtoraja ylitetty"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi-tiedonsiirtoraja ylitetty"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> yli asetetun rajan"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Rajoitettu taustatietojen käyttö"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 3896c16..eb7a45b 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite á aplicación modificar o historial ou os favoritos do navegador que están almacenados no teu teléfono. É posible que esta acción permita á aplicación borrar ou modificar os datos do navegador. Nota: É posible que este permiso non sexa executado por navegadores de terceiros ou outras aplicacións con funcionalidades de navegación web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"definir unha alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite á aplicación definir unha alarma nunha aplicación de espertador instalada. É posible que algunhas aplicacións de espertador non implementen esta función."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"escribir correos de voz"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Permite á aplicación modificar e eliminar mensaxes da caixa de entrada do teu correo de voz."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"engadir correo de voz"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite á aplicación engadir mensaxes á caixa de entrada do teu correo de voz."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"ler correo de voz"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Permite á aplicación ler os teus correos de voz."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modificar os permisos de xeolocalización do navegador"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite á aplicación modificar os permisos de xeolocalización do navegador. É posible que as aplicacións maliciosas utilicen esta opción para permitir o envío de información de localización a sitios web arbitrarios."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"verificar paquetes"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index a82e542..b2665e3 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"ऐप्स को आपके फ़ोन में संग्रहीत ब्राउज़र के इतिहास या बुकमार्क को संशोधित करने देता है. इससे ऐप्स ब्राउज़र डेटा को मिटा सकता है या संशोधित कर सकता है. ध्यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्य ऐप्स द्वारा लागू नहीं की जा सकती."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"अलार्म सेट करें"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"ऐप्स को इंस्टॉल किए गए अलार्म घड़ी ऐप्स में अलार्म सेट करने देता है. हो सकता है कुछ अलार्म घड़ी ऐप्स में यह सुविधा न हो."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"ध्वनिमेल लिखें"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"ऐप्स को आपके ध्वनिमेल इनबॉक्स के संदेशों को बदलने और निकालने देती है."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ध्वनिमेल जोड़ें"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"ऐप्स को आपके ध्वनिमेल इनबॉक्स में संदेश जोड़ने देता है."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"ध्वनिमेल पढ़ें"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"ऐप्स को आपका ध्वनिमेल पढ़ने देती है."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ब्राउज़र भौगोलिक-स्थान अनुमतियों को बदलें"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ऐप्स को ब्राउज़र के भौगोलिक-स्थान की अनुमतियां संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स इसका उपयोग एकपक्षीय वेबसाइट को स्थान जानकारी भेजने में कर सकते हैं."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"पैकेज सत्यापित करें"</string>
@@ -1752,7 +1748,7 @@
<string name="lock_to_app_positive" msgid="7085139175671313864">"प्रारंभ करें"</string>
<string name="lock_to_app_start" msgid="3074665051586318340">"ऐप्स-पर-लॉक किया गया"</string>
<string name="lock_to_app_exit" msgid="8967089657201849300">"अब ऐप्स-पर-लॉक नहीं है"</string>
- <string name="lock_to_app_use_screen_lock" msgid="1434584309048590886">"बाहर निकलने से पहले %1$s से पूछें"</string>
+ <string name="lock_to_app_use_screen_lock" msgid="1434584309048590886">"बाहर निकलने से पहले %1$s के लिए पूछें"</string>
<string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"पिन"</string>
<string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"पैटर्न अनलॉक करें"</string>
<string name="lock_to_app_unlock_password" msgid="795224196583495868">"पासवर्ड"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3d11cd3..2883233 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Aplikaciji omogućuje izmjenu povijesti i oznaka Preglednika pohranjenih na telefonu. To aplikaciji može omogućiti brisanje ili izmjenu podataka Preglednika. Napomena: tu dozvolu ne mogu primijeniti preglednici treće strane ili druge aplikacije s mogućnostima pregledavanja weba."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"postavljanje alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Omogućuje aplikaciji postavljanje alarma na instaliranoj aplikaciji budilici. Neke aplikacije budilice možda neće primijeniti tu značajku."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"pisanje govorne pošte"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Omogućuje aplikaciji izmjenjivanje i uklanjanje poruka iz dolazne govorne pošte."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"dodaj govornu poštu"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Omogućuje aplikaciji da doda poruke u vašu govornu poštu."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"čitanje govorne pošte"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Omogućuje aplikaciji čitanje vaše govorne pošte."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmjena dozvola za geolociranje u pregledniku"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Omogućuje aplikaciji promjenu geolokacijskih dozvola preglednika. Zlonamjerne aplikacije mogu to upotrijebiti da bi dopustile slanje podataka o lokaciji nasumičnim web-lokacijama."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"provjeri pakete"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Omogućuje aplikaciji povezivanje s uslugom pouzdanog predstavnika."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Interakcija s ažuriranjem i sustavom za oporavak"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Omogućuje aplikaciji interakciju sa sustavom za oporavak i ažuriranjima sustava."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Stvaranje sesija za projiciranje medija"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Omogućuje aplikaciji stvaranje sesija za projiciranje medija. Te sesije mogu omogućiti aplikaciji snimanje zaslona i audiosadržaja. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dodirnite dvaput za upravljanje zumiranjem"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget nije moguće dodati."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Idi"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Uredi"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Upozorenje o upotrebi podataka"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Dod. za prikaz upotrebe i post."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G-3G podaci isključeni"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G podaci isključeni"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Mobilni podaci isključeni"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Wi-Fi podaci isključeni"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Ograničenje dosegnuto"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Prekoračeno ograničenje 2G-3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Prekoračeno je ograničenje 4G podataka"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Limit mobilnih podataka premašen"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Prekorač. Wi-Fi ogranič. pod."</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"Veličina <xliff:g id="SIZE">%s</xliff:g> prelazi navedeno ograničenje."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Pozadinski podaci ograničeni"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index c9570d2..4dfa0db 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a böngésző előzményeit vagy a telefonon tárolt könyvjelzőket. Az engedéllyel rendelkező alkalmazás törölheti vagy módosíthatja a böngésző adatait. Megjegyzés: előfordulhat, hogy ezt az engedélyt harmadik felek által üzemeltetett böngészők vagy egyéb böngészésre képes alkalmazások nem léptetik életbe."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ébresztés beállítása"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Lehetővé teszi az alkalmazás számára, hogy ébresztőt állítson be egy telepített ébresztőóra alkalmazásban. Egyes ilyen alkalmazásokban lehet, hogy nem működik ez a funkció."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"a hangüzenetek módosítása"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Lehetővé teszi az alkalmazás számára, hogy üzeneteket módosítson vagy távolítson el a bejövő hangpostafiókból."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"hangposta hozzáadása"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Lehetővé teszi az alkalmazás számára, hogy üzeneteket adjon hozzá bejövő hangpostájához."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"a hangüzenetek olvasása"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Engedélyezi az alkalmazásnak a hangüzenetek olvasását."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"a böngésző helymeghatározási engedélyeinek módosítása"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a böngésző helymeghatározási engedélyeit. Rosszindulatú alkalmazások ezt arra használhatják, hogy a helyére vonatkozó információkat küldjenek tetszőleges webhelyeknek."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"csomagok ellenőrzése"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index cf020122..327d2ac 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Memungkinkan aplikasi mengubah riwayat atau bookmark Browser yang tersimpan dalam ponsel Anda. Izin ini memungkinkan aplikasi menghapus atau mengubah data Browser. Catatan: izin ini tidak dapat diberlakukan oleh browser pihak ketiga atau aplikasi lain dengan kemampuan menjelajahi web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"setel alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Mengizinkan apl menyetel alarm di apl jam alarm yang terpasang. Beberapa apl jam alarm mungkin tidak menerapkan fitur ini."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"tulis kotak pesan"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Memungkinkan aplikasi memodifikasi dan membuang pesan dari kotak masuk pesan suara Anda."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"tambahkan kotak pesan"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Mengizinkan apl menambahkan pesan ke kotak masuk untuk pesan suara Anda."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"baca kotak pesan"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Memungkinkan aplikasi membaca kotak pesan Anda."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"memodifikasi izin geolokasi Browser"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Mengizinkan apl memodifikasi izin geolokasi Browser. Apl berbahaya dapat menggunakan izin ini untuk memungkinkan pengiriman informasi lokasi ke sembarang situs web."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"verifikasi paket"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Mengizinkan aplikasi mengikat ke layanan agen kepercayaan."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Berinteraksi dengan sistem pemulihan dan pembaruan"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Mengizinkan aplikasi berinteraksi dengan sistem pemulihan dan pembaruan sistem."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Membuat sesi proyeksi media"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Memungkinkan aplikasi membuat sesi proyeksi media. Sesi ini dapat memberikan kemampuan pada aplikasi untuk menangkap konten audio dan layar. Tidak diperlukan oleh aplikasi normal."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mengontrol perbesar/perkecil"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Tidak dapat menambahkan widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Buka"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Edit"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Peringatan penggunaan data"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Sentuh utk mlht pnggnaan & stln."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"Data 2G-3G nonaktif"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"Data 4G nonaktif"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Data seluler nonaktif"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Data Wi-Fi nonaktif"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Batas tercapai"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Batas data 2G-3G terlampaui"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Batas data 4G terlampaui"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Batas data seluler terlampaui"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Batas data Wi-Fi terlampaui"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> melebihi batas yang ditentukan."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Data latar belakang dibatasi"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 270fb8c..c76d4d79 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Leyfir forriti að breyta vafraferlinum eða bókamerkjum sem vistuð eru í símanum. Þetta getur gert forritinu kleift að eyða eða breyta vafragögnum. Athugaðu: Ekki er víst að þessi heimild sé virt í vöfrum frá þriðja aðila eða öðrum forritum með vafraeiginleika."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"stilla vekjara"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Leyfir forriti að stilla vekjara á uppsettri vekjaraklukku. Verið getur að sum vekjaraklukkuforrit séu ekki búin þessum eiginleika."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"skrifa talhólfsskilaboð"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Leyfir forritinu að breyta og fjarlægja skilaboð úr talhólfinu."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"bæta við talhólfi"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Leyfir forriti að bæta skilaboðum við talhólfið þitt."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"lesa talhólfsskilaboð"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Leyfir forritinu að lesa talhólfsskilaboðin þín."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"breyta staðsetningarheimildum vafrans"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Leyfir forriti að breyta heimildum vafrans fyrir landfræðilega staðsetningu. Spilliforrit geta notað þetta til að leyfa sendingu staðsetningarupplýsinga á vafasöm vefsvæði."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"staðfesta pakka"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 1241118..bf821f5 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Consente all\'applicazione di modificare la cronologia o i segnalibri del Browser memorizzati sul telefono. Ciò potrebbe consentire all\'applicazione di cancellare o modificare i dati del Browser. Nota. È possibile che questa autorizzazione non sia applicabile da browser di terze parti o altre applicazioni con funzionalità di navigazione web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"impostazione sveglia"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Consente all\'applicazione di impostare una sveglia in un\'applicazione sveglia installata. È possibile che alcune applicazioni sveglia non possano implementare questa funzione."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"scrivi messaggi vocali"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Consente all\'app di modificare e rimuovere messaggi dalla segreteria."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"aggiunta di un messaggio vocale"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Consente all\'applicazione di aggiungere messaggi alla casella della segreteria."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"leggi messaggi vocali"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Consente all\'app di leggere i messaggi vocali."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modifica delle autorizzazioni di localizzazione geografica del browser"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Consente all\'applicazione di modificare le autorizzazioni di geolocalizzazione del Browser. Le applicazioni dannose potrebbero farne uso per consentire l\'invio di informazioni sulla posizione a siti web arbitrari."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"verifica dei pacchetti"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 73b9f94..00be975 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"携帯端末に保存されているブラウザの履歴やブックマークの変更をアプリに許可します。これにより、アプリがブラウザデータを消去または変更できるようになる可能性があります。注: この許可は、サードパーティブラウザまたはウェブブラウジング機能を備えたその他のアプリでは適用されない場合があります。"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"アラームの設定"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"インストール済みアラームアプリのアラームを設定することをアプリに許可します。この機能が実装されていないアラームアプリもあります。"</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"ボイスメールの書き込み"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"ボイスメール受信トレイからメッセージを修正、削除することをアプリに許可します。"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ボイスメールの追加"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"ボイスメール受信トレイにメッセージを追加することをアプリに許可します。"</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"ボイスメールの読み取り"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"ボイスメールの読み取りをアプリに許可します。"</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ブラウザの現在地情報に対する権限の変更"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ブラウザの現在地情報に対する権限の変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、任意のウェブサイトに現在地情報が送信される恐れがあります。"</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"パッケージのベリファイ"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"信頼できるエージェントサービスにバインドすることをアプリに許可します。"</string>
<string name="permlab_recovery" msgid="3157024487744125846">"アップデートと回復システムへのアクセス"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"回復システムとシステムアップデートへのアクセスをアプリに許可します。"</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"メディアプロジェクションセッションの作成"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"メディアプロジェクションセッションの作成をアプリに許可します。これらのセッションでは、アプリがディスプレイ/オーディオコンテンツをキャプチャできます。通常のアプリでは不要です。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ダブルタップでズームコントロール"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"ウィジェットを追加できませんでした。"</string>
<string name="ime_action_go" msgid="8320845651737369027">"移動"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"編集"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"データ使用の警告"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"タップして使用状況と設定を表示します。"</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G~3Gデータが無効になりました"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4Gデータが無効になりました"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"モバイルデータが無効になりました"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Wi-Fiデータが無効になりました"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"上限に達しました"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G~3Gデータの上限を超えました"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4Gデータの上限を超えました"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"モバイルデータの上限を超えました"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fiデータの上限を超えました"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"指定した上限を<xliff:g id="SIZE">%s</xliff:g>超えました。"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"バックグラウンドデータに上限あり"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 342887e..86d6e66 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1752,25 +1752,16 @@
<string name="item_is_selected" msgid="949687401682476608">"არჩეულია <xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> წაიშალა"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"სამსახური <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_toast (2126866321272822564) -->
- <skip />
+ <string name="lock_to_app_toast" msgid="2126866321272822564">"თქვენ იმყოფებით აპის ფიქსაციის რეჟიმში. გამოსასვლელად, დააჭირეთ და დააყოვნეთ ბოლო აპების ღილაკზე"</string>
<string name="lock_to_app_toast_locked" msgid="4229650395479263497">"თქვენ იმყოფებით აპის ფიქსაციის რეჟიმში."</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"გსურთ „აპში ჩაკეტვის“ გამოყენება?"</string>
- <!-- no translation found for lock_to_app_description (2800403592608529611) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (2259143719362732728) -->
- <skip />
+ <string name="lock_to_app_description" msgid="2800403592608529611">"„აპში ჩაკეტვა“ კეტავს ეკრანს ერთ აპში.\n\nგასასვლელად დააჭირეთ და არ აუშვათ ღილაკს „ბოლო აპები“."</string>
+ <string name="lock_to_app_negative" msgid="2259143719362732728">"არა, გმადლობთ"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"დაწყება"</string>
- <!-- no translation found for lock_to_app_start (3074665051586318340) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (8967089657201849300) -->
- <skip />
- <!-- no translation found for lock_to_app_use_screen_lock (1434584309048590886) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_pin (7908385370846820001) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_pattern (7763071104790758405) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_password (795224196583495868) -->
- <skip />
+ <string name="lock_to_app_start" msgid="3074665051586318340">"აპზე დაფიქსირებული"</string>
+ <string name="lock_to_app_exit" msgid="8967089657201849300">"აპზე დაფიქსირებული აღარ არის"</string>
+ <string name="lock_to_app_use_screen_lock" msgid="1434584309048590886">"გასვლამდე %1$s-ის მოთხოვნა"</string>
+ <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN-კოდი"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"განბლოკვის ნიმუში"</string>
+ <string name="lock_to_app_unlock_password" msgid="795224196583495868">"პაროლი"</string>
</resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 7cbaca8..ba6c0ac 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1392,10 +1392,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"ឲ្យកម្មវិធីភ្ជាប់សេវាកម្មភ្នាក់ងារដែលទុកចិត្ត។"</string>
<string name="permlab_recovery" msgid="3157024487744125846">"អន្តរកម្មជាមួយបច្ចុប្បន្នភាព និងប្រព័ន្ធសង្គ្រោះ"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"ឲ្យកម្មវិធីមានអន្តរកម្មជាមួយប្រព័ន្ធសង្គ្រោះ និងបច្ចុប្បន្នភាពប្រព័ន្ធ។"</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"បង្កើតសម័យគម្រោងមេឌៀ"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"ឲ្យកម្មវិធីបង្កើតសម័យគម្រោងមេឌៀ។ សម័យទាំងនេះអាចធ្វើឲ្យកម្មវិធីមានលទ្ធភាពចាប់យកមាតិកានៃការបង្ហាញ និងសំឡេង។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ប៉ះពីរដង ដើម្បីគ្រប់គ្រងការពង្រីក"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"មិនអាចបន្ថែមធាតុក្រាហ្វិក។"</string>
<string name="ime_action_go" msgid="8320845651737369027">"ទៅ"</string>
@@ -1520,20 +1518,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"ការព្រមានប្រើទិន្នន័យ"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"ប៉ះ ដើម្បីមើលការប្រើ និងការកំណត់។"</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"ទិន្នន័យ 2G-3G បានបិទ"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"ទិន្នន័យ 4G បានបិទ"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"ទិន្នន័យចល័តបានបិទ"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"ទិន្នន័យវ៉ាយហ្វាយបានបិទ"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"បានដល់ដែនកំណត់"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"លើសដែនកំណត់ទិន្នន័យ 2G-3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"បានលើសដែនកំណត់ទិន្នន័យ 4G"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"បានលើសដែនកំណត់ទិន្នន័យចល័ត"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"លើសដែនកំណត់ទិន្នន័យវ៉ាយហ្វាយ"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> លើដែនកំណត់បានបញ្ជាក់។"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"បានដាក់កម្រិតទិន្នន័យផ្ទៃខាងក្រោយ"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index c9e0519..d6143e1 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ಬ್ರೌಸರ್ನ ಇತಿಹಾಸ ಅಥವಾ ಬುಕ್ಮಾರ್ಕ್ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ಬ್ರೌಸರ್ನ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಅಥವಾ ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಕಲ್ಪಿಸಿಕೊಡಬಹುದು. ಗಮನಿಸಿ: ಈ ಅನುಮತಿಯನ್ನು ವೆಬ್ ಬ್ರೌಸಿಂಗ್ ಸಾಮರ್ಥ್ಯಗಳನ್ನು ಹೊಂದಿರುವ ಮೂರನೇ-ವ್ಯಕ್ತಿ ಬ್ರೌಸರ್ಗಳು ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಮೂಲಕ ಜಾರಿಗೊಳಿಸಲಾಗುವುದಿಲ್ಲ."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ಅಲಾರಮ್ ಹೊಂದಿಸಿ"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"ಸ್ಥಾಪಿಸಲಾದ ಅಲಾರಾಂ ಗಡಿಯಾರ ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ ಅಲಾರಾಂ ಹೊಂದಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಕೆಲವು ಅಲಾರಾಂ ಗಡಿಯಾರ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸದಿರಬಹುದು."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"ಧ್ವನಿಮೇಲ್ಗಳನ್ನು ಬರೆಯಿರಿ"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"ನಿಮ್ಮ ಧ್ವನಿಮೇಲ್ ಇನ್ಬಾಕ್ಸ್ನಿಂದ ಸಂದೇಶಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಮತ್ತು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ಧ್ವನಿಮೇಲ್ ಸೇರಿಸಿ"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"ನಿಮ್ಮ ದ್ವನಿಮೇಲ್ ಇನ್ಬಾಕ್ಸ್ಗೆ ಸಂದೇಶಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"ಧ್ವನಿಮೇಲ್ ಓದಿ"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"ನಿಮ್ಮ ಎಲ್ಲಾ ಧ್ವನಿಮೇಲ್ಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ಬ್ರೌಸರ್ ಜಿಯೋಲೊಕೇಶನ್ ಅನುಮತಿಗಳನ್ನು ಮಾರ್ಪಡಿಸಿ"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ಬ್ರೌಸರ್ನ ಜಿಯೋಲೊಕೇಶನ್ ಅನುಮತಿಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಅನಿರ್ಬಂಧಿತ ವೆಬ್ ಸೈಟ್ಗಳಿಗೆ ಸ್ಥಳ ಮಾಹಿತಿ ಕಳುಹಿಸುವುದನ್ನು ಅನುಮತಿಸಲು ಇದನ್ನು ಬಳಸಬಹುದು."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"ಪ್ಯಾಕೇಜ್ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 1afab473..7b9c05a 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1390,10 +1390,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"애플리케이션이 Trust Agent 서비스에 바인딩할 수 있도록 허용합니다."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"업데이트 및 복구 시스템과 상호작용"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"애플리케이션이 복구 시스템 및 시스템 업데이트와 상호작용할 수 있도록 허용합니다."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"미디어 프로젝션 세션 만들기"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"애플리케이션이 미디어 프로젝션 세션을 만드는 것을 허용합니다. 이 세션은 애플리케이션에 디스플레이 및 오디오 컨텐츠를 캡처하는 기능을 제공할 수 있습니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"확대/축소하려면 두 번 터치하세요."</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"위젯을 추가할 수 없습니다."</string>
<string name="ime_action_go" msgid="8320845651737369027">"이동"</string>
@@ -1518,20 +1516,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"수정"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"데이터 사용 경고"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"사용량 및 설정을 보려면 터치하세요."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G-3G 데이터 사용 중지됨"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G 데이터 사용 중지됨"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"이동통신 데이터 사용 중지됨"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Wi-Fi 데이터 사용 중지됨"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"한도 도달"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G - 3G 데이터 제한 초과됨"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4GB의 데이터 제한 초과됨"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"이동통신 데이터 한도 초과"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi 데이터 한도 초과됨"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> - 지정된 한도 초과"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"백그라운드 데이터 사용이 제한됨"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index cdc2b47..5eb55c1 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Leidžiama programai keisti naršyklės istoriją ar žymes, išsaugotas telefone. Dėl to programai gali būti leidžiama ištrinti ar keisti naršyklės duomenis. Pastaba: šis leidimas nesuteikiamas trečiosios šalies naršyklėms ar kitoms programoms, kuriomis galima naršyti žiniatinklį."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"nustatyti pavojaus signalą"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Leidžiama programai nustatyti signalą įdiegtoje žadintuvo programoje. Kai kuriose žadintuvo programose ši funkcija gali nebūti nevykdoma."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"rašyti balso pašto pranešimus"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Programai leidžiama keisti ir šalinti pranešimus iš balso pašto gautųjų."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"pridėti balso pašto pranešimų"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Leidžia programai pridėti pranešimų prie jūsų balso pašto gautųjų."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"skaityti balso pašto pranešimus"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Programai leidžiama skaityti balso pašto pranešimus."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"keisti naršyklės geografinės vietos leidimus"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Leidžiama programai keisti naršyklės geografinės vietos leidimus. Kenkėjiškos programos gali tai naudoti, kad leistų siųsti vietos informaciją abejotinoms svetainėms."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"patikrinti paketus"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Programai leidžiama susisaistyti su „trust agent“ paslauga."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Sąveikauti su naujiniu ir atkūrimo sistema"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Programai leidžiama sąveikauti su atkūrimo sistema ir sistemos naujiniais."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Kurti medijos projekcijų seansus"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Programai leidžiama kurti medijos projekcijų seansus. Sukūrusios šiuos seansus, programos gali fiksuoti vaizdo ir garso turinį. To niekada neturėtų prireikti naudojant įprastas programas."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dukart palieskite, kad valdytumėte mastelio keitimą"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nepavyko pridėti."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Pradėti"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Redaguoti"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Įspėjimas dėl duomenų naudojimo"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Palieskite ir žr. naud. ir nust."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G–3G duomenys išjungti"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G duomenys išjungti"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Mobil. ryšio duomenys išjungti"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"„Wi-Fi“ duomenys išjungti"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Pasiektas limitas"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Viršyta 2G–3G duomenų riba"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Viršyta 4G duomenų riba"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Viršytas mobil. duom. limitas"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Viršytas „Wi-Fi“ duomenų aprib."</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> viršyta nurodyta riba."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Apriboti foniniai duomenys"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 66a4fad..f005960 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ļauj lietotnei mainīt tālrunī saglabāto pārlūkprogrammas vēsturi vai grāmatzīmes. Tas var ļaut lietotnei dzēst vai pārveidot pārlūkprogrammas datus. Piezīme: šo atļauju nevar piemērot trešo pušu pārlūkprogrammas vai citas lietojumprogrammas ar tīmekļa pārlūkošanas iespējām."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"iestatīt modinātāju"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Ļauj lietotnei iestatīt signālu instalētajā modinātājpulksteņa lietotnē. Dažās modinātājpulksteņu lietotnēs šo funkciju, iespējams, nevar ieviest."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"rakstīt balss pasta ziņojumus"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Ļauj lietotnei rediģēt un noņemt ziņojumus no jūsu balss pasta iesūtnes."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"pievienot balss pastu"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ļauj lietotnei pievienot ziņojumus jūsu balss pasta iesūtnei."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"lasīt balss pastu"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Ļauj lietotnei lasīt jūsu balss pasta ziņojumu."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"pārveidot pārlūkprogrammas ģeogrāfiskās atrašanās vietas atļaujas"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Ļauj lietotnei modificēt pārlūkprogrammas ģeogrāfiskās atrašanās vietas atļaujas. Ļaunprātīgas lietotnes to var izmantot, lai atļautu atrašanās vietas informācijas sūtīšanu uz citām vietnēm."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"pakotņu verificēšana"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Ļauj lietojumprogrammai izveidot savienojumu ar uzticamības pārbaudes pakalpojumu."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Mijiedarbošanās ar atjauninājumu un atkopšanas sistēmu"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Ļauj lietojumprogrammai mijiedarboties ar atkopšanas sistēmu un sistēmas atjauninājumiem."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Izveidot satura projekcijas sesijas"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Ļauj lietojumprogrammai izveidot satura projekcijas sesijas. Šīs sesijas var atļaut lietojumprogrammām uzņemt ekrāna un skaņas saturu. Parastām lietotnēm tas nekad nav nepieciešams."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Pieskarieties divreiz, lai kontrolētu tālummaiņu."</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nevarēja pievienot logrīku."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Doties uz"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Rediģēt"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Datu izmantošanas brīdinājums"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Piesk., lai sk. lietoš. un iest."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G–3G dati ir atslēgti"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G dati ir atslēgti"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Mobilie dati ir atslēgti"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Wi-Fi dati ir atslēgti"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Sasniegts ierobežojums"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G datu ierobež. pārsniegts"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G datu limits pārsniegts"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Pārsniegts mob. datu ierobežojums"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi datu ierobež. pārsniegts"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> virs norādītā ierobežojuma."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Fona dati ir ierobežoti."</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 5636655..d49a824 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Овозможува апликацијата да ја менува историјата на прелистувачот или обележувачите зачувани во вашиот телефон. Ова може да овозможи апликацијата да избрише или да измени податоци за прелистувач. Напомена: оваа дозвола не може да ја наметнат прелистувачи на трети лица или други апликации со способности за прелистување на интернет."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"постави аларм"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Дозволува апликацијата да постави аларм во инсталираната апликација со будилник. Некои апликации со будилници може да не ја применуваат оваа можност."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"пишувај говорна пошта"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Ѝ дозволува на апликацијата да ги менува и да ги отстранува пораките од приемното сандаче за говорна пошта."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"додај говорна пошта"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Дозволува апликацијата да додава пораки во сандачето за гласовна пошта."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"читај говорна пошта"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Ѝ дозволува на апликацијата да ги чита говорните пораки."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"измени дозволи за геолокација на прелистувач"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Дозволува апликацијата да ги измени дозволите за геолокација на прелистувачот. Злонамерните апликации може да го искористат тоа за да се дозволи испраќање информации за локација до случајни веб-локации."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"потврди пакети"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Дозволува апликацијата да се поврзе со услуга за агенти за доверба."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Комуницирај со системот за обновување и ажурирање"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Овозможува апликацијата да комуницира со системот за обновување и ажурирање."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Создади сесии за проектирање на медиуми"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Дозволува апликацијата да создава сесии за проектирање на медиуми. Овие сесии им обезбедуваат можност на апликациите да снимаат екранска и аудиосодржина. Не би требало да се користи кај вообичаени апликации."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Допрете двапати за регулирање на зумирањето"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Не можеше да се додаде виџет."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Оди"</string>
@@ -1520,20 +1514,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Уреди"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Предупредување за користење податоци"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Допри за да видиш употреба и подесувања."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"Податоците 2G-3G се исклучени"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"Податоците 4G се исклучени"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Мобилните податоци се исклучени"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Подат. преку Wi-Fi се исклучени"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Го достигнавте лимитот"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Надминат лимит од 2G-3G податоци"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Надминат лимит од 4G податоци"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Лимитот за моб. подат. е надминат"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Надминат лимит на Wi-Fi податоци"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> над назначената граница."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Подат. од заднина се ограничени"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 4760788..9115ba2 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"നിങ്ങളുടെ ഫോണിൽ സംഭരിച്ചിരിക്കുന്ന ബ്രൗസറിന്റെ ചരിത്രമോ ബുക്ക്മാർക്കുകളോ പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് ബ്രൗസർ ഡാറ്റ മായ്ക്കാനോ പരിഷ്ക്കരിക്കാനോ അപ്ലിക്കേഷനെ അനുവദിക്കാനിടയുണ്ട്. ശ്രദ്ധിക്കുക: ഈ അനുമതി മൂന്നാം കക്ഷി ബ്രൗസറുകളോ വെബ് ബ്രൗസിംഗ് കഴിവുകളുള്ള മറ്റ് അപ്ലിക്കേഷനുകളോ നടപ്പിലാക്കാനിടയില്ല."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ഒരു അലാറം സജ്ജീകരിക്കുക"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"ഒരു ഇൻസ്റ്റാളുചെയ്ത അലാറം ക്ലോക്ക് അപ്ലിക്കേഷനിൽ അലാറം സജ്ജീകരിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ചില അലാറം ക്ലോക്ക് അപ്ലിക്കേഷനുകൾ ഈ സവിശേഷത നടപ്പിലാക്കാതിരുന്നേക്കാം."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"വോയ്സ്മെയിലുകൾ റൈറ്റുചെയ്യുക"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"നിങ്ങളുടെ വോയ്സ്മെയിൽ ഇൻബോക്സിൽ നിന്നും സന്ദേശങ്ങൾ പരിഷ്ക്കരിക്കാനും നീക്കംചെയ്യാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"വോയ്സ് മെയിൽ ചേർക്കുക"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"നിങ്ങളുടെ വോയ്സ്മെയിൽ ഇൻബോക്സിലേക്ക് സന്ദേശങ്ങൾ ചേർക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"വോയ്സ്മെയിൽ റീഡുചെയ്യുക"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"നിങ്ങളുടെ വോയ്സ്മെയിലുകൾ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ബ്രൗസർ ജിയോലൊക്കേഷൻ അനുമതികൾ പരിഷ്ക്കരിക്കുക"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ബ്രൗസറിന്റെ ജിയോലൊക്കേഷൻ അനുമതികളെ പരിഷ്ക്കരിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. അനിയന്ത്രിതമായ വെബ്സൈറ്റുകളിലേക്ക് ലൊക്കേഷൻ വിവരം അയയ്ക്കാൻ അനുവദിക്കുന്നതിന് ദോഷകരമായ അപ്ലിക്കേഷനുകൾ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"പാക്കേജുകൾ പരിശോധിച്ചുറപ്പിക്കുക"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 73ff335..30e0efb 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"आपल्या फोनवर संचयित केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अनुप्रयोगांद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"अलार्म सेट करा"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"स्थापित केलेल्या अलार्म घड्याळ अॅपमध्ये अलार्म सेट करण्यासाठी अॅप ला अनुमती देते. काही अलार्म घड्याळ अॅप्स हे वैशिष्ट्य लागू करू शकत नाहीत."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"व्हॉइसमेल लिहा"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"आपल्या व्हॉइसमेल इनबॉक्समधील संदेश सुधारित करण्यासाठी आणि ते काढण्यासाठी अॅप ला अनुमती देते."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"व्हॉइसमेल जोडा"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"आपल्या व्हॉइसमेल इनबॉक्समध्ये संदेश जोडण्यासाठी अॅप ला अनुमती देते."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"व्हॉइसमेल वाचा"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"आपले व्हॉइसमेल वाचण्याची अॅपला अनुमती देते."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ब्राउझर भौगोलिक स्थान परवानग्या सुधारित करा"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ब्राउझरच्या भौगोलिक स्थान परवानग्या सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स यादृच्छिक वेबसाइटवर स्थान माहिती पाठविण्यास अनुमती देण्यासाठी याचा वापर करू शकतात."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"पॅकेज सत्यापित करा"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 5fedab5..fc823ee 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1752,25 +1752,16 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dipadamkan"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Kerja <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_toast (2126866321272822564) -->
- <skip />
+ <string name="lock_to_app_toast" msgid="2126866321272822564">"Anda berada dalam mod kunci ke apl. Untuk keluar, sentuh dan tahan butang Terbaru"</string>
<string name="lock_to_app_toast_locked" msgid="4229650395479263497">"Anda berada dalam mod Kunci ke Apl."</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"Gunakan kunci ke apl?"</string>
- <!-- no translation found for lock_to_app_description (2800403592608529611) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (2259143719362732728) -->
- <skip />
+ <string name="lock_to_app_description" msgid="2800403592608529611">"Kunci dalam apl mengunci paparan dalam apl tunggal.\n\nUntuk keluar, sentuh dan tahan butang Terbaru."</string>
+ <string name="lock_to_app_negative" msgid="2259143719362732728">"TIDAK, TERIMA KASIH"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"MULA"</string>
- <!-- no translation found for lock_to_app_start (3074665051586318340) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (8967089657201849300) -->
- <skip />
- <!-- no translation found for lock_to_app_use_screen_lock (1434584309048590886) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_pin (7908385370846820001) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_pattern (7763071104790758405) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_password (795224196583495868) -->
- <skip />
+ <string name="lock_to_app_start" msgid="3074665051586318340">"Dikunci ke apl"</string>
+ <string name="lock_to_app_exit" msgid="8967089657201849300">"Tidak lagi dikunci ke apl"</string>
+ <string name="lock_to_app_use_screen_lock" msgid="1434584309048590886">"Minta %1$s sebelum keluar"</string>
+ <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"corak buka kunci"</string>
+ <string name="lock_to_app_unlock_password" msgid="795224196583495868">"kata laluan"</string>
</resources>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index f3fc7cc..46b536a 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"အပလီကေးရှင်းအား ဘရောင်ဇာမှ မှတ်တမ်း သို့ မှတ်သားမှု အမှတ်များအား ပြင်ဆင်ခွင့် ပေးခြင်း။ အပလီကေးရှင်းမှ ဘရောင်ဇာ မှတ်တမ်းများကို ဖျက်ပစ်ခွင့် သို့ ပြင်ဆင်ခွင့် ရှိပါမည်။ မှတ်ချက်။ ဒီခွင့်ပြုချက်ကို တတိယပါတီ ဘရောင်ဇာများ၊ တခြား အပလီကေးရှင်းများမှ သုံးမည် မဟုတ်ပါ။"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"နှိုးစက်သတ်မှတ်ရန်"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"appအား တပ်ဆင်ထားသည့် နှိုးစက်နာရီ app ထဲတွင် နှိုးစက်ကို သတ်မှတ်ခွင့် ပြုသည်။ အချို့ နှိုးစက် appများက ထိုအင်္ဂါရပ်ကို ပြီးမြောက်အောင် မလုပ်နိုင်ကြပါ။"</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"အသံမေးလ်ကို ရေးရန်"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"appအား သင်၏ အသံမေးလ် ဝင်စာများကို မွမ်းမံခွင့် နှင့် ဖယ်ရှားခွင့် ပြုသည်။"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"အသံစာပို့စနစ်အားထည့်ရန်"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"appအား သင့် အသံမေးလ် ဝင်စာသို့ စာများကို ထည့်ခွင့် ပြုသည်။"</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"အသံမေးလ်ကို ဖတ်ရန်"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"appအား သင်၏ အသံမေးလ်များကို ဖတ်ခွင့် ပြုရန်"</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ဘရောင်ဇာ ဘူမိဇုန်သတ်မှတ်မှု ခွင့်ပြုချက်များကို မွမ်းမံခြင်း"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"appအား ဘရောင်ဇာ၏ ဘူမိဇုန်သတ်မှတ်ရေး ခွင့်ပြုချက်များကို မွမ်းမံခွင့် ပြုသည်။ ကြံဖန် appများက ၎င်းကို အသုံးချပြီး လိုရာ ဝက်ဘ်ဆိုက်များသို့ တည်နေရာ အချက်အလက် ပို့မှုကို လုပ်နိုင်သည်။"</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"packages များကိုအတည်ပြုစိစစ်ခြင်း"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 502e0b8..d8efcc6 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"stille alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Lar appen stille inn alarmen for en installert alarmklokke-app. Enkelte alarmklokke-apper implementerer kanskje ikke denne funksjonen."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"skrive talepost"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Lar appen endre og fjerne meldinger fra talepostkassen."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"legge til talepost"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Lar appen legge til meldinger i talepostkassen din."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"lese talepost"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Lar appen lese taleposten din."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"endre nettleserens tillatelser for geoposisjonering"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Lar appen endre nettleserens tillatelser for geoposisjonering. Ondsinnede apper kan bruke dette for å tillate sending av posisjonsinformasjon til vilkårlige nettsteder."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"bekrefte pakker"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index bff75b5..d5b152d 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1398,10 +1398,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"विश्वस्त प्रतिनिधि सेवालाई बाँध्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
<string name="permlab_recovery" msgid="3157024487744125846">"अद्यावधिक र रिकभरी प्रणालीको साथ अन्तर्क्रिया"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"अनुप्रयोगलाई रिकभरी प्रणाली र प्रणाली अद्यावधिकहरूको साथ अन्तर्क्रिया गर्न अनुमति दिन्छ।"</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"मिडिया प्रक्षेपण सत्रहरू सिर्जना गर्नुहोस्"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"मिडिया प्रक्षेपण सत्र सिर्जना गर्न अनुप्रयोग लाई अनुमति दिन्छ। यी सत्रले प्रदर्शन र अडियो सामग्री खिच्ने क्षमताका अनुप्रयोगहरू प्रदान गर्न सक्छन्। सामान्य अनुप्रयोगहरूको कहिल्यै पनि आवश्यक पर्दैन।"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"जुम नियन्त्रणको लागि दुई चोटि टच गर्नुहोस्"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"विजेट थप गर्न सकिँदैन।"</string>
<string name="ime_action_go" msgid="8320845651737369027">"जानुहोस्"</string>
@@ -1526,20 +1524,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"सम्पादन गर्नुहोस्"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"डेटा प्रयोग चेतावनी"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"उपयोग र सेटिङहरू हेर्न छुनुहोस्।"</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G-3G डेटा बन्द छ"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G डेटा बन्द छ"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"सेलुलर डेटा बन्द छ"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"वाइफाइ डेटा बन्द छ"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"सिमा पुग्यो"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G डेटा सीमा भन्दा पार भएको छ"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G डेटा SIMा नाघ्यो"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"सेलुलर डेटा सीमा नाघ्यो"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"वाइफाइ डेटा SIMा नाघ्यो"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> उल्लेखित सीमा भन्दा बढी छ।"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"पृष्ठभूमिका डेटा प्रतिबन्धित गरिएको छ"</string>
@@ -1760,25 +1752,18 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> चयन गरियो"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> हटाइयो"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_toast (2126866321272822564) -->
- <skip />
+ <string name="lock_to_app_toast" msgid="2126866321272822564">"तपाईँ अनुप्रयोग बन्द गर्ने ढाँचामा हुनुहुन्छ। निस्कनका लागि हालैको अनुप्रयोगहरूका बटन थिच्नुहोस् र समाउनुहोस्।"</string>
<string name="lock_to_app_toast_locked" msgid="4229650395479263497">"तपाईं Lock-to-App मोडमा हुनुहुन्छ।"</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"लक-देखि-अनुप्रयोग प्रयोग गर्ने?"</string>
- <!-- no translation found for lock_to_app_description (2800403592608529611) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (2259143719362732728) -->
- <skip />
+ <string name="lock_to_app_description" msgid="2800403592608529611">"लक-गर्न अनुप्रयोगले एकल अनुप्रयोगमा प्रदर्शन बन्द गर्छ।\n\n,निस्कनका लागि हालैको अनुप्रयोगहरूका बटन थिच्नुहोस् र समाउनुहोस्।"</string>
+ <string name="lock_to_app_negative" msgid="2259143719362732728">"होइन, धन्यवाद"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"START"</string>
- <!-- no translation found for lock_to_app_start (3074665051586318340) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (8967089657201849300) -->
- <skip />
+ <string name="lock_to_app_start" msgid="3074665051586318340">"अनुप्रयोग बन्द"</string>
+ <string name="lock_to_app_exit" msgid="8967089657201849300">"अनुप्रयोग अब बन्द छैन"</string>
+ <!-- String.format failed for translation -->
<!-- no translation found for lock_to_app_use_screen_lock (1434584309048590886) -->
<skip />
- <!-- no translation found for lock_to_app_unlock_pin (7908385370846820001) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_pattern (7763071104790758405) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_password (795224196583495868) -->
- <skip />
+ <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"शैली बन्द गर्नुहोस"</string>
+ <string name="lock_to_app_unlock_password" msgid="795224196583495868">"पासवर्ड"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 89c18a2..7bcbbe2 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op uw telefoon. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"een alarm instellen"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Hiermee kan de app een alarm instellen in een geïnstalleerde wekkerapp. Deze functie wordt door sommige wekkerapps niet geïmplementeerd."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"voicemails schrijven"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Hiermee kan de app berichten in de inbox van uw voicemail aanpassen en verwijderen."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"voicemail toevoegen"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Hiermee kan de app berichten toevoegen aan de inbox van uw voicemail."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"voicemail lezen"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Hiermee kan de app uw voicemails lezen."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"geolocatierechten voor browser aanpassen"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Hiermee kan de app de geolocatierechten van de browser aanpassen. Schadelijke apps kunnen dit gebruiken om locatiegegevens te verzenden naar willekeurige websites."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"pakketten controleren"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 9da0d6d..3822c4e 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Pozwala aplikacji na modyfikowanie historii i zakładek przeglądarki zapisanych na telefonie. Aplikacja będzie mogła usunąć lub zmodyfikować dane przeglądarki. Uwaga: to uprawnienie może nie być egzekwowane przez przeglądarki innych firm oraz inne aplikacje z możliwością przeglądania internetu."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ustawianie alarmu"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Pozwala aplikacji na ustawienie alarmu w zainstalowanej aplikacji budzika. Funkcja ta może nie być zaimplementowana w niektórych aplikacjach tego typu."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"zapisywanie poczty głosowej"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Zezwala aplikacji na modyfikowanie i usuwanie Twoich odebranych wiadomości poczty głosowej."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"dodawanie poczty głosowej"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Pozwala aplikacji na dodawanie wiadomości do skrzynki odbiorczej poczty głosowej."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"odczytywanie poczty głosowej"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Zezwala aplikacji na odczytywanie poczty głosowej."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modyfikowanie pozwoleń przeglądarki dotyczących lokalizacji geograficznej"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Pozwala aplikacji na modyfikowanie uprawnień przeglądarki dotyczących lokalizacji geograficznej. Złośliwe aplikacje mogą używać tej opcji do wysyłania informacji o lokalizacji do dowolnych witryn."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"weryfikowanie pakietów"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 6769153..5941e18 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite que a aplicação modifique o histórico do Navegador ou marcadores guardados no telemóvel. Isto pode permitir que a aplicação apague ou modifique dados do Navegador. Nota: esta autorização pode não ser aplicada por navegadores de terceiros ou outras aplicações com capacidades de navegação na Web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"definir um alarme"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que a aplicação defina um alarme numa aplicação de despertador instalada. Algumas aplicações de despertador podem não integrar esta funcionalidade."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"escrever mensagens de correio de voz"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Permite que a aplicação modifique e remova mensagens da caixa de entrada de correio de voz."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"adicionar correio de voz"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite que a aplicação adicione mensagens à sua caixa de entrada de correio de voz."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"ler correio de voz"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Permite que a aplicação leia as mensagens de correio de voz."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modificar permissões de geolocalização do Navegador"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite que a aplicação modifique as permissões de geolocalização do navegador. As aplicações maliciosas podem usar isto para permitir o envio de informações de localização para Web sites arbitrárias."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"verificar pacotes"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 024d827..f1a4b96 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1390,10 +1390,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permite unei aplicații să se asocieze la un serviciu „agent de încredere”."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Interacțiune cu sistemul de recuperare și de actualizare"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Permite unei aplicații să interacționeze cu sistemul de recuperare și cu actualizările de sistem."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Creați sesiuni de proiecție media"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Permite unei aplicații să creeze sesiuni de proiecție media. Aceste sesiuni pot permite aplicațiilor să captureze conținuturi vizuale și audio. Nu trebuie utilizată pentru aplicații obișnuite."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Atingeţi de două ori pentru a mări/micşora"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nu s-a putut adăuga widgetul."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Accesaţi"</string>
@@ -1518,20 +1516,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Editaţi"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Avertisment de utiliz. a datelor"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Atingeţi pt. a afişa utiliz./set."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"Datele 2G-3G sunt dezactivate"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"Datele 4G sunt dezactivate"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Datele mobile sunt dezactivate"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Datele Wi-Fi sunt dezactivate"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Limita a fost atinsă"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"S-a depăşit limita de date 2G-3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"S-a depăşit limita de date 4G"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Limită de date mobile depășită"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"S-a depăşit limita de date Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> peste limita specificată."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Datele de fundal restricţionate"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 218c3a54..d74a215 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1390,10 +1390,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Приложение сможет подключаться к службе Trust Agents."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Взаимодействовать с системой восстановления и обновлениями"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Приложение сможет взаимодействовать с системой восстановления и обновлениями системы."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Создание сеансов трансляции контента"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Создание сеансов трансляции контента, во время которых приложение получит доступ к изображению на экране и аудио. Это разрешение обычно используется только специальными приложениями."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Нажмите дважды для изменения масштаба"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Не удалось добавить виджет."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Выбрать"</string>
@@ -1518,20 +1516,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Изменить"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Осталось мало трафика"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Проверьте трафик и настройки."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"Передача данных 2G/3G отключена"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"Передача данных 4G отключена"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Передача мобильных данных отключена"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Передача данных Wi-Fi отключена"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Достигнут лимит"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Превышен лимита трафика 2G и 3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Превышен лимит на трафик 4G"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Превышен лимит мобильного трафика"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Превышен лимит трафика Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"Лимит превышен на <xliff:g id="SIZE">%s</xliff:g>."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Фоновый режим ограничен"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 331db28..38b153d 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1755,25 +1755,16 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> තෝරාගෙන ඇත"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> මකා දමන ලදි"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_toast (2126866321272822564) -->
- <skip />
+ <string name="lock_to_app_toast" msgid="2126866321272822564">"යෙදුමට-අඟුළු දැමීමේ ආකාරය තුළ ඔබ සිටි. පිටවීමට, මෑත යෙදුම් බොත්තම ඔබා අල්ලා ගෙන සිටින්න"</string>
<string name="lock_to_app_toast_locked" msgid="4229650395479263497">"යෙදුමට-අඟුළු දැමීමේ ආකාරය තුළ ඔබ සිටි."</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"අගුළු-යෙදුම භාවිතා කරන්නද?"</string>
- <!-- no translation found for lock_to_app_description (2800403592608529611) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (2259143719362732728) -->
- <skip />
+ <string name="lock_to_app_description" msgid="2800403592608529611">"අගුළු-යෙදුම තනි යෙදුමක පෙනුම අගුළු දමයි.\n\nඉවත්ව යාමට මෑත යෙදුම් බොත්තම ඔබා රඳවා ගන්න"</string>
+ <string name="lock_to_app_negative" msgid="2259143719362732728">"නැත, ස්තූතියි"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"ආරම්භය"</string>
- <!-- no translation found for lock_to_app_start (3074665051586318340) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (8967089657201849300) -->
- <skip />
- <!-- no translation found for lock_to_app_use_screen_lock (1434584309048590886) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_pin (7908385370846820001) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_pattern (7763071104790758405) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_password (795224196583495868) -->
- <skip />
+ <string name="lock_to_app_start" msgid="3074665051586318340">"යෙදුමට-අඟුළු දැමීම"</string>
+ <string name="lock_to_app_exit" msgid="8967089657201849300">"යෙදුමට අඟුළු දැමීම තවදුරටත් නැත"</string>
+ <string name="lock_to_app_use_screen_lock" msgid="1434584309048590886">"පිටවීමට පෙර %1$s සඳහා ආසන්න"</string>
+ <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"අඟුළු ඇරීමේ රටාව"</string>
+ <string name="lock_to_app_unlock_password" msgid="795224196583495868">"මුරපදය"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 00f22bb..63bb72b 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1390,10 +1390,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Umožňuje aplikácii viazať sa na službu zástupcu dôveryhodnosti."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Interakcia so systémom aktualizácií a obnovenia"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Umožňuje aplikácii interakciu so systémom obnovenia a s aktualizáciami systému."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Vytváranie relácií projekcie médií"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Umožňuje aplikácii vytvárať relácie projekcie médií. Tieto relácie môžu aplikáciám umožniť zaznamenávať obsah na obrazovke a zvukový obsah. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Ovládacie prvky lupy zobrazíte dvojitým dotknutím"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Miniaplikáciu sa nepodarilo pridať."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Hľadať"</string>
@@ -1518,20 +1516,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Upraviť"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Upozornenie o využití dát"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Zobr. využív. dát a nastavení."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"dáta 2G–3G sú vypnuté"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"dáta 4G sú vypnuté"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Mobilné dáta sú vypnuté"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Dáta siete Wi-Fi sú vypnuté"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Dosiahli ste limit"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G, 3G dátový limit prekročený"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Dátový limit 4G bol prekročený"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Presiahli ste limit mobil. dát"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Dát. limit Wi-Fi bol prekročený"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> nad stanovenou hranicou."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Údaje na pozadí sú obmedzené"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index bfc28ca..cda7606 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1186,9 +1186,9 @@
<string name="whichApplicationNamed" msgid="8260158865936942783">"Dokončanje dejanja z aplikacijo %1$s"</string>
<string name="whichViewApplication" msgid="3272778576700572102">"Odpiranje z aplikacijo"</string>
<string name="whichViewApplicationNamed" msgid="2286418824011249620">"Odpiranje z aplikacijo %1$s"</string>
- <string name="whichEditApplication" msgid="144727838241402655">"Urejanje z"</string>
+ <string name="whichEditApplication" msgid="144727838241402655">"Urejanje z aplikacijo"</string>
<string name="whichEditApplicationNamed" msgid="1775815530156447790">"Urejanje z aplikacijo %1$s"</string>
- <string name="whichSendApplication" msgid="6902512414057341668">"Skupna raba z"</string>
+ <string name="whichSendApplication" msgid="6902512414057341668">"Skupna raba z aplikacijo"</string>
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"Skupna raba z aplikacijo %1$s"</string>
<string name="whichHomeApplication" msgid="4616420172727326782">"Izberite aplikacijo za začetno stran"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Privzeta uporaba za to dejanje."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 25e3c8d..c234818 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Дозвољава апликацији да мења историју Прегледача или обележиваче ускладиштене на телефону. Ово може да омогући апликацији да брише или мења податке Прегледача. Напомена: Ова дозвола се можда на примењује на прегледаче треће стране и друге апликације са могућношћу веб прегледања."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"подешавање аларма"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Дозвољава апликацији да подеси аларм у инсталираној апликацији будилника. Неке апликације будилника можда не примењују ову функцију."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"пиши поруке говорне поште"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Дозвољава апликацији да мења и уклања поруке из пријемног сандучета говорне поште."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"додавање говорне поште"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Дозвољава апликацији да додаје поруке у пријемно сандуче говорне поште."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"читај говорну пошту"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Дозвољава апликацији да чита поруке говорне поште."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"измена дозвола за географске локације Прегледача"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Дозвољава апликацији да измени дозволе Прегледача за утврђивање географске локације. Злонамерне апликације то могу да злоупотребе и искористе за слање информација о локацији насумичним веб сајтовима."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"верификовање пакета"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Дозвољава апликацији да се веже за услугу Trust agents."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Интеракција са системом за ажурирање и опоравак"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Дозвољава апликацији да ступа у интеракцију са системом за опоравак и ажурирањима система."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Прави сесије пројекција медија"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Омогућава апликацији да прави сесије пројекција медија. Ове сесије могу да омогуће апликацијама да снимају садржај на екрану или аудио садржај. Никада не би требало да буде потребно за стандардне апликације."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Додирните двапут да бисте контролисали зум"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Није могуће додати виџет."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Иди"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Измени"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Упозорење о потрошњи података"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Додирните за преглед кор. и под."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G–3G подаци су искључени"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G подаци су искључени"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Мобилни подаци су искључени"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Wi-Fi подаци су искључени"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Ограничење је достигнуто"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Прекорачен пренос 2G-3G података"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Прекорачење преноса 4G података"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Ограничење мобилних података је прекорачено"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Прекорачење преноса Wi-Fi подат."</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> преко наведеног ограничења."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Позадински подаци су ограничени"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 6b885d9..913bc90 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Tillåter att appen ändrar historiken för besökta sidor i webbläsaren eller bokmärken som sparats på telefonen. Det kan innebära att appen kan ta bort eller ändra webbläsarinformation. Observera att den här behörigheten kanske inte är tillämplig för webbläsare från tredje part eller andra appar med surffunktion."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ställa in ett alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Tillåter att appen ställer in ett alarm i en befintlig alarmapp. Vissa alarmappar har inte den här funktionen."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"skriva röstmeddelanden"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Tillåter att appen ändrar och tar bort meddelanden från röstbrevlådans inkorg."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"lägg till röstbrevlåda"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Gör att appen lägger till meddelanden i röstbrevlådans inkorg."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"läsa röstmeddelanden"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Tillåter att appen läser dina röstmeddelanden."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Ändra geografisk plats för webbläsaren"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Tillåter att appen ändrar webbläsarens behörigheter för geografisk plats. Skadliga appar kan använda detta för att tillåta att platsinformation skickas till godtyckliga webbplatser."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"kontrollera paket"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index a9c3c52..acbef24 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -719,8 +719,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Inaruhusu kishikilizi kuunganishwa kwenye kusano cha kiwango cha juu cha huduma ya kisikilizi cha arifa. Haipaswi kuhitajika tena kwa programu za kawaida."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"bandika kwenye huduma ya mtoa masharti"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Humruhusu mmiliki kubandika kwenye kiolesura cha kiwango cha juu cha huduma ya mtoa masharti. Isihitajike kamwe kwa pogramu za kawaida."</string>
- <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"shurutisha kwa huduma ya njia za sauti, picha na video."</string>
- <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Humruhusu mmiliki kushurutisha kwa kiolesura cha ngazi ya juu cha huduma ya njia za sauti, picha na video. Haipaswi kuhitajika kwa programu za kawaida."</string>
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"bandika kwenye huduma ya njia za sauti, picha na video."</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Humruhusu mmiliki kubandika kwenye kiolesura cha ngazi ya juu cha huduma ya njia za sauti, picha na video. Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"shurutisha kwa huduma murua"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Huruhusu mmiliki kushurutisha kwenye kiolesura cha kiwango cha juu cha huduma murua. Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"omba programu ya usakinishaji inayotolewa na mtoa huduma."</string>
@@ -1292,10 +1292,10 @@
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Ruhusu Kila mara"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Usiruhusu Kamwe"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM kadi imeondolewa"</string>
- <string name="sim_removed_message" msgid="5450336489923274918">"Mtandao wa simu za mkononi hautapatikana hadi utakapoanzisha tena kifaa chako kikiwa kimeingizwa SIM kadi sahihi."</string>
+ <string name="sim_removed_message" msgid="5450336489923274918">"Mitandao ya simu za mkononi haitapatikana hadi utakapozima na kuwasha tena kifaa chako kikiwa kimeingizwa SIM kadi sahihi."</string>
<string name="sim_done_button" msgid="827949989369963775">"Nimemaliza"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM kadi imeongezwa"</string>
- <string name="sim_added_message" msgid="7797975656153714319">"Anzisha kifaa chako tena ili ufikie mitandao ya simu za mkononi."</string>
+ <string name="sim_added_message" msgid="7797975656153714319">"Zima na uwashe kifaa chako tena ili ufikie mitandao ya simu za mkononi."</string>
<string name="sim_restart_button" msgid="4722407842815232347">"Anza upya"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Weka muda"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Weka tarehe"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index e74feb4..eacc824 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"உங்கள் மொபைலில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த பயன்பாட்டை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ பயன்பாட்டை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற பயன்பாடுகள் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"அலாரத்தை அமைத்தல்"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"நிறுவிய அலார கடிகாரப் பயன்பாட்டில் அலாரத்தை அமைக்க, பயன்பாட்டை அனுமதிக்கிறது. சில அலார கடிகார பயன்பாடுகளில் இந்த அம்சம் இல்லாமல் இருக்கலாம்."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"குரலஞ்சல்களை எழுது"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"குரலஞ்சல் இன்பாக்ஸிலிருந்து செய்திகளைத் திருத்தவும் அகற்றவும், பயன்பாட்டை அனுமதிக்கிறது."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"குரலஞ்சலைச் சேர்த்தல்"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"குரலஞ்சல் இன்பாக்ஸில் செய்திகளைச் சேர்க்க, பயன்பாட்டை அனுமதிக்கிறது."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"குரலஞ்சலைப் படி"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"குரலஞ்சல்களைப் படிக்கப் பயன்பாட்டை அனுமதிக்கிறது."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்துதல்"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்த, பயன்பாட்டை அனுமதிக்கிறது. இடத் தகவலை தன்னிச்சையான இணையதளங்களுக்கு அனுப்புவதை அனுமதிக்க, தீங்குவிளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"தொகுப்புகளைச் சரிபார்த்தல்"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index f951d5c..b373cc7 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"మీ ఫోన్లో నిల్వ చేయబడిన బ్రౌజర్ చరిత్రను లేదా బుక్మార్క్లను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది బ్రౌజర్ డేటాను ఎరేజ్ చేయడానికి లేదా సవరించడానికి అనువర్తనాన్ని అనుమతించవచ్చు. గమనిక: ఈ అనుమతి మూడవ పక్షం బ్రౌజర్లు లేదా వెబ్ బ్రౌజింగ్ సామర్థ్యాలు గల ఇతర అనువర్తనాల ద్వారా అమలు చేయబడకపోవచ్చు."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"అలారం సెట్ చేయడం"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"ఇన్స్టాల్ చేయబడిన అలారం గడియారం అనువర్తనంలో అలారంను సెట్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. కొన్ని అలారం గల గడియారం అనువర్తనాలు ఈ లక్షణాన్ని అమలు చేయకపోవచ్చు."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"వాయిస్ మెయిల్లను వ్రాయడం"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"మీ వాయిస్ మెయిల్ ఇన్బాక్స్ నుండి సందేశాలను సవరించడానికి మరియు తీసివేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"వాయిస్ మెయిల్ను జోడించడం"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"మీ వాయిస్ మెయిల్ ఇన్బాక్స్కి సందేశాలను జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"వాయిస్ మెయిల్లను చదవడం"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"మీ వాయిస్ మెయిల్లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"బ్రౌజర్ భౌగోళిక స్థానం అనుమతులను సవరించడం"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"బ్రౌజర్ యొక్క భౌగోళిక స్థానం అనుమతులను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు ఏకపక్ష వెబ్ సైట్లకు స్థాన సమాచారాన్ని అనుమతించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"ప్యాకేజీలను ధృవీకరించడం"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index d546738..31ad764 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงประวัติหรือบุ๊กมาร์กของเบราว์เซอร์ที่จัดเก็บไว้ในโทรศัพท์ ซึ่งทำให้แอปพลิเคชันสามารถลบหรือเปลี่ยนข้อมูลเบราว์เซอร์ได้ หมายเหตุ: การอนุญาตนี้อาจไม่สามารถใช้งานได้กับเบราว์เซอร์ของบุคคลที่สามหรือแอปพลิเคชันอื่นๆ ที่มีความสามารถในการเรียกดูบนเว็บ"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ตั้งปลุก"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"อนุญาตให้แอปพลิเคชันตั้งเวลาปลุกในแอปพลิเคชันนาฬิกาปลุกที่ติดตั้ง แอปพลิเคชันนาฬิกาปลุกบางรายการอาจไม่ใช้คุณลักษณะนี้"</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"เขียนข้อความเสียง"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"อนุญาตให้แอปแก้ไขและนำข้อความออกจากกล่องข้อความเสียงของคุณ"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"เพิ่มข้อวามเสียง"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"อนุญาตให้แอปพลิเคชันเพิ่มข้อความลงในกล่องข้อความเสียงของคุณ"</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"อ่านข้อความเสียง"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"อนุญาตให้แอปอ่านข้อความเสียงของคุณได้"</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"แก้ไขการอนุญาตเกี่ยวกับการระบุตำแหน่งทางภูมิศาสตร์ของเบราว์เซอร์"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"อนุญาตให้แอปพลิเคชันแก้ไขการอนุญาตตำแหน่งทางภูมิศาสตร์ของเบราว์เซอร์ แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ในการส่งข้อมูลตำแหน่งไปยังเว็บไซต์ต่างๆ ได้ตามต้องการ"</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"ยืนยันแพ็กเกจ"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"อนุญาตให้แอปพลิเคชันผูกกับบริการของตัวแทนที่เชื่อถือได้"</string>
<string name="permlab_recovery" msgid="3157024487744125846">"โต้ตอบกับการอัปเดตและระบบการกู้คืน"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"ช่วยให้แอปพลิเคชันสามารถโต้ตอบกับระบบการกู้คืนและการอัปเดตระบบ"</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"สร้างเซสชันการฉายภาพสื่อ"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"อนุญาตให้แอปพลิเคชันสร้างเซสชันการฉายภาพสื่อ เซสชันดังกล่าวช่วยให้แอปพลิเคชันสามารถจับภาพหน้าจอและเนื้อหาเสียงได้ แอปทั่วไปไม่จำเป็นต้องใช้"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"แตะสองครั้งเพื่อควบคุมการซูม"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"ไม่สามารถเพิ่มวิดเจ็ต"</string>
<string name="ime_action_go" msgid="8320845651737369027">"ไป"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"แก้ไข"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"คำเตือนการใช้ข้อมูล"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"แตะเพื่อดูการใช้งานและการตั้งค่า"</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"ข้อมูล 2G-3G ปิดอยู่"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"ข้อมูล 4G ปิดอยู่"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"ข้อมูลมือถือปิดอยู่"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"ข้อมูล Wi-Fi ปิดอยู่"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"ถึงขีดจำกัดแล้ว"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"เกินขีดจำกัดข้อมูล 2G - 3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"เกินขีดจำกัดของข้อมูล 4G"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"ถึงขีดจำกัดข้อมูลมือถือแล้ว"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"เกินขีดจำกัดข้อมูล WiFi แล้ว"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> เกินขีดจำกัดที่ระบุไว้"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"จำกัดข้อมูลแบ็กกราวด์"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 377708c..36990ee 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -719,10 +719,8 @@
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Nagbibigay-daan sa may-ari na mapailalim sa interface sa tuktok na antas ng isang serbisyo ng notification listener. Hindi dapat kailanganin para sa karaniwang apps kahit kailan."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"i-bind sa isang serbisyo sa pagbibigay ng kundisyon"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Nagbibigay-daan sa naghahawak na i-bind ang top-level na interface ng isang serbisyo sa pagbibigay ng kundisyon. Hindi kailanman dapat kailanganin ng mga normal na app."</string>
- <!-- no translation found for permlab_bindMediaRouteService (6637740382272686835) -->
- <skip />
- <!-- no translation found for permdesc_bindMediaRouteService (6436655024972496687) -->
- <skip />
+ <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"mag-bind sa isang serbisyo ng media route"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Nagbibigay-daan sa may-hawak na mag-bind sa top-level na interface ng isang serbisyo ng media route. Hindi kailanman dapat kailanganin ng mga normal na app."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"sumailalim sa isang serbisyo ng dream"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"Pinapayagan ang may-ari na sumailalim sa interface ng serbisyo ng dream na nasa nangungunang antas. Hindi kailanman dapat na kailanganin para sa mga normal na app."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"paganahin ang app ng configuration na ibinigay ng carrier"</string>
@@ -1008,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Pinapayagan ang app na baguhin ang kasaysayan o mga bookmark ng Browser na naka-imbak sa iyong telepono. Maaari nitong payagan ang app na burahin o baguhin ang data ng Browser. Tandaan: hindi maaaring ipatupad ang pahintulot na ito ng mga third-party na browser o iba pang mga application na may mga kakayahan sa pagba-browse sa web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"magtakda ng alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Pinapayagan ang app na magtakda ng alarm sa isang naka-install na app ng alarm clock. Maaaring hindi ipatupad ng ilang apps ng alarm clock ang tampok na ito."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"sumulat ng mga voicemail"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Pinapayagan ang app na magbago at mag-alis ng mga mensahe sa iyong inbox ng voicemail."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"magdagdag ng voicemail"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Pinapayagan ang app na magdagdag ng mga mensahe sa iyong inbox ng voicemail."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"basahin ang voicemail"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Pinapayagan ang app na basahin ang iyong mga voicemail."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"baguhin ang mga pahintulot ng geolocation ng Browser"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Pinapayagan ang app na baguhin ang mga pahintulot sa geolocation ng Browser. Maaari itong gamitin ng nakakahamak na apps upang payagan ang pagpapadala ng impormasyon ng lokasyon sa mga hindi tukoy na web site."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"i-verify ang mga package"</string>
@@ -1185,20 +1179,13 @@
<string name="capital_on" msgid="1544682755514494298">"I-ON"</string>
<string name="capital_off" msgid="6815870386972805832">"I-OFF"</string>
<string name="whichApplication" msgid="4533185947064773386">"Kumpletuhin ang pagkilos gamit ang"</string>
- <!-- no translation found for whichApplicationNamed (8260158865936942783) -->
- <skip />
- <!-- no translation found for whichViewApplication (3272778576700572102) -->
- <skip />
- <!-- no translation found for whichViewApplicationNamed (2286418824011249620) -->
- <skip />
- <!-- no translation found for whichEditApplication (144727838241402655) -->
- <skip />
- <!-- no translation found for whichEditApplicationNamed (1775815530156447790) -->
- <skip />
- <!-- no translation found for whichSendApplication (6902512414057341668) -->
- <skip />
- <!-- no translation found for whichSendApplicationNamed (2799370240005424391) -->
- <skip />
+ <string name="whichApplicationNamed" msgid="8260158865936942783">"Tapusin ang pagkilos gamit ang %1$s"</string>
+ <string name="whichViewApplication" msgid="3272778576700572102">"Buksan gamit ang"</string>
+ <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Buksan gamit ang %1$s"</string>
+ <string name="whichEditApplication" msgid="144727838241402655">"I-edit gamit ang"</string>
+ <string name="whichEditApplicationNamed" msgid="1775815530156447790">"I-edit gamit ang %1$s"</string>
+ <string name="whichSendApplication" msgid="6902512414057341668">"Ibahagi gamit ang"</string>
+ <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Ibahagi gamit ang %1$s"</string>
<string name="whichHomeApplication" msgid="4616420172727326782">"Pumili ng home app"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Gamitin bilang default para sa pagkilos na ito."</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"I-clear ang default sa mga setting ng System > Apps > Na-download."</string>
@@ -1301,12 +1288,10 @@
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Palaging Payagan"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Huwag kailanman Payagan"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Naalis ang SIM card"</string>
- <!-- no translation found for sim_removed_message (5450336489923274918) -->
- <skip />
+ <string name="sim_removed_message" msgid="5450336489923274918">"Magiging unavailable ang cellular network hanggang mag-restart ka nang may nakalagay na wastong SIM card."</string>
<string name="sim_done_button" msgid="827949989369963775">"Tapos na"</string>
<string name="sim_added_title" msgid="3719670512889674693">"Idinagdag ang SIM card"</string>
- <!-- no translation found for sim_added_message (7797975656153714319) -->
- <skip />
+ <string name="sim_added_message" msgid="7797975656153714319">"I-restart ang iyong device upang ma-access ang cellular network."</string>
<string name="sim_restart_button" msgid="4722407842815232347">"I-restart"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Magtakda ng oras"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Itakda ang petsa"</string>
@@ -1401,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Pinapayagan ang isang application na sumailalim sa isang serbisyo ng trust agent."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Makipag-ugnay sa system ng pag-update at pagbawi"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Binibigyang-daan ang isang application na makipag-ugnay sa system ng pagbawi at mga pag-update ng system."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Gumawa ng mga media projection session"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Nagbibigay-daan sa isang application upang gumawa ng mga media projection session. Makakapagbigay ang mga session na ito ng kakayahan sa mga application na ma-capture ang mga nilalaman ng display at audio. Hindi kailanman dapat kailanganin ng mga normal na app."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Pindutin nang dalawang beses para sa pagkontrol ng zoom"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Hindi maidagdag ang widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Pumunta"</string>
@@ -1529,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"I-edit"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Babala sa paggamit ng data"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Pindutin upang tingnan ang paggamit at mga setting."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"Naka-off ang 2G-3G data"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"Naka-off ang 4G data"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Naka-off ang cellular data"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Naka-off ang Wi-Fi data"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Naabot na ang limitasyon"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"lumampas sa 2G-3G na limitasyon ng data"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Lumampas sa 4G na limitasyon ng data"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Lampas na sa cellular data limit"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Lumampas sa limitasyon ng data ng Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"Lampas ng <xliff:g id="SIZE">%s</xliff:g> sa tinukoy na limitasyon."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Pinaghihigpitan ang data ng background"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 7433771..3f79c61 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1390,10 +1390,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Bir uygulamanın, güven aracı hizmetine bağlanmasına izin verir."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Güncelleme ve kurtarma sistemiyle etkileşim kur"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Bir uygulamaya, kurtarma sistemi ve sistem güncellemeriyle etkileşim kurma izni verir."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Medya yansıtma oturumları oluştur"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Bir uygulamanın medya yansıtma oturumları oluşturmasına izin verir. Bu oturumlar, uygulamaların görüntü ve ses içeriklerini kaydetmesine olanak sağlar. Normal uygulamalar için hiçbir zaman gerekli olmaz."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Yakınlaştırma denetimi için iki kez dokunun"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget eklenemedi."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Git"</string>
@@ -1518,20 +1516,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Düzenle"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Veri kullanım uyarısı"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Kullanımı ve ayarları görmek için dokunun."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G-3G veri kullanımı kapalı"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G veri kullanımı kapalı"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Hücresel veri kapalı"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Kablosuz veri kapalı"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Sınıra ulaşıldı"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G veri limiti aşıldı"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G veri limiti aşıldı"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Hücresel veri sınırı aşıldı"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Kablosuz veri limiti aşıldı"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g>, belirlenen limiti aşıyor."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Arka plan verileri kısıtlı"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index eeb6e15..ac415eb 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Дозволяє програмі змінювати історію чи закладки веб-переглядача, збережені у вашому телефоні. Це може дозволити програмі стирати чи змінювати дані веб-переглядача. Зауважте: цей дозвіл не може застосовуватися веб-переглядачами третіх сторін або іншими програмами з можливостями веб-перегляду."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"установлювати будильник"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Дозволяє програмі налаштовувати сигнал у встановленій програмі будильника. У деяких програмах будильника ця функція може не застосовуватися."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"записувати голосові повідомлення"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Додаток може змінювати голосові повідомлення та видаляти їх із папки \"Вхідні\"."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"додавати голосову пошту"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Дозволяє програмі додавати повідомлення в папку \"Вхідні\" голосової пошти."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"читати голосові повідомлення"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Додаток може читати голосові повідомлення."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"змінювати дозволи географічного місцезнаходження у веб-переглядачі"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Дозволяє програмі змінювати дозволи географічного місцезнаходження у веб-переглядачі. Шкідливі програми можуть використовувати це, щоб дозволяти надсилати інформацію про місцезнаходження довільним веб-сайтам."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"перевіряти пакети"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Дозволяє додатку прив’язуватися до служби довірчих агентів."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Взаємодіяти з оновленнями системи та системою відновлення."</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Дозволяє додатку взаємодіяти із системою відновлення й оновленнями системи."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Створювати сеанси проектування медіа"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Додаток може створювати сеанси проектування медіа. Під час цих сеансів додатки зможуть збирати аудіовміст і вміст дисплея. Не використовується звичайними додатками."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Двічі торкніться, щоб керувати масштабом"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Не вдалося додати віджет."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Йти"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Редагувати"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Застереження про використ. даних"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Торкн.,щоб див. викор. і налашт."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"Дані 2G–3G вимкнено"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"Дані 4G вимкнено"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Мобільні дані вимкнено"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Дані Wi-Fi вимкнено"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Досягнуто ліміту"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Перевищено ліміт даних 2G–3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Перевищено ліміт даних 4G"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Перевищено ліміт мобільних даних"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Перевищено ліміт даних Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> – понад указаний ліміт."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Викор-ня фонових даних обмежено"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 7da441c..c3feb4c 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -720,7 +720,7 @@
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"شرط فراہم کرنے والی ایک سروس کے پابند بنیں"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"حامل کو شرط فراہم کنندہ کی سروس کے اعلی سطحی انٹرفیس کا پابند ہونے کی اجازت دیتا ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہيں ہونی چاہئے۔"</string>
<string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"میڈیا روٹ سروس کا پابند بنیں"</string>
- <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"حامل کو میڈیا روٹ سروس کے اعلی سطحی انٹرفیس کا پابند کرنے کی اجازت دیتا ہے۔ معمول کے ایپس کیلئے کبھی درکار نہیں ہونا چاہئے۔"</string>
+ <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"حامل کو میڈیا روٹ سروس کے اعلی سطحی انٹرفیس کا پابند کرنے کی اجازت دیتا ہے۔ معمول کی ایپس کیلئے کبھی درکار نہیں ہونا چاہئے۔"</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"ایک ڈریم سروس کا پابند بنیں"</string>
<string name="permdesc_bindDreamService" msgid="7325825272223347863">"حامل کو ڈریم سروس کے اعلی سطحی انٹرفیس کا پابند ہونے کی اجازت دیتی ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہيں ہونی چاہیے۔"</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"کیریئر کے ذریعے فراہم کردہ کنفگریشن ایپ طلب کریں"</string>
@@ -1292,10 +1292,10 @@
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"ہمیشہ اجازت دیں"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"کبھی بھی اجازت نہ دیں"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM کارڈ ہٹا دیا گیا"</string>
- <string name="sim_removed_message" msgid="5450336489923274918">"سیلولر نیٹ ورک اس وقت تک دستیاب نہیں ہو گا جب تک آپ ایک درست SIM داخل کرکے اسے دوبارہ چالو نہ کریں۔"</string>
+ <string name="sim_removed_message" msgid="5450336489923274918">"سیلولر نیٹ ورک اس وقت تک دستیاب نہیں ہو گا جب تک آپ ایک درست SIM داخل کرکے اسے دوبارہ سٹارٹ نہ کریں۔"</string>
<string name="sim_done_button" msgid="827949989369963775">"ہو گیا"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM شامل کیا گیا"</string>
- <string name="sim_added_message" msgid="7797975656153714319">"سیلولر نیٹ ورک تک رسائی کیلئے اپنا آلہ دوبارہ چالو کریں۔"</string>
+ <string name="sim_added_message" msgid="7797975656153714319">"سیلولر نیٹ ورک تک رسائی کیلئے اپنا آلہ دوبارہ سٹارٹ کریں۔"</string>
<string name="sim_restart_button" msgid="4722407842815232347">"دوبارہ شروع کریں"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"وقت سیٹ کریں"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"تاریخ سیٹ کریں"</string>
@@ -1390,10 +1390,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"ایک ایپلیکیشن کو ایک ٹرسٹ ایجنٹ سروس کا پابند ہونے دیتا ہے۔"</string>
<string name="permlab_recovery" msgid="3157024487744125846">"اپ ڈیٹ اور بازیابی سسٹم کے ساتھ تعامل کریں"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"کسی ایپ کو بازیابی سسٹم اور بازیابی اپ ڈیٹس کے ساتھ تعامل کرنے کی اجازت دیتا ہے۔"</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"میڈیا پروجیکشن سیشنز بنائیں"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"ایک ایپلیکیشن کو میڈیا پروجیکشن سیشنز بنانے کی اجازت دیتی ہے۔ یہ سیشنز ایپلیکیشنز کو ڈسپلے اور آڈیو مواد کو کیپچر کرنے کی اہلیت فراہم کر سکتے ہیں۔ عام ایپس کو کبھی بھی ان کی ضرورت نہیں ہونی چاہیے۔"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"زوم کے کنٹرول کیلئے دو بار ٹچ کریں"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"ویجٹس کو شامل نہیں کرسکا۔"</string>
<string name="ime_action_go" msgid="8320845651737369027">"جائیں"</string>
@@ -1518,20 +1516,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"ترمیم کریں"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"ڈیٹا کے استعمال کی وارننگ"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"استعمال و ترتیبات دیکھنے کیلئے ٹچ کریں۔"</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G-3G ڈیٹا آف ہے"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G ڈیٹا آف ہے"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"سیلولر ڈیٹا آف ہے"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Wi-Fi ڈیٹا آف ہے"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"حد تک پہنچ گیا"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G ڈیٹا حد سے متجاوز ہو گیا"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G ڈیٹا حد سے متجاوز ہو گیا"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"سیلولر ڈیٹا کی حد سے تجاوز کرگیا"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi ڈیٹا حد سے متجاوز ہو گیا"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> متعینہ حد سے زیادہ ہے۔"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"پس منظر ڈیٹا محدود ہے"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7ef5017..b1c7acc 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Cho phép ứng dụng sửa đổi lịch sử hoặc dấu trang của Trình duyệt được lưu trữ trên điện thoại của bạn. Việc này có thể cho phép ứng dụng xóa hoặc sửa đổi dữ liệu của Trình duyệt. Lưu ý: quyền này có thể không được thực thi bởi các trình duyệt của bên thứ ba hoặc các ứng dụng khác có khả năng duyệt web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"đặt báo thức"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Cho phép ứng dụng đặt báo thức trong ứng dụng đồng hồ báo thức được cài đặt. Một số ứng dụng đồng hồ báo thức có thể không thực thi tính năng này."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"viết thư thoại"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Cho phép ứng dụng sửa đổi và xóa thư khỏi hộp thư thoại đến của bạn."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"thêm thư thoại"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Cho phép ứng dụng thêm thông báo vào hộp thư thoại đến của bạn."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"đọc thư thoại"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Cho phép ứng dụng đọc thư thoại của bạn."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"sửa đổi các quyền về vị trí địa lý của Trình duyệt"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Cho phép ứng dụng sửa đổi cấp phép vị trí địa lý của Trình duyệt. Ứng dụng độc hại có thể lợi dụng quyền này để cho phép gửi thông tin vị trí tới các trang web tùy ý."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"xác minh gói"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Cho phép ứng dụng liên kết với một dịch vụ của đại lý đáng tin cậy."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Tương tác với hệ thống khôi phục và bản cập nhật"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Cho phép ứng dụng tương tác với hệ thống khôi phục và bản cập nhật hệ thống."</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"Tạo phiên chiếu phương tiện"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"Cho phép ứng dụng tạo các phiên chiếu phương tiện. Các phiên này có thể cấp cho ứng dụng khả năng chụp màn hình và ghi nội dung âm thanh. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Chạm hai lần để kiểm soát thu phóng"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Không thể thêm tiện ích."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Đến"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Chỉnh sửa"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Cảnh báo sử dụng dữ liệu"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Chạm để xem sử dụng và cài đặt."</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"Dữ liệu 2G-3G bị tắt"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"Dữ liệu 4G bị tắt"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"Dữ liệu di động bị tắt"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Dữ liệu Wi-Fi bị tắt"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"Đã đạt giới hạn"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Đã vượt quá g.hạn dữ liệu 2G-3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Đã vượt quá giới hạn dữ liệu 4G"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Đã vượt quá giới hạn dữ liệu DĐ"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Vượt quá g.hạn d.liệu Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> vượt quá g.hạn được chỉ định."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Dữ liệu nền bị giới hạn"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index ac91926..be51b82 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -120,7 +120,7 @@
<string name="roamingTextSearching" msgid="8360141885972279963">"正在搜索服务"</string>
<string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:无法转接"</string>
<string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:<xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
- <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:<xliff:g id="TIME_DELAY">{2}</xliff:g> 秒后<xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+ <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:<xliff:g id="TIME_DELAY">{2}</xliff:g>秒后<xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:无法转接"</string>
<string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:无法转接"</string>
<string name="fcComplete" msgid="3118848230966886575">"功能代码已拨完。"</string>
@@ -188,7 +188,7 @@
<string name="global_action_lockdown" msgid="8751542514724332873">"立即锁定"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
- <string name="android_system_label" msgid="6577375335728551336">"Android 系统"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android系统"</string>
<string name="user_owner_label" msgid="6465364741001216388">"个人应用"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"工作"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"需要您付费的服务"</string>
@@ -643,8 +643,8 @@
<string name="permdesc_changeNetworkState" msgid="6789123912476416214">"允许应用更改网络连接的状态。"</string>
<string name="permlab_changeTetherState" msgid="5952584964373017960">"更改网络共享连接"</string>
<string name="permdesc_changeTetherState" msgid="1524441344412319780">"允许应用更改绑定网络连接的状态。"</string>
- <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"更改后台数据使用设置"</string>
- <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"允许应用更改后台数据使用设置。"</string>
+ <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"更改后台流量设置"</string>
+ <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"允许应用更改后台流量设置。"</string>
<string name="permlab_accessWifiState" msgid="5202012949247040011">"查看 WLAN 连接"</string>
<string name="permdesc_accessWifiState" msgid="5002798077387803726">"允许该应用查看 WLAN 网络的相关信息,例如是否启用了 WLAN 以及连接的 WLAN 设备的名称。"</string>
<string name="permlab_changeWifiState" msgid="6550641188749128035">"连接 WLAN 和断开连接"</string>
@@ -921,7 +921,7 @@
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,手机将重置为出厂默认设置,所有用户数据将会丢失。"</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁平板电脑。平板电脑现在将重置为出厂默认设置。"</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁手机。手机现在将重置为出厂默认设置。"</string>
- <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> 秒后重试。"</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g>秒后重试。"</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"忘记了图案?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"帐户解锁"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"图案尝试次数过多"</string>
@@ -1051,69 +1051,69 @@
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 个月前"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 个月前"</string>
<plurals name="num_seconds_ago">
- <item quantity="one" msgid="4869870056547896011">"1 秒前"</item>
- <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> 秒前"</item>
+ <item quantity="one" msgid="4869870056547896011">"1秒前"</item>
+ <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g>秒前"</item>
</plurals>
<plurals name="num_minutes_ago">
- <item quantity="one" msgid="3306787433088810191">"1 分钟前"</item>
- <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> 分钟前"</item>
+ <item quantity="one" msgid="3306787433088810191">"1分钟前"</item>
+ <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g>分钟前"</item>
</plurals>
<plurals name="num_hours_ago">
- <item quantity="one" msgid="9150797944610821849">"1 小时前"</item>
- <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> 小时前"</item>
+ <item quantity="one" msgid="9150797944610821849">"1小时前"</item>
+ <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g>小时前"</item>
</plurals>
<plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"过去 <xliff:g id="COUNT">%d</xliff:g> 天"</item>
+ <item quantity="other" msgid="3069992808164318268">"过去<xliff:g id="COUNT">%d</xliff:g>天"</item>
</plurals>
- <string name="last_month" msgid="3959346739979055432">"上月"</string>
+ <string name="last_month" msgid="3959346739979055432">"上个月"</string>
<string name="older" msgid="5211975022815554840">"往前"</string>
<plurals name="num_days_ago">
<item quantity="one" msgid="861358534398115820">"昨天"</item>
- <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> 天前"</item>
+ <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g>天前"</item>
</plurals>
<plurals name="in_num_seconds">
- <item quantity="one" msgid="2729745560954905102">"1 秒后"</item>
- <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> 秒后"</item>
+ <item quantity="one" msgid="2729745560954905102">"1秒后"</item>
+ <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g>秒后"</item>
</plurals>
<plurals name="in_num_minutes">
- <item quantity="one" msgid="8793095251325200395">"1 分钟后"</item>
- <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> 分钟后"</item>
+ <item quantity="one" msgid="8793095251325200395">"1分钟后"</item>
+ <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g>分钟后"</item>
</plurals>
<plurals name="in_num_hours">
- <item quantity="one" msgid="7164353342477769999">"1 小时后"</item>
- <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> 小时后"</item>
+ <item quantity="one" msgid="7164353342477769999">"1小时后"</item>
+ <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g>小时后"</item>
</plurals>
<plurals name="in_num_days">
<item quantity="one" msgid="5413088743009839518">"明天"</item>
<item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> 天后"</item>
</plurals>
<plurals name="abbrev_num_seconds_ago">
- <item quantity="one" msgid="1849036840200069118">"1 秒前"</item>
- <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> 秒前"</item>
+ <item quantity="one" msgid="1849036840200069118">"1秒前"</item>
+ <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g>秒前"</item>
</plurals>
<plurals name="abbrev_num_minutes_ago">
- <item quantity="one" msgid="6361490147113871545">"1 分钟前"</item>
- <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> 分钟前"</item>
+ <item quantity="one" msgid="6361490147113871545">"1分钟前"</item>
+ <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g>分钟前"</item>
</plurals>
<plurals name="abbrev_num_hours_ago">
- <item quantity="one" msgid="4796212039724722116">"1 小时前"</item>
- <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> 小时前"</item>
+ <item quantity="one" msgid="4796212039724722116">"1小时前"</item>
+ <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g>小时前"</item>
</plurals>
<plurals name="abbrev_num_days_ago">
<item quantity="one" msgid="8463161711492680309">"昨天"</item>
- <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> 天前"</item>
+ <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g>天前"</item>
</plurals>
<plurals name="abbrev_in_num_seconds">
- <item quantity="one" msgid="5842225370795066299">"1 秒后"</item>
- <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> 秒后"</item>
+ <item quantity="one" msgid="5842225370795066299">"1秒后"</item>
+ <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g>秒后"</item>
</plurals>
<plurals name="abbrev_in_num_minutes">
- <item quantity="one" msgid="562786149928284878">"1 分钟后"</item>
- <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> 分钟后"</item>
+ <item quantity="one" msgid="562786149928284878">"1分钟后"</item>
+ <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g>分钟后"</item>
</plurals>
<plurals name="abbrev_in_num_hours">
- <item quantity="one" msgid="3274708118124045246">"1 小时后"</item>
- <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> 小时后"</item>
+ <item quantity="one" msgid="3274708118124045246">"1小时后"</item>
+ <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g>小时后"</item>
</plurals>
<plurals name="abbrev_in_num_days">
<item quantity="one" msgid="2178576254385739855">"明天"</item>
@@ -1135,16 +1135,16 @@
<string name="year" msgid="4001118221013892076">"年"</string>
<string name="years" msgid="6881577717993213522">"年"</string>
<plurals name="duration_seconds">
- <item quantity="one" msgid="6962015528372969481">"1 秒"</item>
- <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> 秒"</item>
+ <item quantity="one" msgid="6962015528372969481">"1秒"</item>
+ <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g>秒"</item>
</plurals>
<plurals name="duration_minutes">
- <item quantity="one" msgid="4915414002546085617">"1 分钟"</item>
- <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> 分钟"</item>
+ <item quantity="one" msgid="4915414002546085617">"1分钟"</item>
+ <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g>分钟"</item>
</plurals>
<plurals name="duration_hours">
- <item quantity="one" msgid="8917467491248809972">"1 小时"</item>
- <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> 小时"</item>
+ <item quantity="one" msgid="8917467491248809972">"1小时"</item>
+ <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g>小时"</item>
</plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"视频问题"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"抱歉,该视频不适合在此设备上播放。"</string>
@@ -1183,7 +1183,7 @@
<string name="capital_on" msgid="1544682755514494298">"开启"</string>
<string name="capital_off" msgid="6815870386972805832">"关闭"</string>
<string name="whichApplication" msgid="4533185947064773386">"选择要使用的应用:"</string>
- <string name="whichApplicationNamed" msgid="8260158865936942783">"需使用%1$s完成操作"</string>
+ <string name="whichApplicationNamed" msgid="8260158865936942783">"使用%1$s完成操作"</string>
<string name="whichViewApplication" msgid="3272778576700572102">"打开方式"</string>
<string name="whichViewApplicationNamed" msgid="2286418824011249620">"使用%1$s打开"</string>
<string name="whichEditApplication" msgid="144727838241402655">"编辑方式"</string>
@@ -1292,10 +1292,10 @@
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"始终允许"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"永不允许"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"已移除 SIM 卡"</string>
- <string name="sim_removed_message" msgid="5450336489923274918">"您必须先插入有效的SIM卡再重新开机,然后才能使用移动数据网络。"</string>
+ <string name="sim_removed_message" msgid="5450336489923274918">"您需要先插入有效的SIM卡再重新开机,然后才能使用移动网络。"</string>
<string name="sim_done_button" msgid="827949989369963775">"完成"</string>
<string name="sim_added_title" msgid="3719670512889674693">"已添加 SIM 卡"</string>
- <string name="sim_added_message" msgid="7797975656153714319">"请重新启动您的设备,以便访问移动数据网络。"</string>
+ <string name="sim_added_message" msgid="7797975656153714319">"请重新启动您的设备,以便使用移动网络。"</string>
<string name="sim_restart_button" msgid="4722407842815232347">"重新启动"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"设置时间"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"设置日期"</string>
@@ -1516,7 +1516,7 @@
<string name="storage_sd_card" msgid="3282948861378286745">"SD 卡"</string>
<string name="storage_usb" msgid="3017954059538517278">"USB 存储器"</string>
<string name="extract_edit_menu_button" msgid="8940478730496610137">"修改"</string>
- <string name="data_usage_warning_title" msgid="1955638862122232342">"流量使用警告"</string>
+ <string name="data_usage_warning_title" msgid="1955638862122232342">"流量警告"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"触摸可查看使用情况和设置。"</string>
<!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
<skip />
@@ -1534,7 +1534,7 @@
<skip />
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"超出了 WLAN 数据流量上限"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"超出规定上限 <xliff:g id="SIZE">%s</xliff:g>。"</string>
- <string name="data_usage_restricted_title" msgid="5965157361036321914">"后台数据受限制"</string>
+ <string name="data_usage_restricted_title" msgid="5965157361036321914">"后台流量受限制"</string>
<string name="data_usage_restricted_body" msgid="6741521330997452990">"触摸可去除限制。"</string>
<string name="ssl_certificate" msgid="6510040486049237639">"安全证书"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"该证书有效。"</string>
@@ -1752,25 +1752,16 @@
<string name="item_is_selected" msgid="949687401682476608">"已选择<xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"已删除<xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_toast (2126866321272822564) -->
- <skip />
+ <string name="lock_to_app_toast" msgid="2126866321272822564">"您目前处于单应用模式。要退出,请触摸并按住“最近用过的应用”按钮"</string>
<string name="lock_to_app_toast_locked" msgid="4229650395479263497">"您目前处于单应用模式。"</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"要使用“单应用模式”吗?"</string>
- <!-- no translation found for lock_to_app_description (2800403592608529611) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (2259143719362732728) -->
- <skip />
+ <string name="lock_to_app_description" msgid="2800403592608529611">"“单应用模式”功能会锁定屏幕,使其只显示一个应用。{\n\n要退出,请触摸并按住“最近用过的应用”按钮。"</string>
+ <string name="lock_to_app_negative" msgid="2259143719362732728">"不用了"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"启动"</string>
- <!-- no translation found for lock_to_app_start (3074665051586318340) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (8967089657201849300) -->
- <skip />
- <!-- no translation found for lock_to_app_use_screen_lock (1434584309048590886) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_pin (7908385370846820001) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_pattern (7763071104790758405) -->
- <skip />
- <!-- no translation found for lock_to_app_unlock_password (795224196583495868) -->
- <skip />
+ <string name="lock_to_app_start" msgid="3074665051586318340">"开启单应用模式"</string>
+ <string name="lock_to_app_exit" msgid="8967089657201849300">"不再使用单应用模式"</string>
+ <string name="lock_to_app_use_screen_lock" msgid="1434584309048590886">"退出前要求%1$s"</string>
+ <string name="lock_to_app_unlock_pin" msgid="7908385370846820001">"PIN码"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="7763071104790758405">"解锁图案"</string>
+ <string name="lock_to_app_unlock_password" msgid="795224196583495868">"密码"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 43ab412..8f7b5a0 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"允許應用程式修改手機上儲存的瀏覽器記錄或書籤。如此一來,應用程式或可清除或修改瀏覽器資料。注意:這項權限可能不適用於第三方瀏覽器或其他具備網頁瀏覽功能的應用程式。"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"設定鬧鐘"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"允許應用程式在安裝的鬧鐘應用程式中設定鬧鐘,某些鬧鐘應用程式可能沒有這項功能。"</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"寫入語音留言"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"允許應用程式修改及移除語音留言收件匣中的訊息。"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"新增留言"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"允許應用程式將訊息加到您的留言信箱收件箱。"</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"讀取語音留言"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"允許應用程式讀取您的語音留言。"</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"修改瀏覽器地理資訊的權限"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"允許應用程式修改瀏覽器的地理資訊權限。惡意應用程式可能會藉此允許將您的位置資訊任意傳送給某些網站。"</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"驗證套件"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"允許應用程式繫結至信任的代理程式服務。"</string>
<string name="permlab_recovery" msgid="3157024487744125846">"與更新和復原系統互動"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"允許應用程式與復原系統和系統更新互動。"</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"建立媒體投影工作階段"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"允許應用程式建立媒體投影工作階段。這類工作階段可讓應用程式擷取畫面內容和音訊內容 (一般應用程式並不需用)。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"輕觸兩下即可控制縮放"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"無法新增小工具。"</string>
<string name="ime_action_go" msgid="8320845651737369027">"開始"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"編輯"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"資料用量警告"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"輕觸即可查看使用量和設定。"</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G-3G 數據連線已關閉"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G 數據連線已關閉"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"流動數據連線已關閉"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Wi-Fi 數據連線已關閉"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"已達上限"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"已達 2G-3G 數據上限"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"已達 4G 數據上限"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"已超過流動數據流量上限"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"已達 Wi-Fi 數據上限"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> 超過規定上限。"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"已限制背景資料"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 288b314..fbffc99 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"允許應用程式修改手機上儲存的瀏覽紀錄或書籤。這項設定會讓應用程式具有清除或修改瀏覽資料的權限。注意:這項權限不適用於第三方瀏覽器或其他具備網頁瀏覽功能的應用程式。"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"設定鬧鐘"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"允許應用程式在安裝的鬧鐘應用程式中設定鬧鐘,某些鬧鐘應用程式可能無法執行這項功能。"</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"寫入語音留言"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"允許應用程式修改及移除語音留言收件匣中的訊息。"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"新增語音留言"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"允許應用程式將訊息新增至您的語音信箱收件匣。"</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"讀取語音留言"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"允許應用程式讀取您的語音留言。"</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"修改瀏覽器地理資訊的權限"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"允許應用程式修改瀏覽器的地理位置權限。請注意,惡意應用程式可能利用此功能允許將您的位置資訊任意傳送給某些網站。"</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"驗證套件"</string>
@@ -1390,10 +1386,8 @@
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"允許應用程式繫結至信任的代理程式服務。"</string>
<string name="permlab_recovery" msgid="3157024487744125846">"與更新和還原系統互動"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"允許應用程式與還原系統及系統更新互動。"</string>
- <!-- no translation found for permlab_createMediaProjection (4941338725487978112) -->
- <skip />
- <!-- no translation found for permdesc_createMediaProjection (1284530992706219702) -->
- <skip />
+ <string name="permlab_createMediaProjection" msgid="4941338725487978112">"建立媒體投影工作階段"</string>
+ <string name="permdesc_createMediaProjection" msgid="1284530992706219702">"允許應用程式建立媒體投影工作階段。這類工作階段可讓應用程式擷取畫面內容和音訊內容 (一般應用程式並不需要)。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"輕觸兩下即可控制縮放"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"無法新增小工具。"</string>
<string name="ime_action_go" msgid="8320845651737369027">"開始"</string>
@@ -1518,20 +1512,14 @@
<string name="extract_edit_menu_button" msgid="8940478730496610137">"編輯"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"資料用量警告"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"輕觸即可查看使用量和設定。"</string>
- <!-- no translation found for data_usage_3g_limit_title (4462365924791862301) -->
- <skip />
- <!-- no translation found for data_usage_4g_limit_title (7476424187522765328) -->
- <skip />
- <!-- no translation found for data_usage_mobile_limit_title (3393439305227911006) -->
- <skip />
- <!-- no translation found for data_usage_wifi_limit_title (3461968509557554571) -->
- <skip />
- <!-- no translation found for data_usage_limit_body (6131350187562939365) -->
- <skip />
+ <string name="data_usage_3g_limit_title" msgid="4462365924791862301">"2G-3G 數據連線已關閉"</string>
+ <string name="data_usage_4g_limit_title" msgid="7476424187522765328">"4G 數據連線已關閉"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3393439305227911006">"行動數據連線已關閉"</string>
+ <string name="data_usage_wifi_limit_title" msgid="3461968509557554571">"Wi-Fi 數據連線已關閉"</string>
+ <string name="data_usage_limit_body" msgid="6131350187562939365">"已達上限"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"已超過 2G-3G 數據上限"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"已超過 4G 數據上限"</string>
- <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
- <skip />
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"已超過行動數據流量上限"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"已超過 Wi-Fi 數據上限"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> 超過規定上限。"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"已限制背景資料"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index d196a21..7f4e78b 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1006,16 +1006,12 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ivumela uhlelo lokusebenza ukushintsha umlando wamabhukhimakhi noma wesiphequluli alondolozwe efonini yakho. Lokhu kungavumela uhlelo lokusebenza ukususa noma ukushintsha idatha yesiphequluli. Qaphela: le mvume kungenzeka ingaphoqelelwa iziphequluli ezivela eceleni noma ezinye izinhlelo zokusebenza ezinamandla okuphequlula iwebhu."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"setha i-alamu"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Ivumela uhlelo lokusebenza ukuthi isethe i-alamu ensizeni efkiwe ye-alamu. Ezinye izinhlelo zokusebenza ze-alamu kungenzeka zingakusebenzisi lokho."</string>
- <!-- no translation found for permlab_writeVoicemail (7309899891683938100) -->
- <skip />
- <!-- no translation found for permdesc_writeVoicemail (6592572839715924830) -->
- <skip />
+ <string name="permlab_writeVoicemail" msgid="7309899891683938100">"bhala ivoyisimeyili"</string>
+ <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Ivumela uhlelo lokusebenza ukuthi liguqule liphinde lisuse imilayezo esuka kubhokisi lakho lokungenayo lwe-voyisimeyili."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"engeza imeyili yezwi"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ivumela uhlelo lokusebenza ukwengeza imiyalezo kwibhokisi lakho lemeyili yezwi."</string>
- <!-- no translation found for permlab_readVoicemail (8415201752589140137) -->
- <skip />
- <!-- no translation found for permdesc_readVoicemail (8926534735321616550) -->
- <skip />
+ <string name="permlab_readVoicemail" msgid="8415201752589140137">"funda ivoyisimeyili"</string>
+ <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Ivumela uhlelo lokusebenza ukufunda amavoyisimeyili wakho."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Gugula izimvume zendawo Yesiphequluli"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Ivumela uhlelo lokusebenza ukuthi iguqule izimvume eziphathelene nezindawo Zesiphequluli. Izuhlelo lokusebenza eziyingozi zingasebenzisa lokhu ukuvumela ukuvumela imininingwane yendawo kunoma imaphi amawebusayithi."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"qinisekisa amaphakheji"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2c5cfe1..73c6a67 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3114,6 +3114,28 @@
<attr name="checked" />
<!-- Drawable used for the check mark graphic. -->
<attr name="checkMark" format="reference"/>
+ <!-- Tint to apply to the check mark. -->
+ <attr name="checkMarkTint" format="color" />
+ <!-- Blending mode used to apply the check mark tint. -->
+ <attr name="checkMarkTintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
+ </attr>
</declare-styleable>
<declare-styleable name="EditText">
</declare-styleable>
@@ -3579,7 +3601,7 @@
result to valid color values. Saturate(S + D) -->
<enum name="add" value="16" />
</attr>
- <!-- Tint to apply to the indepterminate progress indicator. -->
+ <!-- Tint to apply to the indeterminate progress indicator. -->
<attr name="indeterminateTint" format="color" />
<!-- Blending mode used to apply the indeterminate progress indicator tint. -->
<attr name="indeterminateTintMode">
@@ -4163,6 +4185,8 @@
<attr name="dropDownSelector" />
<!-- Background drawable to use for the dropdown in spinnerMode="dropdown". -->
<attr name="popupBackground" />
+ <!-- Window elevation to use for the dropdown in spinnerMode="dropdown". -->
+ <attr name="popupElevation" />
<!-- Vertical offset from the spinner widget for positioning the dropdown in
spinnerMode="dropdown". -->
<attr name="dropDownVerticalOffset" />
@@ -4887,9 +4911,9 @@
<enum name="disabled" value="-1" />
<!-- Replicates the edge color. -->
<enum name="clamp" value="0" />
- <!-- Repeats the bitmap in both direction. -->
+ <!-- Repeats the bitmap horizontally. -->
<enum name="repeat" value="1" />
- <!-- Repeats the shader's image horizontally and vertically, alternating
+ <!-- Repeats the shader's image horizontally, alternating
mirror images so that adjacent images always seam. -->
<enum name="mirror" value="2" />
</attr>
@@ -4900,9 +4924,9 @@
<enum name="disabled" value="-1" />
<!-- Replicates the edge color. -->
<enum name="clamp" value="0" />
- <!-- Repeats the bitmap in both direction. -->
+ <!-- Repeats the bitmap vertically. -->
<enum name="repeat" value="1" />
- <!-- Repeats the shader's image horizontally and vertically, alternating
+ <!-- Repeats the shader's image vertically, alternating
mirror images so that adjacent images always seam. -->
<enum name="mirror" value="2" />
</attr>
@@ -5446,11 +5470,9 @@
Corresponds to {@link android.transition.Visibility#setMode(int)}. -->
<attr name="visibilityMode">
<!-- Only appearing Views will be supported. -->
- <enum name="mode_in" value="1" />
+ <flag name="mode_in" value="1" />
<!-- Only disappearing Views will be supported. -->
- <enum name="mode_out" value="2" />
- <!-- Both appearing and disappearing views will be supported. -->
- <enum name="mode_in_out" value="3" />
+ <flag name="mode_out" value="2" />
</attr>
</declare-styleable>
<!-- Use <code>target</code> as the root tag of the XML resource that
@@ -6876,6 +6898,9 @@
<attr name="contentInsetRight" format="dimension" />
<!-- Elevation for the action bar itself -->
<attr name="elevation" />
+ <!-- Reference to a theme that should be used to inflate popups
+ shown by widgets in the action bar. -->
+ <attr name="popupTheme" />
</declare-styleable>
<declare-styleable name="ActionMode">
@@ -7164,6 +7189,9 @@
<flag name="bottom" value="0x50" />
</attr>
<attr name="collapseIcon" format="reference" />
+ <!-- Reference to a theme that should be used to inflate popups
+ shown by widgets in the toolbar. -->
+ <attr name="popupTheme" format="reference" />
</declare-styleable>
<declare-styleable name="Toolbar_LayoutParams">
@@ -7191,24 +7219,6 @@
the settings for this service. -->
<attr name="settingsActivity" />
<!-- Type of this service. -->
- <attr name="tvInputType">
- <!-- Should be in sync with constant values defined in
- {@link android.media.tv.TvInputInfo}. -->
-
- <!-- Virtual input (default) -->
- <enum name="virtual" value="0" />
-
- <enum name="otherHardware" value="1" />
- <enum name="tuner" value="2" />
- <enum name="composite" value="3" />
- <enum name="svideo" value="4" />
- <enum name="scart" value="5" />
- <enum name="component" value="6" />
- <enum name="vga" value="7" />
- <enum name="dvi" value="8" />
- <enum name="hdmi" value="9" />
- <enum name="displayPort" value="10" />
- </attr>
</declare-styleable>
<declare-styleable name="ResolverDrawerLayout">
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 021edc5..7311a60 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -212,6 +212,9 @@
<!-- Additional flag from base permission type: this permission can also
(optionally) be granted to development applications. -->
<flag name="development" value="0x20" />
+ <!-- Additional flag from base permission type: this permission is closely
+ associated with an app op for controlling access. -->
+ <flag name="appop" value="0x40" />
</attr>
<!-- Flags indicating more context for a permission group. -->
@@ -905,7 +908,7 @@
<enum name="persistRootOnly" value="0" />
<!-- If this activity forms the root of a task then that task will not be persisted
across reboots -->
- <enum name="doNotPersist" value="1" />
+ <enum name="persistNever" value="1" />
<!-- If this activity forms the root of a task then the task and this activity will
be persisted across reboots. If the activity above this activity is also
tagged with the attribute <code>"persist"</code> then it will be persisted as well.
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e4484ad..a6e85e9 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2097,7 +2097,6 @@
<public type="attr" name="isGame" id="0x10103f4" />
<public type="attr" name="allowEmbedded" id="0x10103f5" />
<public type="attr" name="setupActivity" id="0x10103f6"/>
- <public type="attr" name="tvInputType" id="0x10103f7"/>
<!-- ===============================================================
Resources added in version 21 of the platform
@@ -2240,7 +2239,7 @@
<public type="attr" name="launchTaskBehindSourceAnimation" />
<!-- Attribute specified in a restriction entry to denote the type of restriction. -->
<public type="attr" name="restrictionType" />
-
+ <!-- For the DatePicker -->
<public type="attr" name="dateSelectorDayOfWeekBackgroundColor" />
<public type="attr" name="dateSelectorDayOfWeekTextAppearance" />
<public type="attr" name="dateSelectorBackgroundColor" />
@@ -2251,7 +2250,6 @@
<public type="attr" name="dateSelectorYearListSelectedCircleColor" />
<public type="attr" name="calendarTextColor" />
<public type="attr" name="recognitionService" />
-
<!-- For the TimePicker -->
<public type="attr" name="timePickerStyle" />
<public type="attr" name="timePickerDialogTheme" />
@@ -2265,8 +2263,11 @@
<public type="attr" name="amPmTextColor" />
<public type="attr" name="amPmUnselectedBackgroundColor" />
<public type="attr" name="amPmSelectedBackgroundColor" />
-
<public type="attr" name="searchKeyphraseRecognitionFlags" />
+ <public type="attr" name="checkMarkTint" />
+ <public type="attr" name="checkMarkTintMode" />
+ <public type="attr" name="popupTheme" />
+ <public type="attr" name="toolbarStyle" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0d9da35..b41e37c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -774,6 +774,12 @@
about currently and recently running tasks. This may allow the app to
discover information about which applications are used on the device.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_startTasksFromRecents">start a task from recents</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_startTasksFromRecents">Allows the app to use an ActivityManager.RecentTaskInfo
+ object to launch a defunct task that was returned from ActivityManager.getRecentTaskList().</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
<string name="permlab_interactAcrossUsers">interact across users</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index b9cacd7..2dccaf2 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1203,6 +1203,7 @@
<item name="navigationButtonStyle">@style/Widget.Toolbar.Button.Navigation</item>
<item name="collapseIcon">?attr/homeAsUpIndicator</item>
<item name="contentInsetStart">16dp</item>
+ <item name="touchscreenBlocksFocus">true</item>
</style>
<style name="Widget.Toolbar.Button.Navigation" parent="Widget">
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 575bbe83..a8974c6 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -543,6 +543,7 @@
<style name="Widget.Material.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
<item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
<item name="popupBackground">@drawable/popup_background_material</item>
+ <item name="popupElevation">@dimen/floating_window_z</item>
</style>
<style name="Widget.Material.CompoundButton" parent="Widget.CompoundButton"/>
@@ -663,6 +664,7 @@
<style name="Widget.Material.PopupWindow.ActionMode">
<item name="popupBackground">@drawable/popup_background_material</item>
+ <item name="popupElevation">@dimen/floating_window_z</item>
<item name="popupAnimationStyle">@style/Animation.PopupWindow.ActionMode</item>
</style>
@@ -731,6 +733,7 @@
<item name="background">@drawable/spinner_background_material</item>
<item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
<item name="popupBackground">@drawable/popup_background_material</item>
+ <item name="popupElevation">@dimen/floating_window_z</item>
<item name="dropDownVerticalOffset">0dip</item>
<item name="dropDownHorizontalOffset">0dip</item>
<item name="dropDownWidth">wrap_content</item>
@@ -863,14 +866,15 @@
<item name="divider">?attr/dividerVertical</item>
<item name="titleTextStyle">@style/TextAppearance.Material.Widget.ActionBar.Title</item>
<item name="subtitleTextStyle">@style/TextAppearance.Material.Widget.ActionBar.Subtitle</item>
- <item name="progressBarStyle">@style/Widget.Material.ProgressBar.Horizontal</item>
- <item name="indeterminateProgressStyle">@style/Widget.Material.ProgressBar</item>
+ <item name="progressBarStyle">?attr/progressBarStyleHorizontal</item>
+ <item name="indeterminateProgressStyle">?attr/progressBarStyle</item>
<item name="progressBarPadding">32dip</item>
<item name="itemPadding">8dip</item>
<item name="homeLayout">@layout/action_bar_home_material</item>
<item name="gravity">center_vertical</item>
<item name="contentInsetStart">16dp</item>
<item name="elevation">8dp</item>
+ <item name="popupTheme">?attr/actionBarPopupTheme</item>
</style>
<style name="Widget.Material.ActionBar.Solid">
@@ -1032,23 +1036,8 @@
<style name="Widget.Material.Light.ActionBar.TabText" parent="Widget.Material.ActionBar.TabText"/>
<style name="Widget.Material.Light.ActionMode" parent="Widget.Material.ActionMode" />
<style name="Widget.Material.Light.ActionButton.CloseMode" parent="Widget.Material.ActionButton.CloseMode" />
-
- <style name="Widget.Material.Light.ActionBar" parent="Widget.Material.ActionBar">
- <item name="titleTextStyle">@style/TextAppearance.Material.Widget.ActionBar.Title</item>
- <item name="subtitleTextStyle">@style/TextAppearance.Material.Widget.ActionBar.Subtitle</item>
- <item name="background">@null</item>
- <item name="backgroundStacked">@null</item>
- <item name="backgroundSplit">@null</item>
- <item name="progressBarStyle">@style/Widget.Material.Light.ProgressBar.Horizontal</item>
- <item name="indeterminateProgressStyle">@style/Widget.Material.Light.ProgressBar</item>
- </style>
-
- <style name="Widget.Material.Light.ActionBar.Solid">
- <item name="background">?attr/colorPrimary</item>
- <item name="backgroundStacked">?attr/colorPrimary</item>
- <item name="backgroundSplit">?attr/colorPrimary</item>
- </style>
-
+ <style name="Widget.Material.Light.ActionBar" parent="Widget.Material.ActionBar" />
+ <style name="Widget.Material.Light.ActionBar.Solid" parent="Widget.Material.ActionBar.Solid" />
<style name="Widget.Material.Light.FastScroll" parent="Widget.Material.FastScroll"/>
<style name="Widget.Material.Light.MediaRouteButton" parent="Widget.Material.MediaRouteButton" />
diff --git a/docs/html/about/versions/android-4.2.jd b/docs/html/about/versions/android-4.2.jd
index 73d51c5..76acb8a 100644
--- a/docs/html/about/versions/android-4.2.jd
+++ b/docs/html/about/versions/android-4.2.jd
@@ -361,8 +361,7 @@
href="{@docRoot}google/gcm/index.html">Google Cloud Messaging</a>.</p>
<p>Beware that if your app requests one of the hardware device identifiers (such as the WiFi MAC
-address, the {@link android.os.Build#SERIAL} number, or the {@link
-android.provider.Settings.Secure#ANDROID_ID} number), they will provide the same value for each
+address or the {@link android.os.Build#SERIAL} number), they will provide the same value for each
user because these identifiers are tied to the hardware and not the user. Not to mention the other
problems these identifiers introduce as discussed in the <a
href="http://android-developers.blogspot.com/2011/03/identifying-app-installations.html">Identifying
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index eec4e8d..1664923 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -90,10 +90,10 @@
</div>
<div class="layout-content-col span-4">
<a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear Toolkit AI']);"
- href="{@docRoot}downloads/design/Android_Wear_Toolkit_20140626.ai">Adobe® Illustrator® Toolkit</a>
+ href="{@docRoot}downloads/design/Android_Wear_Toolkit_20140722.ai">Adobe® Illustrator® Toolkit</a>
<a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear Toolkit PDF']);"
- href="{@docRoot}downloads/design/Android_Wear_Toolkit_20140626.pdf">PDF Toolkit</a>
+ href="{@docRoot}downloads/design/Android_Wear_Toolkit_20140722.pdf">PDF Toolkit</a>
</div>
</div>
@@ -111,9 +111,9 @@
</div>
<div class="layout-content-col span-4">
<a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear App Patterns AI']);"
- href="{@docRoot}downloads/design/Android_Wear_Patterns_20140626.ai">Adobe® Illustrator® App Patterns</a>
+ href="{@docRoot}downloads/design/Android_Wear_Patterns_20140722.ai">Adobe® Illustrator® App Patterns</a>
<a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear App Patterns PDF']);"
- href="{@docRoot}downloads/design/Android_Wear_Patterns_20140626.pdf">PDF App Patterns</a>
+ href="{@docRoot}downloads/design/Android_Wear_Patterns_20140722.pdf">PDF App Patterns</a>
</div>
</div>
diff --git a/docs/html/google/play-services/ads.jd b/docs/html/google/play-services/ads.jd
index ed346c6..52f643e 100644
--- a/docs/html/google/play-services/ads.jd
+++ b/docs/html/google/play-services/ads.jd
@@ -59,6 +59,11 @@
<h4>Flexible and powerful tools </h4>
<p>Filters and controls help you manage your ads. If you want to use multiple ad
networks, you can do that too, with free ad network mediation.</p>
+
+ <h4>Ad Policy Compliant</h4>
+ <p>The Google Mobile Ads SDK available in Google Play services is compliant with
+ Google Play Ad Poilcy regarding the usage of
+ <a href="{@docRoot}google/play-services/id.html">advertising ID</a>.</p>
</div>
<div class="col-6 normal-links">
diff --git a/docs/html/google/play-services/id.jd b/docs/html/google/play-services/id.jd
index db50c7f..43d1809 100644
--- a/docs/html/google/play-services/id.jd
+++ b/docs/html/google/play-services/id.jd
@@ -55,6 +55,19 @@
</div>
</div>
+<p class="caution" style=
+"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">
+ As a reminder, please note that starting <strong>1 August 2014</strong>, new
+ apps and app updates distributed through Google Play must use the advertising
+ ID in lieu of any other persistent identifiers for any advertising purposes,
+ on devices that support the advertising ID.<br>
+ <br>
+ To learn how to check your app's compliance through the Developer Console, or
+ for details on the associated developer policy changes, please see the
+ <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6048248">Advertising
+ ID topic</a> in the Google Play developer help center.
+</p>
<h2 id="get_started">Using the Advertising ID</h2>
diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd
index c4d5083..f0e93b9 100644
--- a/docs/html/guide/topics/manifest/activity-element.jd
+++ b/docs/html/guide/topics/manifest/activity-element.jd
@@ -453,7 +453,7 @@
created to handle a new intent. However, if the target task already has an
existing instance of the activity at the top of its stack, that instance
will receive the new intent (in an
-<code>{@link android.app.Activity#onNewIntent onNewIntent()}</code> call);
+{@link android.app.Activity#onNewIntent onNewIntent()} call);
a new instance is not created.
In other circumstances — for example, if an existing instance of the
"{@code singleTop}" activity is in the target task, but not at the top of
@@ -461,6 +461,22 @@
— a new instance would be created and pushed on the stack.
</p>
+<p>Similarly, if you
+<a href="{@docRoot}training/implementing-navigation/ancestral.html">navigate
+up</a> to an activity on the current stack, the behavior is determined by the
+parent activity's launch mode. If the parent activity has launch mode {@code
+singleTop} (or the <code>up</code> intent contains {@link
+android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}), the parent is brought to the
+top of the stack, and its state is preserved. The navigation intent is received
+by the parent activity's {@link android.app.Activity#onNewIntent onNewIntent()}
+method. If the parent activity has launch mode {@code standard} (and the
+<code>up</code> intent does not contain {@link
+android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}), the current activity and its
+parent are both popped off the stack, and a new instance of the parent activity
+is created to receive the navigation intent.
+</p>
+
+
<p>
The "{@code singleTask}" and "{@code singleInstance}" modes also differ from
each other in only one respect: A "{@code singleTask}" activity allows other
diff --git a/docs/html/guide/topics/text/creating-input-method.jd b/docs/html/guide/topics/text/creating-input-method.jd
index 205fd96..4b6b7b7 100644
--- a/docs/html/guide/topics/text/creating-input-method.jd
+++ b/docs/html/guide/topics/text/creating-input-method.jd
@@ -4,6 +4,30 @@
<div id="qv-wrapper">
<div id="qv">
+<h2>In This Document</h2>
+<ol>
+ <li>
+ <a href="#InputMethodLifecycle">The IME Lifecycle</a>
+ </li>
+ <li>
+ <a href="#DefiningIME">Declaring IME Components in the Manifest</a>
+ </li>
+ <li>
+ <a href="#IMEAPI">The Input Method API</a>
+ </li>
+ <li>
+ <a href="#IMEUI">Designing the Input Method UI</a>
+ </li>
+ <li>
+ <a href="#SendText">Sending Text to the Application</a>
+ </li>
+ <li>
+ <a href="#IMESubTypes">Creating an IME Subtype</a>
+ </li>
+ <li>
+ <a href="#GeneralDesign">General IME Considerations</a>
+ </li>
+</ol>
<h2>See also</h2>
<ol>
<li>
@@ -16,29 +40,20 @@
</div>
</div>
<p>
- An input method editor (IME) is a user control that enables users to enter text. Android
- provides an extensible input method framework that allows applications to provide users
- alternative input methods, such as on-screen keyboards or even speech input. Once installed,
- users can select which IME they want to use from the system settings and use it across the
+ An input method editor (IME) is a user control that enables users to enter text. Android
+ provides an extensible input method framework that allows applications to provide users
+ alternative input methods, such as on-screen keyboards or even speech input. Once installed,
+ users can select which IME they want to use from the system settings and use it across the
entire system; only one IME may be enabled at a time.
</p>
<p>
To add an IME to the Android system, you create an Android application
- containing a class that extends {@link android.inputmethodservice.InputMethodService}. In
+ containing a class that extends {@link android.inputmethodservice.InputMethodService}. In
addition, you usually create a "settings" activity that passes options to the IME
service. You can also define a settings UI that's displayed as part of the system settings.
</p>
-<p>This article covers the following:</p>
-<ul>
- <li>The IME lifecycle.</li>
- <li>Declaring IME components in the application manifest.</li>
- <li>The IME API.</li>
- <li>Designing an IME UI.</li>
- <li>Sending text from an IME to an application.</li>
- <li>Working with IME subtypes.</li>
-</ul>
<p>
- If you haven't worked with IMEs before, you should read the introductory article
+ If you haven't worked with IMEs before, you should read the introductory article
<a href="http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html">Onscreen Input Methods</a> first.
Also, the Soft Keyboard sample app included in the SDK contains sample code that you can modify
to start building your own IME.
@@ -59,16 +74,16 @@
<h2 id="DefiningIME">Declaring IME Components in the Manifest</h2>
<p>
In the Android system, an IME is an Android application that contains a special IME service.
- The application's manifest file must declare the service, request the necessary permissions,
- provide an intent filter that matches the action <code>action.view.InputMethod</code>, and
+ The application's manifest file must declare the service, request the necessary permissions,
+ provide an intent filter that matches the action <code>action.view.InputMethod</code>, and
provide metadata that defines characteristics of the IME. In addition, to provide a settings
interface that allows the user to modify the behavior of the IME, you can define a "settings"
activity that can be launched from System Settings.
</p>
<p>
The following snippet declares IME service. It requests the permission {@link
- android.Manifest.permission#BIND_INPUT_METHOD} to allow the service to connect the IME to
- the system, sets up an intent filter that matches the action
+ android.Manifest.permission#BIND_INPUT_METHOD} to allow the service to connect the IME to
+ the system, sets up an intent filter that matches the action
<code>android.view.InputMethod</code>, and defines metadata for the IME:
</p>
<pre>
@@ -88,7 +103,7 @@
for the IME application:</p>
<pre>
<!-- Optional: an activity for controlling the IME settings -->
- <activity android:name="FastInputIMESettings"
+ <activity android:name="FastInputIMESettings"
android:label="@string/fast_input_settings">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
@@ -105,12 +120,12 @@
handling keyboard characters.
</p>
<p>
- The central part of an IME is a service component, a class that extends
- {@link android.inputmethodservice.InputMethodService}. In addition to implementing the
- normal service lifecycle, this class has callbacks for providing your IME's UI, handling user
+ The central part of an IME is a service component, a class that extends
+ {@link android.inputmethodservice.InputMethodService}. In addition to implementing the
+ normal service lifecycle, this class has callbacks for providing your IME's UI, handling user
input, and delivering text to the field that currently has focus. By default, the
- {@link android.inputmethodservice.InputMethodService} class provides most of the implementation
- for managing the state and visibility of the IME and communicating with the current
+ {@link android.inputmethodservice.InputMethodService} class provides most of the implementation
+ for managing the state and visibility of the IME and communicating with the current
input field.
</p>
<p>
@@ -122,13 +137,13 @@
Defines the communication channel from an {@link android.view.inputmethod.InputMethod}
back to the application that is receiving its input. You use it to read text around the
cursor, commit text to the text box, and send raw key events to the application.
- Applications should extend this class rather than implementing the base interface
+ Applications should extend this class rather than implementing the base interface
{@link android.view.inputmethod.InputConnection}.
</dd>
<dt>{@link android.inputmethodservice.KeyboardView}</dt>
<dd>
An extension of {@link android.view.View} that renders a keyboard and responds to user
- input events. The keyboard layout is specified by an instance of
+ input events. The keyboard layout is specified by an instance of
{@link android.inputmethodservice.Keyboard}, which you can define in an XML file.
</dd>
</dl>
@@ -141,40 +156,40 @@
<h3 id="InputView">Input view</h3>
<p>
The input view is the UI where the user inputs text, in the form of keyclicks, handwriting or
- gestures. When the iIME is displayed for the first time, the system calls the
+ gestures. When the iIME is displayed for the first time, the system calls the
{@link android.inputmethodservice.InputMethodService#onCreateInputView()} callback. In your
implementation of this method, you create the layout you want to display in the IME
window and return the layout to the system. This snippet is an example of implementing the
{@link android.inputmethodservice.InputMethodService#onCreateInputView()} method:
<pre>
- @Override
- public View onCreateInputView() {
- MyKeyboardView inputView =
+ @Override
+ public View onCreateInputView() {
+ MyKeyboardView inputView =
(MyKeyboardView) getLayoutInflater().inflate( R.layout.input, null);
-
- inputView.setOnKeyboardActionListener(this); inputView.setKeyboard(mLatinKeyboard);
-
- return mInputView;
- }
+
+ inputView.setOnKeyboardActionListener(this); inputView.setKeyboard(mLatinKeyboard);
+
+ return mInputView;
+ }
</pre>
<p>
- In this example, {@code MyKeyboardView} is an instance of a custom implementation of
- {@link android.inputmethodservice.KeyboardView} that renders a
- {@link android.inputmethodservice.Keyboard}. If you’re building a traditional QWERTY keyboard,
- see the Soft Keyboard <a href="{@docRoot}tools/samples/index.html">sample
+ In this example, {@code MyKeyboardView} is an instance of a custom implementation of
+ {@link android.inputmethodservice.KeyboardView} that renders a
+ {@link android.inputmethodservice.Keyboard}. If you’re building a traditional QWERTY keyboard,
+ see the Soft Keyboard <a href="{@docRoot}tools/samples/index.html">sample
app</a> for an example of how to extend the {@link android.inputmethodservice.KeyboardView} class.
</p>
<h3 id="CandidateView">Candidates view</h3>
<p>
The candidates view is the UI where the IME displays potential word corrections or
- suggestions for the user to select. In the IME lifecycle, the system calls
- {@link android.inputmethodservice.InputMethodService#onCreateCandidatesView()} when it's ready
+ suggestions for the user to select. In the IME lifecycle, the system calls
+ {@link android.inputmethodservice.InputMethodService#onCreateCandidatesView()} when it's ready
to display the candidate view. In your implementation of this method, return a layout that shows
word suggestions, or return null if you don’t want to show anything (a null response is the
default behavior, so you don’t have to implement this if you don’t provide suggestions).</p>
<p>
- For an example implementation that provides user suggestions, see the
- Soft Keyboard <a href="{@docRoot}tools/samples/index.html">sample
+ For an example implementation that provides user suggestions, see the
+ Soft Keyboard <a href="{@docRoot}tools/samples/index.html">sample
app</a>.
</p>
<h3 id="DesignConsiderations">UI design considerations</h3>
@@ -209,10 +224,10 @@
<strong>Figure 2.</strong> Latin IME input types.
</p>
<p>
- When an input field receives focus and your IME starts, the system calls
+ When an input field receives focus and your IME starts, the system calls
{@link android.inputmethodservice.InputMethodService#onStartInputView(EditorInfo, boolean)
- onStartInputView()}, passing in an {@link android.view.inputmethod.EditorInfo} object that
- contains details about the input type and other attributes of the text field. In this object,
+ onStartInputView()}, passing in an {@link android.view.inputmethod.EditorInfo} object that
+ contains details about the input type and other attributes of the text field. In this object,
the {@link android.view.inputmethod.EditorInfo#inputType} field contains the text field's input
type.
</p>
@@ -223,7 +238,7 @@
this:
</p>
<pre>
-inputType & InputType.TYPE_MASK_CLASS
+inputType & InputType.TYPE_MASK_CLASS
</pre>
<p>
The input type bit pattern can have one of several values, including:
@@ -248,7 +263,7 @@
</dd>
</dl>
<p>
- These constants are described in more detail in the reference documentation for
+ These constants are described in more detail in the reference documentation for
{@link android.text.InputType}.
</p>
<p>
@@ -287,8 +302,8 @@
<p>
As the user inputs text with your IME, you can send text to the application by
sending individual key events or by editing the text around the cursor in the application's text
- field. In either case, you use an instance of {@link android.view.inputmethod.InputConnection}
- to deliver the text. To get this instance, call
+ field. In either case, you use an instance of {@link android.view.inputmethod.InputConnection}
+ to deliver the text. To get this instance, call
{@link android.inputmethodservice.InputMethodService#getCurrentInputConnection
InputMethodService.getCurrentInputConnection()}.
</p>
@@ -336,18 +351,18 @@
</p>
<pre>
InputConnection ic = getCurrentInputConnection();
-
+
ic.deleteSurroundingText(4, 0);
-
+
ic.commitText("Hello", 1);
-
+
ic.commitText("!", 1);
</pre>
<h3 id="ComposeThenCommit">Composing text before committing</h3>
<p>
If your IME does text prediction or requires multiple steps to compose a glyph or
word, you can show the progress in the text field until the user commits the word, and then you
- can replace the partial composition with the completed text. You may give special treatment to
+ can replace the partial composition with the completed text. You may give special treatment to
the text by adding a "span" to it when you pass it to InputConnection#setComposingText().
</p>
<p>
@@ -385,10 +400,10 @@
selection during composition. You may also want to trap the back key to dismiss any popups
originating from the input method window.</p>
<p>
- To intercept hardware keys, override
+ To intercept hardware keys, override
{@link android.inputmethodservice.InputMethodService#onKeyDown(int, KeyEvent) onKeyDown()}
- and {@link android.inputmethodservice.InputMethodService#onKeyUp(int, KeyEvent) onKeyUp()}.
- See the Soft Keyboard <a href="{@docRoot}tools/samples/index.html">sample
+ and {@link android.inputmethodservice.InputMethodService#onKeyUp(int, KeyEvent) onKeyUp()}.
+ See the Soft Keyboard <a href="{@docRoot}tools/samples/index.html">sample
app</a> for an example.
</p>
<p>
@@ -396,7 +411,7 @@
</p>
<h2 id="IMESubTypes">Creating an IME Subtype</h2>
<p>
- Subtypes allow the IME to expose multiple input modes and languages supported by an IME. A
+ Subtypes allow the IME to expose multiple input modes and languages supported by an IME. A
subtype can represent:
</p>
<ul>
@@ -414,13 +429,13 @@
<p>
Subtype information is used for an IME switcher dialog that's available from the notification
bar and also for IME settings. The information also allows the framework to bring up a
- specific subtype of an IME directly. When you build an IME, use the subtype facility, because
+ specific subtype of an IME directly. When you build an IME, use the subtype facility, because
it helps the user identify and switch between different IME languages and modes.
</p>
<p>
You define subtypes in one of the input method's XML resource files, using the
- <code><subtype></code> element. The following snippet defines an IME with two
- subtypes: a keyboard subtype for the US English locale, and another keyboard subtype for the
+ <code><subtype></code> element. The following snippet defines an IME with two
+ subtypes: a keyboard subtype for the US English locale, and another keyboard subtype for the
French language locale for France:
</p>
<pre>
@@ -457,8 +472,8 @@
android:imeSubtypeMode="keyboard" />
</pre>
<p>
- The next snippet is part of the IME's <code>strings.xml</code> file. The string
- resource <code>label_subtype_generic</code>, which is used by the input method UI definition to
+ The next snippet is part of the IME's <code>strings.xml</code> file. The string
+ resource <code>label_subtype_generic</code>, which is used by the input method UI definition to
set the subtype's label, is defined as:
</p>
<pre>
@@ -487,9 +502,9 @@
<h3 id="SubtypeSettings">Choosing IME subtypes from System Settings</h3>
<p>
A user can control how subtypes are used in the “Language & input” settings panel in the
- System Settings area. In the Soft Keyboard sample, the file
- <code>InputMethodSettingsFragment.java</code> contains an implementation that
- facilitates a subtype enabler in the IME settings. Please refer to the SoftKeyboard sample in
+ System Settings area. In the Soft Keyboard sample, the file
+ <code>InputMethodSettingsFragment.java</code> contains an implementation that
+ facilitates a subtype enabler in the IME settings. Please refer to the SoftKeyboard sample in
the Android SDK for more information about how to support Input Method Subtypes in your IME.
</p>
<img src="{@docRoot}resources/articles/images/inputmethod_subtype_settings.png" alt=""
@@ -497,6 +512,7 @@
<p class="img-caption">
<strong>Figure 6.</strong> Choosing a language for the IME.
</p>
+
<h2 id="GeneralDesign">General IME Considerations</h2>
<p>
Here are some other things to consider as you're implementing your IME:
@@ -506,22 +522,22 @@
Provide a way for users to set options directly from the IME's UI.
</li>
<li>
- Because multiple IMEs may be installed on the device, provide a way for the user to switch to a
+ Because multiple IMEs may be installed on the device, provide a way for the user to switch to a
different IME directly from the input method UI.
</li>
<li>
- Bring up the IME's UI quickly. Preload or load on demand any large resources so that users
- see the IME as soon as they tap on a text field. Cache resources and views for subsequent
+ Bring up the IME's UI quickly. Preload or load on demand any large resources so that users
+ see the IME as soon as they tap on a text field. Cache resources and views for subsequent
invocations of the input method.
</li>
<li>
- Conversely, you should release large memory allocations soon after the input method window is
+ Conversely, you should release large memory allocations soon after the input method window is
hidden, so that applications can have sufficient memory to run. Consider using a delayed message
to release resources if the IME is in a hidden state for a few seconds.
-</li>
+</li>
<li>
- Make sure that users can enter as many characters as possible for the language or locale
- associated with the IME. Remember that users may use punctuation in passwords or user
+ Make sure that users can enter as many characters as possible for the language or locale
+ associated with the IME. Remember that users may use punctuation in passwords or user
names, so your IME has to provide many different characters to allow users to enter a
password and get access to the device.
</li>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 6e98f5e..2bbdfc8c 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -306,6 +306,9 @@
<p>
Android Studio is a new IDE powered by IntelliJ that provides new features and improvements
over ADT. It's currently in beta but will be the official Android IDE once it's ready.</p>
+ <p>
+ If you're a new Android developer, you should consider starting with Android Studio, because the
+ ADT plugin for Eclipse is no longer in active development.</p>
<p style="margin: 0;">
<a href="/sdk/installing/studio.html">Learn more about Android Studio</a></p>
</div>
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 88bc733..864e82e 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -28,8 +28,7 @@
<li>Eclipse <a href="http://www.eclipse.org/jdt">JDT</a> plugin (included
in most Eclipse IDE packages) </li>
<li><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">JDK 6</a>
- (JRE alone is not sufficient)</li>oid Development Tools plugin</a>
-(recommended)</li>
+ (JRE alone is not sufficient)</li>
<li><strong>Not</strong> compatible with GNU Compiler for Java (gcj)</li>
</ul>
@@ -79,73 +78,6 @@
<a href="{@docRoot}sdk/installing/adding-packages.html">Adding Platforms and Packages</a>.</p>
-<h2 id="tmgr">Download the ADT Translation Manager Plugin</h2>
-
-<div class="sidebox-wrapper">
-<div class="sidebox">
-<h2>App Translations in Google Play</h2>
-<p>Google Play <a href="{@docRoot}distribute/tools/localization-checklist.html#gp-trans">App
-Translation Service</a> is available in the Developer Console to help you
-localize your app for a global user base. You can browse qualified vendors, get
-estimates, upload strings for translation, and then import the translations directly
-into your app.</p>
-</div>
-</div>
-
-<p>ADT Translation Manager Plugin is an Android SDK Tools plugin that helps
-you work with strings that you are localizing. It's designed to work
-with the translation services built into the Google Play Developer
-Console that let you quickly find and purchase translations of
-your app from a list of pre-qualified vendors. </p>
-
-<p>The plugin simplifies the management of strings
-during translation. It lets you easily export your default strings
-and upload them directly to the Developer Console, from which you
-can get estimates or purchase translations. When your translations
-are ready, the plugin lets you quickly download and import them
-back into your project. During import, it moves all of the translated resources into
-the correct locations under <code>res/values</code>, so that
-localization works instantly.</p>
-
-<p>For more information about translation services in Google Play, see <a
-href="{@docRoot}distribute/tools/localization-checklist.html#gp-trans">Purchase
-professional translations through the Developer Console</a>.</p>
-
-<p>To install the ADT Translation Manager Plugin follow these steps:</p>
-
-<ol>
- <li>Install the ADT Plugin, as described above. </li>
- <li>In Eclipse, select <strong>Help</strong> > <strong>Install New
-Software</strong>.</li>
- <li>Click <strong>Add</strong>, in the top-right corner.</li>
- <li>In the Add Repository dialog that appears, enter a repository name for the <em>Name</em>
- and the following URL for the <em>Location</em>:
- <pre>https://dl.google.com/alt/</pre>
- </li>
- <li>Click <strong>OK</strong>.
- <li>In the Available Software dialog, select the checkbox next to <strong>Android Developer Tools
- - Translation Manager</strong> and click <strong>Next</strong>.</li>
- <li>In the next window, you'll see a list of the tools to be downloaded. Click
-<strong>Next</strong>. </li>
- <li>Read and accept the license agreements, then click <strong>Finish</strong>.
- <p>If you get a security warning saying that the authenticity or validity of
-the software can't be established, click <strong>OK</strong>.</p></li>
- <li>When the installation completes, restart Eclipse. </li>
-</ol>
-
-<h4 id="translation-manager-notes">Installation notes</h4>
-
-<ul>
-<li>The full ADT Plugin must be installed in your Eclipse environment before you install the ADT Translation Manager Plugin.</li>
-<li>ADT Translation Manager Plugin is designed for use with the translation services offered through the Google Play Developer Console. It is not designed for general purpose import/export of strings. </li>
-<li>To use the plugin, you must <a href="{@docRoot}distribute/googleplay/start.html">set up a Developer Console account</a>. </li>
-<li>Currently, translation services are available through the Developer Console only as part of a pilot program. To use the plugin, you must first sign up for the pilot program by visiting the Developer Console.</li>
-<li>If you downloaded ADT as part of the SDK ADT bundle, you may encounter an error when attempting to download the ADT Translation Manager Plugin from the remote repository. In that case, open the <strong>Install New
-Software</strong>, uncheck "Contact all update sites during install to find required software" at the bottom and try again. </li>
-</ul>
-
-
-
<h2 id="Troubleshooting">Troubleshooting ADT Installation</h2>
<p>If you are having trouble downloading the ADT plugin after following the
diff --git a/docs/html/training/implementing-navigation/ancestral.jd b/docs/html/training/implementing-navigation/ancestral.jd
index 57251c1..8aa0fd6 100644
--- a/docs/html/training/implementing-navigation/ancestral.jd
+++ b/docs/html/training/implementing-navigation/ancestral.jd
@@ -133,7 +133,25 @@
navigateUpFromSameTask()}. When you call this method, it finishes the current activity and
starts (or resumes) the appropriate parent activity.
If the target parent activity is in the task's back stack, it is brought
-forward as defined by {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}.</p>
+forward. The way it is brought forward depends on whether the parent activity
+is able to handle an {@link
+android.app.Activity#onNewIntent onNewIntent()} call:</p>
+
+<ul>
+ <li>If the parent activity has launch mode <a
+ href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
+ <singleTop>}</a>, or the <code>up</code> intent contains {@link
+ android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}, the parent activity is
+ brought to the top of the stack, and receives the intent through its
+ {@link android.app.Activity#onNewIntent onNewIntent()} method.</li>
+
+ <li>If the parent activity has launch mode <a
+ href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
+ <standard>}</a>, and the <code>up</code> intent does not contain
+ {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}, the parent activity
+ is popped off the stack, and a new instance of that activity is created on
+ top of the stack to receive the intent.</li>
+</ul>
<p>For example:</p>
@@ -157,7 +175,6 @@
navigating <em>Up</em> should create a new task that belongs to your app, which
requires that you create a new back stack.</p>
-
<h3 id="BuildBackStack">Navigate up with a new back stack</h3>
<p>If your activity provides any <a
diff --git a/docs/html/training/notepad/index.jd b/docs/html/training/notepad/index.jd
index d1aa221..507b232 100644
--- a/docs/html/training/notepad/index.jd
+++ b/docs/html/training/notepad/index.jd
@@ -17,13 +17,9 @@
application. The exercises explain each step in detail and provide all the
sample code you need to complete the application. </p>
-<p>When you are finished with the tutorial, you will have created a functioning
+<p><p>When you are finished with the tutorial, you will have created a functioning
Android application and will have learned many of the most important
-concepts in Android development. If you want to add more complex features to
-your application, you can examine the code in an alternative implementation
-of a Note Pad application, in the
-<a href="{@docRoot}resources/samples/index.html">Sample Code</a> section. </p>
-
+concepts in Android development.</p>
<a name="who"></a>
<h2>Who Should Use this Tutorial</h2>
@@ -122,17 +118,13 @@
<li>For a lighter but broader introduction to concepts not covered in the
tutorial,
take a look at <a href="{@docRoot}resources/faq/commontasks.html">Common Android Tasks</a>.</li>
-<li>The Android SDK includes a variety of fully functioning sample applications
-that make excellent opportunities for further learning. You can find the sample
-applications in the <code>samples/</code> directory of your downloaded SDK, or browser them
-here, in the <a href="{@docRoot}resources/samples/index.html">Sample Code</a> section.</li>
+
<li>This tutorial draws from the full Notepad application included in the
-<code>samples/</code> directory of the SDK, though it does not match it exactly.
-When you are done with the tutorial,
-it is highly recommended that you take a closer look at this version of the Notepad
-application,
-as it demonstrates a variety of interesting additions for your application,
-such as:</li>
+<code>samples/legacy/NotePad</code> directory of the SDK, though it does not
+match it exactly. When you are done with the tutorial, it is highly recommended
+that you take a closer look at this version of the Notepad application, as it
+demonstrates a variety of interesting additions for your application, such
+as:</li>
<ul>
<li>Setting up a custom striped list for the list of notes.</li>
<li>Creating a custom text edit view that overrides the <code>draw()</code>
diff --git a/docs/html/training/wearables/apps/voice.jd b/docs/html/training/wearables/apps/voice.jd
index 3dea5d7..639d90a 100644
--- a/docs/html/training/wearables/apps/voice.jd
+++ b/docs/html/training/wearables/apps/voice.jd
@@ -263,7 +263,7 @@
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
- if (requestCode == SPEECH_REQUEST && resultCode == RESULT_OK) {
+ if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) {
List<String> results = data.getStringArrayListExtra(
RecognizerIntent.EXTRA_RESULTS);
String spokenText = results.get(0);
@@ -271,4 +271,4 @@
}
super.onActivityResult(requestCode, resultCode, data);
}
-</pre>
\ No newline at end of file
+</pre>
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index db5c8e3..525e01d 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -386,6 +386,7 @@
*
* @see #setTileModeY(android.graphics.Shader.TileMode)
* @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode)
+ * @attr ref android.R.styleable#BitmapDrawable_tileModeX
*/
public void setTileModeX(Shader.TileMode mode) {
setTileModeXY(mode, mBitmapState.mTileModeY);
@@ -401,6 +402,7 @@
*
* @see #setTileModeX(android.graphics.Shader.TileMode)
* @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode)
+ * @attr ref android.R.styleable#BitmapDrawable_tileModeY
*/
public final void setTileModeY(Shader.TileMode mode) {
setTileModeXY(mBitmapState.mTileModeX, mode);
diff --git a/location/java/android/location/GpsClock.java b/location/java/android/location/GpsClock.java
index f327c4e..963b604 100644
--- a/location/java/android/location/GpsClock.java
+++ b/location/java/android/location/GpsClock.java
@@ -18,6 +18,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Log;
/**
* A class containing a GPS clock timestamp.
@@ -26,44 +27,65 @@
* @hide
*/
public class GpsClock implements Parcelable {
- // mandatory parameters
- private long mTimeInNs;
+ private static final String TAG = "GpsClock";
- // optional parameters
- private boolean mHasLeapSecond;
+ // The following enumerations must be in sync with the values declared in gps.h
+
+ /**
+ * The type of the time stored is not available or it is unknown.
+ */
+ public static final byte TYPE_UNKNOWN = 0;
+
+ /**
+ * The source of the time value reported by this class is the 'Local Hardware Clock'.
+ */
+ public static final byte TYPE_LOCAL_HW_TIME = 1;
+
+ /**
+ * The source of the time value reported by this class is the 'GPS time' derived from
+ * satellites (epoch = Jan 6, 1980).
+ */
+ public static final byte TYPE_GPS_TIME = 2;
+
+ private static final short HAS_NO_FLAGS = 0;
+ private static final short HAS_LEAP_SECOND = (1<<0);
+ private static final short HAS_TIME_UNCERTAINTY = (1<<1);
+ private static final short HAS_FULL_BIAS = (1<<2);
+ private static final short HAS_BIAS = (1<<3);
+ private static final short HAS_BIAS_UNCERTAINTY = (1<<4);
+ private static final short HAS_DRIFT = (1<<5);
+ private static final short HAS_DRIFT_UNCERTAINTY = (1<<6);
+
+ // End enumerations in sync with gps.h
+
+ private short mFlags;
private short mLeapSecond;
- private boolean mHasTimeUncertaintyInNs;
+ private byte mType;
+ private long mTimeInNs;
private double mTimeUncertaintyInNs;
- private boolean mHasBiasInNs;
+ private long mFullBiasInNs;
private double mBiasInNs;
- private boolean mHasBiasUncertaintyInNs;
private double mBiasUncertaintyInNs;
- private boolean mHasDriftInNsPerSec;
private double mDriftInNsPerSec;
- private boolean mHasDriftUncertaintyInNsPerSec;
private double mDriftUncertaintyInNsPerSec;
GpsClock() {
- reset();
+ initialize();
}
/**
* Sets all contents to the values stored in the provided object.
*/
public void set(GpsClock clock) {
- mTimeInNs = clock.mTimeInNs;
-
- mHasLeapSecond = clock.mHasLeapSecond;
+ mFlags = clock.mFlags;
mLeapSecond = clock.mLeapSecond;
- mHasTimeUncertaintyInNs = clock.mHasTimeUncertaintyInNs;
+ mType = clock.mType;
+ mTimeInNs = clock.mTimeInNs;
mTimeUncertaintyInNs = clock.mTimeUncertaintyInNs;
- mHasBiasInNs = clock.mHasBiasInNs;
+ mFullBiasInNs = clock.mFullBiasInNs;
mBiasInNs = clock.mBiasInNs;
- mHasBiasUncertaintyInNs = clock.mHasBiasUncertaintyInNs;
mBiasUncertaintyInNs = clock.mBiasUncertaintyInNs;
- mHasDriftInNsPerSec = clock.mHasDriftInNsPerSec;
mDriftInNsPerSec = clock.mDriftInNsPerSec;
- mHasDriftUncertaintyInNsPerSec = clock.mHasDriftUncertaintyInNsPerSec;
mDriftUncertaintyInNsPerSec = clock.mDriftUncertaintyInNsPerSec;
}
@@ -71,25 +93,61 @@
* Resets all the contents to its original state.
*/
public void reset() {
- mTimeInNs = Long.MIN_VALUE;
+ initialize();
+ }
- resetLeapSecond();
- resetTimeUncertaintyInNs();
- resetBiasInNs();
- resetBiasUncertaintyInNs();
- resetDriftInNsPerSec();
- resetDriftUncertaintyInNsPerSec();
+ /**
+ * Gets the type of time reported by {@link #getTimeInNs()}.
+ */
+ public byte getType() {
+ return mType;
+ }
+
+ /**
+ * Sets the type of time reported.
+ */
+ public void setType(byte value) {
+ switch (value) {
+ case TYPE_UNKNOWN:
+ case TYPE_GPS_TIME:
+ case TYPE_LOCAL_HW_TIME:
+ mType = value;
+ break;
+ default:
+ Log.d(TAG, "Sanitizing invalid 'type': " + value);
+ mType = TYPE_UNKNOWN;
+ break;
+ }
+ }
+
+ /**
+ * Gets a string representation of the 'type'.
+ * For internal and logging use only.
+ */
+ private String getTypeString() {
+ switch (mType) {
+ case TYPE_UNKNOWN:
+ return "Unknown";
+ case TYPE_GPS_TIME:
+ return "GpsTime";
+ case TYPE_LOCAL_HW_TIME:
+ return "LocalHwClock";
+ default:
+ return "<Invalid>";
+ }
}
/**
* Returns true if {@link #getLeapSecond()} is available, false otherwise.
*/
public boolean hasLeapSecond() {
- return mHasLeapSecond;
+ return isFlagSet(HAS_LEAP_SECOND);
}
/**
* Gets the leap second associated with the clock's time.
+ * The sign of the value is defined by the following equation:
+ * utc_time_ns = time_ns + (full_bias_ns + bias_ns) - leap_second * 1,000,000,000
*
* The value is only available if {@link #hasLeapSecond()} is true.
*/
@@ -101,7 +159,7 @@
* Sets the leap second associated with the clock's time.
*/
public void setLeapSecond(short leapSecond) {
- mHasLeapSecond = true;
+ setFlag(HAS_LEAP_SECOND);
mLeapSecond = leapSecond;
}
@@ -109,13 +167,25 @@
* Resets the leap second associated with the clock's time.
*/
public void resetLeapSecond() {
- mHasLeapSecond = false;
+ resetFlag(HAS_LEAP_SECOND);
mLeapSecond = Short.MIN_VALUE;
}
/**
- * Gets the GPS clock Time in nanoseconds; it represents the uncorrected receiver's GPS time
- * since 0000Z, January 6, 1980; this is, including {@link #getBiasInNs()}.
+ * Gets the GPS receiver internal clock value in nanoseconds.
+ * This can be either the 'local hardware clock' value ({@link #TYPE_LOCAL_HW_TIME}), or the
+ * current GPS time derived inside GPS receiver ({@link #TYPE_GPS_TIME}).
+ * {@link #getType()} defines the time reported.
+ *
+ * For 'local hardware clock' this value is expected to be monotonically increasing during the
+ * reporting session. The real GPS time can be derived by compensating
+ * {@link #getFullBiasInNs()} (when it is available) from this value.
+ *
+ * For 'GPS time' this value is expected to be the best estimation of current GPS time that GPS
+ * receiver can achieve. {@link #getTimeUncertaintyInNs()} should be available when GPS time is
+ * specified.
+ *
+ * Sub-nanosecond accuracy can be provided by means of {@link #getBiasInNs()}.
* The reported time includes {@link #getTimeUncertaintyInNs()}.
*/
public long getTimeInNs() {
@@ -123,7 +193,7 @@
}
/**
- * Sets the GPS clock Time in nanoseconds.
+ * Sets the GPS receiver internal clock in nanoseconds.
*/
public void setTimeInNs(long timeInNs) {
mTimeInNs = timeInNs;
@@ -133,11 +203,12 @@
* Returns true if {@link #getTimeUncertaintyInNs()} is available, false otherwise.
*/
public boolean hasTimeUncertaintyInNs() {
- return mHasTimeUncertaintyInNs;
+ return isFlagSet(HAS_TIME_UNCERTAINTY);
}
/**
* Gets the clock's time Uncertainty (1-Sigma) in nanoseconds.
+ * The uncertainty is represented as an absolute (single sided) value.
*
* The value is only available if {@link #hasTimeUncertaintyInNs()} is true.
*/
@@ -149,7 +220,7 @@
* Sets the clock's Time Uncertainty (1-Sigma) in nanoseconds.
*/
public void setTimeUncertaintyInNs(double timeUncertaintyInNs) {
- mHasTimeUncertaintyInNs = true;
+ setFlag(HAS_TIME_UNCERTAINTY);
mTimeUncertaintyInNs = timeUncertaintyInNs;
}
@@ -157,34 +228,73 @@
* Resets the clock's Time Uncertainty (1-Sigma) in nanoseconds.
*/
public void resetTimeUncertaintyInNs() {
- mHasTimeUncertaintyInNs = false;
+ resetFlag(HAS_TIME_UNCERTAINTY);
mTimeUncertaintyInNs = Double.NaN;
}
/**
+ * Returns true if {@link @getFullBiasInNs()} is available, false otherwise.
+ */
+ public boolean hasFullBiasInNs() {
+ return isFlagSet(HAS_FULL_BIAS);
+ }
+
+ /**
+ * Gets the difference between hardware clock ({@link #getTimeInNs()}) inside GPS receiver and
+ * the true GPS time since 0000Z, January 6, 1980, in nanoseconds.
+ *
+ * This value is available if {@link #TYPE_LOCAL_HW_TIME} is set, and GPS receiver has solved
+ * the clock for GPS time.
+ * {@link #getBiasUncertaintyInNs()} should be used for quality check.
+ *
+ * The sign of the value is defined by the following equation:
+ * true time (GPS time) = time_ns + (full_bias_ns + bias_ns)
+ *
+ * The reported full bias includes {@link #getBiasUncertaintyInNs()}.
+ * The value is onl available if {@link #hasFullBiasInNs()} is true.
+ */
+ public long getFullBiasInNs() {
+ return mFullBiasInNs;
+ }
+
+ /**
+ * Sets the full bias in nanoseconds.
+ */
+ public void setFullBiasInNs(long value) {
+ setFlag(HAS_FULL_BIAS);
+ mFullBiasInNs = value;
+ }
+
+ /**
+ * Resets the full bias in nanoseconds.
+ */
+ public void resetFullBiasInNs() {
+ resetFlag(HAS_FULL_BIAS);
+ mFullBiasInNs = Long.MIN_VALUE;
+ }
+
+ /**
* Returns true if {@link #getBiasInNs()} is available, false otherwise.
*/
public boolean hasBiasInNs() {
- return mHasBiasInNs;
+ return isFlagSet(HAS_BIAS);
}
/**
- * Gets the clock's Bias in nanoseconds.
- * The sign of the value (if available), is defined by the following equation:
- * true time = time - bias.
+ * Gets the clock's sub-nanosecond bias.
* The reported bias includes {@link #getBiasUncertaintyInNs()}.
*
* The value is only available if {@link #hasBiasInNs()} is true.
*/
- public Double getBiasInNs() {
+ public double getBiasInNs() {
return mBiasInNs;
}
/**
- * Sets the clock's Bias in nanoseconds.
+ * Sets the sub-nanosecond bias.
*/
public void setBiasInNs(double biasInNs) {
- mHasBiasInNs = true;
+ setFlag(HAS_BIAS);
mBiasInNs = biasInNs;
}
@@ -192,7 +302,7 @@
* Resets the clock's Bias in nanoseconds.
*/
public void resetBiasInNs() {
- mHasBiasInNs = false;
+ resetFlag(HAS_BIAS);
mBiasInNs = Double.NaN;
}
@@ -200,7 +310,7 @@
* Returns true if {@link #getBiasUncertaintyInNs()} is available, false otherwise.
*/
public boolean hasBiasUncertaintyInNs() {
- return mHasBiasUncertaintyInNs;
+ return isFlagSet(HAS_BIAS_UNCERTAINTY);
}
/**
@@ -216,7 +326,7 @@
* Sets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
*/
public void setBiasUncertaintyInNs(double biasUncertaintyInNs) {
- mHasBiasUncertaintyInNs = true;
+ setFlag(HAS_BIAS_UNCERTAINTY);
mBiasUncertaintyInNs = biasUncertaintyInNs;
}
@@ -224,7 +334,7 @@
* Resets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
*/
public void resetBiasUncertaintyInNs() {
- mHasBiasUncertaintyInNs = false;
+ resetFlag(HAS_BIAS_UNCERTAINTY);
mBiasUncertaintyInNs = Double.NaN;
}
@@ -232,7 +342,7 @@
* Returns true if {@link #getDriftInNsPerSec()} is available, false otherwise.
*/
public boolean hasDriftInNsPerSec() {
- return mHasDriftInNsPerSec;
+ return isFlagSet(HAS_DRIFT);
}
/**
@@ -250,7 +360,7 @@
* Sets the clock's Drift in nanoseconds per second.
*/
public void setDriftInNsPerSec(double driftInNsPerSec) {
- mHasDriftInNsPerSec = true;
+ setFlag(HAS_DRIFT);
mDriftInNsPerSec = driftInNsPerSec;
}
@@ -258,7 +368,7 @@
* Resets the clock's Drift in nanoseconds per second.
*/
public void resetDriftInNsPerSec() {
- mHasDriftInNsPerSec = false;
+ resetFlag(HAS_DRIFT);
mDriftInNsPerSec = Double.NaN;
}
@@ -266,7 +376,7 @@
* Returns true if {@link #getDriftUncertaintyInNsPerSec()} is available, false otherwise.
*/
public boolean hasDriftUncertaintyInNsPerSec() {
- return mHasDriftUncertaintyInNsPerSec;
+ return isFlagSet(HAS_DRIFT_UNCERTAINTY);
}
/**
@@ -282,7 +392,7 @@
* Sets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
*/
public void setDriftUncertaintyInNsPerSec(double driftUncertaintyInNsPerSec) {
- mHasDriftUncertaintyInNsPerSec = true;
+ setFlag(HAS_DRIFT_UNCERTAINTY);
mDriftUncertaintyInNsPerSec = driftUncertaintyInNsPerSec;
}
@@ -290,7 +400,7 @@
* Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
*/
public void resetDriftUncertaintyInNsPerSec() {
- mHasDriftUncertaintyInNsPerSec = false;
+ resetFlag(HAS_DRIFT_UNCERTAINTY);
mDriftUncertaintyInNsPerSec = Double.NaN;
}
@@ -298,19 +408,16 @@
@Override
public GpsClock createFromParcel(Parcel parcel) {
GpsClock gpsClock = new GpsClock();
- gpsClock.mTimeInNs = parcel.readLong();
- gpsClock.mHasLeapSecond = parcel.readInt() != 0;
+ gpsClock.mFlags = (short) parcel.readInt();
gpsClock.mLeapSecond = (short) parcel.readInt();
- gpsClock.mHasTimeUncertaintyInNs = parcel.readInt() != 0;
+ gpsClock.mType = parcel.readByte();
+ gpsClock.mTimeInNs = parcel.readLong();
gpsClock.mTimeUncertaintyInNs = parcel.readDouble();
- gpsClock.mHasBiasInNs = parcel.readInt() != 0;
+ gpsClock.mFullBiasInNs = parcel.readLong();
gpsClock.mBiasInNs = parcel.readDouble();
- gpsClock.mHasBiasUncertaintyInNs = parcel.readInt() != 0;
gpsClock.mBiasUncertaintyInNs = parcel.readDouble();
- gpsClock.mHasDriftInNsPerSec = parcel.readInt() != 0;
gpsClock.mDriftInNsPerSec = parcel.readDouble();
- gpsClock.mHasDriftUncertaintyInNsPerSec = parcel.readInt() != 0;
gpsClock.mDriftUncertaintyInNsPerSec = parcel.readDouble();
return gpsClock;
@@ -323,19 +430,15 @@
};
public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeLong(mTimeInNs);
-
- parcel.writeInt(mHasLeapSecond ? 1 : 0);
+ parcel.writeInt(mFlags);
parcel.writeInt(mLeapSecond);
- parcel.writeInt(mHasTimeUncertaintyInNs ? 1 : 0);
+ parcel.writeByte(mType);
+ parcel.writeLong(mTimeInNs);
parcel.writeDouble(mTimeUncertaintyInNs);
- parcel.writeInt(mHasBiasInNs ? 1 : 0);
+ parcel.writeLong(mFullBiasInNs);
parcel.writeDouble(mBiasInNs);
- parcel.writeInt(mHasBiasUncertaintyInNs ? 1 : 0);
parcel.writeDouble(mBiasUncertaintyInNs);
- parcel.writeInt(mHasDriftInNsPerSec ? 1 : 0);
parcel.writeDouble(mDriftInNsPerSec);
- parcel.writeInt(mHasDriftUncertaintyInNsPerSec ? 1 : 0);
parcel.writeDouble(mDriftUncertaintyInNsPerSec);
}
@@ -346,37 +449,64 @@
@Override
public String toString() {
- final String format = " %-15s = %-25s %-26s = %s\n";
+ final String format = " %-15s = %s\n";
+ final String formatWithUncertainty = " %-15s = %-25s %-26s = %s\n";
StringBuilder builder = new StringBuilder("GpsClock:\n");
- builder.append(String.format(
- format,
- "LeapSecond",
- mHasLeapSecond ? mLeapSecond : null,
- "",
- ""));
+ builder.append(String.format(format, "Type", getTypeString()));
+
+ builder.append(String.format(format, "LeapSecond", hasLeapSecond() ? mLeapSecond : null));
builder.append(String.format(
- format,
+ formatWithUncertainty,
"TimeInNs",
mTimeInNs,
"TimeUncertaintyInNs",
- mHasTimeUncertaintyInNs ? mTimeUncertaintyInNs : null));
+ hasTimeUncertaintyInNs() ? mTimeUncertaintyInNs : null));
builder.append(String.format(
format,
+ "FullBiasInNs",
+ hasFullBiasInNs() ? mFullBiasInNs : null));
+
+ builder.append(String.format(
+ formatWithUncertainty,
"BiasInNs",
- mHasBiasInNs ? mBiasInNs : null,
+ hasBiasInNs() ? mBiasInNs : null,
"BiasUncertaintyInNs",
- mHasBiasUncertaintyInNs ? mBiasUncertaintyInNs : null));
+ hasBiasUncertaintyInNs() ? mBiasUncertaintyInNs : null));
builder.append(String.format(
- format,
+ formatWithUncertainty,
"DriftInNsPerSec",
- mHasDriftInNsPerSec ? mDriftInNsPerSec : null,
+ hasDriftInNsPerSec() ? mDriftInNsPerSec : null,
"DriftUncertaintyInNsPerSec",
- mHasDriftUncertaintyInNsPerSec ? mDriftUncertaintyInNsPerSec : null));
+ hasDriftUncertaintyInNsPerSec() ? mDriftUncertaintyInNsPerSec : null));
return builder.toString();
}
+
+ private void initialize() {
+ mFlags = HAS_NO_FLAGS;
+ resetLeapSecond();
+ setType(TYPE_UNKNOWN);
+ setTimeInNs(Long.MIN_VALUE);
+ resetTimeUncertaintyInNs();
+ resetBiasInNs();
+ resetBiasUncertaintyInNs();
+ resetDriftInNsPerSec();
+ resetDriftUncertaintyInNsPerSec();
+ }
+
+ private void setFlag(short flag) {
+ mFlags |= flag;
+ }
+
+ private void resetFlag(short flag) {
+ mFlags &= ~flag;
+ }
+
+ private boolean isFlagSet(short flag) {
+ return (mFlags & flag) == flag;
+ }
}
diff --git a/location/java/android/location/GpsMeasurement.java b/location/java/android/location/GpsMeasurement.java
index e5a8c8c..591a6ca 100644
--- a/location/java/android/location/GpsMeasurement.java
+++ b/location/java/android/location/GpsMeasurement.java
@@ -28,143 +28,177 @@
public class GpsMeasurement implements Parcelable {
private static final String TAG = "GpsMeasurement";
- // mandatory parameters
+ private int mFlags;
private byte mPrn;
- private long mLocalTimeInNs;
+ private double mTimeOffsetInNs;
+ private short mState;
private long mReceivedGpsTowInNs;
+ private long mReceivedGpsTowUncertaintyInNs;
private double mCn0InDbHz;
private double mPseudorangeRateInMetersPerSec;
private double mPseudorangeRateUncertaintyInMetersPerSec;
+ private short mAccumulatedDeltaRangeState;
private double mAccumulatedDeltaRangeInMeters;
private double mAccumulatedDeltaRangeUncertaintyInMeters;
-
- // optional parameters
- private boolean mHasPseudorangeInMeters;
private double mPseudorangeInMeters;
- private boolean mHasPseudorangeUncertaintyInMeters;
private double mPseudorangeUncertaintyInMeters;
- private boolean mHasCodePhaseInChips;
private double mCodePhaseInChips;
- private boolean mHasCodePhaseUncertaintyInChips;
private double mCodePhaseUncertaintyInChips;
- private boolean mHasCarrierFrequencyInHz;
private float mCarrierFrequencyInHz;
- private boolean mHasCarrierCycles;
private long mCarrierCycles;
- private boolean mHasCarrierPhase;
private double mCarrierPhase;
- private boolean mHasCarrierPhaseUncertainty;
private double mCarrierPhaseUncertainty;
- private short mLossOfLock;
- private boolean mHasBitNumber;
+ private byte mLossOfLock;
private short mBitNumber;
- private boolean mHasTimeFromLastBitInNs;
- private long mTimeFromLastBitInNs;
- private boolean mHasDopplerShiftInHz;
+ private short mTimeFromLastBitInMs;
private double mDopplerShiftInHz;
- private boolean mHasDopplerShiftUncertaintyInHz;
private double mDopplerShiftUncertaintyInHz;
- private short mMultipathIndicator;
- private boolean mHasSnrInDb;
+ private byte mMultipathIndicator;
private double mSnrInDb;
- private boolean mHasElevationInDeg;
private double mElevationInDeg;
- private boolean mHasElevationUncertaintyInDeg;
private double mElevationUncertaintyInDeg;
- private boolean mHasAzimuthInDeg;
private double mAzimuthInDeg;
- private boolean mHasAzimuthUncertaintyInDeg;
private double mAzimuthUncertaintyInDeg;
private boolean mUsedInFix;
// The following enumerations must be in sync with the values declared in gps.h
+ private static final int HAS_NO_FLAGS = 0;
+ private static final int HAS_SNR = (1<<0);
+ private static final int HAS_ELEVATION = (1<<1);
+ private static final int HAS_ELEVATION_UNCERTAINTY = (1<<2);
+ private static final int HAS_AZIMUTH = (1<<3);
+ private static final int HAS_AZIMUTH_UNCERTAINTY = (1<<4);
+ private static final int HAS_PSEUDORANGE = (1<<5);
+ private static final int HAS_PSEUDORANGE_UNCERTAINTY = (1<<6);
+ private static final int HAS_CODE_PHASE = (1<<7);
+ private static final int HAS_CODE_PHASE_UNCERTAINTY = (1<<8);
+ private static final int HAS_CARRIER_FREQUENCY = (1<<9);
+ private static final int HAS_CARRIER_CYCLES = (1<<10);
+ private static final int HAS_CARRIER_PHASE = (1<<11);
+ private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
+ private static final int HAS_BIT_NUMBER = (1<<13);
+ private static final int HAS_TIME_FROM_LAST_BIT = (1<<14);
+ private static final int HAS_DOPPLER_SHIFT = (1<<15);
+ private static final int HAS_DOPPLER_SHIFT_UNCERTAINTY = (1<<16);
+
/**
* The indicator is not available or it is unknown.
*/
- public static final short LOSS_OF_LOCK_UNKNOWN = 0;
+ public static final byte LOSS_OF_LOCK_UNKNOWN = 0;
/**
* The measurement does not present any indication of 'loss of lock'.
*/
- public static final short LOSS_OF_LOCK_OK = 1;
+ public static final byte LOSS_OF_LOCK_OK = 1;
/**
* 'Loss of lock' detected between the previous and current observation: cycle slip possible.
*/
- public static final short LOSS_OF_LOCK_CYCLE_SLIP = 2;
+ public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2;
/**
* The indicator is not available or it is unknown.
*/
- public static final short MULTIPATH_INDICATOR_UNKNOWN = 0;
+ public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0;
/**
* The measurement has been indicated to use multi-path.
*/
- public static final short MULTIPATH_INDICATOR_DETECTED = 1;
+ public static final byte MULTIPATH_INDICATOR_DETECTED = 1;
/**
* The measurement has been indicated not tu use multi-path.
*/
- public static final short MULTIPATH_INDICATOR_NOT_USED = 2;
+ public static final byte MULTIPATH_INDICATOR_NOT_USED = 2;
+
+ /**
+ * The state of GPS receiver the measurement is invalid or unknown.
+ */
+ public static final short STATE_UNKNOWN = 0;
+
+ /**
+ * The state of the GPS receiver is ranging code lock.
+ */
+ public static final short STATE_CODE_LOCK = (1<<0);
+
+ /**
+ * The state of the GPS receiver is in bit sync.
+ */
+ public static final short STATE_BIT_SYNC = (1<<1);
+
+ /**
+ *The state of the GPS receiver is in sub-frame sync.
+ */
+ public static final short STATE_SUBFRAME_SYNC = (1<<2);
+
+ /**
+ * The state of the GPS receiver has TOW decoded.
+ */
+ public static final short STATE_TOW_DECODED = (1<<3);
+
+ /**
+ * The state of the 'Accumulated Delta Range' is invalid or unknown.
+ */
+ public static final short ADR_STATE_UNKNOWN = 0;
+
+ /**
+ * The state of the 'Accumulated Delta Range' is valid.
+ */
+ public static final short ADR_STATE_VALID = (1<<0);
+
+ /**
+ * The state of the 'Accumulated Delta Range' has detected a reset.
+ */
+ public static final short ADR_STATE_RESET = (1<<1);
+
+ /**
+ * The state of the 'Accumulated Delta Range' has a cycle slip detected.
+ */
+ public static final short ADR_STATE_CYCLE_SLIP = (1<<2);
// End enumerations in sync with gps.h
GpsMeasurement() {
- reset();
+ initialize();
}
/**
* Sets all contents to the values stored in the provided object.
*/
public void set(GpsMeasurement measurement) {
+ mFlags = measurement.mFlags;
mPrn = measurement.mPrn;
- mLocalTimeInNs = measurement.mLocalTimeInNs;
+ mTimeOffsetInNs = measurement.mTimeOffsetInNs;
+ mState = measurement.mState;
mReceivedGpsTowInNs = measurement.mReceivedGpsTowInNs;
+ mReceivedGpsTowUncertaintyInNs = measurement.mReceivedGpsTowUncertaintyInNs;
mCn0InDbHz = measurement.mCn0InDbHz;
mPseudorangeRateInMetersPerSec = measurement.mPseudorangeRateInMetersPerSec;
mPseudorangeRateUncertaintyInMetersPerSec =
measurement.mPseudorangeRateUncertaintyInMetersPerSec;
+ mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
mAccumulatedDeltaRangeInMeters = measurement.mAccumulatedDeltaRangeInMeters;
mAccumulatedDeltaRangeUncertaintyInMeters =
measurement.mAccumulatedDeltaRangeUncertaintyInMeters;
-
- mHasPseudorangeInMeters = measurement.mHasPseudorangeInMeters;
mPseudorangeInMeters = measurement.mPseudorangeInMeters;
- mHasPseudorangeUncertaintyInMeters = measurement.mHasPseudorangeUncertaintyInMeters;
mPseudorangeUncertaintyInMeters = measurement.mPseudorangeUncertaintyInMeters;
- mHasCodePhaseInChips = measurement.mHasCodePhaseInChips;
mCodePhaseInChips = measurement.mCodePhaseInChips;
- mHasCodePhaseUncertaintyInChips = measurement.mHasCodePhaseUncertaintyInChips;
mCodePhaseUncertaintyInChips = measurement.mCodePhaseUncertaintyInChips;
- mHasCarrierFrequencyInHz = measurement.mHasCarrierFrequencyInHz;
mCarrierFrequencyInHz = measurement.mCarrierFrequencyInHz;
- mHasCarrierCycles = measurement.mHasCarrierCycles;
mCarrierCycles = measurement.mCarrierCycles;
- mHasCarrierPhase = measurement.mHasCarrierPhase;
mCarrierPhase = measurement.mCarrierPhase;
- mHasCarrierPhaseUncertainty = measurement.mHasCarrierPhaseUncertainty;
mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
mLossOfLock = measurement.mLossOfLock;
- mHasBitNumber = measurement.mHasBitNumber;
mBitNumber = measurement.mBitNumber;
- mHasTimeFromLastBitInNs = measurement.mHasTimeFromLastBitInNs;
- mTimeFromLastBitInNs = measurement.mTimeFromLastBitInNs;
- mHasDopplerShiftInHz = measurement.mHasDopplerShiftInHz;
+ mTimeFromLastBitInMs = measurement.mTimeFromLastBitInMs;
mDopplerShiftInHz = measurement.mDopplerShiftInHz;
- mHasDopplerShiftUncertaintyInHz = measurement.mHasDopplerShiftUncertaintyInHz;
mDopplerShiftUncertaintyInHz = measurement.mDopplerShiftUncertaintyInHz;
mMultipathIndicator = measurement.mMultipathIndicator;
- mHasSnrInDb = measurement.mHasSnrInDb;
mSnrInDb = measurement.mSnrInDb;
- mHasElevationInDeg = measurement.mHasElevationInDeg;
mElevationInDeg = measurement.mElevationInDeg;
- mHasElevationUncertaintyInDeg = measurement.mHasElevationUncertaintyInDeg;
mElevationUncertaintyInDeg = measurement.mElevationUncertaintyInDeg;
- mHasAzimuthInDeg = measurement.mHasAzimuthInDeg;
mAzimuthInDeg = measurement.mAzimuthInDeg;
- mHasAzimuthUncertaintyInDeg = measurement.mHasAzimuthUncertaintyInDeg;
mAzimuthUncertaintyInDeg = measurement.mAzimuthUncertaintyInDeg;
mUsedInFix = measurement.mUsedInFix;
}
@@ -173,35 +207,7 @@
* Resets all the contents to its original state.
*/
public void reset() {
- mPrn = Byte.MIN_VALUE;
- mLocalTimeInNs = Long.MIN_VALUE;
- mReceivedGpsTowInNs = Long.MIN_VALUE;
- mCn0InDbHz = Double.MIN_VALUE;
- mPseudorangeRateInMetersPerSec = Double.MIN_VALUE;
- mPseudorangeRateUncertaintyInMetersPerSec = Double.MIN_VALUE;
- mAccumulatedDeltaRangeInMeters = Double.MIN_VALUE;
- mAccumulatedDeltaRangeUncertaintyInMeters = Double.MIN_VALUE;
-
- resetPseudorangeInMeters();
- resetPseudorangeUncertaintyInMeters();
- resetCodePhaseInChips();
- resetCodePhaseUncertaintyInChips();
- resetCarrierFrequencyInHz();
- resetCarrierCycles();
- resetCarrierPhase();
- resetCarrierPhaseUncertainty();
- setLossOfLock(LOSS_OF_LOCK_UNKNOWN);
- resetBitNumber();
- resetTimeFromLastBitInNs();
- resetDopplerShiftInHz();
- resetDopplerShiftUncertaintyInHz();
- setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
- resetSnrInDb();
- resetElevationInDeg();
- resetElevationUncertaintyInDeg();
- resetAzimuthInDeg();
- resetAzimuthUncertaintyInDeg();
- setUsedInFix(false);
+ initialize();
}
/**
@@ -220,22 +226,87 @@
}
/**
- * Gets the local (hardware) time at which the measurement was taken in nanoseconds.
+ * Gets the time offset at which the measurement was taken in nanoseconds.
+ * The reference receiver's time is specified by {@link GpsClock#getTimeInNs()} and should be
+ * interpreted in the same way as indicated by {@link GpsClock#getType()}.
+ *
+ * The sign of this value is given by the following equation:
+ * measurement time = time_ns + time_offset_ns
+ *
+ * The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
+ * accuracy.
*/
- public long getLocalTimeInNs() {
- return mLocalTimeInNs;
+ public double getTimeOffsetInNs() {
+ return mTimeOffsetInNs;
}
/**
- * Sets the measurement's local (hardware) time in nanoseconds.
+ * Sets the time offset at which the measurement was taken in nanoseconds.
*/
- public void setLocalTimeInNs(long value) {
- mLocalTimeInNs = value;
+ public void setTimeOffsetInNs(double value) {
+ mTimeOffsetInNs = value;
}
/**
- * Gets the received GPS Time-of-Week in nanoseconds.
+ * Gets per-satellite sync state.
+ * It represents the current sync state for the associated satellite.
+ *
+ * This value helps interpret {@link #getReceivedGpsTowInNs()}.
+ */
+ public short getState() {
+ return mState;
+ }
+
+ /**
+ * Sets the sync state.
+ */
+ public void setState(short value) {
+ switch (value) {
+ case STATE_UNKNOWN:
+ case STATE_BIT_SYNC:
+ case STATE_CODE_LOCK:
+ case STATE_SUBFRAME_SYNC:
+ case STATE_TOW_DECODED:
+ mState = value;
+ break;
+ default:
+ Log.d(TAG, "Sanitizing invalid 'sync state': " + value);
+ mState = STATE_UNKNOWN;
+ break;
+ }
+ }
+
+ /**
+ * Gets a string representation of the 'sync state'.
+ * For internal and logging use only.
+ */
+ private String getStateString() {
+ switch (mState) {
+ case STATE_UNKNOWN:
+ return "Unknown";
+ case STATE_BIT_SYNC:
+ return "BitSync";
+ case STATE_CODE_LOCK:
+ return "CodeLock";
+ case STATE_SUBFRAME_SYNC:
+ return "SubframeSync";
+ case STATE_TOW_DECODED:
+ return "TowDecoded";
+ default:
+ return "<Invalid>";
+ }
+ }
+
+ /**
+ * Gets the received GPS Time-of-Week at the measurement time, in nanoseconds.
* The value is relative to the beginning of the current GPS week.
+ *
+ * Given {@link #getState()} of the GPS receiver, the range of this field can be:
+ * Searching : [ 0 ] : {@link #STATE_UNKNOWN} is set
+ * Ranging code lock : [ 0 1 ms ] : {@link #STATE_CODE_LOCK} is set
+ * Bit sync : [ 0 20 ms ] : {@link #STATE_BIT_SYNC} is set
+ * Subframe sync : [ 0 6 ms ] : {@link #STATE_SUBFRAME_SYNC} is set
+ * TOW decoded : [ 0 1 week ] : {@link #STATE_TOW_DECODED} is set
*/
public long getReceivedGpsTowInNs() {
return mReceivedGpsTowInNs;
@@ -249,6 +320,20 @@
}
/**
+ * Gets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
+ */
+ public long getReceivedGpsTowUncertaintyInNs() {
+ return mReceivedGpsTowUncertaintyInNs;
+ }
+
+ /**
+ * Sets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
+ */
+ public void setReceivedGpsTowUncertaintyInNs(long value) {
+ mReceivedGpsTowUncertaintyInNs = value;
+ }
+
+ /**
* Gets the Carrier-to-noise density in dB-Hz.
* Range: [0, 63].
*
@@ -296,8 +381,56 @@
}
/**
+ * Gets 'Accumulated Delta Range' state.
+ * It indicates whether {@link #getAccumulatedDeltaRangeInMeters()} is reset or there is a
+ * cycle slip (indicating 'loss of lock').
+ */
+ public short getAccumulatedDeltaRangeState() {
+ return mAccumulatedDeltaRangeState;
+ }
+
+ /**
+ * Sets the 'Accumulated Delta Range' state.
+ */
+ public void setAccumulatedDeltaRangeState(short value) {
+ switch (value) {
+ case ADR_STATE_UNKNOWN:
+ case ADR_STATE_VALID:
+ case ADR_STATE_RESET:
+ case ADR_STATE_CYCLE_SLIP:
+ mAccumulatedDeltaRangeState = value;
+ break;
+ default:
+ Log.d(TAG, "Sanitizing invalid 'Accumulated Delta Range state': " + value);
+ mAccumulatedDeltaRangeState = ADR_STATE_UNKNOWN;
+ break;
+ }
+ }
+
+ /**
+ * Gets a string representation of the 'Accumulated Delta Range state'.
+ * For internal and logging use only.
+ */
+ private String getAccumulatedDeltaRangeStateString() {
+ switch (mAccumulatedDeltaRangeState) {
+ case ADR_STATE_UNKNOWN:
+ return "Unknown";
+ case ADR_STATE_VALID:
+ return "Valid";
+ case ADR_STATE_RESET:
+ return "Reset";
+ case ADR_STATE_CYCLE_SLIP:
+ return "CycleSlip";
+ default:
+ return "<Invalid>";
+ }
+ }
+
+ /**
* Gets the accumulated delta range since the last channel reset, in meters.
* The reported value includes {@link #getAccumulatedDeltaRangeUncertaintyInMeters()}.
+ *
+ * The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
*/
public double getAccumulatedDeltaRangeInMeters() {
return mAccumulatedDeltaRangeInMeters;
@@ -320,6 +453,8 @@
/**
* Sets the accumulated delta range's uncertainty (1-sigma) in meters.
+ *
+ * The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
*/
public void setAccumulatedDeltaRangeUncertaintyInMeters(double value) {
mAccumulatedDeltaRangeUncertaintyInMeters = value;
@@ -329,7 +464,7 @@
* Returns true if {@link #getPseudorangeInMeters()} is available, false otherwise.
*/
public boolean hasPseudorangeInMeters() {
- return mHasPseudorangeInMeters;
+ return isFlagSet(HAS_PSEUDORANGE);
}
/**
@@ -346,7 +481,7 @@
* Sets the Pseudo-range in meters.
*/
public void setPseudorangeInMeters(double value) {
- mHasPseudorangeInMeters = true;
+ setFlag(HAS_PSEUDORANGE);
mPseudorangeInMeters = value;
}
@@ -354,7 +489,7 @@
* Resets the Pseudo-range in meters.
*/
public void resetPseudorangeInMeters() {
- mHasPseudorangeInMeters = false;
+ resetFlag(HAS_PSEUDORANGE);
mPseudorangeInMeters = Double.NaN;
}
@@ -362,7 +497,7 @@
* Returns true if {@link #getPseudorangeUncertaintyInMeters()} is available, false otherwise.
*/
public boolean hasPseudorangeUncertaintyInMeters() {
- return mHasPseudorangeUncertaintyInMeters;
+ return isFlagSet(HAS_PSEUDORANGE_UNCERTAINTY);
}
/**
@@ -380,7 +515,7 @@
* Sets the pseudo-range's uncertainty (1-Sigma) in meters.
*/
public void setPseudorangeUncertaintyInMeters(double value) {
- mHasPseudorangeUncertaintyInMeters = true;
+ setFlag(HAS_PSEUDORANGE_UNCERTAINTY);
mPseudorangeUncertaintyInMeters = value;
}
@@ -388,7 +523,7 @@
* Resets the pseudo-range's uncertainty (1-Sigma) in meters.
*/
public void resetPseudorangeUncertaintyInMeters() {
- mHasPseudorangeUncertaintyInMeters = false;
+ resetFlag(HAS_PSEUDORANGE_UNCERTAINTY);
mPseudorangeUncertaintyInMeters = Double.NaN;
}
@@ -396,7 +531,7 @@
* Returns true if {@link #getCodePhaseInChips()} is available, false otherwise.
*/
public boolean hasCodePhaseInChips() {
- return mHasCodePhaseInChips;
+ return isFlagSet(HAS_CODE_PHASE);
}
/**
@@ -415,7 +550,7 @@
* Sets the Code-phase in chips.
*/
public void setCodePhaseInChips(double value) {
- mHasCodePhaseInChips = true;
+ setFlag(HAS_CODE_PHASE);
mCodePhaseInChips = value;
}
@@ -423,7 +558,7 @@
* Resets the Code-phase in chips.
*/
public void resetCodePhaseInChips() {
- mHasCodePhaseInChips = false;
+ resetFlag(HAS_CODE_PHASE);
mCodePhaseInChips = Double.NaN;
}
@@ -431,7 +566,7 @@
* Returns true if {@link #getCodePhaseUncertaintyInChips()} is available, false otherwise.
*/
public boolean hasCodePhaseUncertaintyInChips() {
- return mHasCodePhaseUncertaintyInChips;
+ return isFlagSet(HAS_CODE_PHASE_UNCERTAINTY);
}
/**
@@ -448,7 +583,7 @@
* Sets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
*/
public void setCodePhaseUncertaintyInChips(double value) {
- mHasCodePhaseUncertaintyInChips = true;
+ setFlag(HAS_CODE_PHASE_UNCERTAINTY);
mCodePhaseUncertaintyInChips = value;
}
@@ -456,7 +591,7 @@
* Resets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
*/
public void resetCodePhaseUncertaintyInChips() {
- mHasCodePhaseUncertaintyInChips = false;
+ resetFlag(HAS_CODE_PHASE_UNCERTAINTY);
mCodePhaseUncertaintyInChips = Double.NaN;
}
@@ -464,7 +599,7 @@
* Returns true if {@link #getCarrierFrequencyInHz()} is available, false otherwise.
*/
public boolean hasCarrierFrequencyInHz() {
- return mHasCarrierFrequencyInHz;
+ return isFlagSet(HAS_CARRIER_FREQUENCY);
}
/**
@@ -481,7 +616,7 @@
* Sets the Carrier frequency (L1 or L2) in Hz.
*/
public void setCarrierFrequencyInHz(float carrierFrequencyInHz) {
- mHasCarrierFrequencyInHz = true;
+ setFlag(HAS_CARRIER_FREQUENCY);
mCarrierFrequencyInHz = carrierFrequencyInHz;
}
@@ -489,7 +624,7 @@
* Resets the Carrier frequency (L1 or L2) in Hz.
*/
public void resetCarrierFrequencyInHz() {
- mHasCarrierFrequencyInHz = false;
+ resetFlag(HAS_CARRIER_FREQUENCY);
mCarrierFrequencyInHz = Float.NaN;
}
@@ -497,7 +632,7 @@
* Returns true if {@link #getCarrierCycles()} is available, false otherwise.
*/
public boolean hasCarrierCycles() {
- return mHasCarrierCycles;
+ return isFlagSet(HAS_CARRIER_CYCLES);
}
/**
@@ -514,7 +649,7 @@
* Sets the number of full carrier cycles between the satellite and the receiver.
*/
public void setCarrierCycles(long value) {
- mHasCarrierCycles = true;
+ setFlag(HAS_CARRIER_CYCLES);
mCarrierCycles = value;
}
@@ -522,7 +657,7 @@
* Resets the number of full carrier cycles between the satellite and the receiver.
*/
public void resetCarrierCycles() {
- mHasCarrierCycles = false;
+ resetFlag(HAS_CARRIER_CYCLES);
mCarrierCycles = Long.MIN_VALUE;
}
@@ -530,7 +665,7 @@
* Returns true if {@link #getCarrierPhase()} is available, false otherwise.
*/
public boolean hasCarrierPhase() {
- return mHasCarrierPhase;
+ return isFlagSet(HAS_CARRIER_PHASE);
}
/**
@@ -551,7 +686,7 @@
* Sets the RF phase detected by the receiver.
*/
public void setCarrierPhase(double value) {
- mHasCarrierPhase = true;
+ setFlag(HAS_CARRIER_PHASE);
mCarrierPhase = value;
}
@@ -559,7 +694,7 @@
* Resets the RF phase detected by the receiver.
*/
public void resetCarrierPhase() {
- mHasCarrierPhase = false;
+ resetFlag(HAS_CARRIER_PHASE);
mCarrierPhase = Double.NaN;
}
@@ -567,7 +702,7 @@
* Returns true if {@link #getCarrierPhaseUncertainty()} is available, false otherwise.
*/
public boolean hasCarrierPhaseUncertainty() {
- return mHasCarrierPhaseUncertainty;
+ return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
}
/**
@@ -584,7 +719,7 @@
* Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
*/
public void setCarrierPhaseUncertainty(double value) {
- mHasCarrierPhaseUncertainty = true;
+ setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
mCarrierPhaseUncertainty = value;
}
@@ -592,21 +727,21 @@
* Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
*/
public void resetCarrierPhaseUncertainty() {
- mHasCarrierPhaseUncertainty = false;
+ resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
mCarrierPhaseUncertainty = Double.NaN;
}
/**
* Gets a value indicating the 'loss of lock' state of the event.
*/
- public short getLossOfLock() {
+ public byte getLossOfLock() {
return mLossOfLock;
}
/**
* Sets the 'loss of lock' status.
*/
- public void setLossOfLock(short value) {
+ public void setLossOfLock(byte value) {
switch (value) {
case LOSS_OF_LOCK_UNKNOWN:
case LOSS_OF_LOCK_OK:
@@ -633,7 +768,7 @@
case LOSS_OF_LOCK_CYCLE_SLIP:
return "CycleSlip";
default:
- return "Invalid";
+ return "<Invalid>";
}
}
@@ -641,7 +776,7 @@
* Returns true if {@link #getBitNumber()} is available, false otherwise.
*/
public boolean hasBitNumber() {
- return mHasBitNumber;
+ return isFlagSet(HAS_BIT_NUMBER);
}
/**
@@ -657,7 +792,7 @@
* Sets the bit number within the broadcast frame.
*/
public void setBitNumber(short bitNumber) {
- mHasBitNumber = true;
+ setFlag(HAS_BIT_NUMBER);
mBitNumber = bitNumber;
}
@@ -665,48 +800,48 @@
* Resets the bit number within the broadcast frame.
*/
public void resetBitNumber() {
- mHasBitNumber = false;
+ resetFlag(HAS_BIT_NUMBER);
mBitNumber = Short.MIN_VALUE;
}
/**
- * Returns true if {@link #getTimeFromLastBitInNs()} is available, false otherwise.
+ * Returns true if {@link #getTimeFromLastBitInMs()} is available, false otherwise.
*/
- public boolean hasTimeFromLastBitInNs() {
- return mHasTimeFromLastBitInNs;
+ public boolean hasTimeFromLastBitInMs() {
+ return isFlagSet(HAS_TIME_FROM_LAST_BIT);
}
/**
- * Gets the elapsed time since the last received bit in nanoseconds.
- * Range: [0, 20000000].
+ * Gets the elapsed time since the last received bit in milliseconds.
+ * Range: [0, 20].
*
- * The value is only available if {@link #hasTimeFromLastBitInNs()} is true.
+ * The value is only available if {@link #hasTimeFromLastBitInMs()} is true.
*/
- public long getTimeFromLastBitInNs() {
- return mTimeFromLastBitInNs;
+ public short getTimeFromLastBitInMs() {
+ return mTimeFromLastBitInMs;
}
/**
- * Sets the elapsed time since the last received bit in nanoseconds.
+ * Sets the elapsed time since the last received bit in milliseconds.
*/
- public void setTimeFromLastBitInNs(long value) {
- mHasTimeFromLastBitInNs = true;
- mTimeFromLastBitInNs = value;
+ public void setTimeFromLastBitInMs(short value) {
+ setFlag(HAS_TIME_FROM_LAST_BIT);
+ mTimeFromLastBitInMs = value;
}
/**
- * Resets the elapsed time since the last received bit in nanoseconds.
+ * Resets the elapsed time since the last received bit in milliseconds.
*/
- public void resetTimeFromLastBitInNs() {
- mHasTimeFromLastBitInNs = false;
- mTimeFromLastBitInNs = Long.MIN_VALUE;
+ public void resetTimeFromLastBitInMs() {
+ resetFlag(HAS_TIME_FROM_LAST_BIT);
+ mTimeFromLastBitInMs = Short.MIN_VALUE;
}
/**
* Returns true if {@link #getDopplerShiftInHz()} is available, false otherwise.
*/
public boolean hasDopplerShiftInHz() {
- return mHasDopplerShiftInHz;
+ return isFlagSet(HAS_DOPPLER_SHIFT);
}
/**
@@ -726,7 +861,7 @@
* Sets the Doppler shift in Hz.
*/
public void setDopplerShiftInHz(double value) {
- mHasDopplerShiftInHz = true;
+ setFlag(HAS_DOPPLER_SHIFT);
mDopplerShiftInHz = value;
}
@@ -734,7 +869,7 @@
* Resets the Doppler shift in Hz.
*/
public void resetDopplerShiftInHz() {
- mHasDopplerShiftInHz = false;
+ resetFlag(HAS_DOPPLER_SHIFT);
mDopplerShiftInHz = Double.NaN;
}
@@ -742,7 +877,7 @@
* Returns true if {@link #getDopplerShiftUncertaintyInHz()} is available, false otherwise.
*/
public boolean hasDopplerShiftUncertaintyInHz() {
- return mHasDopplerShiftUncertaintyInHz;
+ return isFlagSet(HAS_DOPPLER_SHIFT_UNCERTAINTY);
}
/**
@@ -759,7 +894,7 @@
* Sets the Doppler's shift uncertainty (1-Sigma) in Hz.
*/
public void setDopplerShiftUncertaintyInHz(double value) {
- mHasDopplerShiftUncertaintyInHz = true;
+ setFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
mDopplerShiftUncertaintyInHz = value;
}
@@ -767,21 +902,21 @@
* Resets the Doppler's shift uncertainty (1-Sigma) in Hz.
*/
public void resetDopplerShiftUncertaintyInHz() {
- mHasDopplerShiftUncertaintyInHz = false;
+ resetFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
mDopplerShiftUncertaintyInHz = Double.NaN;
}
/**
* Gets a value indicating the 'multipath' state of the event.
*/
- public short getMultipathIndicator() {
+ public byte getMultipathIndicator() {
return mMultipathIndicator;
}
/**
* Sets the 'multi-path' indicator.
*/
- public void setMultipathIndicator(short value) {
+ public void setMultipathIndicator(byte value) {
switch (value) {
case MULTIPATH_INDICATOR_UNKNOWN:
case MULTIPATH_INDICATOR_DETECTED:
@@ -806,9 +941,9 @@
case MULTIPATH_INDICATOR_DETECTED:
return "Detected";
case MULTIPATH_INDICATOR_NOT_USED:
- return "NotDetected";
+ return "NotUsed";
default:
- return "Invalid";
+ return "<Invalid>";
}
}
@@ -816,7 +951,7 @@
* Returns true if {@link #getSnrInDb()} is available, false otherwise.
*/
public boolean hasSnrInDb() {
- return mHasSnrInDb;
+ return isFlagSet(HAS_SNR);
}
/**
@@ -832,7 +967,7 @@
* Sets the Signal-to-noise ratio (SNR) in dB.
*/
public void setSnrInDb(double snrInDb) {
- mHasSnrInDb = true;
+ setFlag(HAS_SNR);
mSnrInDb = snrInDb;
}
@@ -840,7 +975,7 @@
* Resets the Signal-to-noise ratio (SNR) in dB.
*/
public void resetSnrInDb() {
- mHasSnrInDb = false;
+ resetFlag(HAS_SNR);
mSnrInDb = Double.NaN;
}
@@ -848,7 +983,7 @@
* Returns true if {@link #getElevationInDeg()} is available, false otherwise.
*/
public boolean hasElevationInDeg() {
- return mHasElevationInDeg;
+ return isFlagSet(HAS_ELEVATION);
}
/**
@@ -866,7 +1001,7 @@
* Sets the Elevation in degrees.
*/
public void setElevationInDeg(double elevationInDeg) {
- mHasElevationInDeg = true;
+ setFlag(HAS_ELEVATION);
mElevationInDeg = elevationInDeg;
}
@@ -874,7 +1009,7 @@
* Resets the Elevation in degrees.
*/
public void resetElevationInDeg() {
- mHasElevationInDeg = false;
+ resetFlag(HAS_ELEVATION);
mElevationInDeg = Double.NaN;
}
@@ -882,7 +1017,7 @@
* Returns true if {@link #getElevationUncertaintyInDeg()} is available, false otherwise.
*/
public boolean hasElevationUncertaintyInDeg() {
- return mHasElevationUncertaintyInDeg;
+ return isFlagSet(HAS_ELEVATION_UNCERTAINTY);
}
/**
@@ -901,7 +1036,7 @@
* Sets the elevation's uncertainty (1-Sigma) in degrees.
*/
public void setElevationUncertaintyInDeg(double value) {
- mHasElevationUncertaintyInDeg = true;
+ setFlag(HAS_ELEVATION_UNCERTAINTY);
mElevationUncertaintyInDeg = value;
}
@@ -909,7 +1044,7 @@
* Resets the elevation's uncertainty (1-Sigma) in degrees.
*/
public void resetElevationUncertaintyInDeg() {
- mHasElevationUncertaintyInDeg = false;
+ resetFlag(HAS_ELEVATION_UNCERTAINTY);
mElevationUncertaintyInDeg = Double.NaN;
}
@@ -917,7 +1052,7 @@
* Returns true if {@link #getAzimuthInDeg()} is available, false otherwise.
*/
public boolean hasAzimuthInDeg() {
- return mHasAzimuthInDeg;
+ return isFlagSet(HAS_AZIMUTH);
}
/**
@@ -936,7 +1071,7 @@
* Sets the Azimuth in degrees.
*/
public void setAzimuthInDeg(double value) {
- mHasAzimuthInDeg = true;
+ setFlag(HAS_AZIMUTH);
mAzimuthInDeg = value;
}
@@ -944,7 +1079,7 @@
* Resets the Azimuth in degrees.
*/
public void resetAzimuthInDeg() {
- mHasAzimuthInDeg = false;
+ resetFlag(HAS_AZIMUTH);
mAzimuthInDeg = Double.NaN;
}
@@ -952,7 +1087,7 @@
* Returns true if {@link #getAzimuthUncertaintyInDeg()} is available, false otherwise.
*/
public boolean hasAzimuthUncertaintyInDeg() {
- return mHasAzimuthUncertaintyInDeg;
+ return isFlagSet(HAS_AZIMUTH_UNCERTAINTY);
}
/**
@@ -971,7 +1106,7 @@
* Sets the Azimuth's uncertainty (1-Sigma) in degrees.
*/
public void setAzimuthUncertaintyInDeg(double value) {
- mHasAzimuthUncertaintyInDeg = true;
+ setFlag(HAS_AZIMUTH_UNCERTAINTY);
mAzimuthUncertaintyInDeg = value;
}
@@ -979,7 +1114,7 @@
* Resets the Azimuth's uncertainty (1-Sigma) in degrees.
*/
public void resetAzimuthUncertaintyInDeg() {
- mHasAzimuthUncertaintyInDeg = false;
+ resetFlag(HAS_AZIMUTH_UNCERTAINTY);
mAzimuthUncertaintyInDeg = Double.NaN;
}
@@ -989,7 +1124,7 @@
*
* @return A non-null value if the data is available, null otherwise.
*/
- public Boolean isUsedInFix() {
+ public boolean isUsedInFix() {
return mUsedInFix;
}
@@ -1005,50 +1140,36 @@
public GpsMeasurement createFromParcel(Parcel parcel) {
GpsMeasurement gpsMeasurement = new GpsMeasurement();
+ gpsMeasurement.mFlags = parcel.readInt();
gpsMeasurement.mPrn = parcel.readByte();
- gpsMeasurement.mLocalTimeInNs = parcel.readLong();
+ gpsMeasurement.mTimeOffsetInNs = parcel.readDouble();
+ gpsMeasurement.mState = (short) parcel.readInt();
gpsMeasurement.mReceivedGpsTowInNs = parcel.readLong();
+ gpsMeasurement.mReceivedGpsTowUncertaintyInNs = parcel.readLong();
gpsMeasurement.mCn0InDbHz = parcel.readDouble();
gpsMeasurement.mPseudorangeRateInMetersPerSec = parcel.readDouble();
gpsMeasurement.mPseudorangeRateUncertaintyInMetersPerSec = parcel.readDouble();
+ gpsMeasurement.mAccumulatedDeltaRangeState = (short) parcel.readInt();
gpsMeasurement.mAccumulatedDeltaRangeInMeters = parcel.readDouble();
gpsMeasurement.mAccumulatedDeltaRangeUncertaintyInMeters = parcel.readDouble();
-
- gpsMeasurement.mHasPseudorangeInMeters = parcel.readInt() != 0;
gpsMeasurement.mPseudorangeInMeters = parcel.readDouble();
- gpsMeasurement.mHasPseudorangeUncertaintyInMeters = parcel.readInt() != 0;
gpsMeasurement.mPseudorangeUncertaintyInMeters = parcel.readDouble();
- gpsMeasurement.mHasCodePhaseInChips = parcel.readInt() != 0;
gpsMeasurement.mCodePhaseInChips = parcel.readDouble();
- gpsMeasurement.mHasCodePhaseUncertaintyInChips = parcel.readInt() != 0;
gpsMeasurement.mCodePhaseUncertaintyInChips = parcel.readDouble();
- gpsMeasurement.mHasCarrierFrequencyInHz = parcel.readInt() != 0;
gpsMeasurement.mCarrierFrequencyInHz = parcel.readFloat();
- gpsMeasurement.mHasCarrierCycles = parcel.readInt() != 0;
gpsMeasurement.mCarrierCycles = parcel.readLong();
- gpsMeasurement.mHasCarrierPhase = parcel.readInt() != 0;
gpsMeasurement.mCarrierPhase = parcel.readDouble();
- gpsMeasurement.mHasCarrierPhaseUncertainty = parcel.readInt() != 0;
gpsMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
- gpsMeasurement.mLossOfLock = (short) parcel.readInt();
- gpsMeasurement.mHasBitNumber = parcel.readInt() != 0;
+ gpsMeasurement.mLossOfLock = parcel.readByte();
gpsMeasurement.mBitNumber = (short) parcel.readInt();
- gpsMeasurement.mHasTimeFromLastBitInNs = parcel.readInt() != 0;
- gpsMeasurement.mTimeFromLastBitInNs = parcel.readLong();
- gpsMeasurement.mHasDopplerShiftInHz = parcel.readInt() != 0;
+ gpsMeasurement.mTimeFromLastBitInMs = (short) parcel.readInt();
gpsMeasurement.mDopplerShiftInHz = parcel.readDouble();
- gpsMeasurement.mHasDopplerShiftUncertaintyInHz = parcel.readInt() != 0;
gpsMeasurement.mDopplerShiftUncertaintyInHz = parcel.readDouble();
- gpsMeasurement.mMultipathIndicator = (short) parcel.readInt();
- gpsMeasurement.mHasSnrInDb = parcel.readInt() != 0;
+ gpsMeasurement.mMultipathIndicator = parcel.readByte();
gpsMeasurement.mSnrInDb = parcel.readDouble();
- gpsMeasurement.mHasElevationInDeg = parcel.readInt() != 0;
gpsMeasurement.mElevationInDeg = parcel.readDouble();
- gpsMeasurement.mHasElevationUncertaintyInDeg = parcel.readInt() != 0;
gpsMeasurement.mElevationUncertaintyInDeg = parcel.readDouble();
- gpsMeasurement.mHasAzimuthInDeg = parcel.readInt() != 0;
gpsMeasurement.mAzimuthInDeg = parcel.readDouble();
- gpsMeasurement.mHasAzimuthUncertaintyInDeg = parcel.readInt() != 0;
gpsMeasurement.mAzimuthUncertaintyInDeg = parcel.readDouble();
gpsMeasurement.mUsedInFix = parcel.readInt() != 0;
@@ -1062,50 +1183,36 @@
};
public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(mFlags);
parcel.writeByte(mPrn);
- parcel.writeLong(mLocalTimeInNs);
+ parcel.writeDouble(mTimeOffsetInNs);
+ parcel.writeInt(mState);
parcel.writeLong(mReceivedGpsTowInNs);
+ parcel.writeLong(mReceivedGpsTowUncertaintyInNs);
parcel.writeDouble(mCn0InDbHz);
parcel.writeDouble(mPseudorangeRateInMetersPerSec);
parcel.writeDouble(mPseudorangeRateUncertaintyInMetersPerSec);
+ parcel.writeInt(mAccumulatedDeltaRangeState);
parcel.writeDouble(mAccumulatedDeltaRangeInMeters);
parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyInMeters);
-
- parcel.writeInt(mHasPseudorangeInMeters ? 1 : 0);
parcel.writeDouble(mPseudorangeInMeters);
- parcel.writeInt(mHasPseudorangeUncertaintyInMeters ? 1 : 0);
parcel.writeDouble(mPseudorangeUncertaintyInMeters);
- parcel.writeInt(mHasCodePhaseInChips ? 1 : 0);
parcel.writeDouble(mCodePhaseInChips);
- parcel.writeInt(mHasCodePhaseUncertaintyInChips ? 1 : 0);
parcel.writeDouble(mCodePhaseUncertaintyInChips);
- parcel.writeInt(mHasCarrierFrequencyInHz ? 1 : 0);
parcel.writeFloat(mCarrierFrequencyInHz);
- parcel.writeInt(mHasCarrierCycles ? 1 : 0);
parcel.writeLong(mCarrierCycles);
- parcel.writeInt(mHasCarrierPhase ? 1 : 0);
parcel.writeDouble(mCarrierPhase);
- parcel.writeInt(mHasCarrierPhaseUncertainty ? 1 : 0);
parcel.writeDouble(mCarrierPhaseUncertainty);
- parcel.writeInt(mLossOfLock);
- parcel.writeInt(mHasBitNumber ? 1 : 0);
+ parcel.writeByte(mLossOfLock);
parcel.writeInt(mBitNumber);
- parcel.writeInt(mHasTimeFromLastBitInNs ? 1 : 0);
- parcel.writeLong(mTimeFromLastBitInNs);
- parcel.writeInt(mHasDopplerShiftInHz ? 1 : 0);
+ parcel.writeInt(mTimeFromLastBitInMs);
parcel.writeDouble(mDopplerShiftInHz);
- parcel.writeInt(mHasDopplerShiftUncertaintyInHz ? 1 : 0);
parcel.writeDouble(mDopplerShiftUncertaintyInHz);
- parcel.writeInt(mMultipathIndicator);
- parcel.writeInt(mHasSnrInDb ? 1 : 0);
+ parcel.writeByte(mMultipathIndicator);
parcel.writeDouble(mSnrInDb);
- parcel.writeInt(mHasElevationInDeg ? 1 : 0);
parcel.writeDouble(mElevationInDeg);
- parcel.writeInt(mHasElevationUncertaintyInDeg ? 1 : 0);
parcel.writeDouble(mElevationUncertaintyInDeg);
- parcel.writeInt(mHasAzimuthInDeg ? 1 : 0);
parcel.writeDouble(mAzimuthInDeg);
- parcel.writeInt(mHasAzimuthUncertaintyInDeg ? 1 : 0);
parcel.writeDouble(mAzimuthUncertaintyInDeg);
parcel.writeInt(mUsedInFix ? 1 : 0);
}
@@ -1123,9 +1230,16 @@
builder.append(String.format(format, "Prn", mPrn));
- builder.append(String.format(format, "LocalTimeInNs", mLocalTimeInNs));
+ builder.append(String.format(format, "TimeOffsetInNs", mTimeOffsetInNs));
- builder.append(String.format(format, "ReceivedGpsTowInNs", mReceivedGpsTowInNs));
+ builder.append(String.format(format, "State", getStateString()));
+
+ builder.append(String.format(
+ formatWithUncertainty,
+ "ReceivedGpsTowInNs",
+ mReceivedGpsTowInNs,
+ "ReceivedGpsTowUncertaintyInNs",
+ mReceivedGpsTowUncertaintyInNs));
builder.append(String.format(format, "Cn0InDbHz", mCn0InDbHz));
@@ -1137,86 +1251,137 @@
mPseudorangeRateUncertaintyInMetersPerSec));
builder.append(String.format(
+ format,
+ "AccumulatedDeltaRangeState",
+ getAccumulatedDeltaRangeStateString()));
+
+ builder.append(String.format(
formatWithUncertainty,
"AccumulatedDeltaRangeInMeters",
mAccumulatedDeltaRangeInMeters,
"AccumulatedDeltaRangeUncertaintyInMeters",
mAccumulatedDeltaRangeUncertaintyInMeters));
-
builder.append(String.format(
formatWithUncertainty,
"PseudorangeInMeters",
- mHasPseudorangeInMeters ? mPseudorangeInMeters : null,
+ hasPseudorangeInMeters() ? mPseudorangeInMeters : null,
"PseudorangeUncertaintyInMeters",
- mHasPseudorangeUncertaintyInMeters ? mPseudorangeUncertaintyInMeters : null));
+ hasPseudorangeUncertaintyInMeters() ? mPseudorangeUncertaintyInMeters : null));
builder.append(String.format(
formatWithUncertainty,
"CodePhaseInChips",
- mHasCodePhaseInChips ? mCodePhaseInChips : null,
+ hasCodePhaseInChips() ? mCodePhaseInChips : null,
"CodePhaseUncertaintyInChips",
- mHasCodePhaseUncertaintyInChips ? mCodePhaseUncertaintyInChips : null));
+ hasCodePhaseUncertaintyInChips() ? mCodePhaseUncertaintyInChips : null));
builder.append(String.format(
format,
"CarrierFrequencyInHz",
- mHasCarrierFrequencyInHz ? mCarrierFrequencyInHz : null));
+ hasCarrierFrequencyInHz() ? mCarrierFrequencyInHz : null));
builder.append(String.format(
format,
"CarrierCycles",
- mHasCarrierCycles ? mCarrierCycles : null));
+ hasCarrierCycles() ? mCarrierCycles : null));
builder.append(String.format(
formatWithUncertainty,
"CarrierPhase",
- mHasCarrierPhase ? mCarrierPhase : null,
+ hasCarrierPhase() ? mCarrierPhase : null,
"CarrierPhaseUncertainty",
- mHasCarrierPhaseUncertainty ? mCarrierPhaseUncertainty : null));
+ hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
builder.append(String.format(format, "LossOfLock", getLossOfLockString()));
builder.append(String.format(
format,
"BitNumber",
- mHasBitNumber ? mBitNumber : null));
+ hasBitNumber() ? mBitNumber : null));
builder.append(String.format(
format,
- "TimeFromLastBitInNs",
- mHasTimeFromLastBitInNs ? mTimeFromLastBitInNs : null));
+ "TimeFromLastBitInMs",
+ hasTimeFromLastBitInMs() ? mTimeFromLastBitInMs : null));
builder.append(String.format(
formatWithUncertainty,
"DopplerShiftInHz",
- mHasDopplerShiftInHz ? mDopplerShiftInHz : null,
+ hasDopplerShiftInHz() ? mDopplerShiftInHz : null,
"DopplerShiftUncertaintyInHz",
- mHasDopplerShiftUncertaintyInHz ? mDopplerShiftUncertaintyInHz : null));
+ hasDopplerShiftUncertaintyInHz() ? mDopplerShiftUncertaintyInHz : null));
builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
builder.append(String.format(
format,
"SnrInDb",
- mHasSnrInDb ? mSnrInDb : null));
+ hasSnrInDb() ? mSnrInDb : null));
builder.append(String.format(
formatWithUncertainty,
"ElevationInDeg",
- mHasElevationInDeg ? mElevationInDeg : null,
+ hasElevationInDeg() ? mElevationInDeg : null,
"ElevationUncertaintyInDeg",
- mHasElevationUncertaintyInDeg ? mElevationUncertaintyInDeg : null));
+ hasElevationUncertaintyInDeg() ? mElevationUncertaintyInDeg : null));
builder.append(String.format(
formatWithUncertainty,
"AzimuthInDeg",
- mHasAzimuthInDeg ? mAzimuthInDeg : null,
+ hasAzimuthInDeg() ? mAzimuthInDeg : null,
"AzimuthUncertaintyInDeg",
- mHasAzimuthUncertaintyInDeg ? mAzimuthUncertaintyInDeg : null));
+ hasAzimuthUncertaintyInDeg() ? mAzimuthUncertaintyInDeg : null));
builder.append(String.format(format, "UsedInFix", mUsedInFix));
return builder.toString();
}
+
+ private void initialize() {
+ mFlags = HAS_NO_FLAGS;
+ setPrn(Byte.MIN_VALUE);
+ setTimeOffsetInNs(Long.MIN_VALUE);
+ setState(STATE_UNKNOWN);
+ setReceivedGpsTowInNs(Long.MIN_VALUE);
+ setReceivedGpsTowUncertaintyInNs(Long.MAX_VALUE);
+ setCn0InDbHz(Double.MIN_VALUE);
+ setPseudorangeRateInMetersPerSec(Double.MIN_VALUE);
+ setPseudorangeRateUncertaintyInMetersPerSec(Double.MIN_VALUE);
+ setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
+ setAccumulatedDeltaRangeInMeters(Double.MIN_VALUE);
+ setAccumulatedDeltaRangeUncertaintyInMeters(Double.MIN_VALUE);
+ resetPseudorangeInMeters();
+ resetPseudorangeUncertaintyInMeters();
+ resetCodePhaseInChips();
+ resetCodePhaseUncertaintyInChips();
+ resetCarrierFrequencyInHz();
+ resetCarrierCycles();
+ resetCarrierPhase();
+ resetCarrierPhaseUncertainty();
+ setLossOfLock(LOSS_OF_LOCK_UNKNOWN);
+ resetBitNumber();
+ resetTimeFromLastBitInMs();
+ resetDopplerShiftInHz();
+ resetDopplerShiftUncertaintyInHz();
+ setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
+ resetSnrInDb();
+ resetElevationInDeg();
+ resetElevationUncertaintyInDeg();
+ resetAzimuthInDeg();
+ resetAzimuthUncertaintyInDeg();
+ setUsedInFix(false);
+ }
+
+ private void setFlag(int flag) {
+ mFlags |= flag;
+ }
+
+ private void resetFlag(int flag) {
+ mFlags &= ~flag;
+ }
+
+ private boolean isFlagSet(int flag) {
+ return (mFlags & flag) == flag;
+ }
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index a1a7af9..ef42549 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -3500,7 +3500,13 @@
loadTouchSoundAssets();
- mSoundPool = new SoundPool(NUM_SOUNDPOOL_CHANNELS, AudioSystem.STREAM_SYSTEM, 0);
+ mSoundPool = new SoundPool.Builder()
+ .setMaxStreams(NUM_SOUNDPOOL_CHANNELS)
+ .setAudioAttributes(new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+ .build())
+ .build();
mSoundPoolCallBack = null;
mSoundPoolListenerThread = new SoundPoolListenerThread();
mSoundPoolListenerThread.start();
@@ -3750,7 +3756,8 @@
break;
case MSG_MEDIA_SERVER_DIED:
- if (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK) {
+ if (!mSystemReady ||
+ (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
Log.e(TAG, "Media server died.");
sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SENDMSG_NOOP, 0, 0,
null, 500);
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 16a2235..b5cebe3 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -65,6 +65,13 @@
* <tr><td>{@link #KEY_SAMPLE_RATE}</td><td>Integer</td><td></td></tr>
* <tr><td>{@link #KEY_IS_ADTS}</td><td>Integer</td><td>optional, if <em>decoding</em> AAC audio content, setting this key to 1 indicates that each audio frame is prefixed by the ADTS header.</td></tr>
* <tr><td>{@link #KEY_AAC_PROFILE}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is AAC audio, specifies the desired profile.</td></tr>
+ * <tr><td>{@link #KEY_AAC_SBR_MODE}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is AAC audio, specifies the desired SBR mode.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_TARGET_REFERENCE_LEVEL}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the target reference level.</td></tr>
+ * <tr><td>{@link #KEY_AAC_ENCODED_TARGET_LEVEL}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the target reference level used at encoder.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_BOOST_FACTOR}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the DRC boost factor.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_ATTENUATION_FACTOR}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the DRC attenuation factor.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_HEAVY_COMPRESSION}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies whether to use heavy compression.</td></tr>
+ * <tr><td>{@link #KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the maximum number of channels the decoder outputs.</td></tr>
* <tr><td>{@link #KEY_CHANNEL_MASK}</td><td>Integer</td><td>optional, a mask of audio channel assignments</td></tr>
* <tr><td>{@link #KEY_FLAC_COMPRESSION_LEVEL}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is FLAC audio, specifies the desired compression level.</td></tr>
* </table>
@@ -261,6 +268,110 @@
public static final String KEY_AAC_PROFILE = "aac-profile";
/**
+ * A key describing the AAC SBR mode to be used (AAC audio formats only).
+ * The associated value is an integer and can be set to following values:
+ * <ul>
+ * <li>0 - no SBR should be applied</li>
+ * <li>1 - single rate SBR</li>
+ * <li>2 - double rate SBR</li>
+ * </ul>
+ * Note: If this key is not defined the default SRB mode for the desired AAC profile will
+ * be used.
+ * <p>This key is only used during encoding.
+ */
+ public static final String KEY_AAC_SBR_MODE = "aac-sbr-mode";
+
+ /**
+ * A key describing the maximum number of channels that can be output by the AAC decoder.
+ * By default, the decoder will output the same number of channels as present in the encoded
+ * stream, if supported. Set this value to limit the number of output channels, and use
+ * the downmix information in the stream, if available.
+ * <p>Values larger than the number of channels in the content to decode are ignored.
+ * <p>This key is only used during decoding.
+ */
+ public static final String KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT = "aac-max-output-channel_count";
+
+ /**
+ * A key describing a gain to be applied so that the output loudness matches the
+ * Target Reference Level. This is typically used to normalize loudness across program items.
+ * The gain is derived as the difference between the Target Reference Level and the
+ * Program Reference Level. The latter can be given in the bitstream and indicates the actual
+ * loudness value of the program item.
+ * <p>The value is given as an integer value between
+ * 0 and 127, and is calculated as -0.25 * Target Reference Level in dBFS.
+ * Therefore, it represents the range of Full Scale (0 dBFS) to -31.75 dBFS.
+ * <p>This key is only used during decoding.
+ */
+ public static final String KEY_AAC_DRC_TARGET_REFERENCE_LEVEL = "aac-target-ref-level";
+
+ /**
+ * A key describing the target reference level that was assumed at the encoder for
+ * calculation of attenuation gains for clipping prevention. This information can be provided
+ * if it is known, otherwise a worst-case assumption is used.
+ * <p>The value is given as an integer value between
+ * 0 and 127, and is calculated as -0.25 * Target Reference Level in dBFS.
+ * Therefore, it represents the range of Full Scale (0 dBFS) to -31.75 dBFS.
+ * The default value is the worst-case assumption of 127.
+ * <p>The value is ignored when heavy compression is used (see
+ * {@link #KEY_AAC_DRC_HEAVY_COMPRESSION}).
+ * <p>This key is only used during decoding.
+ */
+ public static final String KEY_AAC_ENCODED_TARGET_LEVEL = "aac-encoded-target-level";
+
+ /**
+ * A key describing the boost factor allowing to adapt the dynamics of the output to the
+ * actual listening requirements. This relies on DRC gain sequences that can be transmitted in
+ * the encoded bitstream to be able to reduce the dynamics of the output signal upon request.
+ * This factor enables the user to select how much of the gains are applied.
+ * <p>Positive gains (boost) and negative gains (attenuation, see
+ * {@link #KEY_AAC_DRC_ATTENUATION_FACTOR}) can be controlled separately for a better match
+ * to different use-cases.
+ * <p>Typically, attenuation gains are sent for loud signal segments, and boost gains are sent
+ * for soft signal segments. If the output is listened to in a noisy environment, for example,
+ * the boost factor is used to enable the positive gains, i.e. to amplify soft signal segments
+ * beyond the noise floor. But for listening late at night, the attenuation
+ * factor is used to enable the negative gains, to prevent loud signal from surprising
+ * the listener. In applications which generally need a low dynamic range, both the boost factor
+ * and the attenuation factor are used in order to enable all DRC gains.
+ * <p>In order to prevent clipping, it is also recommended to apply the attenuation factors
+ * in case of a downmix and/or loudness normalization to high target reference levels.
+ * <p>Both the boost and the attenuation factor parameters are given as integer values
+ * between 0 and 127, representing the range of the factor of 0 (i.e. don't apply)
+ * to 1 (i.e. fully apply boost/attenuation factors respectively).
+ * <p>This key is only used during decoding.
+ */
+ public static final String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
+
+ /**
+ * A key describing the attenuation factor allowing to adapt the dynamics of the output to the
+ * actual listening requirements.
+ * See {@link #KEY_AAC_DRC_BOOST_FACTOR} for a description of the role of this attenuation
+ * factor and the value range.
+ * <p>This key is only used during decoding.
+ */
+ public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
+
+ /**
+ * A key describing the selection of the heavy compression profile for DRC.
+ * Two separate DRC gain sequences can be transmitted in one bitstream: MPEG-4 DRC light
+ * compression, and DVB-specific heavy compression. When selecting the application of the heavy
+ * compression, one of the sequences is selected:
+ * <ul>
+ * <li>0 enables light compression,</li>
+ * <li>1 enables heavy compression instead.
+ * </ul>
+ * Note that only light compression offers the features of scaling of DRC gains
+ * (see {@link #KEY_AAC_DRC_BOOST_FACTOR} and {@link #KEY_AAC_DRC_ATTENUATION_FACTOR} for the
+ * boost and attenuation factors, and frequency-selective (multiband) DRC.
+ * Light compression usually contains clipping prevention for stereo downmixing while heavy
+ * compression, if additionally provided in the bitstream, is usually stronger, and contains
+ * clipping prevention for stereo and mono downmixing.
+ * <p>The default is light compression.
+ * <p>This key is only used during decoding.
+ */
+ public static final String KEY_AAC_DRC_HEAVY_COMPRESSION = "aac-drc-heavy-compression";
+
+ /**
* A key describing the FLAC compression level to be used (FLAC audio format only).
* The associated value is an integer ranging from 0 (fastest, least compression)
* to 8 (slowest, most compression).
diff --git a/media/java/android/media/MediaMetadataEditor.java b/media/java/android/media/MediaMetadataEditor.java
index ca44e9d..566b93f 100644
--- a/media/java/android/media/MediaMetadataEditor.java
+++ b/media/java/android/media/MediaMetadataEditor.java
@@ -17,6 +17,7 @@
package android.media;
import android.graphics.Bitmap;
+import android.media.session.MediaSession;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
@@ -26,8 +27,10 @@
* An abstract class for editing and storing metadata that can be published by
* {@link RemoteControlClient}. See the {@link RemoteControlClient#editMetadata(boolean)}
* method to instantiate a {@link RemoteControlClient.MetadataEditor} object.
+ *
+ * @deprecated Use {@link MediaMetadata} instead together with {@link MediaSession}.
*/
-public abstract class MediaMetadataEditor {
+@Deprecated public abstract class MediaMetadataEditor {
private final static String TAG = "MediaMetadataEditor";
/**
diff --git a/media/java/android/media/Metadata.java b/media/java/android/media/Metadata.java
index eb543b4..54ad60e 100644
--- a/media/java/android/media/Metadata.java
+++ b/media/java/android/media/Metadata.java
@@ -40,8 +40,9 @@
the right get* method to fetch its value.
@hide
+ @deprecated Use {@link MediaMetadata}.
*/
-public class Metadata
+@Deprecated public class Metadata
{
// The metadata are keyed using integers rather than more heavy
// weight strings. We considered using Bundle to ship the metadata
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 740a9d3..0235871 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -63,8 +63,10 @@
* // create and register the remote control client
* RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
* myAudioManager.registerRemoteControlClient(myRemoteControlClient);</pre>
+ *
+ * @deprecated Use {@link MediaSession} instead.
*/
-public class RemoteControlClient
+@Deprecated public class RemoteControlClient
{
private final static String TAG = "RemoteControlClient";
private final static boolean DEBUG = false;
@@ -425,8 +427,10 @@
* has been set, use {@link #apply()} to make it the new metadata that should be displayed
* for the associated client. Once the metadata has been "applied", you cannot reuse this
* instance of the MetadataEditor.
+ *
+ * @deprecated Use {@link MediaMetadata} and {@link MediaSession} instead.
*/
- public class MetadataEditor extends MediaMetadataEditor {
+ @Deprecated public class MetadataEditor extends MediaMetadataEditor {
// only use RemoteControlClient.editMetadata() to get a MetadataEditor instance
private MetadataEditor() { }
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 9ea3f26..966fbb0 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -57,8 +57,10 @@
* <p>
* Registration requires the {@link OnClientUpdateListener} listener to be one of the enabled
* notification listeners (see {@link android.service.notification.NotificationListenerService}).
+ *
+ * @deprecated Use {@link MediaController} instead.
*/
-public final class RemoteController
+@Deprecated public final class RemoteController
{
private final static int MAX_BITMAP_DIMENSION = 512;
private final static int TRANSPORT_UNKNOWN = 0;
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 44c193f..9b9c767 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -126,12 +126,71 @@
* @param srcQuality the sample-rate converter quality. Currently has no
* effect. Use 0 for the default.
* @return a SoundPool object, or null if creation failed
+ * @deprecated use {@link SoundPool.Builder} instead to create and configure a
+ * SoundPool instance
*/
public SoundPool(int maxStreams, int streamType, int srcQuality) {
+ this(maxStreams,
+ new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build());
+ }
+
+ private SoundPool(int maxStreams, AudioAttributes attributes) {
if (SystemProperties.getBoolean("config.disable_media", false)) {
mImpl = new SoundPoolStub();
} else {
- mImpl = new SoundPoolImpl(this, maxStreams, streamType, srcQuality);
+ mImpl = new SoundPoolImpl(this, maxStreams, attributes);
+ }
+ }
+
+ /**
+ * Builder class for {@link SoundPool} objects.
+ */
+ public static class Builder {
+ private int mMaxStreams = 1;
+ private AudioAttributes mAudioAttributes;
+
+ /**
+ * Constructs a new Builder with the defaults format values.
+ */
+ public Builder() {
+ }
+
+ /**
+ * Sets the maximum of number of simultaneous streams that can be played simultaneously.
+ * @param maxStreams a value equal to 1 or greater.
+ * @return the same Builder instance
+ * @throws IllegalArgumentException
+ */
+ public Builder setMaxStreams(int maxStreams) throws IllegalArgumentException {
+ if (maxStreams <= 0) {
+ throw new IllegalArgumentException(
+ "Strictly positive value required for the maximum number of streams");
+ }
+ mMaxStreams = maxStreams;
+ return this;
+ }
+
+ /**
+ * Sets the {@link AudioAttributes}. For examples, game applications will use attributes
+ * built with usage information set to {@link AudioAttributes#USAGE_GAME}.
+ * @param attributes a non-null
+ * @return
+ */
+ public Builder setAudioAttributes(AudioAttributes attributes)
+ throws IllegalArgumentException {
+ if (attributes == null) {
+ throw new IllegalArgumentException("Invalid null AudioAttributes");
+ }
+ mAudioAttributes = attributes;
+ return this;
+ }
+
+ public SoundPool build() {
+ if (mAudioAttributes == null) {
+ mAudioAttributes = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA).build();
+ }
+ return new SoundPool(mMaxStreams, mAudioAttributes);
}
}
@@ -457,7 +516,7 @@
private SoundPool mProxy;
private final Object mLock;
- private final int mStreamType;
+ private final AudioAttributes mAttributes;
private final IAppOpsService mAppOps;
// SoundPool messages
@@ -465,15 +524,15 @@
// must match SoundPool.h
private static final int SAMPLE_LOADED = 1;
- public SoundPoolImpl(SoundPool proxy, int maxStreams, int streamType, int srcQuality) {
+ public SoundPoolImpl(SoundPool proxy, int maxStreams, AudioAttributes attr) {
// do native setup
- if (native_setup(new WeakReference(this), maxStreams, streamType, srcQuality) != 0) {
+ if (native_setup(new WeakReference(this), maxStreams, attr) != 0) {
throw new RuntimeException("Native setup failed");
}
mLock = new Object();
mProxy = proxy;
- mStreamType = streamType;
+ mAttributes = attr;
IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
mAppOps = IAppOpsService.Stub.asInterface(b);
}
@@ -548,9 +607,9 @@
private boolean isRestricted() {
try {
- final int usage = AudioAttributes.usageForLegacyStreamType(mStreamType);
final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO,
- usage, Process.myUid(), ActivityThread.currentPackageName());
+ mAttributes.getUsage(),
+ Process.myUid(), ActivityThread.currentPackageName());
return mode != AppOpsManager.MODE_ALLOWED;
} catch (RemoteException e) {
return false;
@@ -648,7 +707,8 @@
public native final void release();
- private native final int native_setup(Object weakRef, int maxStreams, int streamType, int srcQuality);
+ private native final int native_setup(Object weakRef, int maxStreams,
+ Object/*AudioAttributes*/ attributes);
protected void finalize() { release(); }
}
diff --git a/media/java/android/media/browse/IMediaBrowserService.aidl b/media/java/android/media/browse/IMediaBrowserService.aidl
new file mode 100644
index 0000000..177bd1b
--- /dev/null
+++ b/media/java/android/media/browse/IMediaBrowserService.aidl
@@ -0,0 +1,22 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+
+package android.media.browse;
+
+import android.content.res.Configuration;
+import android.media.browse.IMediaBrowserServiceCallbacks;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * Media API allows clients to browse through hierarchy of a user’s media collection,
+ * playback a specific media entry and interact with the now playing queue.
+ * @hide
+ */
+oneway interface IMediaBrowserService {
+ void connect(String pkg, in Bundle rootHints, IMediaBrowserServiceCallbacks callbacks);
+ void disconnect(IMediaBrowserServiceCallbacks callbacks);
+
+ void addSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
+ void removeSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
+ void loadThumbnail(in Uri uri, int width, int height, IMediaBrowserServiceCallbacks callbacks);
+}
\ No newline at end of file
diff --git a/media/java/android/media/browse/IMediaBrowserServiceCallbacks.aidl b/media/java/android/media/browse/IMediaBrowserServiceCallbacks.aidl
new file mode 100644
index 0000000..1f03a1a
--- /dev/null
+++ b/media/java/android/media/browse/IMediaBrowserServiceCallbacks.aidl
@@ -0,0 +1,28 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+
+package android.media.browse;
+
+import android.content.pm.ParceledListSlice;
+import android.graphics.Bitmap;
+import android.media.session.MediaSession;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * Media API allows clients to browse through hierarchy of a user’s media collection,
+ * playback a specific media entry and interact with the now playing queue.
+ * @hide
+ */
+oneway interface IMediaBrowserServiceCallbacks {
+ /**
+ * Invoked when the connected has been established.
+ * @param root The root Uri for browsing.
+ * @param session The {@link MediaSession.Token media session token} that can be used to control
+ * the playback of the media app.
+ * @param extra Extras returned by the media service.
+ */
+ void onConnect(in Uri root, in MediaSession.Token session, in Bundle extras);
+ void onConnectFailed();
+ void onLoadChildren(in Uri uri, in ParceledListSlice list);
+ void onLoadThumbnail(in Uri uri, int width, int height, in Bitmap bitmap);
+}
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
new file mode 100644
index 0000000..d17f95d
--- /dev/null
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -0,0 +1,842 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.browse;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ParceledListSlice;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.media.session.MediaSession;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Browses media content offered by a link MediaBrowserService.
+ * <p>
+ * This object is not thread-safe. All calls should happen on the thread on which the browser
+ * was constructed.
+ * </p>
+ */
+public final class MediaBrowser {
+ private static final String TAG = "MediaBrowser";
+ private static final boolean DBG = false;
+
+ private static final int CONNECT_STATE_DISCONNECTED = 0;
+ private static final int CONNECT_STATE_CONNECTING = 1;
+ private static final int CONNECT_STATE_CONNECTED = 2;
+ private static final int CONNECT_STATE_SUSPENDED = 3;
+
+ private final Context mContext;
+ private final ComponentName mServiceComponent;
+ private final ConnectionCallback mCallback;
+ private final Bundle mRootHints;
+ private final Handler mHandler = new Handler();
+ private final ArrayMap<Uri,Subscription> mSubscriptions =
+ new ArrayMap<Uri, MediaBrowser.Subscription>();
+ private final ArrayMap<ThumbnailRequest, HashSet<ThumbnailCallback>> mThumbnailCallbacks =
+ new ArrayMap<ThumbnailRequest, HashSet<ThumbnailCallback>>();
+
+ private int mState = CONNECT_STATE_DISCONNECTED;
+ private MediaServiceConnection mServiceConnection;
+ private IMediaBrowserService mServiceBinder;
+ private IMediaBrowserServiceCallbacks mServiceCallbacks;
+ private Uri mRootUri;
+ private MediaSession.Token mMediaSessionToken;
+ private Bundle mExtras;
+
+ /**
+ * Creates a media browser for the specified media browse service.
+ *
+ * @param context The context.
+ * @param serviceComponent The component name of the media browse service.
+ * @param callback The connection callback.
+ * @param rootHints An optional bundle of service-specific arguments to send
+ * to the media browse service when connecting and retrieving the root uri
+ * for browsing, or null if none. The contents of this bundle may affect
+ * the information returned when browsing.
+ */
+ public MediaBrowser(Context context, ComponentName serviceComponent,
+ ConnectionCallback callback, Bundle rootHints) {
+ if (context == null) {
+ throw new IllegalArgumentException("context must not be null");
+ }
+ if (serviceComponent == null) {
+ throw new IllegalArgumentException("service component must not be null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("connection callback must not be null");
+ }
+ mContext = context;
+ mServiceComponent = serviceComponent;
+ mCallback = callback;
+ mRootHints = rootHints;
+ }
+
+ /**
+ * Connects to the media browse service.
+ * <p>
+ * The connection callback specified in the constructor will be invoked
+ * when the connection completes or fails.
+ * </p>
+ */
+ public void connect() {
+ if (mState != CONNECT_STATE_DISCONNECTED) {
+ throw new IllegalStateException("connect() called while not disconnected (state="
+ + getStateLabel(mState) + ")");
+ }
+ // TODO: remove this extra check.
+ if (DBG) {
+ if (mServiceConnection != null) {
+ throw new RuntimeException("mServiceConnection should be null. Instead it is "
+ + mServiceConnection);
+ }
+ }
+ if (mServiceBinder != null) {
+ throw new RuntimeException("mServiceBinder should be null. Instead it is "
+ + mServiceBinder);
+ }
+ if (mServiceCallbacks != null) {
+ throw new RuntimeException("mServiceCallbacks should be null. Instead it is "
+ + mServiceCallbacks);
+ }
+
+ mState = CONNECT_STATE_CONNECTING;
+
+ final Intent intent = new Intent(MediaBrowserService.SERVICE_ACTION);
+ intent.setComponent(mServiceComponent);
+
+ final ServiceConnection thisConnection = mServiceConnection = new MediaServiceConnection();
+
+ try {
+ mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ } catch (Exception ex) {
+ Log.e(TAG, "Failed binding to service " + mServiceComponent);
+
+ // Tell them that it didn't work. We are already on the main thread,
+ // but we don't want to do callbacks inside of connect(). So post it,
+ // and then check that we are on the same ServiceConnection. We know
+ // we won't also get an onServiceConnected or onServiceDisconnected,
+ // so we won't be doing double callbacks.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // Ensure that nobody else came in or tried to connect again.
+ if (thisConnection == mServiceConnection) {
+ forceCloseConnection();
+ mCallback.onConnectionFailed();
+ }
+ }
+ });
+ }
+
+ if (DBG) {
+ Log.d(TAG, "connect...");
+ dump();
+ }
+ }
+
+ /**
+ * Disconnects from the media browse service.
+ * After this, no more callbacks will be received.
+ */
+ public void disconnect() {
+ // It's ok to call this any state, because allowing this lets apps not have
+ // to check isConnected() unnecessarily. They won't appreciate the extra
+ // assertions for this. We do everything we can here to go back to a sane state.
+ if (mServiceCallbacks != null) {
+ try {
+ mServiceBinder.disconnect(mServiceCallbacks);
+ } catch (RemoteException ex) {
+ // We are disconnecting anyway. Log, just for posterity but it's not
+ // a big problem.
+ Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
+ }
+ }
+ forceCloseConnection();
+
+ if (DBG) {
+ Log.d(TAG, "disconnect...");
+ dump();
+ }
+ }
+
+ /**
+ * Null out the variables and unbind from the service. This doesn't include
+ * calling disconnect on the service, because we only try to do that in the
+ * clean shutdown cases.
+ * <p>
+ * Everywhere that calls this EXCEPT for disconnect() should follow it with
+ * a call to mCallback.onConnectionFailed(). Disconnect doesn't do that callback
+ * for a clean shutdown, but everywhere else is a dirty shutdown and should
+ * notify the app.
+ */
+ private void forceCloseConnection() {
+ if (mServiceConnection != null) {
+ mContext.unbindService(mServiceConnection);
+ }
+ mState = CONNECT_STATE_DISCONNECTED;
+ mServiceConnection = null;
+ mServiceBinder = null;
+ mServiceCallbacks = null;
+ mRootUri = null;
+ mMediaSessionToken = null;
+ }
+
+ /**
+ * Returns whether the browser is connected to the service.
+ */
+ public boolean isConnected() {
+ return mState == CONNECT_STATE_CONNECTED;
+ }
+
+ /**
+ * Gets the root Uri.
+ * <p>
+ * Note that the root uri may become invalid or change when when the
+ * browser is disconnected.
+ * </p>
+ *
+ * @throws IllegalStateException if not connected.
+ */
+ public @NonNull Uri getRoot() {
+ if (mState != CONNECT_STATE_CONNECTED) {
+ throw new IllegalStateException("getSessionToken() called while not connected (state="
+ + getStateLabel(mState) + ")");
+ }
+ return mRootUri;
+ }
+
+ /**
+ * Gets any extras for the media service.
+ *
+ * @throws IllegalStateException if not connected.
+ */
+ public @Nullable Bundle getExtras() {
+ if (mState != CONNECT_STATE_CONNECTED) {
+ throw new IllegalStateException("getExtras() called while not connected (state="
+ + getStateLabel(mState) + ")");
+ }
+ return mExtras;
+ }
+
+ /**
+ * Gets the media session token associated with the media browser.
+ * <p>
+ * Note that the session token may become invalid or change when when the
+ * browser is disconnected.
+ * </p>
+ *
+ * @return The session token for the browser, never null.
+ *
+ * @throws IllegalStateException if not connected.
+ */
+ public @NonNull MediaSession.Token getSessionToken() {
+ if (mState != CONNECT_STATE_CONNECTED) {
+ throw new IllegalStateException("getSessionToken() called while not connected (state="
+ + mState + ")");
+ }
+ return mMediaSessionToken;
+ }
+
+ /**
+ * Queries for information about the media items that are contained within
+ * the specified Uri and subscribes to receive updates when they change.
+ * <p>
+ * The list of subscriptions is maintained even when not connected and is
+ * restored after reconnection. It is ok to subscribe while not connected
+ * but the results will not be returned until the connection completes.
+ * </p><p>
+ * If the uri is already subscribed with a different callback then the new
+ * callback will replace the previous one.
+ * </p>
+ *
+ * @param parentUri The uri of the parent media item whose list of children
+ * will be subscribed.
+ * @param callback The callback to receive the list of children.
+ */
+ public void subscribe(@NonNull Uri parentUri, @NonNull SubscriptionCallback callback) {
+ // Check arguments.
+ if (parentUri == null) {
+ throw new IllegalArgumentException("parentUri is null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("callback is null");
+ }
+
+ // Update or create the subscription.
+ Subscription sub = mSubscriptions.get(parentUri);
+ boolean newSubscription = sub == null;
+ if (newSubscription) {
+ sub = new Subscription(parentUri);
+ mSubscriptions.put(parentUri, sub);
+ }
+ sub.callback = callback;
+
+ // If we are connected, tell the service that we are watching. If we aren't
+ // connected, the service will be told when we connect.
+ if (mState == CONNECT_STATE_CONNECTED && newSubscription) {
+ try {
+ mServiceBinder.addSubscription(parentUri, mServiceCallbacks);
+ } catch (RemoteException ex) {
+ // Process is crashing. We will disconnect, and upon reconnect we will
+ // automatically reregister. So nothing to do here.
+ Log.d(TAG, "addSubscription failed with RemoteException parentUri=" + parentUri);
+ }
+ }
+ }
+
+ /**
+ * Unsubscribes for changes to the children of the specified Uri.
+ * <p>
+ * The query callback will no longer be invoked for results associated with
+ * this Uri once this method returns.
+ * </p>
+ *
+ * @param parentUri The uri of the parent media item whose list of children
+ * will be unsubscribed.
+ */
+ public void unsubscribe(@NonNull Uri parentUri) {
+ // Check arguments.
+ if (parentUri == null) {
+ throw new IllegalArgumentException("parentUri is null");
+ }
+
+ // Remove from our list.
+ final Subscription sub = mSubscriptions.remove(parentUri);
+
+ // Tell the service if necessary.
+ if (mState == CONNECT_STATE_CONNECTED && sub != null) {
+ try {
+ mServiceBinder.removeSubscription(parentUri, mServiceCallbacks);
+ } catch (RemoteException ex) {
+ // Process is crashing. We will disconnect, and upon reconnect we will
+ // automatically reregister. So nothing to do here.
+ Log.d(TAG, "removeSubscription failed with RemoteException parentUri=" + parentUri);
+ }
+ }
+ }
+
+ /**
+ * Loads the thumbnail of a media item.
+ *
+ * @param uri The uri of the thumbnail.
+ * @param width The preferred width of the icon in dp.
+ * @param height The preferred width of the icon in dp.
+ * @param callback The callback to receive the thumbnail.
+ */
+ public void loadThumbnail(final @NonNull Uri uri, final int width, final int height,
+ final @NonNull ThumbnailCallback callback) {
+ if (uri == null) {
+ throw new IllegalArgumentException("thumbnail uri cannot be null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("thumbnail callback cannot be null");
+ }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ HashSet<ThumbnailCallback> callbackSet;
+ ThumbnailRequest request = new ThumbnailRequest(uri, width, height);
+ callbackSet = mThumbnailCallbacks.get(request);
+ if (callbackSet != null) {
+ callbackSet.add(callback);
+ mThumbnailCallbacks.put(request, callbackSet);
+ // same request has been sent. we will wait for the callback.
+ return;
+ }
+ callbackSet = new HashSet<ThumbnailCallback>();
+ callbackSet.add(callback);
+ mThumbnailCallbacks.put(request, callbackSet);
+ if (mState == CONNECT_STATE_CONNECTED) {
+ try {
+ mServiceBinder.loadThumbnail(uri, width, height, mServiceCallbacks);
+ } catch (RemoteException e) {
+ // Process is crashing. We will disconnect, and upon reconnect we will
+ // automatically reload the thumbnails. So nothing to do here.
+ Log.d(TAG, "loadThumbnail failed with RemoteException uri=" + uri);
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * For debugging.
+ */
+ private static String getStateLabel(int state) {
+ switch (state) {
+ case CONNECT_STATE_DISCONNECTED:
+ return "CONNECT_STATE_DISCONNECTED";
+ case CONNECT_STATE_CONNECTING:
+ return "CONNECT_STATE_CONNECTING";
+ case CONNECT_STATE_CONNECTED:
+ return "CONNECT_STATE_CONNECTED";
+ case CONNECT_STATE_SUSPENDED:
+ return "CONNECT_STATE_SUSPENDED";
+ default:
+ return "UNKNOWN/" + state;
+ }
+ }
+
+ private final void onServiceConnected(final IMediaBrowserServiceCallbacks callback,
+ final Uri root, final MediaSession.Token session, final Bundle extra) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // Check to make sure there hasn't been a disconnect or a different
+ // ServiceConnection.
+ if (!isCurrent(callback, "onConnect")) {
+ return;
+ }
+ // Don't allow them to call us twice.
+ if (mState != CONNECT_STATE_CONNECTING) {
+ Log.w(TAG, "onConnect from service while mState="
+ + getStateLabel(mState) + "... ignoring");
+ return;
+ }
+ mRootUri = root;
+ mMediaSessionToken = session;
+ mExtras = extra;
+ mState = CONNECT_STATE_CONNECTED;
+
+ if (DBG) {
+ Log.d(TAG, "ServiceCallbacks.onConnect...");
+ dump();
+ }
+ mCallback.onConnected();
+
+ // we may receive some subscriptions before we are connected, so re-subscribe
+ // everything now
+ for (Uri uri : mSubscriptions.keySet()) {
+ try {
+ mServiceBinder.addSubscription(uri, mServiceCallbacks);
+ } catch (RemoteException ex) {
+ // Process is crashing. We will disconnect, and upon reconnect we will
+ // automatically reregister. So nothing to do here.
+ Log.d(TAG, "addSubscription failed with RemoteException parentUri=" + uri);
+ }
+ }
+
+ for (ThumbnailRequest request : mThumbnailCallbacks.keySet()) {
+ try {
+ mServiceBinder.loadThumbnail(request.uri, request.width, request.height,
+ mServiceCallbacks);
+ } catch (RemoteException e) {
+ // Process is crashing. We will disconnect, and upon reconnect we will
+ // automatically reload. So nothing to do here.
+ Log.d(TAG, "loadThumbnail failed with RemoteException uri=" + request.uri);
+ }
+ }
+
+ }
+ });
+ }
+
+ private final void onConnectionFailed(final IMediaBrowserServiceCallbacks callback) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ Log.e(TAG, "onConnectFailed for " + mServiceComponent);
+
+ // Check to make sure there hasn't been a disconnect or a different
+ // ServiceConnection.
+ if (!isCurrent(callback, "onConnectFailed")) {
+ return;
+ }
+ // Don't allow them to call us twice.
+ if (mState != CONNECT_STATE_CONNECTING) {
+ Log.w(TAG, "onConnect from service while mState="
+ + getStateLabel(mState) + "... ignoring");
+ return;
+ }
+
+ // Clean up
+ forceCloseConnection();
+
+ // Tell the app.
+ mCallback.onConnectionFailed();
+ }
+ });
+ }
+
+ private final void onLoadChildren(final IMediaBrowserServiceCallbacks callback, final Uri uri,
+ final ParceledListSlice list) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // Check that there hasn't been a disconnect or a different
+ // ServiceConnection.
+ if (!isCurrent(callback, "onLoadChildren")) {
+ return;
+ }
+
+ List<MediaBrowserItem> data = list.getList();
+ if (DBG) {
+ Log.d(TAG, "onLoadChildren for " + mServiceComponent + " uri=" + uri);
+ }
+ if (data == null) {
+ data = Collections.emptyList();
+ }
+
+ // Check that the subscription is still subscribed.
+ final Subscription subscription = mSubscriptions.get(uri);
+ if (subscription == null) {
+ if (DBG) {
+ Log.d(TAG, "onLoadChildren for uri that isn't subscribed uri="
+ + uri);
+ }
+ return;
+ }
+
+ // Tell the app.
+ subscription.callback.onChildrenLoaded(uri, data);
+ }
+ });
+ }
+
+ private final void onLoadThumbnail(final IMediaBrowserServiceCallbacks callback,
+ final ThumbnailRequest request, final Bitmap bitmap) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // Check that there hasn't been a disconnect or a different
+ // ServiceConnection.
+ if (!isCurrent(callback, "onLoadThumbnail")) {
+ return;
+ }
+
+ Set<ThumbnailCallback> callbackSet = mThumbnailCallbacks.get(request);
+ if (callbackSet == null) {
+ Log.d(TAG, "onLoadThumbnail called for request=" + request +
+ " but the callback is not registered");
+ return;
+ }
+ for (ThumbnailCallback thumbnailCallback : callbackSet) {
+ thumbnailCallback.onThumbnailLoaded(request.uri, bitmap);
+ }
+ mThumbnailCallbacks.remove(request);
+ }
+ });
+ }
+
+
+ /**
+ * Return true if {@code callback} is the current ServiceCallbacks. Also logs if it's not.
+ */
+ private boolean isCurrent(IMediaBrowserServiceCallbacks callback, String funcName) {
+ if (mServiceCallbacks != callback) {
+ if (mState != CONNECT_STATE_DISCONNECTED) {
+ Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection="
+ + mServiceCallbacks + " this=" + this);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ private ServiceCallbacks getNewServiceCallbacks() {
+ return new ServiceCallbacks(this);
+ }
+
+ /**
+ * Log internal state.
+ * @hide
+ */
+ void dump() {
+ Log.d(TAG, "MediaBrowser...");
+ Log.d(TAG, " mServiceComponent=" + mServiceComponent);
+ Log.d(TAG, " mCallback=" + mCallback);
+ Log.d(TAG, " mRootHints=" + mRootHints);
+ Log.d(TAG, " mState=" + getStateLabel(mState));
+ Log.d(TAG, " mServiceConnection=" + mServiceConnection);
+ Log.d(TAG, " mServiceBinder=" + mServiceBinder);
+ Log.d(TAG, " mServiceCallbacks=" + mServiceCallbacks);
+ Log.d(TAG, " mRootUri=" + mRootUri);
+ Log.d(TAG, " mMediaSessionToken=" + mMediaSessionToken);
+ }
+
+
+ /**
+ * Callbacks for connection related events.
+ */
+ public static class ConnectionCallback {
+ /**
+ * Invoked after {@link MediaBrowser#connect()} when the request has successfully completed.
+ */
+ public void onConnected() {
+ }
+
+ /**
+ * Invoked when the client is disconnected from the media browser.
+ */
+ public void onConnectionSuspended() {
+ }
+
+ /**
+ * Invoked when the connection to the media browser failed.
+ */
+ public void onConnectionFailed() {
+ }
+ }
+
+ /**
+ * Callbacks for subscription related events.
+ */
+ public static abstract class SubscriptionCallback {
+ /**
+ * Called when the list of children is loaded or updated.
+ */
+ public void onChildrenLoaded(@NonNull Uri parentUri,
+ @NonNull List<MediaBrowserItem> children) {
+ }
+
+ /**
+ * Called when the Uri doesn't exist or other errors in subscribing.
+ * <p>
+ * If this is called, the subscription remains until {@link MediaBrowser#unsubscribe}
+ * called, because some errors may heal themselves.
+ * </p>
+ */
+ public void onError(@NonNull Uri uri) {
+ }
+ }
+
+ /**
+ * Callbacks for thumbnail loading.
+ */
+ public static abstract class ThumbnailCallback {
+ /**
+ * Called when the thumbnail is loaded.
+ */
+ public void onThumbnailLoaded(@NonNull Uri uri, @NonNull Bitmap bitmap) {
+ }
+
+ /**
+ * Called when the Uri doesn’t exist or the bitmap cannot be loaded.
+ */
+ public void onError(@NonNull Uri uri) {
+ }
+ }
+
+ private static class ThumbnailRequest {
+ Uri uri;
+ int width;
+ int height;
+ ThumbnailRequest(@NonNull Uri uri, int width, int height) {
+ if (uri == null) {
+ throw new IllegalArgumentException("thumbnail uri cannot be null");
+ }
+ this.uri = uri;
+ this.width = width;
+ this.height = height;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ThumbnailRequest)) return false;
+
+ ThumbnailRequest that = (ThumbnailRequest) o;
+
+ if (height != that.height) return false;
+ if (width != that.width) return false;
+ if (!uri.equals(that.uri)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = uri.hashCode();
+ result = 31 * result + width;
+ result = 31 * result + height;
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ThumbnailRequest{" +
+ "uri=" + uri +
+ ", width=" + width +
+ ", height=" + height +
+ '}';
+ }
+ }
+
+ /**
+ * ServiceConnection to the other app.
+ */
+ private class MediaServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder binder) {
+ if (DBG) {
+ Log.d(TAG, "MediaServiceConnection.onServiceConnected name=" + name
+ + " binder=" + binder);
+ dump();
+ }
+
+ // Make sure we are still the current connection, and that they haven't called
+ // disconnect().
+ if (!isCurrent("onServiceConnected")) {
+ return;
+ }
+
+ // Save their binder
+ mServiceBinder = IMediaBrowserService.Stub.asInterface(binder);
+
+ // We make a new mServiceCallbacks each time we connect so that we can drop
+ // responses from previous connections.
+ mServiceCallbacks = getNewServiceCallbacks();
+
+ // Call connect, which is async. When we get a response from that we will
+ // say that we're connected.
+ try {
+ if (DBG) {
+ Log.d(TAG, "ServiceCallbacks.onConnect...");
+ dump();
+ }
+ mServiceBinder.connect(mContext.getPackageName(), mRootHints, mServiceCallbacks);
+ } catch (RemoteException ex) {
+ // Connect failed, which isn't good. But the auto-reconnect on the service
+ // will take over and we will come back. We will also get the
+ // onServiceDisconnected, which has all the cleanup code. So let that do it.
+ Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
+ if (DBG) {
+ Log.d(TAG, "ServiceCallbacks.onConnect...");
+ dump();
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ if (DBG) {
+ Log.d(TAG, "MediaServiceConnection.onServiceDisconnected name=" + name
+ + " this=" + this + " mServiceConnection=" + mServiceConnection);
+ dump();
+ }
+
+ // Make sure we are still the current connection, and that they haven't called
+ // disconnect().
+ if (!isCurrent("onServiceDisconnected")) {
+ return;
+ }
+
+ // Clear out what we set in onServiceConnected
+ mServiceBinder = null;
+ mServiceCallbacks = null;
+
+ // And tell the app that it's suspended.
+ mState = CONNECT_STATE_SUSPENDED;
+ mCallback.onConnectionSuspended();
+ }
+
+ /**
+ * Return true if this is the current ServiceConnection. Also logs if it's not.
+ */
+ private boolean isCurrent(String funcName) {
+ if (mServiceConnection != this) {
+ if (mState != CONNECT_STATE_DISCONNECTED) {
+ // Check mState, because otherwise this log is noisy.
+ Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection="
+ + mServiceConnection + " this=" + this);
+ }
+ return false;
+ }
+ return true;
+ }
+ };
+
+ /**
+ * Callbacks from the service.
+ */
+ private static class ServiceCallbacks extends IMediaBrowserServiceCallbacks.Stub {
+ private WeakReference<MediaBrowser> mMediaBrowser;
+
+ public ServiceCallbacks(MediaBrowser mediaBrowser) {
+ mMediaBrowser = new WeakReference<MediaBrowser>(mediaBrowser);
+ }
+
+ /**
+ * The other side has acknowledged our connection. The parameters to this function
+ * are the initial data as requested.
+ */
+ @Override
+ public void onConnect(final Uri root, final MediaSession.Token session,
+ final Bundle extras) {
+ MediaBrowser mediaBrowser = mMediaBrowser.get();
+ if (mediaBrowser != null) {
+ mediaBrowser.onServiceConnected(this, root, session, extras);
+ }
+ }
+
+ /**
+ * The other side does not like us. Tell the app via onConnectionFailed.
+ */
+ @Override
+ public void onConnectFailed() {
+ MediaBrowser mediaBrowser = mMediaBrowser.get();
+ if (mediaBrowser != null) {
+ mediaBrowser.onConnectionFailed(this);
+ }
+ }
+
+ @Override
+ public void onLoadChildren(final Uri uri, final ParceledListSlice list) {
+ MediaBrowser mediaBrowser = mMediaBrowser.get();
+ if (mediaBrowser != null) {
+ mediaBrowser.onLoadChildren(this, uri, list);
+ }
+ }
+
+ @Override
+ public void onLoadThumbnail(final Uri uri, int width, int height, final Bitmap bitmap) {
+ MediaBrowser mediaBrowser = mMediaBrowser.get();
+ if (mediaBrowser != null) {
+ ThumbnailRequest request = new ThumbnailRequest(uri, width, height);
+ mediaBrowser.onLoadThumbnail(this, request, bitmap);
+ }
+ }
+ }
+
+ private static class Subscription {
+ final Uri uri;
+ SubscriptionCallback callback;
+
+ Subscription(Uri u) {
+ this.uri = u;
+ }
+ }
+}
diff --git a/media/java/android/media/browse/MediaBrowserItem.java b/media/java/android/media/browse/MediaBrowserItem.java
new file mode 100644
index 0000000..38e765f
--- /dev/null
+++ b/media/java/android/media/browse/MediaBrowserItem.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.browse;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.net.Uri;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Describes a media item in the list of items offered by a {@link MediaBrowserService}.
+ */
+public final class MediaBrowserItem implements Parcelable {
+ private final Uri mUri;
+ private final Uri mIconUri;
+ private final int mIconResId;
+ private final int mFlags;
+ private final CharSequence mTitle;
+ private final CharSequence mSummary;
+ private final Bundle mExtras;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag=true, value = { FLAG_BROWSABLE, FLAG_PLAYABLE })
+ public @interface Flags { }
+
+ /**
+ * Flag: Indicates that the item has children of its own.
+ */
+ public static final int FLAG_BROWSABLE = 1 << 0;
+
+ /**
+ * Flag: Indicates that the item is playable.
+ * <p>
+ * The Uri of this item may be passed to link android.media.session.MediaController#play(Uri)
+ * to start playing it.
+ * </p>
+ */
+ public static final int FLAG_PLAYABLE = 1 << 1;
+
+ /**
+ * Initialize a MediaBrowserItem object.
+ */
+ private MediaBrowserItem(@NonNull Uri uri, @Nullable Uri iconUri, int iconResId, int flags,
+ @NonNull CharSequence title, CharSequence summary, Bundle extras) {
+ if (uri == null) {
+ throw new IllegalArgumentException("uri can not be null");
+ }
+ if (title == null) {
+ throw new IllegalArgumentException("title can not be null");
+ }
+ mUri = uri;
+ mIconUri = iconUri;
+ mIconResId = iconResId;
+ mFlags = flags;
+ mTitle = title;
+ mSummary = summary;
+ mExtras = extras;
+ }
+
+ /**
+ * Private constructor.
+ */
+ private MediaBrowserItem(Parcel in) {
+ mUri = Uri.CREATOR.createFromParcel(in);
+ mIconUri = Uri.CREATOR.createFromParcel(in);
+ mIconResId = in.readInt();
+ mFlags = in.readInt();
+ mTitle = in.readCharSequence();
+ if (in.readInt() != 0) {
+ mSummary = in.readCharSequence();
+ } else {
+ mSummary = null;
+ }
+ if (in.readInt() != 0) {
+ mExtras = Bundle.CREATOR.createFromParcel(in);
+ } else {
+ mExtras = null;
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ mUri.writeToParcel(out, flags);
+ mIconUri.writeToParcel(out, flags);
+ out.writeInt(mIconResId);
+ out.writeInt(mFlags);
+ out.writeCharSequence(mTitle);
+ if (mSummary != null) {
+ out.writeInt(1);
+ out.writeCharSequence(mSummary);
+ } else {
+ out.writeInt(0);
+ }
+ if (mExtras != null) {
+ out.writeInt(1);
+ mExtras.writeToParcel(out, flags);
+ } else {
+ out.writeInt(0);
+ }
+ }
+
+ public static final Parcelable.Creator<MediaBrowserItem> CREATOR =
+ new Parcelable.Creator<MediaBrowserItem>() {
+ @Override
+ public MediaBrowserItem createFromParcel(Parcel in) {
+ return new MediaBrowserItem(in);
+ }
+
+ @Override
+ public MediaBrowserItem[] newArray(int size) {
+ return new MediaBrowserItem[size];
+ }
+ };
+
+ /**
+ * Gets the Uri of the item.
+ */
+ public @NonNull Uri getUri() {
+ return mUri;
+ }
+
+ /**
+ * Gets the Uri of the icon.
+ */
+ public @Nullable Uri getIconUri() {
+ return mIconUri;
+ }
+
+ /**
+ * Gets the resource id of the icon.
+ */
+ public int getIconResId() {
+ return mIconResId;
+ }
+
+ /**
+ * Gets the flags of the item.
+ */
+ public @Flags int getFlags() {
+ return mFlags;
+ }
+
+ /**
+ * Returns whether this item is browsable.
+ * @see #FLAG_BROWSABLE
+ */
+ public boolean isBrowsable() {
+ return (mFlags & FLAG_BROWSABLE) != 0;
+ }
+
+ /**
+ * Returns whether this item is playable.
+ * @see #FLAG_PLAYABLE
+ */
+ public boolean isPlayable() {
+ return (mFlags & FLAG_PLAYABLE) != 0;
+ }
+
+ /**
+ * Gets the title of the item.
+ * @more
+ * The title will be shown as the first line of text when
+ * describing each item to the user.
+ */
+ public @NonNull CharSequence getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Gets summary of the item, or null if none.
+ * @more
+ * The summary will be shown as the second line of text when
+ * describing each item to the user.
+ */
+ public @Nullable CharSequence getSummary() {
+ return mSummary;
+ }
+
+ /**
+ * Gets additional service-specified extras about the
+ * item or its content, or null if none.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Builder for {@link MediaBrowserItem} objects.
+ */
+ public static final class Builder {
+ private final Uri mUri;
+ private final int mFlags;
+ private final CharSequence mTitle;
+ private Uri mIconUri;
+ private int mIconResId;
+ private CharSequence mSummary;
+ private Bundle mExtras;
+
+ /**
+ * Creates an item builder.
+ */
+ public Builder(@NonNull Uri uri, @Flags int flags, @NonNull CharSequence title) {
+ if (uri == null) {
+ throw new IllegalArgumentException("uri can not be null");
+ }
+ if (title == null) {
+ throw new IllegalArgumentException("title can not be null");
+ }
+ mUri = uri;
+ mFlags = flags;
+ mTitle = title;
+ }
+
+ /**
+ * Sets the uri of the icon.
+ * <p>
+ * If both {@link #setIconUri(Uri)} and {@link #setIconResId(int)} are called,
+ * the resource id will be used to load the icon.
+ * </p>
+ */
+ public @NonNull Builder setIconUri(@Nullable Uri iconUri) {
+ mIconUri = iconUri;
+ return this;
+ }
+
+ /**
+ * Sets the resource id of the icon.
+ */
+ public @NonNull Builder setIconResId(int resId) {
+ mIconResId = resId;
+ return this;
+ }
+
+ /**
+ * Sets summary of the item, or null if none.
+ */
+ public @NonNull Builder setSummary(@Nullable CharSequence summary) {
+ mSummary = summary;
+ return this;
+ }
+
+ /**
+ * Sets additional service-specified extras about the
+ * item or its content, or null if none.
+ */
+ public @NonNull Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds the item.
+ */
+ public @NonNull MediaBrowserItem build() {
+ return new MediaBrowserItem(mUri, mIconUri, mIconResId,
+ mFlags, mTitle, mSummary, mExtras);
+ }
+ }
+}
+
diff --git a/media/java/android/media/browse/MediaBrowserService.java b/media/java/android/media/browse/MediaBrowserService.java
new file mode 100644
index 0000000..57befe7
--- /dev/null
+++ b/media/java/android/media/browse/MediaBrowserService.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.browse;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.Service;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.media.session.MediaSession;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Base class for media browse services.
+ * <p>
+ * Media browse services enable applications to browse media content provided by an application
+ * and ask the application to start playing it. They may also be used to control content that
+ * is already playing by way of a {@link MediaSession}.
+ * </p>
+ *
+ * To extend this class, you must declare the service in your manifest file with
+ * an intent filter with the {@link #SERVICE_ACTION} action.
+ *
+ * For example:
+ * </p><pre>
+ * <service android:name=".MyMediaBrowserService"
+ * android:label="@string/service_name" >
+ * <intent-filter>
+ * <action android:name="android.media.browse.MediaBrowserService" />
+ * </intent-filter>
+ * </service>
+ * </pre>
+ *
+ */
+public abstract class MediaBrowserService extends Service {
+ private static final String TAG = "MediaBrowserService";
+
+ private final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap();
+ private final Handler mHandler = new Handler();
+ private ServiceBinder mBinder;
+ MediaSession.Token mSession;
+
+ /**
+ * All the info about a connection.
+ */
+ private class ConnectionRecord {
+ String pkg;
+ Bundle rootHints;
+ IMediaBrowserServiceCallbacks callbacks;
+ BrowserRoot root;
+ HashSet<Uri> subscriptions = new HashSet();
+ }
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_ACTION = "android.media.browse.MediaBrowserService";
+
+ private class ServiceBinder extends IMediaBrowserService.Stub {
+ @Override
+ public void connect(final String pkg, final Bundle rootHints,
+ final IMediaBrowserServiceCallbacks callbacks) {
+
+ final int uid = Binder.getCallingUid();
+ if (!isValidPackage(pkg, uid)) {
+ throw new IllegalArgumentException("Package/uid mismatch: uid=" + uid
+ + " package=" + pkg);
+ }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ final IBinder b = callbacks.asBinder();
+
+ // Clear out the old subscriptions. We are getting new ones.
+ mConnections.remove(b);
+
+ final ConnectionRecord connection = new ConnectionRecord();
+ connection.pkg = pkg;
+ connection.rootHints = rootHints;
+ connection.callbacks = callbacks;
+
+ connection.root = MediaBrowserService.this.onGetRoot(pkg, uid, rootHints);
+
+ // If they didn't return something, don't allow this client.
+ if (connection.root == null) {
+ Log.i(TAG, "No root for client " + pkg + " from service "
+ + getClass().getName());
+ try {
+ callbacks.onConnectFailed();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Calling onConnectFailed() failed. Ignoring. "
+ + "pkg=" + pkg);
+ }
+ } else {
+ try {
+ mConnections.put(b, connection);
+ callbacks.onConnect(connection.root.getRootUri(),
+ mSession, connection.root.getExtras());
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Calling onConnect() failed. Dropping client. "
+ + "pkg=" + pkg);
+ mConnections.remove(b);
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public void disconnect(final IMediaBrowserServiceCallbacks callbacks) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ final IBinder b = callbacks.asBinder();
+
+ // Clear out the old subscriptions. We are getting new ones.
+ final ConnectionRecord old = mConnections.remove(b);
+ if (old != null) {
+ // TODO
+ }
+ }
+ });
+ }
+
+
+ @Override
+ public void addSubscription(final Uri uri, final IMediaBrowserServiceCallbacks callbacks) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ final IBinder b = callbacks.asBinder();
+
+ // Get the record for the connection
+ final ConnectionRecord connection = mConnections.get(b);
+ if (connection == null) {
+ Log.w(TAG, "addSubscription for callback that isn't registered uri="
+ + uri);
+ return;
+ }
+
+ MediaBrowserService.this.addSubscription(uri, connection);
+ }
+ });
+ }
+
+ @Override
+ public void removeSubscription(final Uri uri,
+ final IMediaBrowserServiceCallbacks callbacks) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ final IBinder b = callbacks.asBinder();
+
+ ConnectionRecord connection = mConnections.get(b);
+ if (connection == null) {
+ Log.w(TAG, "removeSubscription for callback that isn't registered uri="
+ + uri);
+ return;
+ }
+ if (!connection.subscriptions.remove(uri)) {
+ Log.w(TAG, "removeSubscription called for " + uri
+ + " which is not subscribed");
+ }
+ }
+ });
+ }
+
+ @Override
+ public void loadThumbnail(final Uri uri, final int width, final int height,
+ final IMediaBrowserServiceCallbacks callbacks) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ Bitmap bitmap = onGetThumbnail(uri, width, height);
+ try {
+ callbacks.onLoadThumbnail(uri, width, height, bitmap);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in calling onLoadThumbnail", e);
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mBinder = new ServiceBinder();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (SERVICE_ACTION.equals(intent.getAction())) {
+ return mBinder;
+ }
+ return null;
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ }
+
+ /**
+ * Called to get the root information for browsing by a particular client.
+ * <p>
+ * The implementation should verify that the client package has
+ * permission to access browse media information before returning
+ * the root uri; it should return null if the client is not
+ * allowed to access this information.
+ * </p>
+ *
+ * @param clientPackageName The package name of the application
+ * which is requesting access to browse media.
+ * @param clientUid The uid of the application which is requesting
+ * access to browse media.
+ * @param rootHints An optional bundle of service-specific arguments to send
+ * to the media browse service when connecting and retrieving the root uri
+ * for browsing, or null if none. The contents of this bundle may affect
+ * the information returned when browsing.
+ */
+ protected abstract @Nullable BrowserRoot onGetRoot(@NonNull String clientPackageName,
+ int clientUid, @Nullable Bundle rootHints);
+
+ /**
+ * Called to get information about the children of a media item.
+ *
+ * @param parentUri The uri of the parent media item whose
+ * children are to be queried.
+ * @return The list of children, or null if the uri is invalid.
+ */
+ protected abstract @Nullable List<MediaBrowserItem> onLoadChildren(@NonNull Uri parentUri);
+
+ /**
+ * Called to get the thumbnail of a particular media item.
+ *
+ * @param uri The uri of the media item.
+ * @param width The requested width of the icon in dp.
+ * @param height The requested height of the icon in dp.
+ *
+ * @return The file descriptor of the thumbnail, which may then be loaded
+ * using a bitmap factory, or null if the item does not have a thumbnail.
+ */
+ protected abstract @Nullable Bitmap onGetThumbnail(@NonNull Uri uri, int width, int height);
+
+ /**
+ * Call to set the media session.
+ * <p>
+ * This must be called before onCreate returns.
+ *
+ * @return The media session token, must not be null.
+ */
+ public void setSessionToken(MediaSession.Token token) {
+ if (token == null) {
+ throw new IllegalStateException(this.getClass().getName()
+ + ".onCreateSession() set invalid MediaSession.Token");
+ }
+ mSession = token;
+ }
+
+ /**
+ * Gets the session token, or null if it has not yet been created
+ * or if it has been destroyed.
+ */
+ public @Nullable MediaSession.Token getSessionToken() {
+ return mSession;
+ }
+
+ /**
+ * Notifies all connected media browsers that the children of
+ * the specified Uri have changed in some way.
+ * This will cause browsers to fetch subscribed content again.
+ *
+ * @param parentUri The uri of the parent media item whose
+ * children changed.
+ */
+ public void notifyChildrenChanged(@NonNull Uri parentUri) {
+ if (parentUri == null) {
+ throw new IllegalArgumentException("parentUri cannot be null in notifyChildrenChanged");
+ }
+ for (IBinder binder : mConnections.keySet()) {
+ ConnectionRecord connection = mConnections.get(binder);
+ Set<Uri> uris = connection.subscriptions;
+ for (Uri uri : uris) {
+ if (uri.equals(parentUri)) {
+ performLoadChildren(uri, connection);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Return whether the given package is one of the ones that is owned by the uid.
+ */
+ private boolean isValidPackage(String pkg, int uid) {
+ if (pkg == null) {
+ return false;
+ }
+ final PackageManager pm = getPackageManager();
+ final String[] packages = pm.getPackagesForUid(uid);
+ final int N = packages.length;
+ for (int i=0; i<N; i++) {
+ if (packages[i].equals(pkg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Save the subscription and if it is a new subscription send the results.
+ */
+ private void addSubscription(Uri uri, ConnectionRecord connection) {
+ // Save the subscription
+ final boolean added = connection.subscriptions.add(uri);
+
+ // If this is a new subscription, send the results
+ if (added) {
+ performLoadChildren(uri, connection);
+ }
+ }
+
+ /**
+ * Call onLoadChildren and then send the results back to the connection.
+ * <p>
+ * Callers must make sure that this connection is still connected.
+ * <p>
+ * TODO: Think about caching and combining these calls.
+ */
+ private void performLoadChildren(Uri uri, ConnectionRecord connection) {
+ final List<MediaBrowserItem> list = onLoadChildren(uri);
+ if (list == null) {
+ throw new IllegalStateException("onLoadChildren returned null for uri " + uri);
+ }
+ final ParceledListSlice<MediaBrowserItem> pls = new ParceledListSlice(list);
+ try {
+ connection.callbacks.onLoadChildren(uri, pls);
+ } catch (RemoteException ex) {
+ // The other side is in the process of crashing.
+ Log.w(TAG, "Calling onLoadChildren() failed for uri=" + uri
+ + " package=" + connection.pkg);
+ }
+ }
+
+ public static class BrowserRoot {
+ final private Uri mUri;
+ final private Bundle mExtras;
+ public BrowserRoot(@NonNull Uri uri, @Nullable Bundle extras) {
+ if (uri == null) {
+ throw new IllegalArgumentException("The root uri in BrowserRoot cannot be null. " +
+ "Use null for BrowserRoot instead.");
+ }
+ mUri = uri;
+ mExtras = extras;
+ }
+
+ Uri getRootUri() {
+ return mUri;
+ }
+
+ Bundle getExtras() {
+ return mExtras;
+ }
+ }
+}
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 78e0404..e98c5c8 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -340,85 +340,85 @@
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
/** A generic channel type. */
- public static final int TYPE_OTHER = 0x0;
+ public static final String TYPE_OTHER = "TYPE_OTHER";
/** The channel type for NTSC. */
- public static final int TYPE_NTSC = 0x1;
+ public static final String TYPE_NTSC = "TYPE_NTSC";
/** The channel type for PAL. */
- public static final int TYPE_PAL = 0x2;
+ public static final String TYPE_PAL = "TYPE_PAL";
/** The channel type for SECAM. */
- public static final int TYPE_SECAM = 0x3;
+ public static final String TYPE_SECAM = "TYPE_SECAM";
/** The channel type for DVB-T (terrestrial). */
- public static final int TYPE_DVB_T = 0x00010000;
+ public static final String TYPE_DVB_T = "TYPE_DVB_T";
/** The channel type for DVB-T2 (terrestrial). */
- public static final int TYPE_DVB_T2 = 0x00010001;
+ public static final String TYPE_DVB_T2 = "TYPE_DVB_T2";
/** The channel type for DVB-S (satellite). */
- public static final int TYPE_DVB_S = 0x00010100;
+ public static final String TYPE_DVB_S = "TYPE_DVB_S";
/** The channel type for DVB-S2 (satellite). */
- public static final int TYPE_DVB_S2 = 0x00010101;
+ public static final String TYPE_DVB_S2 = "TYPE_DVB_S2";
/** The channel type for DVB-C (cable). */
- public static final int TYPE_DVB_C = 0x00010200;
+ public static final String TYPE_DVB_C = "TYPE_DVB_C";
/** The channel type for DVB-C2 (cable). */
- public static final int TYPE_DVB_C2 = 0x00010201;
+ public static final String TYPE_DVB_C2 = "TYPE_DVB_C2";
/** The channel type for DVB-H (handheld). */
- public static final int TYPE_DVB_H = 0x00010300;
+ public static final String TYPE_DVB_H = "TYPE_DVB_H";
/** The channel type for DVB-SH (satellite). */
- public static final int TYPE_DVB_SH = 0x00010400;
+ public static final String TYPE_DVB_SH = "TYPE_DVB_SH";
/** The channel type for ATSC (terrestrial). */
- public static final int TYPE_ATSC_T = 0x00020000;
+ public static final String TYPE_ATSC_T = "TYPE_ATSC_T";
/** The channel type for ATSC (cable). */
- public static final int TYPE_ATSC_C = 0x00020200;
+ public static final String TYPE_ATSC_C = "TYPE_ATSC_C";
/** The channel type for ATSC-M/H (mobile/handheld). */
- public static final int TYPE_ATSC_M_H = 0x00020300;
+ public static final String TYPE_ATSC_M_H = "TYPE_ATSC_M_H";
/** The channel type for ISDB-T (terrestrial). */
- public static final int TYPE_ISDB_T = 0x00030000;
+ public static final String TYPE_ISDB_T = "TYPE_ISDB_T";
/** The channel type for ISDB-Tb (Brazil). */
- public static final int TYPE_ISDB_TB = 0x00030100;
+ public static final String TYPE_ISDB_TB = "TYPE_ISDB_TB";
/** The channel type for ISDB-S (satellite). */
- public static final int TYPE_ISDB_S = 0x00030200;
+ public static final String TYPE_ISDB_S = "TYPE_ISDB_S";
/** The channel type for ISDB-C (cable). */
- public static final int TYPE_ISDB_C = 0x00030300;
+ public static final String TYPE_ISDB_C = "TYPE_ISDB_C";
/** The channel type for 1seg (handheld). */
- public static final int TYPE_1SEG = 0x00030400;
+ public static final String TYPE_1SEG = "TYPE_1SEG";
/** The channel type for DTMB (terrestrial). */
- public static final int TYPE_DTMB = 0x00040000;
+ public static final String TYPE_DTMB = "TYPE_DTMB";
/** The channel type for CMMB (handheld). */
- public static final int TYPE_CMMB = 0x00040100;
+ public static final String TYPE_CMMB = "TYPE_CMMB";
/** The channel type for T-DMB (terrestrial). */
- public static final int TYPE_T_DMB = 0x00050000;
+ public static final String TYPE_T_DMB = "TYPE_T_DMB";
/** The channel type for S-DMB (satellite). */
- public static final int TYPE_S_DMB = 0x00050100;
+ public static final String TYPE_S_DMB = "TYPE_S_DMB";
/** A generic service type. */
- public static final int SERVICE_TYPE_OTHER = 0x0;
+ public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
/** The service type for regular TV channels that have both audio and video. */
- public static final int SERVICE_TYPE_AUDIO_VIDEO = 0x1;
+ public static final String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO";
/** The service type for radio channels that have audio only. */
- public static final int SERVICE_TYPE_AUDIO = 0x2;
+ public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
/** The video format for 240p. */
public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P";
@@ -521,7 +521,7 @@
* </p><p>
* This is a required field.
* </p><p>
- * Type: INTEGER
+ * Type: TEXT
* </p>
*/
public static final String COLUMN_TYPE = "type";
@@ -537,7 +537,7 @@
* </p><p>
* This is a required field.
* </p><p>
- * Type: INTEGER
+ * Type: TEXT
* </p>
*/
public static final String COLUMN_SERVICE_TYPE = "service_type";
@@ -809,12 +809,46 @@
/**
* The title of this TV program.
* <p>
+ * If this program is an episodic TV show, it is recommended that the title is the series
+ * title and its related fields ({@link #COLUMN_SEASON_NUMBER},
+ * {@link #COLUMN_EPISODE_NUMBER}, and {@link #COLUMN_EPISODE_TITLE}) are filled in.
+ * </p><p>
* Type: TEXT
* </p>
**/
public static final String COLUMN_TITLE = "title";
/**
+ * The season number of this TV program for episodic TV shows.
+ * <p>
+ * Can be empty.
+ * </p><p>
+ * Type: INTEGER
+ * </p>
+ **/
+ public static final String COLUMN_SEASON_NUMBER = "season_number";
+
+ /**
+ * The episode number of this TV program for episodic TV shows.
+ * <p>
+ * Can be empty.
+ * </p><p>
+ * Type: INTEGER
+ * </p>
+ **/
+ public static final String COLUMN_EPISODE_NUMBER = "episode_number";
+
+ /**
+ * The episode title of this TV program for episodic TV shows.
+ * <p>
+ * Can be empty.
+ * </p><p>
+ * Type: TEXT
+ * </p>
+ **/
+ public static final String COLUMN_EPISODE_TITLE = "episode_title";
+
+ /**
* The start time of this TV program, in milliseconds since the epoch.
* <p>
* Type: INTEGER (long)
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index 86fd4ff..331283e 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -33,6 +33,7 @@
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.SparseIntArray;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
@@ -47,60 +48,55 @@
private static final boolean DEBUG = false;
private static final String TAG = "TvInputInfo";
+ // Should be in sync with frameworks/base/core/res/res/values/attrs.xml
/**
- * TV input type: the TV input service is not handling input from hardware. For example,
- * services showing streaming from the internet falls into this type.
+ * TV input type: the TV input service is a tuner which provides channels.
*/
- public static final int TYPE_VIRTUAL = 0;
-
- // Should be in sync with TvInputHardwareInfo.
-
+ public static final int TYPE_TUNER = 0;
/**
* TV input type: a generic hardware TV input type.
*/
- public static final int TYPE_OTHER_HARDWARE = TvInputHardwareInfo.TV_INPUT_TYPE_OTHER_HARDWARE;
- /**
- * TV input type: the TV input service is a tuner. (e.g. terrestrial tuner)
- */
- public static final int TYPE_TUNER = TvInputHardwareInfo.TV_INPUT_TYPE_TUNER;
+ public static final int TYPE_OTHER = 1000;
/**
* TV input type: the TV input service represents a composite port.
*/
- public static final int TYPE_COMPOSITE = TvInputHardwareInfo.TV_INPUT_TYPE_COMPOSITE;
+ public static final int TYPE_COMPOSITE = 1001;
/**
* TV input type: the TV input service represents a SVIDEO port.
*/
- public static final int TYPE_SVIDEO = TvInputHardwareInfo.TV_INPUT_TYPE_SVIDEO;
+ public static final int TYPE_SVIDEO = 1002;
/**
* TV input type: the TV input service represents a SCART port.
*/
- public static final int TYPE_SCART = TvInputHardwareInfo.TV_INPUT_TYPE_SCART;
+ public static final int TYPE_SCART = 1003;
/**
* TV input type: the TV input service represents a component port.
*/
- public static final int TYPE_COMPONENT = TvInputHardwareInfo.TV_INPUT_TYPE_COMPONENT;
+ public static final int TYPE_COMPONENT = 1004;
/**
* TV input type: the TV input service represents a VGA port.
*/
- public static final int TYPE_VGA = TvInputHardwareInfo.TV_INPUT_TYPE_VGA;
+ public static final int TYPE_VGA = 1005;
/**
* TV input type: the TV input service represents a DVI port.
*/
- public static final int TYPE_DVI = TvInputHardwareInfo.TV_INPUT_TYPE_DVI;
+ public static final int TYPE_DVI = 1006;
/**
* TV input type: the TV input service is HDMI. (e.g. HDMI 1)
*/
- public static final int TYPE_HDMI = TvInputHardwareInfo.TV_INPUT_TYPE_HDMI;
+ public static final int TYPE_HDMI = 1007;
/**
* TV input type: the TV input service represents a display port.
*/
- public static final int TYPE_DISPLAY_PORT = TvInputHardwareInfo.TV_INPUT_TYPE_DISPLAY_PORT;
+ public static final int TYPE_DISPLAY_PORT = 1008;
/**
* The ID of the TV input to provide to the setup activity and settings activity.
*/
public static final String EXTRA_INPUT_ID = "inputId";
+ private static SparseIntArray sHardwareTypeToTvInputType = new SparseIntArray();
+
private static final String XML_START_TAG_NAME = "tv-input";
private final ResolveInfo mService;
@@ -110,7 +106,22 @@
// Attributes from XML meta data.
private String mSetupActivity;
private String mSettingsActivity;
- private int mType = TYPE_VIRTUAL;
+ private int mType = TYPE_TUNER;
+
+ static {
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_OTHER_HARDWARE,
+ TYPE_OTHER);
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_TUNER, TYPE_TUNER);
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_COMPOSITE, TYPE_COMPOSITE);
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_SVIDEO, TYPE_SVIDEO);
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_SCART, TYPE_SCART);
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_COMPONENT, TYPE_COMPONENT);
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_VGA, TYPE_VGA);
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_DVI, TYPE_DVI);
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_HDMI, TYPE_HDMI);
+ sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_DISPLAY_PORT,
+ TYPE_DISPLAY_PORT);
+ }
/**
* Create a new instance of the TvInputInfo class,
@@ -123,7 +134,7 @@
throws XmlPullParserException, IOException {
return createTvInputInfo(context, service, generateInputIdForComponentName(
new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name)),
- null);
+ null, TYPE_TUNER);
}
/**
@@ -138,7 +149,7 @@
HdmiCecDeviceInfo cecInfo, String parentId) throws XmlPullParserException, IOException {
return createTvInputInfo(context, service, generateInputIdForHdmiCec(
new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name),
- cecInfo), parentId);
+ cecInfo), parentId, TYPE_HDMI);
}
/**
@@ -151,13 +162,14 @@
*/
public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
TvInputHardwareInfo hardwareInfo) throws XmlPullParserException, IOException {
+ int inputType = sHardwareTypeToTvInputType.get(hardwareInfo.getType(), TYPE_TUNER);
return createTvInputInfo(context, service, generateInputIdForHardware(
new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name),
- hardwareInfo), null);
+ hardwareInfo), null, inputType);
}
private static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
- String id, String parentId) throws XmlPullParserException, IOException {
+ String id, String parentId, int inputType) throws XmlPullParserException, IOException {
ServiceInfo si = service.serviceInfo;
PackageManager pm = context.getPackageManager();
XmlResourceParser parser = null;
@@ -182,7 +194,7 @@
"Meta-data does not start with tv-input-service tag in " + si.name);
}
- TvInputInfo input = new TvInputInfo(service, id, parentId);
+ TvInputInfo input = new TvInputInfo(service, id, parentId, inputType);
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.TvInputService);
input.mSetupActivity = sa.getString(
@@ -196,14 +208,6 @@
Log.d(TAG, "Settings activity loaded. [" + input.mSettingsActivity + "] for "
+ si.name);
}
- if (pm.checkPermission(android.Manifest.permission.TV_INPUT_HARDWARE, si.packageName)
- == PackageManager.PERMISSION_GRANTED) {
- input.mType = sa.getInt(
- com.android.internal.R.styleable.TvInputService_tvInputType, TYPE_VIRTUAL);
- if (DEBUG) {
- Log.d(TAG, "Type loaded. [" + input.mType + "] for " + si.name);
- }
- }
sa.recycle();
return input;
@@ -222,11 +226,13 @@
* @param service The ResolveInfo returned from the package manager about this TV input service.
* @param id ID of this TV input. Should be generated via generateInputId*().
* @param parentId ID of this TV input's parent input. {@code null} if none exists.
+ * @param type The type of this TV input service.
*/
- private TvInputInfo(ResolveInfo service, String id, String parentId) {
+ private TvInputInfo(ResolveInfo service, String id, String parentId, int type) {
mService = service;
mId = id;
mParentId = parentId;
+ mType = type;
}
/**
@@ -314,12 +320,7 @@
* @see TvContract#buildChannelUriForPassthroughTvInput(String)
*/
public boolean isPassthroughInputType() {
- if (mType == TYPE_HDMI || mType == TYPE_DISPLAY_PORT || mType == TYPE_SCART
- || mType == TYPE_DVI || mType == TYPE_VGA || mType == TYPE_COMPONENT
- || mType == TYPE_COMPOSITE || mType == TYPE_SVIDEO) {
- return true;
- }
- return false;
+ return mType != TYPE_TUNER;
}
/**
diff --git a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
index bda3b6b..89b2893 100644
--- a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
+++ b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
@@ -32,10 +32,17 @@
jmethodID mPostEvent;
jclass mSoundPoolClass;
} fields;
-
static inline SoundPool* MusterSoundPool(JNIEnv *env, jobject thiz) {
return (SoundPool*)env->GetLongField(thiz, fields.mNativeContext);
}
+static const char* const kAudioAttributesClassPathName = "android/media/AudioAttributes";
+struct audio_attributes_fields_t {
+ jfieldID fieldUsage; // AudioAttributes.mUsage
+ jfieldID fieldContentType; // AudioAttributes.mContentType
+ jfieldID fieldFlags; // AudioAttributes.mFlags
+ jfieldID fieldFormattedTags;// AudioAttributes.mFormattedTags
+};
+static audio_attributes_fields_t javaAudioAttrFields;
// ----------------------------------------------------------------------------
static jint
@@ -176,10 +183,30 @@
}
static jint
-android_media_SoundPool_SoundPoolImpl_native_setup(JNIEnv *env, jobject thiz, jobject weakRef, jint maxChannels, jint streamType, jint srcQuality)
+android_media_SoundPool_SoundPoolImpl_native_setup(JNIEnv *env, jobject thiz, jobject weakRef,
+ jint maxChannels, jobject jaa)
{
+ if (jaa == 0) {
+ ALOGE("Error creating SoundPool: invalid audio attributes");
+ return -1;
+ }
+
+ audio_attributes_t *paa = NULL;
+ // read the AudioAttributes values
+ paa = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
+ const jstring jtags =
+ (jstring) env->GetObjectField(jaa, javaAudioAttrFields.fieldFormattedTags);
+ const char* tags = env->GetStringUTFChars(jtags, NULL);
+ // copying array size -1, char array for tags was calloc'd, no need to NULL-terminate it
+ strncpy(paa->tags, tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
+ env->ReleaseStringUTFChars(jtags, tags);
+ paa->usage = (audio_usage_t) env->GetIntField(jaa, javaAudioAttrFields.fieldUsage);
+ paa->content_type =
+ (audio_content_type_t) env->GetIntField(jaa, javaAudioAttrFields.fieldContentType);
+ paa->flags = env->GetIntField(jaa, javaAudioAttrFields.fieldFlags);
+
ALOGV("android_media_SoundPool_SoundPoolImpl_native_setup");
- SoundPool *ap = new SoundPool(maxChannels, (audio_stream_type_t) streamType, srcQuality);
+ SoundPool *ap = new SoundPool(maxChannels, paa);
if (ap == NULL) {
return -1;
}
@@ -190,6 +217,10 @@
// set callback with weak reference
jobject globalWeakRef = env->NewGlobalRef(weakRef);
ap->setCallback(android_media_callback, globalWeakRef);
+
+ // audio attributes were copied in SoundPool creation
+ free(paa);
+
return 0;
}
@@ -270,7 +301,7 @@
(void *)android_media_SoundPool_SoundPoolImpl_setRate
},
{ "native_setup",
- "(Ljava/lang/Object;III)I",
+ "(Ljava/lang/Object;ILjava/lang/Object;)I",
(void*)android_media_SoundPool_SoundPoolImpl_native_setup
},
{ "release",
@@ -289,27 +320,27 @@
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("ERROR: GetEnv failed\n");
- goto bail;
+ return result;
}
assert(env != NULL);
clazz = env->FindClass(kClassPathName);
if (clazz == NULL) {
ALOGE("Can't find %s", kClassPathName);
- goto bail;
+ return result;
}
fields.mNativeContext = env->GetFieldID(clazz, "mNativeContext", "J");
if (fields.mNativeContext == NULL) {
ALOGE("Can't find SoundPoolImpl.mNativeContext");
- goto bail;
+ return result;
}
fields.mPostEvent = env->GetStaticMethodID(clazz, "postEventFromNative",
"(Ljava/lang/Object;IIILjava/lang/Object;)V");
if (fields.mPostEvent == NULL) {
ALOGE("Can't find android/media/SoundPoolImpl.postEventFromNative");
- goto bail;
+ return result;
}
// create a reference to class. Technically, we're leaking this reference
@@ -317,11 +348,29 @@
fields.mSoundPoolClass = (jclass) env->NewGlobalRef(clazz);
if (AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)) < 0)
- goto bail;
+ return result;
+
+ // Get the AudioAttributes class and fields
+ jclass audioAttrClass = env->FindClass(kAudioAttributesClassPathName);
+ if (audioAttrClass == NULL) {
+ ALOGE("Can't find %s", kAudioAttributesClassPathName);
+ return result;
+ }
+ jclass audioAttributesClassRef = (jclass)env->NewGlobalRef(audioAttrClass);
+ javaAudioAttrFields.fieldUsage = env->GetFieldID(audioAttributesClassRef, "mUsage", "I");
+ javaAudioAttrFields.fieldContentType
+ = env->GetFieldID(audioAttributesClassRef, "mContentType", "I");
+ javaAudioAttrFields.fieldFlags = env->GetFieldID(audioAttributesClassRef, "mFlags", "I");
+ javaAudioAttrFields.fieldFormattedTags =
+ env->GetFieldID(audioAttributesClassRef, "mFormattedTags", "Ljava/lang/String;");
+ env->DeleteGlobalRef(audioAttributesClassRef);
+ if (javaAudioAttrFields.fieldUsage == NULL || javaAudioAttrFields.fieldContentType == NULL
+ || javaAudioAttrFields.fieldFlags == NULL
+ || javaAudioAttrFields.fieldFormattedTags == NULL) {
+ ALOGE("Can't initialize AudioAttributes fields");
+ return result;
+ }
/* success -- return valid version number */
- result = JNI_VERSION_1_4;
-
-bail:
- return result;
+ return JNI_VERSION_1_4;
}
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
index a3a1f8c..3fbd4d8 100644
--- a/packages/PrintSpooler/Android.mk
+++ b/packages/PrintSpooler/Android.mk
@@ -22,8 +22,6 @@
LOCAL_PACKAGE_NAME := PrintSpooler
-LOCAL_JAVA_LIBRARIES := framework-base
-
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 android-support-v7-recyclerview
include $(BUILD_PACKAGE)
diff --git a/packages/PrintSpooler/res/values-cs/strings.xml b/packages/PrintSpooler/res/values-cs/strings.xml
index aee5adc..1b84568 100644
--- a/packages/PrintSpooler/res/values-cs/strings.xml
+++ b/packages/PrintSpooler/res/values-cs/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Velikost papíru:"</string>
<string name="label_color" msgid="1108690305218188969">"Barva"</string>
<string name="label_orientation" msgid="2853142581990496477">"Orientace"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Stránky"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Vše: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Rozsah: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"např. 1–5, 8, 11–13"</string>
<string name="print_preview" msgid="8010217796057763343">"Náhled tisku"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Nainstalovat prohlížeč PDF (umožní náhled)"</string>
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index 7212319..9b72da1 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Taille du papier :"</string>
<string name="label_color" msgid="1108690305218188969">"Couleur"</string>
<string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Pages"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Toutes (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Plage de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string>
<string name="print_preview" msgid="8010217796057763343">"Aperçu avant impression"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Installer un lecteur PDF pour voir l\'aperçu"</string>
diff --git a/packages/PrintSpooler/res/values-hr/strings.xml b/packages/PrintSpooler/res/values-hr/strings.xml
index 58f761d..3b82f85 100644
--- a/packages/PrintSpooler/res/values-hr/strings.xml
+++ b/packages/PrintSpooler/res/values-hr/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Veličina papira:"</string>
<string name="label_color" msgid="1108690305218188969">"U boji"</string>
<string name="label_orientation" msgid="2853142581990496477">"Orijentacija"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Stranice"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Sve stranice (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Raspon od <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"npr. 1 – 5,8,11 – 13"</string>
<string name="print_preview" msgid="8010217796057763343">"Pregled ispisa"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Instaliraj PDF preglednik za pregled"</string>
diff --git a/packages/PrintSpooler/res/values-hy-rAM/strings.xml b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
index a688d35..f77a7e8 100644
--- a/packages/PrintSpooler/res/values-hy-rAM/strings.xml
+++ b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Թղթի չափը՝"</string>
<string name="label_color" msgid="1108690305218188969">"Գույնը"</string>
<string name="label_orientation" msgid="2853142581990496477">"Դիրքավորում"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Էջեր"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Բոլորը՝ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Միջակայքը՝ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"օր.՝ 1-5, 8, 11-13"</string>
<string name="print_preview" msgid="8010217796057763343">"Տպելու նախադիտում"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Նախադիտման համար տեղադրեք PDF դիտարկիչ"</string>
diff --git a/packages/PrintSpooler/res/values-ka-rGE/strings.xml b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
index a6200fa..d885765 100644
--- a/packages/PrintSpooler/res/values-ka-rGE/strings.xml
+++ b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"ფურცლის ზომა:"</string>
<string name="label_color" msgid="1108690305218188969">"ფერი"</string>
<string name="label_orientation" msgid="2853142581990496477">"ორიენტაცია"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"გვერდები"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"ყველა <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>-ის არეალი"</string>
<string name="pages_range_example" msgid="8558694453556945172">"მაგ. 1–5, 8, 11–13"</string>
<string name="print_preview" msgid="8010217796057763343">"ნახვა ამობეჭდვამდე"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"გადახედვისთვის დააყენეთ PDF მნახველი"</string>
diff --git a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
index 0ab170e..8c6a34fd 100644
--- a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
+++ b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Қағаз өлшемі:"</string>
<string name="label_color" msgid="1108690305218188969">"Түс"</string>
<string name="label_orientation" msgid="2853142581990496477">"Бағыты"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Беттер"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Барлық <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ауқымы"</string>
<string name="pages_range_example" msgid="8558694453556945172">"мысалы, 1—5,8,11—13"</string>
<string name="print_preview" msgid="8010217796057763343">"Алдын ала көру"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Алдын ала көру мүмкін болу үшін PDF шолушыны орнатыңыз"</string>
diff --git a/packages/PrintSpooler/res/values-ky-rKG/strings.xml b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
index c14b47f..f60f994 100644
--- a/packages/PrintSpooler/res/values-ky-rKG/strings.xml
+++ b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Барактын өлчөмү:"</string>
<string name="label_color" msgid="1108690305218188969">"Түс"</string>
<string name="label_orientation" msgid="2853142581990496477">"Багыттоо"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Баракчалар"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Бардыгы <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> аралыгы"</string>
<string name="pages_range_example" msgid="8558694453556945172">"мис. 1—5,8,11—13"</string>
<string name="print_preview" msgid="8010217796057763343">"Алдын ала көрүү"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Алдын ала көрүү үчүн PDF-серепчи орнотуңуз"</string>
diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
index 5ee274f..f327334 100644
--- a/packages/PrintSpooler/res/values-ms-rMY/strings.xml
+++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Saiz kertas:"</string>
<string name="label_color" msgid="1108690305218188969">"Warna"</string>
<string name="label_orientation" msgid="2853142581990496477">"Orientasi"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Halaman"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Semua <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Julat <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"cth. 1—5,8,11—13"</string>
<string name="print_preview" msgid="8010217796057763343">"Pratonton cetak"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Pasang pemapar PDF untuk pratonton"</string>
diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml
index 3a8a231..6abc571 100644
--- a/packages/PrintSpooler/res/values-ru/strings.xml
+++ b/packages/PrintSpooler/res/values-ru/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Размер бумаги:"</string>
<string name="label_color" msgid="1108690305218188969">"Печать"</string>
<string name="label_orientation" msgid="2853142581990496477">"Ориентация"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Страницы"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Все <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Диапазон <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"напр., 1–5, 8, 11–13"</string>
<string name="print_preview" msgid="8010217796057763343">"Предварительный просмотр"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Установить средство просмотра PDF"</string>
diff --git a/packages/PrintSpooler/res/values-si-rLK/strings.xml b/packages/PrintSpooler/res/values-si-rLK/strings.xml
index 6963050..f6cc5e2 100644
--- a/packages/PrintSpooler/res/values-si-rLK/strings.xml
+++ b/packages/PrintSpooler/res/values-si-rLK/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"කඩදාසියේ ප්රමාණය:"</string>
<string name="label_color" msgid="1108690305218188969">"වර්ණය"</string>
<string name="label_orientation" msgid="2853142581990496477">"දිශානතිය"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"පිටු"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"සියලුම <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> පරාසය"</string>
<string name="pages_range_example" msgid="8558694453556945172">"උ.දා. 1—5,8,11—13"</string>
<string name="print_preview" msgid="8010217796057763343">"මුද්රණ පෙරදසුන"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"පෙරදසුන සඳහා PDF දක්වනය ස්ථාපනය කරන්න"</string>
diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml
index 47b4f06..439aae4 100644
--- a/packages/PrintSpooler/res/values-sk/strings.xml
+++ b/packages/PrintSpooler/res/values-sk/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Veľkosť papiera:"</string>
<string name="label_color" msgid="1108690305218188969">"Farba"</string>
<string name="label_orientation" msgid="2853142581990496477">"Orientácia"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Strany"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Všetky: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Rozsah: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"napr. 1–5, 8, 11–13"</string>
<string name="print_preview" msgid="8010217796057763343">"Ukážka pred tlačou"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Inštalovať zobrazovač PDF na zobrazenie ukážky"</string>
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
index 7de3adf..de0dfac 100644
--- a/packages/PrintSpooler/res/values-sr/strings.xml
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Величина папира:"</string>
<string name="label_color" msgid="1108690305218188969">"Боја"</string>
<string name="label_orientation" msgid="2853142581990496477">"Положај"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Странице"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Све странице (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Опсег од <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"нпр. 1–5, 8, 11–13"</string>
<string name="print_preview" msgid="8010217796057763343">"Преглед пре штампања"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Инсталирај PDF приказивач за преглед"</string>
diff --git a/packages/PrintSpooler/res/values-th/strings.xml b/packages/PrintSpooler/res/values-th/strings.xml
index 921bfca..d1d45fe 100644
--- a/packages/PrintSpooler/res/values-th/strings.xml
+++ b/packages/PrintSpooler/res/values-th/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"ขนาดของกระดาษ:"</string>
<string name="label_color" msgid="1108690305218188969">"สี"</string>
<string name="label_orientation" msgid="2853142581990496477">"การวางแนว"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"หน้า"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"ทั้ง <xliff:g id="PAGE_COUNT">%1$s</xliff:g> หน้า"</string>
+ <string name="template_page_range" msgid="428638530038286328">"ช่วง <xliff:g id="PAGE_COUNT">%1$s</xliff:g> หน้า"</string>
<string name="pages_range_example" msgid="8558694453556945172">"เช่น 1—5,8,11—13"</string>
<string name="print_preview" msgid="8010217796057763343">"ตัวอย่างก่อนพิมพ์"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"ติดตั้งโปรแกรมดู PDF เพื่อดูหน้าตัวอย่าง"</string>
diff --git a/packages/PrintSpooler/res/values-tl/strings.xml b/packages/PrintSpooler/res/values-tl/strings.xml
index d94627e..70365e7 100644
--- a/packages/PrintSpooler/res/values-tl/strings.xml
+++ b/packages/PrintSpooler/res/values-tl/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Laki ng papel:"</string>
<string name="label_color" msgid="1108690305218188969">"Kulay"</string>
<string name="label_orientation" msgid="2853142581990496477">"Oryentasyon"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Mga Page"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Lahat ng <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Hanay ng <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
<string name="pages_range_example" msgid="8558694453556945172">"hal. 1—5,8,11—13"</string>
<string name="print_preview" msgid="8010217796057763343">"Preview sa pag-print"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Mag-install ng PDF viewer para sa pag-preview"</string>
diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml
index fab011e..ea803f65 100644
--- a/packages/PrintSpooler/res/values-tr/strings.xml
+++ b/packages/PrintSpooler/res/values-tr/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Kağıt boyutu:"</string>
<string name="label_color" msgid="1108690305218188969">"Renkli"</string>
<string name="label_orientation" msgid="2853142581990496477">"Sayfa yönü"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Sayfa"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> sayfanın tamamı"</string>
+ <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> sayfalık aralık"</string>
<string name="pages_range_example" msgid="8558694453556945172">"ör. 1-5,8,11-13"</string>
<string name="print_preview" msgid="8010217796057763343">"Yazdırmayı önizle"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Önizlemek için PDF görüntüleyici yükleyin"</string>
diff --git a/packages/PrintSpooler/res/values-ur-rPK/strings.xml b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
index 2471d8b..1ff57a7 100644
--- a/packages/PrintSpooler/res/values-ur-rPK/strings.xml
+++ b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"کاغذ کا سائز:"</string>
<string name="label_color" msgid="1108690305218188969">"رنگ"</string>
<string name="label_orientation" msgid="2853142581990496477">"سمت بندی"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"صفحات"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"سبھی <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> کی رینج"</string>
<string name="pages_range_example" msgid="8558694453556945172">"مثلاً 1—5,8,11—13"</string>
<string name="print_preview" msgid="8010217796057763343">"پرنٹ کا پیش منظر"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"پیش منظر کیلئے PDF ناظر انسٹال کریں"</string>
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index 71787f3..8ab3410 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"Qog‘oz o‘lchami:"</string>
<string name="label_color" msgid="1108690305218188969">"Rang"</string>
<string name="label_orientation" msgid="2853142581990496477">"Joylashuv"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"Sahifalar"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Barchasi (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+ <string name="template_page_range" msgid="428638530038286328">"O‘zgarish chegarasi (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
<string name="pages_range_example" msgid="8558694453556945172">"masalan: 1—5,8,11—13"</string>
<string name="print_preview" msgid="8010217796057763343">"Chop qilishni oldindan ko‘rish"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"PDF ko‘rsatuvchi dasturni o‘rnatish"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
index 3cf1173..cf452c9 100644
--- a/packages/PrintSpooler/res/values-zh-rTW/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
@@ -25,12 +25,9 @@
<string name="label_paper_size_summary" msgid="5668204981332138168">"紙張大小:"</string>
<string name="label_color" msgid="1108690305218188969">"色彩"</string>
<string name="label_orientation" msgid="2853142581990496477">"方向"</string>
- <!-- no translation found for label_pages (7768589729282182230) -->
- <skip />
- <!-- no translation found for template_all_pages (3322235982020148762) -->
- <skip />
- <!-- no translation found for template_page_range (428638530038286328) -->
- <skip />
+ <string name="label_pages" msgid="7768589729282182230">"頁面"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"全部 <xliff:g id="PAGE_COUNT">%1$s</xliff:g> 頁"</string>
+ <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> 頁"</string>
<string name="pages_range_example" msgid="8558694453556945172">"例如:1—5,8,11—13"</string>
<string name="print_preview" msgid="8010217796057763343">"列印預覽"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"安裝預覽所需的 PDF 檢視器"</string>
diff --git a/packages/Shell/res/values-tl/strings.xml b/packages/Shell/res/values-tl/strings.xml
index c5f18975..8d42ecd 100644
--- a/packages/Shell/res/values-tl/strings.xml
+++ b/packages/Shell/res/values-tl/strings.xml
@@ -18,8 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3701846017049540910">"Shell"</string>
<string name="bugreport_finished_title" msgid="2293711546892863898">"Na-capture ang ulat ng bug"</string>
- <!-- no translation found for bugreport_finished_text (8389172248433597683) -->
- <skip />
+ <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Mag-swipe pakaliwa upang ibahagi ang iyong ulat ng bug"</string>
<string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Pindutin upang ibahagi ang iyong ulat ng bug"</string>
<string name="bugreport_confirm" msgid="5130698467795669780">"Naglalaman ang mga ulat ng bug ng data mula sa iba\'t ibang file ng log ng system, kabilang ang personal at pribadong impormasyon. Magbahagi lang ng mga ulat ng bug sa apps at mga tao na pinagkakatiwalaan mo."</string>
<string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ipakita ang mensaheng ito sa susunod"</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index a038899..686f865 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -74,6 +74,7 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" />
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
+ <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" />
<!-- WindowManager -->
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
@@ -154,6 +155,13 @@
</intent-filter>
</receiver>
+ <receiver android:name=".qs.tiles.HotspotTile$APChangedReceiver"
+ androidprv:primaryUserOnly="true">
+ <intent-filter>
+ <action android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
+ </intent-filter>
+ </receiver>
+
<activity android:name=".usb.UsbStorageActivity"
android:label="@*android:string/usb_storage_activity_title"
android:excludeFromRecents="true">
diff --git a/packages/SystemUI/res/drawable/ic_qs_hotspot_off.xml b/packages/SystemUI/res/drawable/ic_qs_hotspot_off.xml
index 7a62212..0a00d14 100644
--- a/packages/SystemUI/res/drawable/ic_qs_hotspot_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_hotspot_off.xml
@@ -15,16 +15,14 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" >
<size
- android:width="64dp"
- android:height="64dp"/>
+ android:width="64.0dp"
+ android:height="64.0dp"/>
<viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
<path
- android:fill="#00000000"
- android:stroke="#CCCCCC"
- android:strokeWidth="1.0"
- android:pathData="M12.0,11.0c-1.1,0.0 -2.0,0.9 -2.0,2.0c0.0,1.1 0.9,2.0 2.0,2.0c1.1,0.0 2.0,-0.9 2.0,-2.0C14.0,11.9 13.1,11.0 12.0,11.0zM18.0,13.0c0.0,-3.3 -2.7,-6.0 -6.0,-6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,2.2 1.2,4.1 3.0,5.2l1.0,-1.7c-1.2,-0.7 -2.0,-2.0 -2.0,-3.4c0.0,-2.2 1.8,-4.0 4.0,-4.0s4.0,1.8 4.0,4.0c0.0,1.5 -0.8,2.8 -2.0,3.4l1.0,1.7C16.8,17.1 18.0,15.2 18.0,13.0zM12.0,3.0C6.5,3.0 2.0,7.5 2.0,13.0c0.0,3.7 2.0,6.9 5.0,8.6l1.0,-1.7c-2.4,-1.4 -4.0,-4.0 -4.0,-6.9c0.0,-4.4 3.6,-8.0 8.0,-8.0s8.0,3.6 8.0,8.0c0.0,3.0 -1.6,5.5 -4.0,6.9l1.0,1.7c3.0,-1.7 5.0,-5.0 5.0,-8.6C22.0,7.5 17.5,3.0 12.0,3.0z"/>
+ android:fill="#4DFFFFFF"
+ android:pathData="M35.099998,28.500000c0.600000,-1.400000 0.900000,-2.900000 0.900000,-4.500000c0.000000,-6.600000 -5.400000,-12.000000 -12.000000,-12.000000c-1.600000,0.000000 -3.100000,0.300000 -4.500000,0.900000l3.200000,3.200000c0.400000,-0.100000 0.800000,-0.100000 1.200000,-0.100000c4.400000,0.000000 8.000000,3.600000 8.000000,8.000000c0.000000,0.400000 0.000000,0.800000 -0.100000,1.300000L35.099998,28.500000zM24.000000,8.000000c8.800000,0.000000 16.000000,7.200000 16.000000,16.000000c0.000000,2.700000 -0.700000,5.200000 -1.900000,7.500000l2.900000,2.900000c1.900000,-3.000000 3.000000,-6.600000 3.000000,-10.400000c0.000000,-11.000000 -9.000000,-20.000000 -20.000000,-20.000000c-3.800000,0.000000 -7.400000,1.100000 -10.400000,2.900000l2.900000,2.900000C18.700001,8.700000 21.299999,8.000000 24.000000,8.000000zM6.500000,5.000000L4.000000,7.500000l4.200000,4.200000C5.600000,15.100000 4.000000,19.400000 4.000000,24.000000c0.000000,7.400000 4.000000,13.800000 10.000000,17.299999l2.000000,-3.500000c-4.800000,-2.800000 -8.000000,-7.900000 -8.000000,-13.800000c0.000000,-3.500000 1.100000,-6.800000 3.100000,-9.400000l2.900000,2.900000C12.700000,19.400000 12.000000,21.600000 12.000000,24.000000c0.000000,4.400000 2.400000,8.300000 6.000000,10.400000l2.000000,-3.500000c-2.400000,-1.400000 -4.000000,-3.900000 -4.000000,-6.900000c0.000000,-1.300000 0.300000,-2.500000 0.900000,-3.600000l3.200000,3.200000c0.000000,0.100000 0.000000,0.300000 0.000000,0.400000c0.000000,2.200000 1.800000,4.000000 4.000000,4.000000c0.100000,0.000000 0.300000,0.000000 0.400000,0.000000l0.000000,0.000000l0.000000,0.000000l15.000000,15.000000l2.500000,-2.500000L8.500000,7.000000L6.500000,5.000000z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_hotspot_on.xml b/packages/SystemUI/res/drawable/ic_qs_hotspot_on.xml
index 3ccdd81..01cb0ab 100644
--- a/packages/SystemUI/res/drawable/ic_qs_hotspot_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_hotspot_on.xml
@@ -15,14 +15,14 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" >
<size
- android:width="64dp"
- android:height="64dp"/>
+ android:width="64.0dp"
+ android:height="64.0dp"/>
<viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
<path
android:fill="#FFFFFFFF"
- android:pathData="M12.0,11.0c-1.1,0.0 -2.0,0.9 -2.0,2.0c0.0,1.1 0.9,2.0 2.0,2.0c1.1,0.0 2.0,-0.9 2.0,-2.0C14.0,11.9 13.1,11.0 12.0,11.0zM18.0,13.0c0.0,-3.3 -2.7,-6.0 -6.0,-6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,2.2 1.2,4.1 3.0,5.2l1.0,-1.7c-1.2,-0.7 -2.0,-2.0 -2.0,-3.4c0.0,-2.2 1.8,-4.0 4.0,-4.0s4.0,1.8 4.0,4.0c0.0,1.5 -0.8,2.8 -2.0,3.4l1.0,1.7C16.8,17.1 18.0,15.2 18.0,13.0zM12.0,3.0C6.5,3.0 2.0,7.5 2.0,13.0c0.0,3.7 2.0,6.9 5.0,8.6l1.0,-1.7c-2.4,-1.4 -4.0,-4.0 -4.0,-6.9c0.0,-4.4 3.6,-8.0 8.0,-8.0s8.0,3.6 8.0,8.0c0.0,3.0 -1.6,5.5 -4.0,6.9l1.0,1.7c3.0,-1.7 5.0,-5.0 5.0,-8.6C22.0,7.5 17.5,3.0 12.0,3.0z"/>
+ android:pathData="M24.000000,22.000000c-2.200000,0.000000 -4.000000,1.800000 -4.000000,4.000000c0.000000,2.200000 1.800000,4.000000 4.000000,4.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000C28.000000,23.799999 26.200001,22.000000 24.000000,22.000000zM36.000000,26.000000c0.000000,-6.600000 -5.400000,-12.000000 -12.000000,-12.000000c-6.600000,0.000000 -12.000000,5.400000 -12.000000,12.000000c0.000000,4.400000 2.400000,8.300000 6.000000,10.400000l2.000000,-3.500000c-2.400000,-1.400000 -4.000000,-3.900000 -4.000000,-6.900000c0.000000,-4.400000 3.600000,-8.000000 8.000000,-8.000000s8.000000,3.600000 8.000000,8.000000c0.000000,3.000000 -1.600000,5.500000 -4.000000,6.900000l2.000000,3.500000C33.599998,34.299999 36.000000,30.400000 36.000000,26.000000zM24.000000,6.000000C13.000000,6.000000 4.000000,15.000000 4.000000,26.000000c0.000000,7.400000 4.000000,13.800000 10.000000,17.299999l2.000000,-3.500000c-4.800000,-2.800000 -8.000000,-7.900000 -8.000000,-13.800000c0.000000,-8.800000 7.200000,-16.000000 16.000000,-16.000000s16.000000,7.200000 16.000000,16.000000c0.000000,5.900000 -3.200000,11.100000 -8.000000,13.800000l2.000000,3.500000c6.000000,-3.500000 10.000000,-9.900000 10.000000,-17.299999C44.000000,15.000000 35.000000,6.000000 24.000000,6.000000z"/>
</vector>
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
index 3e4c1f6..85668de 100644
--- a/packages/SystemUI/res/layout/recents_task_view.xml
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -62,7 +62,7 @@
android:visibility="invisible"
android:src="@drawable/recents_dismiss_light" />
</com.android.systemui.recents.views.TaskBarView>
- <FrameLayout
+ <com.android.systemui.recents.views.TaskFooterView
android:id="@+id/lock_to_app"
android:layout_width="match_parent"
android:layout_height="@dimen/recents_task_view_lock_to_app_button_height"
@@ -82,7 +82,7 @@
android:fontFamily="sans-serif-medium"
android:singleLine="true"
android:textAllCaps="true" />
- </FrameLayout>
+ </com.android.systemui.recents.views.TaskFooterView>
</com.android.systemui.recents.views.TaskView>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index e75946a..91a1a06 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"إغلاق اللوحة"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"وقت أكثر"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"وقت أقل"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2-3 غيغابايت من البيانات المعطلة"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4 غيغابايت من البيانات المعطلة"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"البيانات الخلوية معطلة"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"البيانات معطلة"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"عطل جهازك البيانات نظرًا لبلوغها الحد الذي تم تعيينه.\n\nعلمًا بأن إعادتها قد يؤدي إلى تحمل رسوم من قبل مشغّل شبكة الجوّال."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"تشغيل البيانات"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"لا يوجد اتصال إنترنت"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi متصل"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"جارٍ البحث عن GPS"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"بحث"</string>
<string name="description_direction_up" msgid="7169032478259485180">"تمرير لأعلى لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"تمرير لليسار لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"بدون إزعاج، بما في ذلك المنبهات"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"بدون مقاطعات"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"المقاطعات ذات الأولوية فقط"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"التنبيه المقبل في <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"التنبيه المقبل في <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"لن تسمع المنبهات في <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"الإشعارات الأقل إلحاحًا أدناه"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"انقر مرة أخرى للفتح"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"فتح إعدادات وضع توفير الطاقة"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"المحتويات مخفية"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"الخروج من وضع الضيف"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> سيبدأ التقاط كل شيء يتم عرضه على الشاشة."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"عدم الإظهار مرة أخرى"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"البدء الآن"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 3412c2a..c50e0e9 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -168,18 +168,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Zavřít panel"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Delší doba"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Kratší doba"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"Data 2G a 3G jsou vypnuta"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"Data 4G jsou vypnuta"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Mobilní data jsou vypnuta"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Data jsou vypnuta"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Zařízení datové přenosy vypnulo, protože dosáhlo limitu, který jste nastavili.\n\nJejich opětovné zapnutí může vézt k účtování poplatků operátorem."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Zapnout data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Žádné přip. k internetu"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: připojeno"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Vyhledávání satelitů GPS"</string>
@@ -257,16 +251,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Žádná přerušení, ani budíky"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Žádná vyrušení"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Pouze prioritní vyrušení"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Další budík je nastaven na: <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Další budík: <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Neuslyšíte budík v <xliff:g id="ALARM_TIME">%s</xliff:g>."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Méně urgentní oznámení níže"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Oznámení otevřete opětovným klepnutím"</string>
@@ -293,12 +283,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otevřít nastavení režimu Úspora baterie"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Skrytý obsah"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Ukončit relaci hosta"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikace <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> začne zaznamenávat vše, co je zobrazeno na obrazovce."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Tuto zprávu příště nezobrazovat"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Spustit"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index dc62683..de11049 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -214,7 +214,7 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi slået fra"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"Der er ingen tilgængelige gemte netværk"</string>
<string name="quick_settings_cast_title" msgid="1893629685050355115">"Cast skærm"</string>
- <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
+ <string name="quick_settings_casting" msgid="6601710681033353316">"Caster"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Enhed uden navn"</string>
<string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Klar til at caste"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Der er ingen tilgængelige enheder"</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 80fb802..10fdd06 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Sule paneel"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Rohkem aega"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Vähem aega"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G–3G andmeside on väljalülitatud"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G andmeside on väljalülitatud"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Mob. andmeside väljalülitatud"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Andmeside on väljalülitatud"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Seade lülitas andmeside välja, sest teie määratud limiit on täis.\n\nKui lülitate andmeside uuesti sisse, siis võivad lisanduda operaatori tasud."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Lülita andmeside sisse"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Interneti-ühendus puudub"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WiFi on ühendatud"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS-i otsimine"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Lohistage vasakule: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Ei mingeid katkestusi, k.a äratus"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Mitte ühtegi katkestust"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Ainult prioriteetsed katkestused"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Teie järgmine äratus on <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Teie järgmine äratus on <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Te ei kuule äratust <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Vähem kiireloomulised märguanded on allpool"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Avamiseks puudutage uuesti"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Ava akusäästja seaded"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Sisu on peidetud"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Välju külastaja režiimist"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> hakkab jäädvustama kõike, mida ekraanil kuvatakse."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Ära kuva uuesti"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Alusta kohe"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 214253a..c864170 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"بستن پانل"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"زمان بیشتر"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"زمان کمتر"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"داده 2G-3G خاموش است"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"داده 4G خاموش است"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"داده شبکه سلولی خاموش است"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"داده خاموش است"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"دستگاه شما خاموش شد زیرا به حد تنظیم شده توسط شما رسید.\n\nروشن کردن مجدد آن میتواند به هزینههایی از طرف شرکت مخابراتی شما منجر شود."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"روشن کردن داده"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"اتصال اینترنتی وجود ندارد"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi متصل شد"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"جستجو برای GPS"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"جستجو"</string>
<string name="description_direction_up" msgid="7169032478259485180">"لغزاندن به بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"لغزاندن به چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"بدون قطع شدن، شامل هشدارها"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"بدون وقفه"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"فقط وقفههای اولویتدار"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"هشدار بعدی شما در ساعت <xliff:g id="ALARM_TIME">%s</xliff:g> است"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"هشدار بعدی شما <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g> است"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"هشدارتان را در ساعت <xliff:g id="ALARM_TIME">%s</xliff:g> نخواهید شنید"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"اعلانهای کمتر فوری در زیر"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"برای باز کردن دوباره ضربه بزنید"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"باز کردن تنظیمات ذخیره کننده باتری"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>٪٪"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"محتواها پنهان هستند"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"خروج مهمان"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> شروع به ضبط هر چیزی میکند که در صفحهنمایش شما نمایش داده میشود."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"دوباره نشان داده نشود"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"اکنون شروع شود"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 0de52c5..e1d4661 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Sulje paneeli"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Lisää aikaa"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Vähennä aikaa"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G–3G-tiedonsiirto ei ole käytössä"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G-tiedonsiirto ei ole käytössä"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Mobiilitiedonsiirto ei ole käytössä"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Tiedonsiirto ei ole käytössä"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Laitteesi poisti tiedonsiirron käytöstä, koska se saavutti asettamasi rajan.\n\nOperaattorisi saattaa veloittaa sinulta lisämaksuja, jos otat sen uudelleen käyttöön."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Ota tiedonsiirto käyttöön"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ei internetyhteyttä"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi yhdistetty"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Haetaan GPS-yhteyttä"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Haku"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Liu\'uta ylös ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Liu\'uta vasemmalle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Ei keskeytyksiä tai hälytyksiä"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Ei häiriöitä"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Vain tärkeät häiriöt"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Seuraava hälytysaika on <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Seuraava hälytysaika on <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Et kuule hälytystä klo <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Vähemmän kiireelliset ilmoitukset ovat alla"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Avaa napauttamalla uudelleen"</string>
@@ -293,12 +283,8 @@
<!-- no translation found for battery_level_template (1609636980292580020) -->
<skip />
<string name="notification_hidden_text" msgid="1135169301897151909">"Sisältö piilotettu"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Kirjaa vieras ulos"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> alkaa tallentaa kaiken näytölläsi näkyvän."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Älä näytä uudelleen"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Aloita nyt"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index da0f6dd..1d586e1 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Zatvori ploču"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Više vremena"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Manje vremena"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G-3G podaci isključeni"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G podaci isključeni"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Mobilni podaci isključeni"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Podaci su isključeni"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Uređaj je isključio podatke jer je dosegnuo ograničenje koje ste postavili.\n\nAko ih ponovno uključite, mogući su dodatni troškovi za mobilne usluge."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Uključi podatke"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nema internetske veze"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi povezan"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Traženje GPS-a"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Kliznite prema gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Kliznite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Bez prekida, uključujući alarme"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Bez prekida"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Samo prioritetni prekidi"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Vaš sljedeći alarm bit će u <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Vaš sljedeći alarm bit će u <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Nećete čuti alarm u <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitne obavijesti pri dnu"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite opet za otvaranje"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otvaranje postavki štednje baterije"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Sadržaj je skriven"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Izlaz iz gostujućeg načina"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> počet će snimati sve što se prikazuje na zaslonu."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne prikazuj ponovo"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Započni sad"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index dbcc71d..8e39734 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Tutup panel"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Lebih lama"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Lebih cepat"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"Data 2G-3G nonaktif"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"Data 4G nonaktif"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Data seluler nonaktif"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Data nonaktif"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Perangkat Anda menonaktifkan data karena data mencapai batas yang Anda setel.\n\nMengaktifkan kembali data dapat membuat Anda terkena biaya dari operator."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Aktifkan data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Tidak ada sambungan internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi tersambung"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Menelusuri GPS"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Geser ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Geser ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Tanpa gangguan, termasuk alarm"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Tidak ada interupsi"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Hanya interupsi prioritas"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Alarm Anda berikutnya pukul <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Alarm Anda berikutnya hari <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Anda tidak akan mendengar alarm pukul <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Pemberitahuan kurang darurat di bawah"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Ketuk lagi untuk membuka"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Buka setelan penghemat baterai"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Konten tersembunyi"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Keluar dari tamu"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan mulai menangkap apa saja yang ditampilkan pada layar Anda."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Jangan tampilkan lagi"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Mulai sekarang"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 856eccf..90d648d 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -168,18 +168,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"パネルを閉じる"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"長くする"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"短くする"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G~3Gデータが無効になりました"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4Gデータが無効になりました"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"モバイルデータが無効になりました"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"データが無効になりました"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"設定された上限に達したため、端末のデータ接続が無効になりました。\n\n有効に戻すと、携帯通信会社から課金される可能性があります。"</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"データ接続を有効にする"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"インターネット未接続"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi接続済み"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPSで検索中"</string>
@@ -257,16 +251,12 @@
<string name="description_target_search" msgid="3091587249776033139">"検索します"</string>
<string name="description_direction_up" msgid="7169032478259485180">"上にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
<string name="description_direction_left" msgid="7207478719805562165">"左にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"サイレント(アラームなど)"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"サイレント"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"優先的な中断のみ"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"次のアラームは<xliff:g id="ALARM_TIME">%s</xliff:g>です"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"次のアラームは<xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>です"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"<xliff:g id="ALARM_TIME">%s</xliff:g>のアラームは鳴りません"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"緊急度の低い通知を下に表示"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"開くにはもう一度タップしてください"</string>
@@ -293,12 +283,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"バッテリーセーバーの設定を開く"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"コンテンツが非表示"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"ゲストを終了"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>で、画面に表示されているコンテンツのキャプチャを開始します。"</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"次回から表示しない"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"今すぐ開始"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index cccb7a8..b9f24ec 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -290,8 +290,7 @@
<string name="battery_saver_notification_text" msgid="7796554871101546872">"მოწყობილობის წარმადობა შემცირებულია."</string>
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ბატარეის დამზოგის პარამეტრების გახსნა"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
- <!-- no translation found for notification_hidden_text (1135169301897151909) -->
- <skip />
+ <string name="notification_hidden_text" msgid="1135169301897151909">"შიგთავსი დამალულია"</string>
<!-- no translation found for guest_exit_guest (1619100760451149682) -->
<skip />
<!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 90f66ae..6b2d46d 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"បិទបន្ទះ"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"ពេលច្រើនជាង"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"ពេលតិចជាង"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"ទិន្នន័យ 2G-3G បានបិទ"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"ទិន្នន័យ 4G បានបិទ"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"ទិន្នន័យចល័តបានបិទ"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"ទិន្នន័យបានបិទ"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"ឧបករណ៍របស់អ្នកបានបិទទិន្នន័យ ព្រោះវាបានដល់កម្រិតដែលអ្នកបានកំណត់។\n\nបើកវាឡើងវិញអាចគិតលុយពីក្រុមហ៊ុនបញ្ជូនរបស់អ្នក។"</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"បើកទិន្នន័យ"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"គ្មានការតភ្ជាប់អ៊ីនធឺណិត"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"បានភ្ជាប់វ៉ាយហ្វាយ"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"ស្វែងរក GPS"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
<string name="description_direction_up" msgid="7169032478259485180">"រុញឡើងលើដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
<string name="description_direction_left" msgid="7207478719805562165">"រុញទៅឆ្វេងដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"មិនមានការផ្អាក រួមទាំងការជូនដំណឹង"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"គ្មានការផ្អាក"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"តែការផ្អាកអាទិភាពប៉ុណ្ណោះ"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"ការជូនដំណឹងបន្ទាប់របស់អ្នកគឺនៅម៉ោង <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"ការជូនដំណឹងបន្ទាប់របស់អ្នកគឺនៅ <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"អ្នកនឹងមិនឮការជូនដំណឹងរបស់អ្នកនៅម៉ោង <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"ការជូនដំណឹងមិនសូវបន្ទាន់ខាងក្រោម"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"ប៉ះម្ដងទៀត ដើម្បីបើក"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"បើកការកំណត់កម្មវិធីសន្សំថ្ម"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"បានលាក់មាតិកា"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"ភ្ញៀវចាកចេញ"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> នឹងចាប់ផ្ដើមចាប់យកអ្វីៗគ្រប់យ៉ាងដែលបង្ហាញលើអេក្រង់របស់អ្នក។"</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"កុំបង្ហាញម្ដងទៀត"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"ចាប់ផ្ដើមឥឡូវ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index cd2c580..4e05e9c 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -168,18 +168,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"패널 닫기"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"시간 늘리기"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"시간 줄이기"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G-3G 데이터 사용 중지됨"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G 데이터 사용 중지됨"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"이동통신 데이터 사용 중지됨"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"데이터 사용 중지됨"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"기기가 설정 한도에 도달하여 데이터를 사용 중지했습니다.\n\n데이터를 다시 사용 설정하면 이동통신사로부터 대금이 청구될 수 있습니다."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"데이터 사용 설정"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"인터넷에 연결되지 않음"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi 연결됨"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS 검색 중"</string>
@@ -257,16 +251,12 @@
<string name="description_target_search" msgid="3091587249776033139">"검색"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"방해 금지(알람 포함)"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"모든 알림 차단"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"최우선 알림만 수신"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"다음 알람 시각: <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"다음 알람 일시: <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"<xliff:g id="ALARM_TIME">%s</xliff:g>에 알람을 들을 수 없습니다."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"아래에 덜 급한 알림 표시"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"다시 탭하여 열기"</string>
@@ -293,12 +283,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"배터리 세이버 설정 열기"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"숨겨진 콘텐츠"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"손님 모드 종료"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에서 화면에 표시된 모든 것을 캡처하기 시작합니다."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"다시 표시 안함"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"시작하기"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index f0ffafe..bdbcf64 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Uždaryti skydelį"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Daugiau laiko"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Mažiau laiko"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G–3G duomenys išjungti"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G duomenys išjungti"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Mobiliojo ryšio duomenys išjungti"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Duomenys išjungti"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Įrenginys išjungė duomenis, nes buvo pasiektas nustatytas limitas.\n\nVėl juos įjungus gali būti taikomi operatoriaus mokesčiai."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Įjungti duomenis"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nėra interneto ryš."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Prisij. prie „Wi-Fi“"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Ieškoma GPS"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Paieška"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Slyskite aukštyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Slyskite į kairę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Jokių pertraukčių, įskaitant signalus"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Jokių pertraukčių"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Tik prioritetinės pertrauktys"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Kito signalo laikas: <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Kito signalo laikas: <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"<xliff:g id="ALARM_TIME">%s</xliff:g> signalo negirdėsite"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mažiau skubūs pranešimai toliau"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Palieskite dar kartą, kad atidarytumėte"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Atidaryti akumuliatoriaus tausojimo priemonės nustatymus"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Turinys paslėptas"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Išeiti iš svečio režimo"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"„<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ pradės fiksuoti viską, kas rodoma jūsų ekrane."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Daugiau neberodyti"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Pradėti dabar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 6c5cfe4..cf3996a 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Aizvērt paneli"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Ilgāk"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Mazāks laiks"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G–3G dati ir atslēgti"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G dati ir atslēgti"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Mobilie dati ir atslēgti"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Dati ir atslēgti"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Jūsu ierīcē tika atslēgta datu lietošana, jo tika sasniegts jūsu noteiktais ierobežojums.\n\nJa atkal ieslēgsiet datu lietošanu, iespējams, jūsu mobilo sakaru operators iekasēs maksu."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Ieslēgt datus"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nav interneta sav."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Izv. sav. ar Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Notiek GPS meklēšana..."</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Meklēt"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Velciet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Velciet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Bez pārtraukumiem, tostarp bez signāliem"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Nepārtraukt"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Tikai prioritārie pārtraukumi"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Jūsu nākamā signāla laiks: <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Jūsu nākamā signāla datums un laiks: <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Jūs nedzirdēsiet iestatīto signālu: <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mazāk steidzami paziņojumi tiek rādīti tālāk"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Pieskarieties vēlreiz, lai atvērtu"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Atvērt akumulatora enerģijas taupīšanas režīma iestatījumus"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Saturs paslēpts"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Iziet no viesa režīma"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sāks uzņemt visu, kas tiks rādīts jūsu ekrānā."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Vairs nerādīt"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Sākt tūlīt"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index b8f6ce5..803e028 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -168,18 +168,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Затвори ја плочата"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Повеќе време"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Помалку време"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"Податоците 2G-3G се исклучени"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"Податоците 4G се исклучени"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Мобилните податоци се исклучени"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Податоците се исклучени"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Вашиот уред ги исклучи податоците затоа што го достигнаа лимитот што го поставивте.\n\nСо повторно вклучување, операторот може да ви наплати за тоа."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Вклучи податоци"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Нема интернет"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Поврзано на Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Се пребарува за ГПС"</string>
@@ -257,16 +251,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Пребарај"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Лизгај нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Лизгај налево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Без прекини, вклучувајќи аларми"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Без прекини"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Само приоритетни прекини"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Следниот аларм е во <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Следниот аларм е <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Нема да го слушнете алармот во <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Долу се помалку итни известувања"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Допрете повторно за да се отвори"</string>
@@ -293,12 +283,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Отвори ги поставките за штедачот на батерија"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Содржините се скриени"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Излези како гостин"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ќе започне да презема сѐ што се прикажува на вашиот екран."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Не покажувај повторно"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Започни сега"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 1e29567..543f0f9 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -290,8 +290,7 @@
<string name="battery_saver_notification_text" msgid="7796554871101546872">"Prestasi peranti dikurangkan."</string>
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Buka tetapan penjimat bateri"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
- <!-- no translation found for notification_hidden_text (1135169301897151909) -->
- <skip />
+ <string name="notification_hidden_text" msgid="1135169301897151909">"Kandungan tersembunyi"</string>
<!-- no translation found for guest_exit_guest (1619100760451149682) -->
<skip />
<!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 8d1347d..baefb81 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"प्यानल बन्द गर्नुहोस्"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"थप समय"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"कम समय"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G-3G डेटा बन्द छ"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G डेटा बन्द छ"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"सेलुलर डेटा बन्द छ"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"तथ्याङ्क बन्द छ"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"तपाईंले सेट गर्नु भएको सीमा पुगेको हुनाले तपाईंको उपकरणले डेटा बंद गर्यो।\n\n यसलाई फिर्ता गर्दा आफ्नो वाहक बाट शुल्क लिन सक्छ।"</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"डेटा खोल्नुहोस्"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"इन्टरनेट जडान छैन"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"वाइफाइ जडित"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPSको लागि खोजी गर्दै"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"खोज्नुहोस्"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि माथि धिसार्नुहोस्"</string>
<string name="description_direction_left" msgid="7207478719805562165">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि बायाँ।"</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"बिना रोकटोक, सचेतक सहित"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"कुनै रुकावटहरू छैन"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"प्राथमिकता रुकावटहरूमा मात्र"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"तपाईंको अर्को सचेतक <xliff:g id="ALARM_TIME">%s</xliff:g> मा छ"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"तपाईंको अर्को सचेतक <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g> हो"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"<xliff:g id="ALARM_TIME">%s</xliff:g> मा तपाईंले आफ्नो सचेतक सुन्नुहुने छैन"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"तल कम जरुरी सूचनाहरू"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"खोल्न पुनः ट्याप गर्नुहोस्"</string>
@@ -290,14 +280,9 @@
<string name="battery_saver_notification_text" msgid="7796554871101546872">"उपकरण कार्य क्षमता कम छ।"</string>
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ब्याट्री सेभर सेटिङ्हरू खुला गर्नुहोस्"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
- <!-- no translation found for notification_hidden_text (1135169301897151909) -->
- <skip />
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="notification_hidden_text" msgid="1135169301897151909">"लुकेका सामाग्रीहरू"</string>
+ <string name="guest_exit_guest" msgid="1619100760451149682">"निकास अतिथि"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले आफ्नो स्क्रीनमा प्रदर्शित हुने सबै खिच्न शुरू गर्नेछ।"</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"फेरि नदेखाउनुहोस्"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"अहिले सुरु गर्नुहोस्"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 3a93f38..19dadc4 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Închideți panoul"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Mai mult timp"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Mai puțin timp"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"Datele 2G-3G sunt dezactivate"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"Datele 4G sunt dezactivate"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Datele mobile sunt dezactivate"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Datele sunt dezactivate"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Dispozitivul dvs. a dezactivat conexiunea de date deoarece s-a atins limita pe care ați setat-o.\n\nReactivarea conexiunii poate genera aplicarea de taxe de către operator."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Activați datele"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Fără conex. internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectat"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Se caută GPS"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Fără întreruperi, inclusiv alarme"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Fără întreruperi"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Numai întreruperi cu prioritate"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Următoarea alarmă este setată la <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Următoarea alarmă este la <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Nu veți auzi alarma la <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificările mai puțin urgente mai jos"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Atingeți din nou pentru a deschide"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Deschideți setările pentru economisirea bateriei"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Conținutul este ascuns"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Închideți invitatul"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> va începe să captureze tot ceea ce se afișează pe ecran."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Nu se mai afișează"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Începeți acum"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index a04e6aa..8bbfd04 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -168,18 +168,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Закрыть панель."</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Увеличить продолжительность."</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Уменьшить продолжительность."</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"Передача данных 2G/3G отключена"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"Передача данных 4G отключена"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Передача мобильных данных отключена"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Передача данных отключена"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Передача данных отключена, поскольку достигнут установленный вами лимит.\n\nВы можете снова включить ее, однако за переданные данные оператор может взимать дополнительную плату."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Включить передачу данных"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Нет интернет-подключения"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi подключено"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Поиск GPS"</string>
@@ -257,16 +251,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Поиск"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Режим \"Не беспокоить\" (звук будильника отключен)"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Не беспокоить"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Только приоритетные оповещения"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Следующий будильник: <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Следующий будильник: <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Следующий будильник: <xliff:g id="ALARM_TIME">%s</xliff:g>. Звук отключен."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Показать менее важные оповещения"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Нажмите ещё раз, чтобы открыть"</string>
@@ -293,12 +283,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Открыть настройки режима энергосбережения"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Содержимое скрыто"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Выйти из гостевого режима"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"Приложение <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> получит доступ к изображению на экране устройства."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Больше не показывать"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Начать"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 905e8ce..7c5c702 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -290,8 +290,7 @@
<string name="battery_saver_notification_text" msgid="7796554871101546872">"උපාංගය ක්රියාකාරිත්වය අඩු කරන ලදී."</string>
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"බැටරි ඉතිරි කරන්නා සැකසීම් විවෘත කරන්න"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
- <!-- no translation found for notification_hidden_text (1135169301897151909) -->
- <skip />
+ <string name="notification_hidden_text" msgid="1135169301897151909">"සැඟවුණු සම්බන්ධතා"</string>
<!-- no translation found for guest_exit_guest (1619100760451149682) -->
<skip />
<!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 3764406..08b6221b 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -168,18 +168,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Zavrieť panel"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Dlhší čas"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Kratší čas"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"dáta 2G–3G sú vypnuté"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"dáta 4G sú vypnuté"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Mobilné dáta sú vypnuté"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Dáta sú vypnuté"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Zariadenie vyplo dáta, pretože dosiahlo limit, ktorý ste nastavili.\n\nAk ich znova zapnete, môže to viesť k účtovaniu poplatkov operátora."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Zapnúť dáta"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Bez prip. na Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: pripojené"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Vyhľadávanie satelitov GPS"</string>
@@ -257,16 +251,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Žiadne prerušenia vrátane budíkov"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Žiadne prerušenia"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Iba prioritné prerušenia"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Ďalší budík: <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Ďalší budík: <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Váš budík o <xliff:g id="ALARM_TIME">%s</xliff:g> sa nespustí"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Menej naliehavé upozornenia sa nachádzajú nižšie"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Upozornenie otvoríte opätovným klepnutím"</string>
@@ -293,12 +283,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otvorte nastavenia šetriča batérie"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g> %%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Skrytý obsah"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Ukončiť režim hosťa"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikácia <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> začne zaznamenávať všetok obsah zobrazený na vašej obrazovke."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Nabudúce nezobrazovať"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Spustiť"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 3b2f1b9..f08af24 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Затворите таблу"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Више времена"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Мање времена"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G–3G подаци су искључени"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G подаци су искључени"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Мобилни пренос података је искључен"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Пренос података је искључен"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Уређај је искључио пренос података јер је достигао ограничење које сте поставили.\n\nАко га поново укључите, можда ће вам мобилни оператер наплатити трошкове."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Укључи пренос података"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Нема интернет везе"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi је повезан"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Тражи се GPS"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Претрага"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Превуците нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Превуците улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Без прекида, укључујући аларме"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Без прекида"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Само приоритетни прекиди"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Следећи аларм је у <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Следећи аларм: <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Нећете чути аларм у <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Мање хитна обавештења су у наставку"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Додирните поново да бисте отворили"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Отворите подешавања Штедње батерије"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Садржај је сакривен"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Изађи из режима госта"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ће почети да снима све што се приказује на екрану."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Не приказуј поново"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Започни одмах"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9a221ea..9c3e05a 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -214,7 +214,7 @@
<string name="quick_settings_cast_title" msgid="1893629685050355115">"Tuma skrini"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"Inatuma"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Kifaa kisichokuwa na jina"</string>
- <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Tayari kwa kutuma"</string>
+ <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Tayari kutuma"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Hakuna vifaa vilivyopatikana"</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ung\'avu"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"KIOTOMATIKI"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 7ebfda6..215d3e1 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"ปิดแผงควบคุม"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"เวลามากขึ้น"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"เวลาน้อยลง"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"ข้อมูล 2G-3G ปิดอยู่"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"ข้อมูล 4G ปิดอยู่"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"ข้อมูลมือถือปิดอยู่"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"ข้อมูลปิดอยู่"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"อุปกรณ์ของคุณปิดการใช้ข้อมูลเนื่องจากถึงขีดจำกัดที่คุณตั้งค่าไว้\n\nผู้ให้บริการอาจเรียกเก็บเงินหากเปิดใช้อีกครั้ง"</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"เปิดใช้ข้อมูล"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"ไม่มีอินเทอร์เน็ต"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"เชื่อมต่อ WiFi แล้ว"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"กำลังค้นหา GPS"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"ค้นหา"</string>
<string name="description_direction_up" msgid="7169032478259485180">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="description_direction_left" msgid="7207478719805562165">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"ไม่มีการรบกวนรวมถึงเสียงปลุก"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"ไม่มีการรบกวน"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"เฉพาะเรื่องสำคัญเท่านั้น"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"การปลุกครั้งถัดไปของคุณคือเวลา <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"การปลุกครั้งถัดไปของคุณคือ <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"คุณจะไม่ได้ยินเสียงปลุกในเวลา <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"การแจ้งเตือนที่เร่งด่วนน้อยด้านล่าง"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"แตะอีกครั้งเพื่อเปิด"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"เปิดการตั้งค่าโหมดประหยัดแบตเตอรี่"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"เนื้อหาที่ซ่อน"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"ออกจากโหมดผู้เยี่ยมชม"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> จะเริ่มจับภาพทุกอย่างที่แสดงบนหน้าจอ"</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"ไม่ต้องแสดงข้อความนี้อีก"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"เริ่มเลย"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 0e3e7dd..9387e9e 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Isara ang panel"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Higit pang oras"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Mas kaunting oras"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"Naka-off ang 2G-3G data"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"Naka-off ang 4G data"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Naka-off ang cellular data"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Naka-off ang data"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Ini-off ng device mo ang data dahil naabot na nito ang limitasyong iyong itinakda.\n\nAng muling pag-o-on dito ay maaaring humantong sa mga singiling magmumula sa iyong carrier."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"I-on ang data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Walang koneksyon sa Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"nakakonekta ang Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Naghahanap ng GPS"</string>
@@ -197,8 +191,7 @@
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> (na) Device)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Naka-off ang Bluetooth"</string>
- <!-- no translation found for quick_settings_bluetooth_detail_empty_text (4910015762433302860) -->
- <skip />
+ <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"Walang available na mga magkapares na device"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brightness"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Awtomatikong i-rotate"</string>
<string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Naka-lock ang pag-ikot"</string>
@@ -213,26 +206,18 @@
<string name="quick_settings_settings_label" msgid="5326556592578065401">"Mga Setting"</string>
<string name="quick_settings_time_label" msgid="4635969182239736408">"Oras"</string>
<string name="quick_settings_user_label" msgid="5238995632130897840">"Ako"</string>
- <!-- no translation found for quick_settings_user_title (4467690427642392403) -->
- <skip />
- <!-- no translation found for quick_settings_user_new_user (9030521362023479778) -->
- <skip />
+ <string name="quick_settings_user_title" msgid="4467690427642392403">"User"</string>
+ <string name="quick_settings_user_new_user" msgid="9030521362023479778">"Bagong user"</string>
<string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
<string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Hindi Nakakonekta"</string>
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Walang Network"</string>
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Naka-off ang Wi-Fi"</string>
- <!-- no translation found for quick_settings_wifi_detail_empty_text (2831702993995222755) -->
- <skip />
- <!-- no translation found for quick_settings_cast_title (1893629685050355115) -->
- <skip />
- <!-- no translation found for quick_settings_casting (6601710681033353316) -->
- <skip />
- <!-- no translation found for quick_settings_cast_device_default_name (5367253104742382945) -->
- <skip />
- <!-- no translation found for quick_settings_cast_device_default_description (2484573682378634413) -->
- <skip />
- <!-- no translation found for quick_settings_cast_detail_empty_text (311785821261640623) -->
- <skip />
+ <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"Walang available na naka-save na mga network"</string>
+ <string name="quick_settings_cast_title" msgid="1893629685050355115">"I-cast ang screen"</string>
+ <string name="quick_settings_casting" msgid="6601710681033353316">"Nagka-cast"</string>
+ <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Walang pangalang device"</string>
+ <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Handang mag-cast"</string>
+ <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Walang available na mga device"</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="quick_settings_inversion_label" msgid="8790919884718619648">"I-invert ang mga kulay"</string>
@@ -240,8 +225,7 @@
<string name="quick_settings_more_settings" msgid="326112621462813682">"Marami pang setting"</string>
<string name="quick_settings_done" msgid="3402999958839153376">"Tapos na"</string>
<string name="quick_settings_connected" msgid="1722253542984847487">"Nakakonekta"</string>
- <!-- no translation found for quick_settings_connecting (47623027419264404) -->
- <skip />
+ <string name="quick_settings_connecting" msgid="47623027419264404">"Kumokonekta..."</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Nagte-tether"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Mga Notification"</string>
@@ -252,8 +236,7 @@
<string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Lumampas sa limitasyon"</string>
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ang nagamit"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ang limitasyon"</string>
- <!-- no translation found for quick_settings_cellular_detail_data_warning (2440098045692399009) -->
- <skip />
+ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Babala sa <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="recents_empty_message" msgid="7883614615463619450">"Walang kamakailang mga app"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Impormasyon ng Application"</string>
<string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lock to app"</string>
@@ -266,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Walang mga pagkaantala, kabilang na ang mga alarma"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Walang mga paggambala"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Mga may priyoridad na paggambala lang"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Ang susunod mong alarma ay sa <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Ang susunod mong alarma ay <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Hindi mo maririnig ang alarma mo ng <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Nasa ibaba ang mga notification na hindi masyadong mahalaga"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"I-tap ulit upang buksan"</string>
@@ -302,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Buksan ang mga setting ng tagatipid ng baterya"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Nakatago ang mga content"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Lumabas bilang guest"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"Sisimulan ng i-capture ng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ang lahat ng ipinapakita sa iyong screen."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Huwag ipakitang muli"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Magsimula ngayon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 7a785d6..c00ec90 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Paneli kapatın"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Daha uzun süre"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Daha kısa süre"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G-3G veri kullanımı kapalı"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G veri kullanımı kapalı"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Hücresel veri kapalı"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Veri kullanımı kapalı"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Ayarladığınız sınıra erişildiğinden cihazınız veri kullanımını kapattı.\n\nVeri kullanımını tekrar açmanız operatörünüzün ek ödemeler almasına neden olabilir."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Veri kullanımını aç"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"İnternet bağlantısı yok"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Kablosuz bağlandı"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS aranıyor"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Ara"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı kaydırın."</string>
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola kaydırın."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Alarmlar dahil hiç kesinti yok"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Kesinti yok"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Sadece öncelikli kesintiler"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Bir sonraki alarmın saati: <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Bir sonraki alarmınız: <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"<xliff:g id="ALARM_TIME">%s</xliff:g> olarak ayarlanan alarmı duymayacaksınız"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az acil bildirimler aşağıdadır"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Açmak için tekrar hafifçe vurun"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Pil tasarrufu ayarlarını aç"</string>
<string name="battery_level_template" msgid="1609636980292580020">"%%<xliff:g id="LEVEL">%d</xliff:g>"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"İçerik gizlendi"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Misafir oturumundan çık"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, ekranınızda görüntülenen her şeyi kaydetmeye başlayacak."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Bir daha gösterme"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Şimdi başla"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 9e453b0..49abb62 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Закрити панель"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Більше часу"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Менше часу"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"Дані 2G–3G вимкнено"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"Дані 4G вимкнено"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Мобільні дані вимкнено"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Дані вимкнено"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Пристрій вимкнув передавання даних, оскільки на ньому досягнуто встановленого вами ліміту.\n\nЯкщо передавання даних знову ввімкнути, оператор може стягувати з вас плату за це."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Увімкнути дані"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Немає з’єднання"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi під’єднано"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Виконується пошук GPS-сигналу"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Проведіть пальцем угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Проведіть пальцем ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Без сповіщень, зокрема сигналів будильника"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Без сповіщень"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Лише пріоритетні сповіщення"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Наступний сигнал: <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Наступний сигнал: <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Сигнал не лунатиме о <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Менше термінових сповіщень нижче"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Торкніться знову, щоб відкрити"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Відкрийте налаштування режиму заощадження заряду акумулятора"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Вміст сховано"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Вийти з гостьового режиму"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> почне збирати всі дані, які відображаються на вашому екрані."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Більше не показувати"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Почати зараз"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 379fb1b..aa15d23 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"پینل بند کریں"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"مزید وقت"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"کم وقت"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G-3G ڈیٹا آف ہے"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G ڈیٹا آف ہے"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"سیلولر ڈیٹا آف ہے"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"ڈیٹا آف ہے"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"آپ کے آلہ نے ڈیٹا کو آف کر دیا کیونکہ یہ آپ کے متعینہ حد کو پہنچ گیا ہے۔\n\nاسے دوبارہ آن کرنے سے آپ کے کیریئر کی جانب سے چارجز عائد ہو سکتے ہیں۔"</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"ڈیٹا آن کریں"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"کوئی انٹرنیٹ کنکشن نہیں"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi مربوط ہے"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS کی تلاش کر رہا ہے"</string>
@@ -197,7 +191,7 @@
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"بلوٹوتھ"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"بلوٹوتھ (<xliff:g id="NUMBER">%d</xliff:g> آلات)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"بلوٹوتھ آف ہے"</string>
- <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"کوئی جوڑ بنائے ہوئے آلات دستیاب نہیں ہیں"</string>
+ <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"کوئی جوڑا بنائے ہوئے آلات دستیاب نہیں ہیں"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"چمکیلا پن"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"خود کار طور پر گھمائیں"</string>
<string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"گردش مقفل ہے"</string>
@@ -242,7 +236,7 @@
<string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"حد سے زیادہ"</string>
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> استعمال کردہ"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> حد"</string>
- <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> انتباہ"</string>
+ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> وارننگ"</string>
<string name="recents_empty_message" msgid="7883614615463619450">"کوئی حالیہ ایپس نہیں ہیں"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"ایپلیکیشن کی معلومات"</string>
<string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"لاک ٹو ایپ"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"تلاش کریں"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> کیلئے اوپر سلائیڈ کریں۔"</string>
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> کیلئے بائیں سلائیڈ کریں۔"</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"الارمز کے بشمول، کوئی مداخلتیں نہیں ہیں"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"کوئی مداخلتیں نہیں ہیں"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"صرف ترجیحی مداخلتیں"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"آپ کا اگلا الارم بوقت <xliff:g id="ALARM_TIME">%s</xliff:g> ہے"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"آپ کا اگلا الارم <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g> ہے"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"آپ کو بوقت <xliff:g id="ALARM_TIME">%s</xliff:g> اپنا الارم سنائی نہیں دیگا"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"کم اہم اطلاعات ذیل میں ہیں"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"کھولنے کیلئے دوبارہ تھپتھپائیں"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"بیٹری سیور کی ترتیبات کھولیں"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"مواد مخفی ہیں"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"مہمان سے باہر نکلیں"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> آپ کی اسکرین پر ڈسپلے ہونے والی ہر چیز کو کیپچر کرنا شروع کر دیگی۔"</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"دوبارہ نہ دکھائیں"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"ابھی شروع کریں"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index d413ed7..bf32e6c 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -166,18 +166,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"Đóng bảng điều khiển"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"Nhiều thời gian hơn"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"Ít thời gian hơn"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"Dữ liệu 2G-3G bị tắt"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"Dữ liệu 4G bị tắt"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Dữ liệu di động bị tắt"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"Dữ liệu bị tắt"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"Thiết bị của bạn bị tắt dữ liệu do đã đạt đến giới hạn bạn đã đặt.\n\nViệc bật lại dữ liệu có thể dẫn tới các khoản phí từ nhà cung cấp dịch vụ của bạn."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"Bật dữ liệu"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ko có k.nối Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Đã kết nối Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Đang tìm kiếm GPS"</string>
@@ -255,16 +249,12 @@
<string name="description_target_search" msgid="3091587249776033139">"Tìm kiếm"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Trượt lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Trượt sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"Không có gián đoạn, bao gồm báo thức"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"Không có gián đoạn nào"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"Chỉ các gián đoạn ưu tiên"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"Lần báo thức tiếp theo của bạn vào lúc <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Lần báo thức tiếp theo của bạn là <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"Bạn sẽ không nghe thấy báo thức lúc <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Thông báo ít khẩn cấp hơn bên dưới"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Nhấn lại để mở"</string>
@@ -291,12 +281,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Mở cài đặt trình tiết kiệm pin"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Nội dung bị ẩn"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"Thoát chế độ khách"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ bắt đầu chụp mọi thứ hiển thị trên màn hình."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Không hiển thị lại"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Bắt đầu ngay"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 2d88348..92ee5a2 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -224,7 +224,7 @@
<string name="quick_settings_cast_title" msgid="1893629685050355115">"投射屏幕"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"正在投射"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"未命名设备"</string>
- <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"准备好投射"</string>
+ <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"已准备好投射"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"没有可用设备"</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自动"</string>
@@ -239,7 +239,7 @@
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"通知"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"手电筒"</string>
<string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"移动数据网络"</string>
- <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"数据流量消耗"</string>
+ <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"流量使用情况"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"剩余流量"</string>
<string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"超出上限"</string>
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"已使用<xliff:g id="DATA_USED">%s</xliff:g>"</string>
@@ -292,8 +292,7 @@
<string name="battery_saver_notification_text" msgid="7796554871101546872">"设备性能已减降。"</string>
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"打开节电助手设置"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
- <!-- no translation found for notification_hidden_text (1135169301897151909) -->
- <skip />
+ <string name="notification_hidden_text" msgid="1135169301897151909">"内容已隐藏"</string>
<!-- no translation found for guest_exit_guest (1619100760451149682) -->
<skip />
<!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index f4c4e14..2e3878d 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -168,18 +168,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"關閉面板"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"更多時間"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"較少時間"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G-3G 數據連線已關閉"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G 數據連線已關閉"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"流動數據連線已關閉"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"數據連線已關閉"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"數據流量已達到您所設定的上限,因此裝置關閉了數據連線。\n\n若重新開啟數據連線,流動網絡供應商可能會向您收費。"</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"開啟數據連線"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"沒有互聯網連線"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi 已連線"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"正在搜尋 GPS"</string>
@@ -257,16 +251,12 @@
<string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
<string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"不允許干擾 (包含鬧鐘)"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"不允許干擾"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"僅限優先干擾"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"下次鬧鐘時間:<xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"下次鬧鐘時間:<xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"您不會聽到<xliff:g id="ALARM_TIME">%s</xliff:g> 的鬧鐘"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"還有 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g> 則通知"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"不太緊急的通知會在下方顯示"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"再次輕按即可開啟"</string>
@@ -293,12 +283,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"開啟省電設定"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"內容已隱藏"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"結束訪客模式"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 將開始擷取您的螢幕上顯示的內容。"</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"不用再顯示"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"立即開始"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 2ffa320..840778b 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -168,18 +168,12 @@
<string name="accessibility_quick_settings_close" msgid="2571790856136835943">"關閉面板"</string>
<string name="accessibility_quick_settings_more_time" msgid="5778794273488176726">"更多時間"</string>
<string name="accessibility_quick_settings_less_time" msgid="101026945195230084">"更少時間"</string>
- <!-- no translation found for data_usage_disabled_dialog_3g_title (2626865386971800302) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_4g_title (4629078114195977196) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_mobile_title (5793456071535876132) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_title (8723412000355709802) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog (6468718338038876604) -->
- <skip />
- <!-- no translation found for data_usage_disabled_dialog_enable (5538068036107372895) -->
- <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G-3G 數據連線已關閉"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G 數據連線已關閉"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"行動數據連線已關閉"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"數據連線已關閉"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"數據流量已達您所設定的上限,因此裝置關閉了數據連線。\n\n如果重新開啟數據連線,行動通訊業者可能會向您收費。"</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"開啟數據連線"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"沒有網際網路連線"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi 已連線"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"正在搜尋 GPS"</string>
@@ -257,16 +251,12 @@
<string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
<string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
- <!-- no translation found for zen_no_interruptions_with_warning (2522931836819051293) -->
- <skip />
+ <string name="zen_no_interruptions_with_warning" msgid="2522931836819051293">"不允許干擾 (包含鬧鐘)"</string>
<string name="zen_no_interruptions" msgid="7970973750143632592">"不允許干擾"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"僅限優先干擾"</string>
- <!-- no translation found for zen_alarm_information_time (5235772206174372272) -->
- <skip />
- <!-- no translation found for zen_alarm_information_day_time (8422733576255047893) -->
- <skip />
- <!-- no translation found for zen_alarm_warning (6873910860111498041) -->
- <skip />
+ <string name="zen_alarm_information_time" msgid="5235772206174372272">"下次鬧鐘時間:<xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"下次鬧鐘時間:<xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+ <string name="zen_alarm_warning" msgid="6873910860111498041">"您不會聽到<xliff:g id="ALARM_TIME">%s</xliff:g> 的鬧鐘"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"還有 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g> 則通知"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"較不緊急的通知會顯示在下方"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"再次輕按即可開啟"</string>
@@ -293,12 +283,8 @@
<string name="battery_saver_notification_action_text" msgid="7546297220816993504">"開啟節約耗電量設定"</string>
<string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"內容已隱藏"</string>
- <!-- no translation found for guest_exit_guest (1619100760451149682) -->
- <skip />
- <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
- <skip />
- <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
- <skip />
- <!-- no translation found for media_projection_action_text (8470872969457985954) -->
- <skip />
+ <string name="guest_exit_guest" msgid="1619100760451149682">"結束訪客模式"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 將開始擷取您的螢幕上顯示的內容。"</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"不要再顯示"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"立即開始"</string>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 627f11c..e9fe09e 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -23,6 +23,7 @@
<color name="system_bar_background_opaque">#ff000000</color>
<color name="system_bar_background_semi_transparent">#66000000</color> <!-- 40% black -->
<color name="system_bar_background_transparent">#00000000</color>
+ <color name="system_bar_background_warning">#fff4511e</color><!-- deep orange 600 -->
<color name="notification_panel_solid_background">#ff000000</color>
<drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
<color name="status_bar_recents_app_label_color">#ffffffff</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 94fcc23..8b11ef1 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -164,5 +164,8 @@
<!-- Volume: time to delay dismissing the volume panel after a click is performed -->
<integer name="volume_panel_dismiss_delay">200</integer>
+
+ <!-- Hotspot tile: number of days to show after feature is used. -->
+ <integer name="days_to_show_hotspot">30</integer>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index fc08cf4..93766af 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -30,11 +30,12 @@
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.FlashlightController;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.Listenable;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RotationLockController;
-import com.android.systemui.statusbar.policy.TetheringController;
+import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.volume.VolumeComponent;
@@ -244,16 +245,16 @@
void collapsePanels();
Looper getLooper();
Context getContext();
+ List<QSTile<?>> getTiles();
BluetoothController getBluetoothController();
LocationController getLocationController();
RotationLockController getRotationLockController();
- List<QSTile<?>> getTiles();
NetworkController getNetworkController();
ZenModeController getZenModeController();
- TetheringController getTetheringController();
+ HotspotController getHotspotController();
CastController getCastController();
- VolumeComponent getVolumeComponent();
FlashlightController getFlashlightController();
+ KeyguardMonitor getKeyguardMonitor();
}
public static class State {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index ab952c6..531ac31 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -30,6 +30,7 @@
import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
import java.util.LinkedHashMap;
import java.util.Set;
@@ -41,11 +42,14 @@
private final CastController mController;
private final CastDetailAdapter mDetailAdapter;
+ private final KeyguardMonitor mKeyguard;
+ private final Callback mCallback = new Callback();
public CastTile(Host host) {
super(host);
mController = host.getCastController();
mDetailAdapter = new CastDetailAdapter();
+ mKeyguard = host.getKeyguardMonitor();
}
@Override
@@ -64,9 +68,11 @@
if (DEBUG) Log.d(TAG, "setListening " + listening);
if (listening) {
mController.addCallback(mCallback);
+ mKeyguard.addCallback(mCallback);
} else {
mController.setDiscovering(false);
mController.removeCallback(mCallback);
+ mKeyguard.removeCallback(mCallback);
}
}
@@ -84,7 +90,7 @@
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
- state.visible = true;
+ state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
state.label = mContext.getString(R.string.quick_settings_cast_title);
state.value = false;
final Set<CastDevice> devices = mController.getCastDevices();
@@ -109,11 +115,16 @@
: mContext.getString(R.string.quick_settings_cast_device_default_name);
}
- private final CastController.Callback mCallback = new CastController.Callback() {
+ private final class Callback implements CastController.Callback, KeyguardMonitor.Callback {
@Override
public void onCastDevicesChanged() {
refreshState();
}
+
+ @Override
+ public void onKeyguardChanged() {
+ refreshState();
+ }
};
private final class CastDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index b610cf3..75e3bc1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -62,7 +62,9 @@
if (arg instanceof Boolean) {
state.value = (Boolean) arg;
}
- state.visible = mFlashlightController.isAvailable();
+ // Always show the tile when the flashlight is on. This is needed because
+ // the camera is not available while it is being used for the flashlight.
+ state.visible = state.value || mFlashlightController.isAvailable();
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
state.iconId = state.value
? R.drawable.ic_qs_flashlight_on : R.drawable.ic_qs_flashlight_off;
@@ -77,4 +79,9 @@
public void onFlashlightError() {
refreshState(false);
}
+
+ @Override
+ public void onFlashlightAvailabilityChanged(boolean available) {
+ refreshState();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index f2ba558..35dfdda 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -16,45 +16,98 @@
package com.android.systemui.qs.tiles;
+import android.content.BroadcastReceiver;
+import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
-import com.android.systemui.statusbar.policy.TetheringController;
+import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
/** Quick settings tile: Hotspot **/
-public class HotspotTile extends QSTile<QSTile.State> {
- private static final Intent TETHER_SETTINGS = new Intent()
- .setClassName("com.android.settings", "com.android.settings.TetherSettings");
+public class HotspotTile extends QSTile<QSTile.BooleanState> {
+ private static final String KEY_LAST_USED_DATE = "lastUsedDate";
+ private static final long MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
- // TODO: implement. see com.android.settings.TetherSettings
-
- private final TetheringController mController;
+ private final HotspotController mController;
+ private final KeyguardMonitor mKeyguard;
+ private final Callback mCallback = new Callback();
+ private final long mTimeToShowTile;
public HotspotTile(Host host) {
super(host);
- mController = host.getTetheringController();
+ mController = host.getHotspotController();
+ mKeyguard = host.getKeyguardMonitor();
+
+ mTimeToShowTile = MILLIS_PER_DAY
+ * mContext.getResources().getInteger(R.integer.days_to_show_hotspot);
}
@Override
- protected State newTileState() {
- return new State();
+ protected BooleanState newTileState() {
+ return new BooleanState();
}
@Override
public void setListening(boolean listening) {
-
+ if (listening) {
+ mController.addCallback(mCallback);
+ mKeyguard.addCallback(mCallback);
+ } else {
+ mController.removeCallback(mCallback);
+ mKeyguard.removeCallback(mCallback);
+ }
}
@Override
protected void handleClick() {
- mHost.startSettingsActivity(TETHER_SETTINGS);
+ final boolean isEnabled = (Boolean) mState.value;
+ mController.setHotspotEnabled(!isEnabled);
}
@Override
- protected void handleUpdateState(State state, Object arg) {
- state.visible = mController != null;
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing())
+ && mController.isHotspotSupported() && isHotspotRecentlyUsed();
state.label = mContext.getString(R.string.quick_settings_hotspot_label);
- state.iconId = R.drawable.ic_qs_hotspot_off;
+
+ state.value = mController.isHotspotEnabled();
+ state.iconId = state.visible && state.value ? R.drawable.ic_qs_hotspot_on
+ : R.drawable.ic_qs_hotspot_off;
+ }
+
+ private boolean isHotspotRecentlyUsed() {
+ long lastDay = getSharedPrefs(mContext).getLong(KEY_LAST_USED_DATE, 0);
+ return (System.currentTimeMillis() - lastDay) < mTimeToShowTile;
+ }
+
+ private static SharedPreferences getSharedPrefs(Context context) {
+ return context.getSharedPreferences(context.getPackageName(), 0);
+ }
+
+ private final class Callback implements HotspotController.Callback, KeyguardMonitor.Callback {
+ @Override
+ public void onHotspotChanged(boolean enabled) {
+ refreshState();
+ }
+
+ @Override
+ public void onKeyguardChanged() {
+ refreshState();
+ }
+ };
+
+ /**
+ * This will catch broadcasts for changes in hotspot state so we can show
+ * the hotspot tile for a number of days after use.
+ */
+ public static class APChangedReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ long currentTime = System.currentTimeMillis();
+ getSharedPrefs(context).edit().putLong(KEY_LAST_USED_DATE, currentTime).commit();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 04f1eb5..c4dd643 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -18,6 +18,7 @@
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.LocationController.LocationSettingsChangeCallback;
@@ -25,10 +26,13 @@
public class LocationTile extends QSTile<QSTile.BooleanState> {
private final LocationController mController;
+ private final KeyguardMonitor mKeyguard;
+ private final Callback mCallback = new Callback();
public LocationTile(Host host) {
super(host);
mController = host.getLocationController();
+ mKeyguard = host.getKeyguardMonitor();
}
@Override
@@ -40,8 +44,10 @@
public void setListening(boolean listening) {
if (listening) {
mController.addSettingsChangedCallback(mCallback);
+ mKeyguard.addCallback(mCallback);
} else {
mController.removeSettingsChangedCallback(mCallback);
+ mKeyguard.removeCallback(mCallback);
}
}
@@ -59,7 +65,7 @@
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
final boolean locationEnabled = mController.isLocationEnabled();
- state.visible = true;
+ state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
state.value = locationEnabled;
if (locationEnabled) {
state.iconId = R.drawable.ic_qs_location_on;
@@ -76,10 +82,16 @@
}
}
- private final LocationSettingsChangeCallback mCallback = new LocationSettingsChangeCallback() {
+ private final class Callback implements LocationSettingsChangeCallback,
+ KeyguardMonitor.Callback {
@Override
public void onLocationSettingsChanged(boolean enabled) {
refreshState();
}
+
+ @Override
+ public void onKeyguardChanged() {
+ refreshState();
+ }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 66e5d14..591149c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -70,10 +71,13 @@
// Task launching
RecentsConfiguration mConfig;
- Rect mWindowRect;
- Rect mTaskStackBounds;
+ Rect mWindowRect = new Rect();
+ Rect mTaskStackBounds = new Rect();
+ Rect mSystemInsets = new Rect();
TaskViewTransform mTmpTransform = new TaskViewTransform();
int mStatusBarHeight;
+ int mNavBarHeight;
+ int mNavBarWidth;
// Variables to keep track of if we need to start recents after binding
View mStatusBarView;
@@ -81,15 +85,23 @@
long mLastToggleTime;
public AlternateRecentsComponent(Context context) {
+ Resources res = context.getResources();
mContext = context;
mSystemServicesProxy = new SystemServicesProxy(context);
mHandler = new Handler();
mConfig = RecentsConfiguration.reinitialize(context, mSystemServicesProxy);
mWindowRect = mSystemServicesProxy.getWindowRect();
mTaskStackBounds = new Rect();
- mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mTaskStackBounds);
- mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_height);
+ mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+ mNavBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
+ mNavBarWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
+ mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight,
+ mNavBarWidth, mTaskStackBounds);
+ if (mConfig.isLandscape && mConfig.transposeRecentsLayoutWithOrientation) {
+ mSystemInsets.set(0, mStatusBarHeight, mNavBarWidth, 0);
+ } else {
+ mSystemInsets.set(0, mStatusBarHeight, 0, mNavBarHeight);
+ }
}
public void onStart() {
@@ -150,7 +162,13 @@
mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy);
mConfig.updateOnConfigurationChange();
mWindowRect = mSystemServicesProxy.getWindowRect();
- mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mTaskStackBounds);
+ mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight,
+ mNavBarWidth, mTaskStackBounds);
+ if (mConfig.isLandscape && mConfig.transposeRecentsLayoutWithOrientation) {
+ mSystemInsets.set(0, mStatusBarHeight, mNavBarWidth, 0);
+ } else {
+ mSystemInsets.set(0, mStatusBarHeight, 0, mNavBarHeight);
+ }
sLastScreenshot = null;
}
@@ -301,7 +319,9 @@
// Get the stack
TaskStackView tsv = new TaskStackView(mContext, stack);
TaskStackViewLayoutAlgorithm algo = tsv.getStackAlgorithm();
- tsv.computeRects(mTaskStackBounds.width(), mTaskStackBounds.height() - mStatusBarHeight, 0, 0);
+ Rect taskStackBounds = new Rect(mTaskStackBounds);
+ taskStackBounds.bottom -= mSystemInsets.bottom;
+ tsv.computeRects(mWindowRect.width(), mWindowRect.height(), taskStackBounds);
tsv.setStackScrollToInitialState();
// Find the running task in the TaskStack
@@ -325,8 +345,6 @@
// Get the transform for the running task
mTmpTransform = algo.getStackTransform(task, tsv.getStackScroll(), mTmpTransform);
- mTmpTransform.rect.offset(mTaskStackBounds.left, mTaskStackBounds.top);
- mTmpTransform.rect.offset(0, mStatusBarHeight);
return new Rect(mTmpTransform.rect);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 5741f22..7d69b94 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -32,18 +32,20 @@
import android.util.Pair;
import android.view.KeyEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewStub;
+import android.widget.FrameLayout;
import android.widget.Toast;
import com.android.systemui.R;
-import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.DebugTrigger;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.SpaceNode;
+import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
-import com.android.systemui.recents.views.FullscreenTransitionOverlayView;
+import com.android.systemui.recents.views.DebugOverlayView;
import com.android.systemui.recents.views.RecentsView;
import com.android.systemui.recents.views.SystemBarScrimViews;
import com.android.systemui.recents.views.ViewAnimation;
@@ -56,8 +58,7 @@
* The main Recents activity that is started from AlternateRecentsComponent.
*/
public class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks,
- RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks,
- FullscreenTransitionOverlayView.FullScreenTransitionViewCallbacks {
+ RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks {
// Actions and Extras sent from AlternateRecentsComponent
final static String EXTRA_TRIGGERED_FROM_ALT_TAB = "extra_triggered_from_alt_tab";
@@ -73,17 +74,14 @@
SystemBarScrimViews mScrimViews;
ViewStub mEmptyViewStub;
View mEmptyView;
- ViewStub mFullscreenOverlayStub;
- FullscreenTransitionOverlayView mFullScreenOverlayView;
+ DebugOverlayView mDebugOverlay;
// Search AppWidget
RecentsAppWidgetHost mAppWidgetHost;
AppWidgetProviderInfo mSearchAppWidgetInfo;
AppWidgetHostView mSearchAppWidgetHostView;
-
// Runnables to finish the Recents activity
- FinishRecentsRunnable mFinishRunnable = new FinishRecentsRunnable();
FinishRecentsRunnable mFinishLaunchHomeRunnable;
/**
@@ -97,10 +95,6 @@
Intent mLaunchIntent;
ActivityOptions mLaunchOpts;
- public FinishRecentsRunnable() {
- // Do nothing
- }
-
/**
* Creates a finish runnable that starts the specified intent, using the given
* ActivityOptions.
@@ -151,8 +145,7 @@
} else if (action.equals(ACTION_START_ENTER_ANIMATION)) {
// Try and start the enter animation (or restart it on configuration changed)
ReferenceCountedTrigger t = new ReferenceCountedTrigger(context, null, null, null);
- mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(
- mFullScreenOverlayView, t));
+ mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t));
onEnterAnimationTriggered();
}
}
@@ -187,11 +180,12 @@
/** Updates the set of recent tasks */
void updateRecentsTasks(Intent launchIntent) {
+ // Load all the tasks
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
ArrayList<TaskStack> stacks = root.getStacks();
if (!stacks.isEmpty()) {
- mRecentsView.setBSP(root);
+ mRecentsView.setTaskStacks(root.getStacks());
}
// Update the configuration based on the launch intent
@@ -207,6 +201,23 @@
mConfig.launchedToTaskId = launchIntent.getIntExtra(
AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_TASK_ID, -1);
+ // Mark the task that is the launch target
+ int taskStackCount = stacks.size();
+ if (mConfig.launchedToTaskId != -1) {
+ for (int i = 0; i < taskStackCount; i++) {
+ TaskStack stack = stacks.get(i);
+ ArrayList<Task> tasks = stack.getTasks();
+ int taskCount = tasks.size();
+ for (int j = 0; j < taskCount; j++) {
+ Task t = tasks.get(j);
+ if (t.key.id == mConfig.launchedToTaskId) {
+ t.isLaunchTarget = true;
+ break;
+ }
+ }
+ }
+ }
+
// Update the top level view's visibilities
if (mConfig.launchedWithNoRecentTasks) {
if (mEmptyView == null) {
@@ -286,9 +297,6 @@
/** Dismisses recents if we are already visible and the intent is to toggle the recents view */
boolean dismissRecentsToFocusedTaskOrHome(boolean checkFilteredStackState) {
if (mVisible) {
- // If we are mid-animation into Recents, reverse the animation now
- if (mFullScreenOverlayView != null &&
- mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) return true;
// If we currently have filtered stacks, then unfilter those first
if (checkFilteredStackState &&
mRecentsView.unfilterFilteredStacks()) return true;
@@ -299,8 +307,8 @@
dismissRecentsToHomeRaw(true);
return true;
}
- // Otherwise, try and return to the first Task in the stack
- if (mRecentsView.launchFirstTask()) return true;
+ // Otherwise, try and return to the Task that Recents was launched from
+ if (mRecentsView.launchPreviousTask()) return true;
// If none of the other cases apply, then just go Home
dismissRecentsToHomeRaw(true);
return true;
@@ -323,9 +331,6 @@
/** Dismisses Recents directly to Home if we currently aren't transitioning. */
boolean dismissRecentsToHome(boolean animated) {
if (mVisible) {
- // If we are mid-animation into Recents, reverse the animation now
- if (mFullScreenOverlayView != null &&
- mFullScreenOverlayView.cancelAnimateOnEnterRecents(mFinishRunnable)) return true;
// Return to Home
dismissRecentsToHomeRaw(animated);
return true;
@@ -363,8 +368,8 @@
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub);
- mFullscreenOverlayStub = (ViewStub) findViewById(R.id.fullscreen_overlay_stub);
mScrimViews = new SystemBarScrimViews(this, mConfig);
+ inflateDebugOverlay();
// Bind the search app widget when we first start up
bindSearchBarAppWidget();
@@ -390,13 +395,6 @@
e.printStackTrace();
}
- // Prepare the screenshot transition if necessary
- if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
- mFullScreenOverlayView = (FullscreenTransitionOverlayView) mFullscreenOverlayStub.inflate();
- mFullScreenOverlayView.setCallbacks(this);
- mFullScreenOverlayView.prepareAnimateOnEnterRecents(AlternateRecentsComponent.getLastScreenshot());
- }
-
// Update if we are getting a configuration change
if (savedInstanceState != null) {
mConfig.updateOnConfigurationChange();
@@ -404,6 +402,19 @@
}
}
+ /** Inflates the debug overlay if debug mode is enabled. */
+ void inflateDebugOverlay() {
+ if (mConfig.debugModeEnabled && mDebugOverlay == null) {
+ ViewGroup parent = (ViewGroup) findViewById(android.R.id.content).getRootView();
+ mDebugOverlay = new DebugOverlayView(this);
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ parent.addView(mDebugOverlay, lp);
+ mRecentsView.setDebugOverlay(mDebugOverlay);
+ }
+ }
+
void onConfigurationChange() {
// Update RecentsConfiguration
mConfig = RecentsConfiguration.reinitialize(this,
@@ -411,8 +422,7 @@
// Try and start the enter animation (or restart it on configuration changed)
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
- mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(
- mFullScreenOverlayView, t));
+ mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t));
onEnterAnimationTriggered();
}
@@ -421,13 +431,13 @@
super.onNewIntent(intent);
setIntent(intent);
+ // Clear any debug rects
+ if (mDebugOverlay != null) {
+ mDebugOverlay.clear();
+ }
+
// Update the recent tasks
updateRecentsTasks(intent);
-
- // Prepare the screenshot transition if necessary
- if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
- mFullScreenOverlayView.prepareAnimateOnEnterRecents(AlternateRecentsComponent.getLastScreenshot());
- }
}
@Override
@@ -531,17 +541,25 @@
/** Called when debug mode is triggered */
public void onDebugModeTriggered() {
+
if (mConfig.developerOptionsEnabled) {
SharedPreferences settings = getSharedPreferences(getPackageName(), 0);
if (settings.getBoolean(Constants.Values.App.Key_DebugModeEnabled, false)) {
// Disable the debug mode
settings.edit().remove(Constants.Values.App.Key_DebugModeEnabled).apply();
+ mConfig.debugModeEnabled = false;
+ inflateDebugOverlay();
+ mDebugOverlay.disable();
} else {
// Enable the debug mode
settings.edit().putBoolean(Constants.Values.App.Key_DebugModeEnabled, true).apply();
+ mConfig.debugModeEnabled = true;
+ inflateDebugOverlay();
+ mDebugOverlay.enable();
}
- Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion +
- ") toggled, please restart Recents now", Toast.LENGTH_SHORT).show();
+ Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion + ") " +
+ (mConfig.debugModeEnabled ? "Enabled" : "Disabled") + ", please restart Recents now",
+ Toast.LENGTH_SHORT).show();
}
}
@@ -551,19 +569,6 @@
mScrimViews.startEnterRecentsAnimation();
}
- /**** FullscreenTransitionOverlayView.FullScreenTransitionViewCallbacks Implementation ****/
-
- @Override
- public void onEnterAnimationComplete() {
- // Reset the full screenshot transition view
- if (Constants.DebugFlags.App.EnableScreenshotAppTransition) {
- mFullScreenOverlayView.reset();
-
- // Recycle the full screen screenshot
- AlternateRecentsComponent.consumeLastScreenshot();
- }
- }
-
/**** RecentsView.RecentsViewCallbacks Implementation ****/
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index a0cab5c..55711cf0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -309,19 +309,16 @@
* Returns the task stack bounds in the current orientation. These bounds do not account for
* the system insets.
*/
- public void getTaskStackBounds(int width, int height, Rect taskStackBounds) {
- if (hasSearchBarAppWidget()) {
- Rect searchBarBounds = new Rect();
- getSearchBarBounds(width, height, searchBarBounds);
- if (isLandscape && transposeRecentsLayoutWithOrientation) {
- // In landscape, the search bar appears on the left, so shift the task rect right
- taskStackBounds.set(searchBarBounds.width(), 0, width, height);
- } else {
- // In portrait, the search bar appears on the top, so shift the task rect below
- taskStackBounds.set(0, searchBarBounds.height(), width, height);
- }
+ public void getTaskStackBounds(int windowWidth, int windowHeight, int topInset, int rightInset,
+ Rect taskStackBounds) {
+ Rect searchBarBounds = new Rect();
+ getSearchBarBounds(windowWidth, windowHeight, topInset, searchBarBounds);
+ if (isLandscape && transposeRecentsLayoutWithOrientation) {
+ // In landscape, the search bar appears on the left
+ taskStackBounds.set(searchBarBounds.right, topInset, windowWidth - rightInset, windowHeight);
} else {
- taskStackBounds.set(0, 0, width, height);
+ // In portrait, the search bar appears on the top (which already has the inset)
+ taskStackBounds.set(0, searchBarBounds.bottom, windowWidth, windowHeight);
}
}
@@ -329,19 +326,20 @@
* Returns the search bar bounds in the current orientation. These bounds do not account for
* the system insets.
*/
- public void getSearchBarBounds(int width, int height, Rect searchBarSpaceBounds) {
+ public void getSearchBarBounds(int windowWidth, int windowHeight, int topInset,
+ Rect searchBarSpaceBounds) {
// Return empty rects if search is not enabled
- if (!Constants.DebugFlags.App.EnableSearchLayout) {
- searchBarSpaceBounds.set(0, 0, 0, 0);
- return;
+ int searchBarSize = searchBarSpaceHeightPx;
+ if (!Constants.DebugFlags.App.EnableSearchLayout || !hasSearchBarAppWidget()) {
+ searchBarSize = 0;
}
if (isLandscape && transposeRecentsLayoutWithOrientation) {
// In landscape, the search bar appears on the left
- searchBarSpaceBounds.set(0, 0, searchBarSpaceHeightPx, height);
+ searchBarSpaceBounds.set(0, topInset, searchBarSize, windowHeight);
} else {
// In portrait, the search bar appears on the top
- searchBarSpaceBounds.set(0, 0, width, searchBarSpaceHeightPx);
+ searchBarSpaceBounds.set(0, topInset, windowWidth, topInset + searchBarSize);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 5fadc71..fb77751 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -38,6 +38,7 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
@@ -437,7 +438,9 @@
Rect windowRect = new Rect();
if (mWm == null) return windowRect;
- mWm.getDefaultDisplay().getRectSize(windowRect);
+ Point p = new Point();
+ mWm.getDefaultDisplay().getRealSize(p);
+ windowRect.set(0, 0, p.x, p.y);
return windowRect;
}
@@ -467,4 +470,13 @@
public Bitmap takeAppScreenshot() {
return takeScreenshot();
}
+
+ public void startActivityFromRecents(int taskId, ActivityOptions options) {
+ if (mIam != null) {
+ try {
+ mIam.startActivityFromRecents(taskId, options == null ? null : options.toBundle());
+ } catch (RemoteException e) {
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 4cf9235..41874fc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -77,6 +77,7 @@
public TaskKey key;
public TaskGrouping group;
public int taskAffiliation;
+ public boolean isLaunchTarget;
public Drawable applicationIcon;
public Drawable activityIcon;
public String activityLabel;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
new file mode 100644
index 0000000..9076818
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.animation.ObjectAnimator;
+import android.graphics.Outline;
+import android.graphics.Rect;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+import com.android.systemui.recents.RecentsConfiguration;
+
+/* An outline provider that has a clip and outline that can be animated. */
+public class AnimateableViewBounds extends ViewOutlineProvider {
+
+ RecentsConfiguration mConfig;
+
+ View mSourceView;
+ Rect mClipRect = new Rect();
+ Rect mOutlineClipRect = new Rect();
+ int mCornerRadius;
+
+ ObjectAnimator mClipTopAnimator;
+ ObjectAnimator mClipBottomAnimator;
+
+ public AnimateableViewBounds(View source, int cornerRadius) {
+ mConfig = RecentsConfiguration.getInstance();
+ mSourceView = source;
+ mCornerRadius = cornerRadius;
+ mSourceView.setClipToOutline(true);
+ setClipTop(getClipTop());
+ setClipBottom(getClipBottom());
+ setOutlineClipBottom(getOutlineClipBottom());
+ }
+
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(Math.max(mClipRect.left, mOutlineClipRect.left),
+ Math.max(mClipRect.top, mOutlineClipRect.top),
+ mSourceView.getMeasuredWidth() - Math.max(mClipRect.right, mOutlineClipRect.right),
+ mSourceView.getMeasuredHeight() - Math.max(mClipRect.bottom, mOutlineClipRect.bottom),
+ mCornerRadius);
+ }
+
+ /** Animates the top clip. */
+ void animateClipTop(int top, int duration) {
+ if (mClipTopAnimator != null) {
+ mClipTopAnimator.removeAllListeners();
+ mClipTopAnimator.cancel();
+ }
+ mClipTopAnimator = ObjectAnimator.ofInt(this, "clipTop", top);
+ mClipTopAnimator.setDuration(duration);
+ mClipTopAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
+ mClipTopAnimator.start();
+ }
+
+ /** Sets the top clip. */
+ public void setClipTop(int top) {
+ if (top != mClipRect.top) {
+ mClipRect.top = top;
+ mSourceView.invalidateOutline();
+ }
+ }
+
+ /** Returns the top clip. */
+ public int getClipTop() {
+ return mClipRect.top;
+ }
+
+ /** Animates the bottom clip. */
+ void animateClipBottom(int bottom, int duration) {
+ if (mClipTopAnimator != null) {
+ mClipTopAnimator.removeAllListeners();
+ mClipTopAnimator.cancel();
+ }
+ mClipTopAnimator = ObjectAnimator.ofInt(this, "clipBottom", bottom);
+ mClipTopAnimator.setDuration(duration);
+ mClipTopAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
+ mClipTopAnimator.start();
+ }
+
+ /** Sets the bottom clip. */
+ public void setClipBottom(int bottom) {
+ if (bottom != mClipRect.bottom) {
+ mClipRect.bottom = bottom;
+ mSourceView.invalidateOutline();
+ }
+ }
+
+ /** Returns the bottom clip. */
+ public int getClipBottom() {
+ return mClipRect.bottom;
+ }
+
+ public void setOutlineClipBottom(int bottom) {
+ if (bottom != mOutlineClipRect.bottom) {
+ mOutlineClipRect.bottom = bottom;
+ mSourceView.invalidateOutline();
+ }
+ }
+
+ public int getOutlineClipBottom() {
+ return mOutlineClipRect.bottom;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/DebugOverlayView.java b/packages/SystemUI/src/com/android/systemui/recents/views/DebugOverlayView.java
new file mode 100644
index 0000000..6c90fe3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/DebugOverlayView.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.Pair;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import java.util.ArrayList;
+
+/**
+ * A full screen overlay layer that allows us to draw views from throughout the system on the top
+ * most layer.
+ */
+public class DebugOverlayView extends FrameLayout {
+
+ final static int sCornerRectSize = 50;
+
+ ArrayList<Pair<Rect, Integer>> mRects = new ArrayList<Pair<Rect, Integer>>();
+ Paint mDebugOutline = new Paint();
+ Paint mTmpPaint = new Paint();
+ boolean mEnabled = true;
+
+ public DebugOverlayView(Context context) {
+ super(context);
+ mDebugOutline.setColor(0xFFff0000);
+ mDebugOutline.setStyle(Paint.Style.STROKE);
+ mDebugOutline.setStrokeWidth(8f);
+ setWillNotDraw(false);
+ }
+
+ /** Enables the debug overlay drawing. */
+ public void enable() {
+ mEnabled = true;
+ invalidate();
+ }
+
+ /** Disables the debug overlay drawing. */
+ public void disable() {
+ mEnabled = false;
+ invalidate();
+ }
+
+ /** Clears all debug rects. */
+ public void clear() {
+ mRects.clear();
+ }
+
+ /** Adds a rect to be drawn. */
+ void addRect(Rect r, int color) {
+ mRects.add(new Pair<Rect, Integer>(r, color));
+ invalidate();
+ }
+
+ /** Adds a view's global rect to be drawn. */
+ void addViewRect(View v, int color) {
+ Rect vr = new Rect();
+ v.getGlobalVisibleRect(vr);
+ mRects.add(new Pair<Rect, Integer>(vr, color));
+ invalidate();
+ }
+
+ /** Adds a rect, relative to a given view to be drawn. */
+ void addRectRelativeToView(View v, Rect r, int color) {
+ Rect vr = new Rect();
+ v.getGlobalVisibleRect(vr);
+ r.offsetTo(vr.left, vr.top);
+ mRects.add(new Pair<Rect, Integer>(r, color));
+ invalidate();
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ addRect(new Rect(0, 0, sCornerRectSize, sCornerRectSize), 0xFFff0000);
+ addRect(new Rect(getMeasuredWidth() - sCornerRectSize, getMeasuredHeight() - sCornerRectSize,
+ getMeasuredWidth(), getMeasuredHeight()), 0xFFff0000);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mEnabled) {
+ // Draw the outline
+ canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mDebugOutline);
+
+ // Draw the rects
+ int numRects = mRects.size();
+ for (int i = 0; i < numRects; i++) {
+ Pair<Rect, Integer> r = mRects.get(i);
+ mTmpPaint.setColor(r.second);
+ canvas.drawRect(r.first, mTmpPaint);
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java
index 3adee0ea..4b5c0bd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java
@@ -17,6 +17,7 @@
package com.android.systemui.recents.views;
import android.content.Context;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
@@ -27,8 +28,6 @@
*/
public class FixedSizeImageView extends ImageView {
- int mFixedWidth;
- int mFixedHeight;
boolean mAllowRelayout = true;
boolean mAllowInvalidate = true;
@@ -49,13 +48,6 @@
}
@Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- mFixedWidth = getMeasuredWidth();
- mFixedHeight = getMeasuredHeight();
- }
-
- @Override
public void requestLayout() {
if (mAllowRelayout) {
super.requestLayout();
@@ -71,7 +63,9 @@
@Override
public void setImageDrawable(Drawable drawable) {
- if (drawable == null || (mFixedWidth > 0 && mFixedHeight > 0)) {
+ boolean isNullBitmapDrawable = (drawable instanceof BitmapDrawable) &&
+ (((BitmapDrawable) drawable).getBitmap() == null);
+ if (drawable == null || isNullBitmapDrawable) {
mAllowRelayout = false;
mAllowInvalidate = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java b/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
deleted file mode 100644
index 63f59be..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.views;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.animation.AccelerateInterpolator;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import com.android.systemui.R;
-import com.android.systemui.recents.RecentsConfiguration;
-
-
-/**
- * The full screen transition view that gets animated down from the full screen into a task
- * thumbnail view.
- */
-public class FullscreenTransitionOverlayView extends FrameLayout {
-
- /** The FullscreenTransitionOverlayView callbacks */
- public interface FullScreenTransitionViewCallbacks {
- void onEnterAnimationComplete();
- }
-
- RecentsConfiguration mConfig;
-
- FullScreenTransitionViewCallbacks mCb;
-
- ImageView mScreenshotView;
- Rect mClipRect = new Rect();
- Paint mLayerPaint = new Paint();
- PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.MULTIPLY);
-
- int mDim;
- int mMaxDim;
- AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator();
-
- boolean mIsAnimating;
- AnimatorSet mEnterAnimation;
-
- public FullscreenTransitionOverlayView(Context context) {
- super(context);
- }
-
- public FullscreenTransitionOverlayView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public FullscreenTransitionOverlayView(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public FullscreenTransitionOverlayView(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- mConfig = RecentsConfiguration.getInstance();
- mMaxDim = mConfig.taskStackMaxDim;
- setClipTop(getClipTop());
- setClipBottom(getClipBottom());
- setDim(getDim());
- setWillNotDraw(false);
- }
-
- @Override
- protected void onFinishInflate() {
- mScreenshotView = (ImageView) findViewById(R.id.image);
- }
-
- /** Sets the callbacks */
- public void setCallbacks(FullScreenTransitionViewCallbacks cb) {
- mCb = cb;
- }
-
- /** Sets the top clip */
- public void setClipTop(int clip) {
- mClipRect.top = clip;
- setClipBounds(mClipRect);
- }
-
- /** Gets the top clip */
- public int getClipTop() {
- return mClipRect.top;
- }
-
- /** Sets the bottom clip */
- public void setClipBottom(int clip) {
- mClipRect.bottom = clip;
- setClipBounds(mClipRect);
- }
-
- /** Gets the top clip */
- public int getClipBottom() {
- return mClipRect.bottom;
- }
-
- /** Returns the current dim. */
- public void setDim(int dim) {
- mDim = dim;
- /*
- int inverse = 255 - mDim;
- mDimColorFilter.setColor(Color.argb(0xFF, inverse, inverse, inverse));
- mLayerPaint.setColorFilter(mDimColorFilter);
- setLayerType(LAYER_TYPE_HARDWARE, mLayerPaint);
- */
- }
-
- /** Returns the current dim. */
- public int getDim() {
- return mDim;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- mClipRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
- }
-
- @Override
- public boolean hasOverlappingRendering() {
- return false;
- }
-
- /** Prepares the screenshot view for the transition into Recents */
- public void prepareAnimateOnEnterRecents(Bitmap screenshot) {
- if (!mConfig.launchedFromAppWithScreenshot) return;
-
- setClipTop(0);
- setClipBottom(getMeasuredHeight());
- setDim(0);
- setTranslationY(0f);
- setScaleX(1f);
- setScaleY(1f);
- setVisibility(mConfig.launchedFromAppWithScreenshot ? View.VISIBLE : View.INVISIBLE);
- if (screenshot != null) {
- mScreenshotView.setImageBitmap(screenshot);
- } else {
- mScreenshotView.setImageDrawable(null);
- }
- }
-
- /** Resets the transition view */
- public void reset() {
- setVisibility(View.GONE);
- mScreenshotView.setImageDrawable(null);
- }
-
- /** Animates this view as it enters recents */
- public void animateOnEnterRecents(ViewAnimation.TaskViewEnterContext ctx,
- final Runnable postAnimRunnable) {
- // Cancel the current animation
- if (mEnterAnimation != null) {
- mEnterAnimation.removeAllListeners();
- mEnterAnimation.cancel();
- }
-
- // Calculate the bottom clip
- Rect targetTaskRect = ctx.targetTaskTransform.rect;
- float scale = (float) targetTaskRect.width() / getMeasuredWidth();
- float scaleYOffset = ((1f - scale) * getMeasuredHeight()) / 2;
- float scaledTopInset = (int) (scale * mConfig.systemInsets.top);
- int translationY = (int) -scaleYOffset + (int) (mConfig.systemInsets.top - scaledTopInset)
- + targetTaskRect.top;
- int clipBottom = mConfig.systemInsets.top + (int) (targetTaskRect.height() / scale);
-
- // Calculate the dim
- float minScale = TaskStackViewLayoutAlgorithm.StackPeekMinScale;
- float scaleRange = 1f - minScale;
- float dim = (1f - ctx.targetTaskTransform.scale) / scaleRange;
- dim = mDimInterpolator.getInterpolation(Math.min(dim, 1f));
- int toDim = Math.max(0, Math.min(mMaxDim, (int) (dim * 255)));
-
- // Enable the HW Layers on the screenshot view
- mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, mLayerPaint);
-
- // Compose the animation
- mEnterAnimation = new AnimatorSet();
- mEnterAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- post(new Runnable() {
- @Override
- public void run() {
- // Mark that we are no longer animating
- mIsAnimating = false;
- // Disable the HW Layers on this view
- setLayerType(View.LAYER_TYPE_NONE, mLayerPaint);
- // Notify any callbacks
- mCb.onEnterAnimationComplete();
- // Run the given post-anim runnable
- postAnimRunnable.run();
- }
- });
- }
- });
- // XXX: Translation y should be negative initially to simulate moving from the top of the screen?
- mEnterAnimation.setStartDelay(0);
- mEnterAnimation.setDuration(475);
- mEnterAnimation.setInterpolator(mConfig.fastOutSlowInInterpolator);
- mEnterAnimation.playTogether(
- // ObjectAnimator.ofInt(this, "clipTop", mConfig.systemInsets.top),
- ObjectAnimator.ofInt(this, "clipBottom", clipBottom),
- ObjectAnimator.ofInt(this, "dim", toDim),
- ObjectAnimator.ofFloat(this, "translationY", translationY),
- ObjectAnimator.ofFloat(this, "scaleX", scale),
- ObjectAnimator.ofFloat(this, "scaleY", scale)
- );
- setClipTop(mConfig.systemInsets.top);
- mEnterAnimation.start();
-
- mIsAnimating = true;
- }
-
- /** Animates this view back out of Recents if we were in the process of animating in. */
- public boolean cancelAnimateOnEnterRecents(final Runnable postAnimRunnable) {
- if (mIsAnimating) {
- // Cancel the current animation
- if (mEnterAnimation != null) {
- mEnterAnimation.removeAllListeners();
- mEnterAnimation.cancel();
- }
-
- // Enable the HW Layers on the screenshot view
- mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, mLayerPaint);
-
- // Compose the animation
- mEnterAnimation = new AnimatorSet();
- mEnterAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- post(new Runnable() {
- @Override
- public void run() {
- // Mark that we are no longer animating
- mIsAnimating = false;
- // Disable the HW Layers on the screenshot view
- mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, mLayerPaint);
- // Notify any callbacks
- mCb.onEnterAnimationComplete();
- // Run the given post-anim runnable
- postAnimRunnable.run();
- }
- });
- }
- });
- mEnterAnimation.setDuration(475);
- mEnterAnimation.setInterpolator(mConfig.fastOutSlowInInterpolator);
- mEnterAnimation.playTogether(
- ObjectAnimator.ofInt(this, "clipTop", 0),
- ObjectAnimator.ofInt(this, "clipBottom", getMeasuredHeight()),
- ObjectAnimator.ofInt(this, "dim", 0),
- ObjectAnimator.ofFloat(this, "translationY", 0f),
- ObjectAnimator.ofFloat(this, "scaleX", 1f),
- ObjectAnimator.ofFloat(this, "scaleY", 1f)
- );
- mEnterAnimation.start();
-
- return true;
- }
- return false;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index e1c652e..356841f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -24,10 +24,8 @@
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
-import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -41,7 +39,6 @@
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsPackageMonitor;
import com.android.systemui.recents.model.RecentsTaskLoader;
-import com.android.systemui.recents.model.SpaceNode;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
@@ -64,13 +61,10 @@
RecentsConfiguration mConfig;
LayoutInflater mInflater;
- Paint mDebugModePaint;
+ DebugOverlayView mDebugOverlay;
- // The space partitioning root of this container
- SpaceNode mBSP;
- // Search bar view
+ ArrayList<TaskStack> mStacks;
View mSearchBar;
- // Recents view callbacks
RecentsViewCallbacks mCb;
public RecentsView(Context context) {
@@ -96,10 +90,13 @@
mCb = cb;
}
- /** Set/get the bsp root node */
- public void setBSP(SpaceNode n) {
- mBSP = n;
+ /** Sets the debug overlay */
+ public void setDebugOverlay(DebugOverlayView overlay) {
+ mDebugOverlay = overlay;
+ }
+ /** Set/get the bsp root node */
+ public void setTaskStacks(ArrayList<TaskStack> stacks) {
// Remove all TaskStackViews (but leave the search bar)
int childCount = getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
@@ -110,21 +107,18 @@
}
// Create and add all the stacks for this partition of space.
- ArrayList<TaskStack> stacks = mBSP.getStacks();
- for (TaskStack stack : stacks) {
+ mStacks = stacks;
+ int numStacks = mStacks.size();
+ for (int i = 0; i < numStacks; i++) {
+ TaskStack stack = mStacks.get(i);
TaskStackView stackView = new TaskStackView(getContext(), stack);
stackView.setCallbacks(this);
+ // Enable debug mode drawing
+ if (mConfig.debugModeEnabled) {
+ stackView.setDebugOverlay(mDebugOverlay);
+ }
addView(stackView);
}
-
- // Enable debug mode drawing
- if (mConfig.debugModeEnabled) {
- mDebugModePaint = new Paint();
- mDebugModePaint.setColor(0xFFff0000);
- mDebugModePaint.setStyle(Paint.Style.STROKE);
- mDebugModePaint.setStrokeWidth(5f);
- setWillNotDraw(false);
- }
}
/** Launches the focused task from the first stack if possible */
@@ -151,8 +145,8 @@
return false;
}
- /** Launches the first task from the first stack if possible */
- public boolean launchFirstTask() {
+ /** Launches the task that Recents was launched from, if possible */
+ public boolean launchPreviousTask() {
// Get the first stack view
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -162,20 +156,17 @@
TaskStack stack = stackView.mStack;
ArrayList<Task> tasks = stack.getTasks();
- // Get the first task in the stack
+ // Find the launch task in the stack
if (!tasks.isEmpty()) {
- Task task = tasks.get(tasks.size() - 1);
- TaskView tv = null;
-
- // Try and use the first child task view as the source of the launch animation
- if (stackView.getChildCount() > 0) {
- TaskView stv = (TaskView) stackView.getChildAt(stackView.getChildCount() - 1);
- if (stv.getTask() == task) {
- tv = stv;
+ int taskCount = tasks.size();
+ for (int j = 0; j < taskCount; j++) {
+ if (tasks.get(j).isLaunchTarget) {
+ Task task = tasks.get(j);
+ TaskView tv = stackView.getChildViewForTask(task);
+ onTaskViewClicked(stackView, tv, stack, task, false);
+ return true;
}
}
- onTaskViewClicked(stackView, tv, stack, task, false);
- return true;
}
}
}
@@ -243,35 +234,31 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
- int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
- int heightMode = MeasureSpec.getMode(heightMeasureSpec);
// Get the search bar bounds and measure the search bar layout
if (mSearchBar != null) {
Rect searchBarSpaceBounds = new Rect();
- mConfig.getSearchBarBounds(width, height - mConfig.systemInsets.top, searchBarSpaceBounds);
+ mConfig.getSearchBarBounds(width, height, mConfig.systemInsets.top, searchBarSpaceBounds);
mSearchBar.measure(
MeasureSpec.makeMeasureSpec(searchBarSpaceBounds.width(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(searchBarSpaceBounds.height(), MeasureSpec.EXACTLY));
}
- // We give the full width of the space, not including the right nav bar insets in landscape,
- // to the stack view, since we want the tasks to render under the search bar in landscape.
- // In addition, we give it the full height, not including the top inset or search bar space,
- // since we want the tasks to render under the navigation buttons in portrait.
Rect taskStackBounds = new Rect();
- mConfig.getTaskStackBounds(width, height, taskStackBounds);
- int childWidth = width - mConfig.systemInsets.right;
- int childHeight = taskStackBounds.height() - mConfig.systemInsets.top;
+ mConfig.getTaskStackBounds(width, height, mConfig.systemInsets.top,
+ mConfig.systemInsets.right, taskStackBounds);
- // Measure each TaskStackView
+ // Measure each TaskStackView with the full width and height of the window since the
+ // transition view is a child of that stack view
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child != mSearchBar && child.getVisibility() != GONE) {
- child.measure(MeasureSpec.makeMeasureSpec(childWidth, widthMode),
- MeasureSpec.makeMeasureSpec(childHeight, heightMode));
+ TaskStackView tsv = (TaskStackView) child;
+ // Set the insets to be the top/left inset + search bounds
+ tsv.setStackInsetRect(taskStackBounds);
+ tsv.measure(widthMeasureSpec, heightMeasureSpec);
}
}
@@ -286,49 +273,30 @@
// Get the search bar bounds so that we lay it out
if (mSearchBar != null) {
Rect searchBarSpaceBounds = new Rect();
- mConfig.getSearchBarBounds(getMeasuredWidth(), getMeasuredHeight(), searchBarSpaceBounds);
- mSearchBar.layout(mConfig.systemInsets.left + searchBarSpaceBounds.left,
- mConfig.systemInsets.top + searchBarSpaceBounds.top,
- mConfig.systemInsets.left + mSearchBar.getMeasuredWidth(),
- mConfig.systemInsets.top + mSearchBar.getMeasuredHeight());
+ mConfig.getSearchBarBounds(getMeasuredWidth(), getMeasuredHeight(),
+ mConfig.systemInsets.top, searchBarSpaceBounds);
+ mSearchBar.layout(searchBarSpaceBounds.left, searchBarSpaceBounds.top,
+ searchBarSpaceBounds.right, searchBarSpaceBounds.bottom);
}
- // We offset the stack view by the left inset (if any), but lay it out under the search bar.
- // In addition, we offset our stack views by the top inset and search bar height, but not
- // the bottom insets because we want it to render under the navigation buttons.
- Rect taskStackBounds = new Rect();
- mConfig.getTaskStackBounds(getMeasuredWidth(), getMeasuredHeight(), taskStackBounds);
- left += mConfig.systemInsets.left;
- top += mConfig.systemInsets.top + taskStackBounds.top;
-
- // Layout each child
- // XXX: Based on the space node for that task view
+ // Layout each TaskStackView with the full width and height of the window since the
+ // transition view is a child of that stack view
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child != mSearchBar && child.getVisibility() != GONE) {
- TaskStackView tsv = (TaskStackView) child;
- child.layout(left, top, left + tsv.getMeasuredWidth(), top + tsv.getMeasuredHeight());
+ child.layout(left, top, left + child.getMeasuredWidth(),
+ top + child.getMeasuredHeight());
}
}
}
@Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- // Debug mode drawing
- if (mConfig.debugModeEnabled) {
- canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mDebugModePaint);
- }
- }
-
- @Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
// Update the configuration with the latest system insets and trigger a relayout
mConfig.updateSystemInsets(insets.getSystemWindowInsets());
requestLayout();
-
- return insets.consumeSystemWindowInsets(false, false, false, true);
+ return insets.consumeSystemWindowInsets();
}
/** Notifies each task view of the user interaction. */
@@ -365,11 +333,12 @@
/** Unfilters any filtered stacks */
public boolean unfilterFilteredStacks() {
- if (mBSP != null) {
+ if (mStacks != null) {
// Check if there are any filtered stacks and unfilter them before we back out of Recents
boolean stacksUnfiltered = false;
- ArrayList<TaskStack> stacks = mBSP.getStacks();
- for (TaskStack stack : stacks) {
+ int numStacks = mStacks.size();
+ for (int i = 0; i < numStacks; i++) {
+ TaskStack stack = mStacks.get(i);
if (stack.hasFilteredTasks()) {
stack.unfilterTasks();
stacksUnfiltered = true;
@@ -452,8 +421,7 @@
public void run() {
if (task.isActive) {
// Bring an active task to the foreground
- RecentsTaskLoader.getInstance().getSystemServicesProxy()
- .moveTaskToFront(task.key.id, launchOpts);
+ ssp.moveTaskToFront(task.key.id, launchOpts);
} else {
// Launch the activity anew with the desired animation
Intent i = new Intent(task.key.baseIntent);
@@ -463,15 +431,9 @@
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
try {
- UserHandle taskUser = new UserHandle(task.userId);
- if (launchOpts != null) {
- getContext().startActivityAsUser(i, launchOpts.toBundle(), taskUser);
-
- } else {
- getContext().startActivityAsUser(i, taskUser);
- if (lockToTask) {
- ssp.lockCurrentTask();
- }
+ ssp.startActivityFromRecents(task.key.id, launchOpts);
+ if (launchOpts == null && lockToTask) {
+ ssp.lockCurrentTask();
}
} catch (ActivityNotFoundException anfe) {
Console.logError(getContext(), "Could not start Activity");
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
index deb9df3..fd636ed 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
@@ -22,6 +22,7 @@
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
@@ -43,8 +44,6 @@
RecentsConfiguration mConfig;
- Task mTask;
-
ImageView mDismissButton;
ImageView mApplicationIcon;
TextView mActivityDescription;
@@ -52,7 +51,8 @@
Drawable mLightDismissDrawable;
Drawable mDarkDismissDrawable;
- Paint mLayerPaint = new Paint();
+ boolean mIsFullscreen;
+
static Paint sHighlightPaint;
public TaskBarView(Context context) {
@@ -113,11 +113,18 @@
@Override
protected void onDraw(Canvas canvas) {
- // Draw the highlight at the top edge (but put the bottom edge just out of view)
- float offset = mConfig.taskViewHighlightPx / 2f;
- float radius = mConfig.taskViewRoundedCornerRadiusPx;
- canvas.drawRoundRect(-offset, 0f, (float) getMeasuredWidth() + offset,
- getMeasuredHeight() + radius, radius, radius, sHighlightPaint);
+ if (!mIsFullscreen) {
+ // Draw the highlight at the top edge (but put the bottom edge just out of view)
+ float offset = mConfig.taskViewHighlightPx / 2f;
+ float radius = mConfig.taskViewRoundedCornerRadiusPx;
+ canvas.drawRoundRect(-offset, 0f, (float) getMeasuredWidth() + offset,
+ getMeasuredHeight() + radius, radius, radius, sHighlightPaint);
+ }
+ }
+
+ /** Sets whether the current task is full screen or not. */
+ void setIsFullscreen(boolean isFullscreen) {
+ mIsFullscreen = isFullscreen;
}
/** Synchronizes this bar view's properties with the task's transform */
@@ -149,7 +156,6 @@
/** Binds the bar view to the task */
void rebindToTask(Task t) {
- mTask = t;
// If an activity icon is defined, then we use that as the primary icon to show in the bar,
// otherwise, we fall back to the application icon
if (t.activityIcon != null) {
@@ -161,7 +167,11 @@
mActivityDescription.setText(t.activityLabel);
}
// Try and apply the system ui tint
- setBackgroundColor(t.colorPrimary);
+ int existingBgColor = (getBackground() instanceof ColorDrawable) ?
+ ((ColorDrawable) getBackground()).getColor() : 0;
+ if (existingBgColor != t.colorPrimary) {
+ setBackgroundColor(t.colorPrimary);
+ }
mActivityDescription.setTextColor(t.useLightOnPrimaryColor ?
mConfig.taskBarViewLightTextColor : mConfig.taskBarViewDarkTextColor);
mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
@@ -170,7 +180,6 @@
/** Unbinds the bar view from the task */
void unbindFromTask() {
- mTask = null;
mApplicationIcon.setImageDrawable(null);
}
@@ -247,14 +256,4 @@
mDismissButton.setAlpha(1f);
}
}
-
- /** Enable the hw layers on this task view */
- void enableHwLayers() {
- mDismissButton.setLayerType(View.LAYER_TYPE_HARDWARE, mLayerPaint);
- }
-
- /** Disable the hw layers on this task view */
- void disableHwLayers() {
- mDismissButton.setLayerType(View.LAYER_TYPE_NONE, mLayerPaint);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskFooterView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskFooterView.java
new file mode 100644
index 0000000..95af1c9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskFooterView.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import com.android.systemui.recents.RecentsConfiguration;
+
+
+/** The task footer view */
+public class TaskFooterView extends FrameLayout {
+
+ interface TaskFooterViewCallbacks {
+ public void onTaskFooterHeightChanged(int height, int maxHeight);
+ }
+
+ RecentsConfiguration mConfig;
+
+ TaskFooterViewCallbacks mCb;
+ int mFooterHeight;
+ int mMaxFooterHeight;
+ ObjectAnimator mFooterAnimator;
+
+ public TaskFooterView(Context context) {
+ this(context, null);
+ }
+
+ public TaskFooterView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TaskFooterView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public TaskFooterView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ mConfig = RecentsConfiguration.getInstance();
+ mMaxFooterHeight = mConfig.taskViewLockToAppButtonHeight;
+ setFooterHeight(getFooterHeight());
+ }
+
+ /** Sets the callbacks for when the footer height changes. */
+ void setCallbacks(TaskFooterViewCallbacks cb) {
+ mCb = cb;
+ mCb.onTaskFooterHeightChanged(mFooterHeight, mMaxFooterHeight);
+ }
+
+ /** Sets the footer height. */
+ public void setFooterHeight(int footerHeight) {
+ if (footerHeight != mFooterHeight) {
+ mFooterHeight = footerHeight;
+ mCb.onTaskFooterHeightChanged(footerHeight, mMaxFooterHeight);
+ }
+ }
+
+ /** Gets the footer height. */
+ public int getFooterHeight() {
+ return mFooterHeight;
+ }
+
+ /** Animates the footer into and out of view. */
+ void animateFooterVisibility(final boolean visible, int duration) {
+ // Return early if there is no footer
+ if (mMaxFooterHeight <= 0) return;
+ // Return early if we are already in the final state
+ if (!visible && getVisibility() != View.VISIBLE) return;
+ if (visible && getVisibility() == View.VISIBLE) return;
+
+ // Cancel the previous animation
+ if (mFooterAnimator != null) {
+ mFooterAnimator.removeAllListeners();
+ mFooterAnimator.cancel();
+ }
+ int finalHeight = visible ? mMaxFooterHeight : 0;
+ if (duration > 0) {
+ // Make the view visible for the animation
+ if (visible && getVisibility() != View.VISIBLE) {
+ setVisibility(View.VISIBLE);
+ }
+ mFooterAnimator = ObjectAnimator.ofInt(this, "footerHeight", finalHeight);
+ mFooterAnimator.setDuration(duration);
+ mFooterAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
+ mFooterAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!visible) {
+ setVisibility(View.INVISIBLE);
+ }
+ }
+ });
+ mFooterAnimator.start();
+ } else {
+ setFooterHeight(finalHeight);
+ setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 8b86258..f135e32 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -23,7 +23,6 @@
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Canvas;
-import android.graphics.Paint;
import android.graphics.Rect;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -73,6 +72,8 @@
ViewPool<TaskView, Task> mViewPool;
ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<TaskViewTransform>();
DozeTrigger mUIDozeTrigger;
+ DebugOverlayView mDebugOverlay;
+ Rect mTaskStackBounds = new Rect();
// The virtual stack scroll that we use for the card layout
int mStackScroll;
@@ -94,14 +95,20 @@
int[] mTmpVisibleRange = new int[2];
Rect mTmpRect = new Rect();
Rect mTmpRect2 = new Rect();
+ TaskViewTransform mTmpTransform = new TaskViewTransform();
+ HashMap<Task, TaskView> mTmpTaskViewMap = new HashMap<Task, TaskView>();
LayoutInflater mInflater;
+ // A convenience runnable to return all views to the pool
Runnable mReturnAllViewsToPoolRunnable = new Runnable() {
@Override
public void run() {
int childCount = getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
- mViewPool.returnViewToPool((TaskView) getChildAt(i));
+ TaskView tv = (TaskView) getChildAt(i);
+ mViewPool.returnViewToPool(tv);
+ // Also hide the view since we don't need it anymore
+ tv.setVisibility(View.INVISIBLE);
}
}
};
@@ -128,33 +135,6 @@
}
}
});
- mHwLayersTrigger = new ReferenceCountedTrigger(getContext(), new Runnable() {
- @Override
- public void run() {
- // Enable hw layers on each of the children
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- TaskView tv = (TaskView) getChildAt(i);
- tv.enableHwLayers();
- }
- }
- }, new Runnable() {
- @Override
- public void run() {
- // Disable hw layers on each of the children
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- TaskView tv = (TaskView) getChildAt(i);
- tv.disableHwLayers();
- }
- }
- }, new Runnable() {
- @Override
- public void run() {
- new Throwable("Invalid hw layers ref count").printStackTrace();
- Console.logError(getContext(), "Invalid HW layers ref count");
- }
- });
}
/** Sets the callbacks */
@@ -162,6 +142,11 @@
mCb = cb;
}
+ /** Sets the debug overlay */
+ public void setDebugOverlay(DebugOverlayView overlay) {
+ mDebugOverlay = overlay;
+ }
+
/** Requests that the views be synchronized with the model */
void requestSynchronizeStackViewsWithModel() {
requestSynchronizeStackViewsWithModel(0);
@@ -179,19 +164,8 @@
}
}
- /** Returns a mapping of child view to Task. */
- HashMap<Task, TaskView> getTaskChildViewMap() {
- HashMap<Task, TaskView> taskViewMap = new HashMap<Task, TaskView>();
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- TaskView tv = (TaskView) getChildAt(i);
- taskViewMap.put(tv.getTask(), tv);
- }
- return taskViewMap;
- }
-
/** Finds the child view given a specific task. */
- TaskView getChildViewForTask(Task t) {
+ public TaskView getChildViewForTask(Task t) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView tv = (TaskView) getChildAt(i);
@@ -210,19 +184,23 @@
/**
* Gets the stack transforms of a list of tasks, and returns the visible range of tasks.
*/
- private void updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
+ private boolean updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
ArrayList<Task> tasks,
int stackScroll,
int[] visibleRangeOut,
boolean boundTranslationsToRect) {
- // XXX: We should be intelligent about where to look for the visible stack range using the
+ // XXX: We should be intelligent about wheee to look for the visible stack range using the
// current stack scroll.
+ // XXX: We should log extra cases like the ones below where we don't expect to hit very often
+ // XXX: Print out approximately how many indices we have to go through to find the first visible transform
int taskTransformCount = taskTransforms.size();
int taskCount = tasks.size();
int frontMostVisibleIndex = -1;
int backMostVisibleIndex = -1;
+
+
// We can reuse the task transforms where possible to reduce object allocation
if (taskTransformCount < taskCount) {
// If there are less transforms than tasks, then add as many transforms as necessary
@@ -256,13 +234,14 @@
if (boundTranslationsToRect) {
transform.translationY = Math.min(transform.translationY,
- mStackAlgorithm.mRect.bottom);
+ mStackAlgorithm.mViewRect.bottom);
}
}
if (visibleRangeOut != null) {
visibleRangeOut[0] = frontMostVisibleIndex;
visibleRangeOut[1] = backMostVisibleIndex;
}
+ return frontMostVisibleIndex != -1 && backMostVisibleIndex != -1;
}
/**
@@ -280,34 +259,33 @@
}
/** Synchronizes the views with the model */
- void synchronizeStackViewsWithModel() {
+ boolean synchronizeStackViewsWithModel() {
if (mStackViewsDirty) {
// Get all the task transforms
ArrayList<Task> tasks = mStack.getTasks();
int stackScroll = getStackScroll();
int[] visibleRange = mTmpVisibleRange;
- updateStackTransforms(mCurrentTaskTransforms, tasks, stackScroll, visibleRange, false);
- TaskViewTransform tmpTransform = new TaskViewTransform();
+ boolean isValidVisibleRange = updateStackTransforms(mCurrentTaskTransforms, tasks, stackScroll, visibleRange, false);
// Return all the invisible children to the pool
- HashMap<Task, TaskView> taskChildViewMap = getTaskChildViewMap();
+ mTmpTaskViewMap.clear();
int childCount = getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
TaskView tv = (TaskView) getChildAt(i);
Task task = tv.getTask();
int taskIndex = mStack.indexOfTask(task);
- if (taskIndex < visibleRange[1] || taskIndex > visibleRange[0]) {
- taskChildViewMap.remove(task);
+ if (visibleRange[1] <= taskIndex && taskIndex <= visibleRange[0]) {
+ mTmpTaskViewMap.put(task, tv);
+ } else {
mViewPool.returnViewToPool(tv);
}
}
// Pick up all the newly visible children and update all the existing children
- boolean isValidVisibleRange = visibleRange[0] != -1 && visibleRange[1] != -1;
for (int i = visibleRange[0]; isValidVisibleRange && i >= visibleRange[1]; i--) {
Task task = tasks.get(i);
TaskViewTransform transform = mCurrentTaskTransforms.get(i);
- TaskView tv = taskChildViewMap.get(task);
+ TaskView tv = mTmpTaskViewMap.get(task);
int taskIndex = mStack.indexOfTask(task);
if (tv == null) {
@@ -316,23 +294,26 @@
// For items in the list, put them in start animating them from the
// approriate ends of the list where they are expected to appear
if (transform.t < 0) {
- tmpTransform = mStackAlgorithm.getStackTransform(tasks.get(0), stackScroll, tmpTransform);
+ mTmpTransform = mStackAlgorithm.getStackTransform(tasks.get(0), stackScroll, mTmpTransform);
} else {
- tmpTransform = mStackAlgorithm.getStackTransform(tasks.get(Math.min(tasks.size() - 1, visibleRange[0] + 1)),
- stackScroll, tmpTransform);
+ int nextTaskStackScroll = mStackAlgorithm.getStackScrollForTaskIndex(task, 1);
+ mStackAlgorithm.getStackTransform(nextTaskStackScroll, stackScroll, mTmpTransform);
}
- tv.updateViewPropertiesToTaskTransform(tmpTransform, 0);
+ tv.updateViewPropertiesToTaskTransform(mTmpTransform, 0);
}
}
- // Update and animate the task into place
+ // Animate the task into place
tv.updateViewPropertiesToTaskTransform(mCurrentTaskTransforms.get(taskIndex),
mStackViewsAnimationDuration);
}
+ // Reset the request-synchronize params
mStackViewsAnimationDuration = 0;
mStackViewsDirty = false;
+ return true;
}
+ return false;
}
/** Updates the clip for each of the task views. */
@@ -368,13 +349,13 @@
clipBottom = (mTmpRect.bottom - scaledMaxFooterHeight - mTmpRect2.top);
}
}
- tv.setClipFromBottom(clipBottom);
+ tv.getViewBounds().setClipBottom(clipBottom);
}
- }
- if (getChildCount() > 0) {
- // The front most task should never be clipped
- TaskView tv = (TaskView) getChildAt(getChildCount() - 1);
- tv.setClipFromBottom(0);
+ if (getChildCount() > 0) {
+ // The front most task should never be clipped
+ TaskView tv = (TaskView) getChildAt(getChildCount() - 1);
+ tv.getViewBounds().setClipBottom(0);
+ }
}
}
@@ -384,18 +365,24 @@
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView tv = (TaskView) getChildAt(i);
- tv.setClipFromBottom(0);
+ tv.getViewBounds().setClipBottom(0);
}
}
mEnableStackClipping = stackClippingEnabled;
}
+ /** The stack insets to apply to the stack contents */
+ public void setStackInsetRect(Rect r) {
+ mTaskStackBounds.set(r);
+ }
+
/** Sets the current stack scroll */
public void setStackScroll(int value) {
mStackScroll = value;
mUIDozeTrigger.poke();
requestSynchronizeStackViewsWithModel();
}
+
/** Sets the current stack scroll without synchronizing the stack view with the model */
public void setStackScrollRaw(int value) {
mStackScroll = value;
@@ -408,7 +395,7 @@
/** Computes the initial stack scroll for the stack. */
int getInitialStackScroll() {
if (mStack.getTaskCount() > 2) {
- return mMaxScroll - (int) (mStackAlgorithm.mTaskRect.height() * (3f/4f));
+ return Math.max(mMinScroll, mMaxScroll - (int) (mStackAlgorithm.mTaskRect.height() * (3f/4f)));
}
return mMaxScroll;
}
@@ -423,17 +410,8 @@
int curScroll = getStackScroll();
int newScroll = Math.max(mMinScroll, Math.min(mMaxScroll, curScroll));
if (newScroll != curScroll) {
- // Enable hw layers on the stack
- addHwLayersRefCount("animateBoundScroll");
-
// Start a new scroll animation
- animateScroll(curScroll, newScroll, new Runnable() {
- @Override
- public void run() {
- // Disable hw layers on the stack
- decHwLayersRefCount("animateBoundScroll");
- }
- });
+ animateScroll(curScroll, newScroll, null);
}
return mScrollAnimator;
}
@@ -478,8 +456,6 @@
if (!mScroller.isFinished()) {
// Abort the scroller
mScroller.abortAnimation();
- // And disable hw layers on the stack
- decHwLayersRefCount("flingScroll");
}
}
@@ -521,7 +497,7 @@
/** Returns whether the specified scroll is out of bounds */
boolean isScrollOutOfBounds() {
- return getScrollAmountOutOfBounds(getStackScroll()) != 0;
+ return getScrollAmountOutOfBounds(mStackScroll) != 0;
}
/** Updates the min and max virtual scroll bounds */
@@ -603,17 +579,6 @@
focusTask(mFocusedTaskIndex, true);
}
- /** Enables the hw layers and increments the hw layer requirement ref count */
- void addHwLayersRefCount(String reason) {
- mHwLayersTrigger.increment();
- }
-
- /** Decrements the hw layer requirement ref count and disables the hw layers when we don't
- need them anymore. */
- void decHwLayersRefCount(String reason) {
- mHwLayersTrigger.decrement();
- }
-
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mTouchHandler.onInterceptTouchEvent(ev);
@@ -629,34 +594,29 @@
if (mScroller.computeScrollOffset()) {
setStackScroll(mScroller.getCurrY());
invalidate();
-
- // If we just finished scrolling, then disable the hw layers
- if (mScroller.isFinished()) {
- decHwLayersRefCount("finishedFlingScroll");
- }
}
}
@Override
public void dispatchDraw(Canvas canvas) {
- synchronizeStackViewsWithModel();
- clipTaskViews();
+ if (synchronizeStackViewsWithModel()) {
+ clipTaskViews();
+ }
super.dispatchDraw(canvas);
}
/** Computes the stack and task rects */
- public void computeRects(int width, int height, int insetLeft, int insetBottom) {
+ public void computeRects(int windowWidth, int windowHeight, Rect taskStackBounds) {
// Compute the rects in the stack algorithm
- mStackAlgorithm.computeRects(mStack.getTasks(), width, height, insetLeft, insetBottom);
+ mStackAlgorithm.computeRects(mStack.getTasks(), windowWidth, windowHeight, taskStackBounds);
// Update the scroll bounds
updateMinMaxScroll(false);
}
/**
- * This is called with the size of the space not including the top or right insets, or the
- * search bar height in portrait (but including the search bar width in landscape, since we want
- * to draw under it.
+ * This is called with the full window width and height to allow stack view children to
+ * perform the full screen transition down.
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
@@ -664,25 +624,43 @@
int height = MeasureSpec.getSize(heightMeasureSpec);
// Compute our stack/task rects
- Rect taskStackBounds = new Rect();
- mConfig.getTaskStackBounds(width, height, taskStackBounds);
- computeRects(width, height, taskStackBounds.left, mConfig.systemInsets.bottom);
+ Rect taskStackBounds = new Rect(mTaskStackBounds);
+ taskStackBounds.bottom -= mConfig.systemInsets.bottom;
+ computeRects(width, height, taskStackBounds);
// If this is the first layout, then scroll to the front of the stack and synchronize the
- // stack views immediately
+ // stack views immediately to load all the views
if (mAwaitingFirstLayout) {
setStackScrollToInitialState();
requestSynchronizeStackViewsWithModel();
synchronizeStackViewsWithModel();
+
+ // Find the first task and mark it as full screen
+ if (mConfig.launchedFromAppWithScreenshot) {
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ TaskView tv = (TaskView) getChildAt(i);
+ if (tv.getTask().isLaunchTarget) {
+ tv.setIsFullScreen(true);
+ break;
+ }
+ }
+ }
}
- // Measure each of the children
+ // Measure each of the TaskViews
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
- TaskView t = (TaskView) getChildAt(i);
- t.measure(MeasureSpec.makeMeasureSpec(mStackAlgorithm.mTaskRect.width(), MeasureSpec.EXACTLY),
+ TaskView tv = (TaskView) getChildAt(i);
+ if (tv.isFullScreenView()) {
+ tv.measure(widthMeasureSpec, heightMeasureSpec);
+ } else {
+ tv.measure(
+ MeasureSpec.makeMeasureSpec(mStackAlgorithm.mTaskRect.width(),
+ MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mStackAlgorithm.mTaskRect.height() +
- t.getMaxFooterHeight(), MeasureSpec.EXACTLY));
+ tv.getMaxFooterHeight(), MeasureSpec.EXACTLY));
+ }
}
setMeasuredDimension(width, height);
@@ -698,54 +676,45 @@
// Layout each of the children
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
- TaskView t = (TaskView) getChildAt(i);
- t.layout(mStackAlgorithm.mTaskRect.left, mStackAlgorithm.mStackRectSansPeek.top,
- mStackAlgorithm.mTaskRect.right, mStackAlgorithm.mStackRectSansPeek.top +
- mStackAlgorithm.mTaskRect.height() + t.getMaxFooterHeight());
+ TaskView tv = (TaskView) getChildAt(i);
+ if (tv.isFullScreenView()) {
+ tv.layout(left, top, left + tv.getMeasuredWidth(), top + tv.getMeasuredHeight());
+ } else {
+ tv.layout(mStackAlgorithm.mTaskRect.left, mStackAlgorithm.mTaskRect.top,
+ mStackAlgorithm.mTaskRect.right, mStackAlgorithm.mTaskRect.bottom +
+ tv.getMaxFooterHeight());
+ }
}
if (mAwaitingFirstLayout) {
- // Mark that we have completely the first layout
mAwaitingFirstLayout = false;
+ onFirstLayout();
+ }
+ }
- // Find the target task with the specified id
- ArrayList<Task> tasks = mStack.getTasks();
- Task targetTask = null;
- int targetTaskId = mConfig.launchedToTaskId;
- if (targetTaskId != -1) {
- int taskCount = tasks.size();
- for (int i = 0; i < taskCount; i++) {
- Task t = tasks.get(i);
- if (t.key.id == targetTaskId) {
- targetTask = t;
- break;
- }
- }
- }
+ /** Handler for the first layout. */
+ void onFirstLayout() {
+ // Prepare the first view for its enter animation
+ int offscreenY = mStackAlgorithm.mViewRect.bottom -
+ (mStackAlgorithm.mTaskRect.top - mStackAlgorithm.mViewRect.top);
+ int childCount = getChildCount();
+ for (int i = childCount - 1; i >= 0; i--) {
+ TaskView tv = (TaskView) getChildAt(i);
+ tv.prepareEnterRecentsAnimation(tv.getTask().isLaunchTarget, offscreenY);
+ }
- // Prepare the first view for its enter animation
- int offsetTopAlign = -mStackAlgorithm.mTaskRect.top;
- int offscreenY = mStackAlgorithm.mRect.bottom -
- (mStackAlgorithm.mTaskRect.top - mStackAlgorithm.mRect.top);
- for (int i = childCount - 1; i >= 0; i--) {
- TaskView tv = (TaskView) getChildAt(i);
- tv.prepareEnterRecentsAnimation(tv.getTask() == targetTask, offsetTopAlign,
- offscreenY);
- }
+ // If the enter animation started already and we haven't completed a layout yet, do the
+ // enter animation now
+ if (mStartEnterAnimationRequestedAfterLayout) {
+ startEnterRecentsAnimation(mStartEnterAnimationContext);
+ mStartEnterAnimationRequestedAfterLayout = false;
+ mStartEnterAnimationContext = null;
+ }
- // If the enter animation started already and we haven't completed a layout yet, do the
- // enter animation now
- if (mStartEnterAnimationRequestedAfterLayout) {
- startEnterRecentsAnimation(mStartEnterAnimationContext);
- mStartEnterAnimationRequestedAfterLayout = false;
- mStartEnterAnimationContext = null;
- }
-
- // Update the focused task index to be the next item to the top task
- if (mConfig.launchedWithAltTab) {
- // When alt-tabbing, we focus the next previous task
- focusTask(Math.max(0, mStack.getTaskCount() - 2), false);
- }
+ // Update the focused task index to be the next item to the top task
+ if (mConfig.launchedWithAltTab) {
+ // When alt-tabbing, we focus the next previous task
+ focusTask(Math.max(0, mStack.getTaskCount() - 2), false);
}
}
@@ -759,30 +728,6 @@
}
if (mStack.getTaskCount() > 0) {
- // Find the target task with the specified id
- ArrayList<Task> tasks = mStack.getTasks();
- Task targetTask = null;
- int targetTaskId = mConfig.launchedToTaskId;
- if (targetTaskId != -1) {
- int taskCount = tasks.size();
- for (int i = 0; i < taskCount; i++) {
- Task t = tasks.get(i);
- if (t.key.id == targetTaskId) {
- targetTask = t;
- break;
- }
- }
- }
-
- // Find the transform for the target task
- if (targetTask != null) {
- ctx.targetTaskTransform = new TaskViewTransform();
- mStackAlgorithm.getStackTransform(targetTask, getStackScroll(), ctx.targetTaskTransform);
- Rect taskStackBounds = new Rect();
- mConfig.getTaskStackBounds(getMeasuredWidth(), getMeasuredHeight(), taskStackBounds);
- ctx.targetTaskTransform.rect.offset(taskStackBounds.left, taskStackBounds.top);
- }
-
// Animate all the task views into view
int childCount = getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
@@ -791,7 +736,7 @@
ctx.currentTaskTransform = new TaskViewTransform();
ctx.currentStackViewIndex = i;
ctx.currentStackViewCount = childCount;
- ctx.isCurrentTaskLaunchTarget = (task == targetTask);
+ ctx.currentTaskRect = mStackAlgorithm.mTaskRect;
mStackAlgorithm.getStackTransform(task, getStackScroll(), ctx.currentTaskTransform);
tv.startEnterRecentsAnimation(ctx);
}
@@ -802,6 +747,11 @@
public void run() {
// Start dozing
mUIDozeTrigger.startDozing();
+ // Request an update of the task views after the animation in to
+ // relayout the fullscreen view back to its normal size
+ if (mConfig.launchedFromAppWithScreenshot) {
+ requestSynchronizeStackViewsWithModel();
+ }
}
});
}
@@ -810,8 +760,8 @@
/** Requests this task stacks to start it's exit-recents animation. */
public void startExitToHomeAnimation(ViewAnimation.TaskViewExitContext ctx) {
// Animate all the task views into view
- ctx.offscreenTranslationY = mStackAlgorithm.mRect.bottom -
- (mStackAlgorithm.mTaskRect.top - mStackAlgorithm.mRect.top);
+ ctx.offscreenTranslationY = mStackAlgorithm.mViewRect.bottom -
+ (mStackAlgorithm.mTaskRect.top - mStackAlgorithm.mViewRect.top);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView tv = (TaskView) getChildAt(i);
@@ -967,9 +917,6 @@
// Detach the view from the hierarchy
detachViewFromParent(tv);
- // Disable HW layers
- tv.disableHwLayers();
-
// Reset the view properties
tv.resetViewProperties();
}
@@ -1013,11 +960,6 @@
} else {
attachViewToParent(tv, insertIndex, tv.getLayoutParams());
}
-
- // Enable hw layers on this view if hw layers are enabled on the stack
- if (mHwLayersTrigger.getCount() > 0) {
- tv.enableHwLayers();
- }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
index 65407a6..7f94a0a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
@@ -17,7 +17,6 @@
package com.android.systemui.recents.views;
import android.graphics.Rect;
-import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
@@ -30,14 +29,14 @@
// These are all going to change
static final float StackOverlapPct = 0.65f; // The overlap height relative to the task height
- static final float StackPeekHeightPct = 0.1f; // The height of the peek space relative to the stack height
+ static final float StackPeekHeightPct = 0.075f; // The height of the peek space relative to the stack height
static final float StackPeekMinScale = 0.8f; // The min scale of the last card in the peek area
static final int StackPeekNumCards = 3; // The number of cards we see in the peek space
RecentsConfiguration mConfig;
// The various rects that define the stack view
- Rect mRect = new Rect();
+ Rect mViewRect = new Rect();
Rect mStackRect = new Rect();
Rect mStackRectSansPeek = new Rect();
Rect mTaskRect = new Rect();
@@ -53,29 +52,21 @@
}
/** Computes the stack and task rects */
- public void computeRects(ArrayList<Task> tasks, int width, int height, int insetLeft, int insetBottom) {
+ public void computeRects(ArrayList<Task> tasks, int windowWidth, int windowHeight,
+ Rect taskStackBounds) {
// Note: We let the stack view be the full height because we want the cards to go under the
// navigation bar if possible. However, the stack rects which we use to calculate
// max scroll, etc. need to take the nav bar into account
// Compute the stack rects
- mRect.set(0, 0, width, height);
- mStackRect.set(mRect);
- mStackRect.left += insetLeft;
- mStackRect.bottom -= insetBottom;
+ mViewRect.set(0, 0, windowWidth, windowHeight);
+ mStackRect.set(taskStackBounds);
int widthPadding = (int) (mConfig.taskStackWidthPaddingPct * mStackRect.width());
int heightPadding = mConfig.taskStackTopPaddingPx;
- if (Constants.DebugFlags.App.EnableSearchLayout) {
- mStackRect.top += heightPadding;
- mStackRect.left += widthPadding;
- mStackRect.right -= widthPadding;
- mStackRect.bottom -= heightPadding;
- } else {
- mStackRect.inset(widthPadding, heightPadding);
- }
+ mStackRect.inset(widthPadding, heightPadding);
mStackRectSansPeek.set(mStackRect);
- mStackRectSansPeek.top += StackPeekHeightPct * mStackRect.height();
+ mStackRectSansPeek.top += StackPeekHeightPct * windowHeight;
// Compute the task rect
int size = mStackRect.width();
@@ -91,7 +82,7 @@
// Compute the min and max scroll values
int numTasks = Math.max(1, tasks.size());
int taskHeight = mTaskRect.height();
- int stackHeight = mStackRectSansPeek.height();
+ int stackHeight = mStackRect.height();
if (numTasks <= 1) {
// If there is only one task, then center the task in the stack rect (sans peek)
@@ -112,12 +103,16 @@
transformOut.reset();
return transformOut;
}
+ return getStackTransform(getStackScrollForTaskIndex(task), stackScroll, transformOut);
+ }
+ /** Update/get the transform */
+ public TaskViewTransform getStackTransform(int taskStackScroll, int stackScroll, TaskViewTransform transformOut) {
// Map the items to an continuous position relative to the specified scroll
int numPeekCards = StackPeekNumCards;
float overlapHeight = StackOverlapPct * mTaskRect.height();
float peekHeight = StackPeekHeightPct * mStackRect.height();
- float t = (getStackScrollForTaskIndex(task) - stackScroll) / overlapHeight;
+ float t = (taskStackScroll - stackScroll) / overlapHeight;
float boundedT = Math.max(t, -(numPeekCards + 1));
// Set the scale relative to its position
@@ -125,8 +120,8 @@
float minScale = StackPeekMinScale;
float scaleRange = 1f - minScale;
float scaleInc = scaleRange / (numPeekCards + numFrontScaledCards);
- float scale = Math.max(minScale, Math.min(1f, minScale +
- ((boundedT + (numPeekCards + 1)) * scaleInc)));
+ float scale = Math.max(minScale, Math.min(1f, minScale +
+ ((boundedT + (numPeekCards + 1)) * scaleInc)));
float scaleYOffset = ((1f - scale) * mTaskRect.height()) / 2;
// Account for the bar offsets being scaled?
float scaleBarYOffset = (1f - scale) * mConfig.taskBarHeight;
@@ -156,7 +151,7 @@
} else {
transformOut.rect.offset(0, transformOut.translationY);
Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
- transformOut.visible = Rect.intersects(mRect, transformOut.rect);
+ transformOut.visible = Rect.intersects(mViewRect, transformOut.rect);
}
transformOut.t = t;
return transformOut;
@@ -178,6 +173,14 @@
}
/**
+ * Returns the scroll to such that the task transform at that task + index will have t=0.
+ * (If the scroll is not bounded)
+ */
+ int getStackScrollForTaskIndex(Task t, int relativeIndexOffset) {
+ return mTaskOffsetMap.get(t.key) + (int) (relativeIndexOffset * getTaskOverlapHeight());
+ }
+
+ /**
* Updates the cache of tasks to offsets.
*/
void updateTaskOffsets(ArrayList<Task> tasks) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 191dc37..b83f9cc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -148,8 +148,6 @@
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
- // Enable HW layers
- mSv.addHwLayersRefCount("stackScroll");
}
mLastMotionX = x;
@@ -160,10 +158,6 @@
case MotionEvent.ACTION_UP: {
// Animate the scroll back if we've cancelled
mSv.animateBoundScroll();
- // Disable HW layers
- if (mIsScrolling) {
- mSv.decHwLayersRefCount("stackScroll");
- }
// Reset the drag state and the velocity tracker
mIsScrolling = false;
mActivePointerId = INACTIVE_POINTER_ID;
@@ -241,8 +235,6 @@
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
- // Enable HW layers
- mSv.addHwLayersRefCount("stackScroll");
}
}
if (mIsScrolling) {
@@ -271,8 +263,6 @@
int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
if (mIsScrolling && (Math.abs(velocity) > mMinimumVelocity)) {
- // Enable HW layers on the stack
- mSv.addHwLayersRefCount("flingScroll");
// XXX: Make this animation a function of the velocity AND distance
int overscrollRange = (int) (Math.min(1f,
Math.abs((float) velocity / mMaximumVelocity)) *
@@ -291,10 +281,6 @@
mSv.animateBoundScroll();
}
- if (mIsScrolling) {
- // Disable HW layers
- mSv.decHwLayersRefCount("stackScroll");
- }
mActivePointerId = INACTIVE_POINTER_ID;
mIsScrolling = false;
mTotalScrollMotion = 0;
@@ -315,10 +301,6 @@
break;
}
case MotionEvent.ACTION_CANCEL: {
- if (mIsScrolling) {
- // Disable HW layers
- mSv.decHwLayersRefCount("stackScroll");
- }
if (mSv.isScrollOutOfBounds()) {
// Animate the scroll back into bounds
// XXX: Make this animation a function of the velocity OR distance
@@ -351,8 +333,6 @@
TaskView tv = (TaskView) v;
// Disable clipping with the stack while we are swiping
tv.setClipViewInStack(false);
- // Enable HW layers on that task
- tv.enableHwLayers();
// Disallow touch events from this task view
tv.setTouchEnabled(false);
// Hide the footer
@@ -372,10 +352,6 @@
@Override
public void onChildDismissed(View v) {
TaskView tv = (TaskView) v;
- // Disable HW layers on that task
- if (mSv.mHwLayersTrigger.getCount() == 0) {
- tv.disableHwLayers();
- }
// Re-enable clipping with the stack (we will reuse this view)
tv.setClipViewInStack(true);
// Re-enable touch events from this task view
@@ -387,10 +363,6 @@
@Override
public void onSnapBackCompleted(View v) {
TaskView tv = (TaskView) v;
- // Disable HW layers on that task
- if (mSv.mHwLayersTrigger.getCount() == 0) {
- tv.disableHwLayers();
- }
// Re-enable clipping with the stack
tv.setClipViewInStack(true);
// Re-enable touch events from this task view
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskThumbnailView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskThumbnailView.java
index 08a25f1..1116d51 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskThumbnailView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskThumbnailView.java
@@ -17,7 +17,7 @@
package com.android.systemui.recents.views;
import android.content.Context;
-import android.graphics.Canvas;
+import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
@@ -27,11 +27,8 @@
/** The task thumbnail view */
public class TaskThumbnailView extends FixedSizeImageView {
- Task mTask;
-
// Task bar clipping
- Rect mClipRect;
- boolean mClipTaskBar = true;
+ Rect mClipRect = new Rect();
public TaskThumbnailView(Context context) {
this(context, null);
@@ -50,40 +47,51 @@
setScaleType(ScaleType.FIT_XY);
}
- @Override
- public void draw(Canvas canvas) {
- if (mClipTaskBar && (mClipRect != null)) {
- int restoreCount = canvas.save(Canvas.CLIP_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
- canvas.clipRect(mClipRect);
- super.draw(canvas);
- canvas.restoreToCount(restoreCount);
- } else {
- super.draw(canvas);
- }
+ /** Updates the clip rect based on the given task bar. */
+ void enableTaskBarClip(View taskBar) {
+ int top = (int) Math.max(0, taskBar.getTranslationY() +
+ taskBar.getMeasuredHeight() - 1);
+ mClipRect.set(0, top, getMeasuredWidth(), getMeasuredHeight());
+ setClipBounds(mClipRect);
}
- /** Updates the clip rect based on the given task bar. */
- void updateTaskBarClip(View taskBar) {
- // If mClipTaskBar is unset first, then we don't bother setting mTaskBar
- if (mClipTaskBar) {
- int top = (int) Math.max(0, taskBar.getTranslationY() +
- taskBar.getMeasuredHeight() - 1);
- mClipRect = new Rect(0, top, getMeasuredWidth(), getMeasuredHeight());
- invalidate(0, 0, taskBar.getMeasuredWidth(), taskBar.getMeasuredHeight() + 1);
- }
+ /** Convenience method to enable task bar clipping as a runnable. */
+ Runnable enableTaskBarClipAsRunnable(final View taskBar) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ enableTaskBarClip(taskBar);
+ }
+ };
}
/** Disables the task bar clipping. */
- void disableClipTaskBarView() {
- mClipTaskBar = false;
- if (mClipRect != null) {
- invalidate(0, 0, mClipRect.width(), mClipRect.top);
+ Runnable disableTaskBarClipAsRunnable() {
+ return new Runnable() {
+ @Override
+ public void run() {
+ mClipRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
+ setClipBounds(mClipRect);
+ }
+ };
+ }
+
+ /** Binds the thumbnail view to the screenshot. */
+ boolean bindToScreenshot(Bitmap ss) {
+ if (ss != null) {
+ setImageBitmap(ss);
+ return true;
}
+ return false;
+ }
+
+ /** Unbinds the thumbnail view from the screenshot. */
+ void unbindFromScreenshot() {
+ setImageBitmap(null);
}
/** Binds the thumbnail view to the task */
void rebindToTask(Task t) {
- mTask = t;
if (t.thumbnail != null) {
setImageBitmap(t.thumbnail);
}
@@ -91,7 +99,6 @@
/** Unbinds the thumbnail view from the task */
void unbindFromTask() {
- mTask = null;
setImageDrawable(null);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 4757c5f..259706b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -22,24 +22,24 @@
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
-import android.graphics.Outline;
+import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
-import android.view.ViewOutlineProvider;
-import android.view.ViewPropertyAnimator;
import android.view.animation.AccelerateInterpolator;
import android.widget.FrameLayout;
import com.android.systemui.R;
+import com.android.systemui.recents.AlternateRecentsComponent;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.model.Task;
-
/* A task view */
-public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.OnClickListener,
- View.OnLongClickListener {
+public class TaskView extends FrameLayout implements Task.TaskCallbacks,
+ TaskFooterView.TaskFooterViewCallbacks, View.OnClickListener, View.OnLongClickListener {
/** The TaskView callbacks */
interface TaskViewCallbacks {
public void onTaskViewAppIconClicked(TaskView tv);
@@ -51,25 +51,23 @@
RecentsConfiguration mConfig;
- int mFooterHeight;
- int mMaxFooterHeight;
- ObjectAnimator mFooterAnimator;
-
int mDim;
int mMaxDim;
AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator();
+ PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.MULTIPLY);
Task mTask;
boolean mTaskDataLoaded;
boolean mIsFocused;
+ boolean mIsFullScreenView;
boolean mIsStub;
boolean mClipViewInStack;
- int mClipFromBottom;
+ AnimateableViewBounds mViewBounds;
Paint mLayerPaint = new Paint();
TaskThumbnailView mThumbnailView;
TaskBarView mBarView;
- View mLockToAppButtonView;
+ TaskFooterView mFooterView;
TaskViewCallbacks mCb;
// Optimizations
@@ -80,18 +78,6 @@
updateDimOverlayFromScale();
}
};
- Runnable mEnableThumbnailClip = new Runnable() {
- @Override
- public void run() {
- mThumbnailView.updateTaskBarClip(mBarView);
- }
- };
- Runnable mDisableThumbnailClip = new Runnable() {
- @Override
- public void run() {
- mThumbnailView.disableClipTaskBarView();
- }
- };
public TaskView(Context context) {
@@ -109,55 +95,11 @@
public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mConfig = RecentsConfiguration.getInstance();
- mMaxFooterHeight = mConfig.taskViewLockToAppButtonHeight;
- setWillNotDraw(false);
- setClipToOutline(true);
- setDim(getDim());
- setFooterHeight(getFooterHeight());
- setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- // The current height is measured with the footer, so account for the footer height
- // and the current clip (in the stack)
- int height = getMeasuredHeight() - mClipFromBottom - mMaxFooterHeight + mFooterHeight;
- outline.setRoundRect(0, 0, getWidth(), height,
- mConfig.taskViewRoundedCornerRadiusPx);
- }
- });
- }
-
- @Override
- protected void onFinishInflate() {
mMaxDim = mConfig.taskStackMaxDim;
-
- // By default, all views are clipped to other views in their stack
mClipViewInStack = true;
-
- // Bind the views
- mBarView = (TaskBarView) findViewById(R.id.task_view_bar);
- mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail);
- mLockToAppButtonView = findViewById(R.id.lock_to_app);
-
- if (mTaskDataLoaded) {
- onTaskDataLoaded();
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int width = MeasureSpec.getSize(widthMeasureSpec);
- int height = MeasureSpec.getSize(heightMeasureSpec);
-
- // Measure the bar view, thumbnail, and lock-to-app buttons
- mBarView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(mConfig.taskBarHeight, MeasureSpec.EXACTLY));
- mLockToAppButtonView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(mConfig.taskViewLockToAppButtonHeight,
- MeasureSpec.EXACTLY));
- // Measure the thumbnail height to be the same as the width
- mThumbnailView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY));
- setMeasuredDimension(width, height);
+ mViewBounds = new AnimateableViewBounds(this, mConfig.taskViewRoundedCornerRadiusPx);
+ setOutlineProvider(mViewBounds);
+ setDim(getDim());
}
/** Set callback */
@@ -170,74 +112,67 @@
return mTask;
}
+ /** Returns the view bounds. */
+ AnimateableViewBounds getViewBounds() {
+ return mViewBounds;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ // Bind the views
+ mBarView = (TaskBarView) findViewById(R.id.task_view_bar);
+ mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail);
+ mFooterView = (TaskFooterView) findViewById(R.id.lock_to_app);
+ mFooterView.setCallbacks(this);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+
+ // Measure the bar view, thumbnail, and footer
+ mBarView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(mConfig.taskBarHeight, MeasureSpec.EXACTLY));
+ mFooterView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(mConfig.taskViewLockToAppButtonHeight,
+ MeasureSpec.EXACTLY));
+ if (mIsFullScreenView) {
+ // Measure the thumbnail height to be the full dimensions
+ mThumbnailView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+ } else {
+ // Measure the thumbnail to be square
+ mThumbnailView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY));
+ }
+ setMeasuredDimension(width, height);
+ }
+
/** Synchronizes this view's properties with the task's transform */
void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration) {
// Update the bar view
mBarView.updateViewPropertiesToTaskTransform(toTransform, duration);
- // Check to see if any properties have changed, and update the task view
- if (duration > 0) {
- ViewPropertyAnimator anim = animate();
- boolean useLayers = false;
-
- // Animate to the final state
- if (toTransform.hasTranslationYChangedFrom(getTranslationY())) {
- anim.translationY(toTransform.translationY);
- }
- if (Constants.DebugFlags.App.EnableShadows &&
- toTransform.hasTranslationZChangedFrom(getTranslationZ())) {
- anim.translationZ(toTransform.translationZ);
- }
- if (toTransform.hasScaleChangedFrom(getScaleX())) {
- anim.scaleX(toTransform.scale)
- .scaleY(toTransform.scale)
- .setUpdateListener(mUpdateDimListener);
- useLayers = true;
- }
- if (toTransform.hasAlphaChangedFrom(getAlpha())) {
- // Use layers if we animate alpha
- anim.alpha(toTransform.alpha);
- useLayers = true;
- }
- if (useLayers) {
- anim.withLayer();
- }
- anim.setStartDelay(toTransform.startDelay)
- .setDuration(duration)
- .setInterpolator(mConfig.fastOutSlowInInterpolator)
- .start();
- } else {
- // Set the changed properties
- if (toTransform.hasTranslationYChangedFrom(getTranslationY())) {
- setTranslationY(toTransform.translationY);
- }
+ // If we are a full screen view, then only update the Z to keep it in order
+ // XXX: Also update/animate the dim as well
+ if (mIsFullScreenView) {
if (Constants.DebugFlags.App.EnableShadows &&
toTransform.hasTranslationZChangedFrom(getTranslationZ())) {
setTranslationZ(toTransform.translationZ);
}
- if (toTransform.hasScaleChangedFrom(getScaleX())) {
- setScaleX(toTransform.scale);
- setScaleY(toTransform.scale);
- updateDimOverlayFromScale();
- }
- if (toTransform.hasAlphaChangedFrom(getAlpha())) {
- setAlpha(toTransform.alpha);
- }
+ return;
}
+
+ // Apply the transform
+ toTransform.applyToTaskView(this, duration, mConfig.fastOutSlowInInterpolator, false,
+ mUpdateDimListener);
}
/** Resets this view's properties */
void resetViewProperties() {
- setTranslationX(0f);
- setTranslationY(0f);
- if (Constants.DebugFlags.App.EnableShadows) {
- setTranslationZ(0f);
- }
- setScaleX(1f);
- setScaleY(1f);
- setAlpha(1f);
setDim(0);
- invalidate();
+ TaskViewTransform.reset(this);
}
/**
@@ -262,20 +197,13 @@
/** Prepares this task view for the enter-recents animations. This is called earlier in the
* first layout because the actual animation into recents may take a long time. */
- public void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask, int offsetY,
- int offscreenY) {
+ public void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask, int offscreenY) {
if (mConfig.launchedFromAppWithScreenshot) {
if (isTaskViewLaunchTargetTask) {
- // Hide the task view as we are going to animate the full screenshot into view
- // and then replace it with this view once we are done
- setVisibility(View.INVISIBLE);
// Also hide the front most task bar view so we can animate it in
mBarView.prepareEnterRecentsAnimation();
} else {
- // Top align the task views
- setTranslationY(offsetY);
- setScaleX(1f);
- setScaleY(1f);
+ // Don't do anything for the side views
}
} else if (mConfig.launchedFromAppWithThumbnail) {
@@ -300,49 +228,56 @@
/** Animates this task view as it enters recents */
public void startEnterRecentsAnimation(final ViewAnimation.TaskViewEnterContext ctx) {
TaskViewTransform transform = ctx.currentTaskTransform;
+ Rect taskRect = ctx.currentTaskRect;
if (mConfig.launchedFromAppWithScreenshot) {
- if (ctx.isCurrentTaskLaunchTarget) {
- // Animate the full screenshot down first, before swapping with this task view
- ctx.fullScreenshotView.animateOnEnterRecents(ctx, new Runnable() {
- @Override
- public void run() {
- // Animate the task bar of the first task view
- mBarView.startEnterRecentsAnimation(0, mEnableThumbnailClip);
- setVisibility(View.VISIBLE);
- // Animate the footer into view
- animateFooterVisibility(true, mConfig.taskBarEnterAnimDuration);
- // Decrement the post animation trigger
- ctx.postAnimationTrigger.decrement();
- }
- });
- } else {
- // Animate the tasks down behind the full screenshot
- animate()
- .scaleX(transform.scale)
- .scaleY(transform.scale)
- .translationY(transform.translationY)
- .setStartDelay(0)
- .setUpdateListener(null)
- .setInterpolator(mConfig.linearOutSlowInInterpolator)
- .setDuration(475)
- .withLayer()
+ if (mTask.isLaunchTarget) {
+ // XXX: We would have to animate the trasnlationY of the task view bar along with the clip and
+ // reset it at the bottom
+
+ // XXX: This should actually be the inset on the current app...
+ mViewBounds.animateClipTop(taskRect.top, mConfig.taskViewEnterFromHomeDuration * 5);
+ mViewBounds.animateClipBottom(getMeasuredHeight() - taskRect.bottom, mConfig.taskViewEnterFromHomeDuration * 5);
+
+ animate().scaleX(((float) taskRect.width() / getMeasuredWidth()) * transform.scale)
+ .scaleY(((float) taskRect.width() / getMeasuredWidth()) * transform.scale)
+ .translationY(taskRect.top + transform.translationY)
+ .setDuration(mConfig.taskViewEnterFromHomeDuration * 5)
.withEndAction(new Runnable() {
@Override
public void run() {
- mEnableThumbnailClip.run();
+ // Animate the task bar of the first task view
+ mBarView.startEnterRecentsAnimation(0, mThumbnailView.enableTaskBarClipAsRunnable(mBarView));
+ // Animate the footer into view (if it is the front most task)
+ animateFooterVisibility(true, mConfig.taskBarEnterAnimDuration);
// Decrement the post animation trigger
ctx.postAnimationTrigger.decrement();
+
+ // XXX Request layout and only start hte next animation after the next
+ // layout
+
+ setIsFullScreen(false);
+ mThumbnailView.unbindFromScreenshot();
+
+ // Recycle the full screen screenshot
+ AlternateRecentsComponent.consumeLastScreenshot();
}
})
.start();
+ } else {
+ // Otherwise, just enable the thumbnail clip
+ mThumbnailView.enableTaskBarClip(mBarView);
+
+ // Animate the footer into view
+ animateFooterVisibility(true, 0);
}
ctx.postAnimationTrigger.increment();
} else if (mConfig.launchedFromAppWithThumbnail) {
- if (ctx.isCurrentTaskLaunchTarget) {
+ if (mTask.isLaunchTarget) {
// Animate the task bar of the first task view
- mBarView.startEnterRecentsAnimation(mConfig.taskBarEnterAnimDelay, mEnableThumbnailClip);
+ mBarView.startEnterRecentsAnimation(mConfig.taskBarEnterAnimDelay,
+ mThumbnailView.enableTaskBarClipAsRunnable(mBarView));
// Animate the dim into view as well
ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", getDimOverlayFromScale());
@@ -360,10 +295,9 @@
ctx.postAnimationTrigger.increment();
// Animate the footer into view
- animateFooterVisibility(true, mConfig.taskBarEnterAnimDuration
- );
+ animateFooterVisibility(true, mConfig.taskBarEnterAnimDuration);
} else {
- mEnableThumbnailClip.run();
+ mThumbnailView.enableTaskBarClip(mBarView);
}
} else if (mConfig.launchedFromHome) {
@@ -382,11 +316,10 @@
.setUpdateListener(null)
.setInterpolator(mConfig.quintOutInterpolator)
.setDuration(mConfig.taskViewEnterFromHomeDuration)
- .withLayer()
.withEndAction(new Runnable() {
@Override
public void run() {
- mEnableThumbnailClip.run();
+ mThumbnailView.enableTaskBarClip(mBarView);
// Decrement the post animation trigger
ctx.postAnimationTrigger.decrement();
}
@@ -395,11 +328,11 @@
ctx.postAnimationTrigger.increment();
// Animate the footer into view
- animateFooterVisibility(true, mConfig.taskViewEnterFromHomeDuration
- );
+ animateFooterVisibility(true, mConfig.taskViewEnterFromHomeDuration);
+
} else {
// Otherwise, just enable the thumbnail clip
- mEnableThumbnailClip.run();
+ mThumbnailView.enableTaskBarClip(mBarView);
// Animate the footer into view
animateFooterVisibility(true, 0);
@@ -414,7 +347,6 @@
.setUpdateListener(null)
.setInterpolator(mConfig.fastOutLinearInInterpolator)
.setDuration(mConfig.taskViewExitToHomeDuration)
- .withLayer()
.withEndAction(ctx.postAnimationTrigger.decrementAsRunnable())
.start();
ctx.postAnimationTrigger.increment();
@@ -424,7 +356,7 @@
public void startLaunchTaskAnimation(final Runnable r, boolean isLaunchingTask) {
if (isLaunchingTask) {
// Disable the thumbnail clip and animate the bar out
- mBarView.startLaunchTaskAnimation(mDisableThumbnailClip, r);
+ mBarView.startLaunchTaskAnimation(mThumbnailView.disableTaskBarClipAsRunnable(), r);
// Animate the dim
if (mDim > 0) {
@@ -450,7 +382,6 @@
.setUpdateListener(null)
.setInterpolator(mConfig.fastOutSlowInInterpolator)
.setDuration(mConfig.taskViewRemoveAnimDuration)
- .withLayer()
.withEndAction(new Runnable() {
@Override
public void run() {
@@ -478,32 +409,23 @@
mBarView.setNoUserInteractionState();
}
- /** Enable the hw layers on this task view */
- void enableHwLayers() {
- mThumbnailView.setLayerType(View.LAYER_TYPE_HARDWARE, mLayerPaint);
- mBarView.enableHwLayers();
- mLockToAppButtonView.setLayerType(View.LAYER_TYPE_HARDWARE, mLayerPaint);
+ /** Sets whether this task view is full screen or not. */
+ void setIsFullScreen(boolean isFullscreen) {
+ mIsFullScreenView = isFullscreen;
+ mBarView.setIsFullscreen(isFullscreen);
+ if (isFullscreen) {
+ // If we are full screen, then disable the bottom outline clip for the footer
+ mViewBounds.setOutlineClipBottom(0);
+ }
}
- /** Disable the hw layers on this task view */
- void disableHwLayers() {
- mThumbnailView.setLayerType(View.LAYER_TYPE_NONE, mLayerPaint);
- mBarView.disableHwLayers();
- mLockToAppButtonView.setLayerType(View.LAYER_TYPE_NONE, mLayerPaint);
+ /** Returns whether this task view should currently be drawn as a full screen view. */
+ boolean isFullScreenView() {
+ return mIsFullScreenView;
}
/** Sets the stubbed state of this task view. */
void setStubState(boolean isStub) {
- if (!mIsStub && isStub) {
- // This is now a stub task view, so clip to the bar height, hide the thumbnail
- setClipBounds(new Rect(0, 0, getMeasuredWidth(), mBarView.getMeasuredHeight()));
- mThumbnailView.setVisibility(View.INVISIBLE);
- // Temporary
- mBarView.mActivityDescription.setText("Stub");
- } else if (mIsStub && !isStub) {
- setClipBounds(null);
- mThumbnailView.setVisibility(View.VISIBLE);
- }
mIsStub = isStub;
}
@@ -512,7 +434,7 @@
* view.
*/
boolean shouldClipViewInStack() {
- return mClipViewInStack && (getVisibility() == View.VISIBLE);
+ return mClipViewInStack && !mIsFullScreenView && (getVisibility() == View.VISIBLE);
}
/** Sets whether this view should be clipped, or clipped against. */
@@ -523,81 +445,28 @@
}
}
- void setClipFromBottom(int clipFromBottom) {
- clipFromBottom = Math.max(0, Math.min(getMeasuredHeight(), clipFromBottom));
- if (mClipFromBottom != clipFromBottom) {
- mClipFromBottom = clipFromBottom;
- invalidateOutline();
- }
- }
-
- /** Sets the footer height. */
- public void setFooterHeight(int footerHeight) {
- if (footerHeight != mFooterHeight) {
- mFooterHeight = footerHeight;
- invalidateOutline();
- invalidate(0, getMeasuredHeight() - mMaxFooterHeight, getMeasuredWidth(),
- getMeasuredHeight());
- }
- }
-
- /** Gets the footer height. */
- public int getFooterHeight() {
- return mFooterHeight;
- }
-
/** Gets the max footer height. */
public int getMaxFooterHeight() {
- return mMaxFooterHeight;
+ return mFooterView.mMaxFooterHeight;
}
/** Animates the footer into and out of view. */
- public void animateFooterVisibility(boolean visible, int duration) {
- if (!mTask.lockToThisTask) {
- if (mLockToAppButtonView.getVisibility() == View.VISIBLE) {
- mLockToAppButtonView.setVisibility(View.INVISIBLE);
- }
- return;
- }
- if (mMaxFooterHeight <= 0) return;
-
- if (mFooterAnimator != null) {
- mFooterAnimator.removeAllListeners();
- mFooterAnimator.cancel();
- }
- int height = visible ? mMaxFooterHeight : 0;
- if (visible && mLockToAppButtonView.getVisibility() != View.VISIBLE) {
- if (duration > 0) {
- setFooterHeight(0);
- } else {
- setFooterHeight(mMaxFooterHeight);
- }
- mLockToAppButtonView.setVisibility(View.VISIBLE);
- }
- if (duration > 0) {
- mFooterAnimator = ObjectAnimator.ofInt(this, "footerHeight", height);
- mFooterAnimator.setDuration(duration);
- mFooterAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
- if (!visible) {
- mFooterAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mLockToAppButtonView.setVisibility(View.INVISIBLE);
- }
- });
- }
- mFooterAnimator.start();
- } else {
- if (!visible) {
- mLockToAppButtonView.setVisibility(View.INVISIBLE);
- }
- }
+ void animateFooterVisibility(boolean visible, int duration) {
+ // Hide the footer if we are a full screen view
+ if (mIsFullScreenView) return;
+ // Hide the footer if the current task can not be locked to
+ if (!mTask.lockToTaskEnabled || !mTask.lockToThisTask) return;
+ // Otherwise, animate the visibility
+ mFooterView.animateFooterVisibility(visible, duration);
}
/** Returns the current dim. */
public void setDim(int dim) {
mDim = dim;
- postInvalidateOnAnimation();
+ int inverse = 255 - mDim;
+ mDimColorFilter.setColor(Color.argb(0xFF, inverse, inverse, inverse));
+ mLayerPaint.setColorFilter(mDimColorFilter);
+ setLayerType(LAYER_TYPE_HARDWARE, mLayerPaint);
}
/** Returns the current dim. */
@@ -619,25 +488,19 @@
setDim(getDimOverlayFromScale());
}
- @Override
- public void draw(Canvas canvas) {
- super.draw(canvas);
-
- // Apply the dim if necessary
- if (mDim > 0) {
- canvas.drawColor(mDim << 24);
- }
- }
+ /**** View drawing ****/
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
- if (mIsStub && (child == mThumbnailView)) {
+ if (mIsStub && (child != mBarView)) {
// Skip the thumbnail view if we are in stub mode
return false;
}
return super.drawChild(canvas, child, drawingTime);
}
+ /**** View focus state ****/
+
/**
* Sets the focused task explicitly. We need a separate flag because requestFocus() won't happen
* if the view is not currently visible, or we are in touch state (where we still want to keep
@@ -691,14 +554,18 @@
public void onTaskDataLoaded() {
if (mThumbnailView != null && mBarView != null) {
// Bind each of the views to the new task data
- mThumbnailView.rebindToTask(mTask);
+ if (mIsFullScreenView) {
+ mThumbnailView.bindToScreenshot(AlternateRecentsComponent.getLastScreenshot());
+ } else {
+ mThumbnailView.rebindToTask(mTask);
+ }
mBarView.rebindToTask(mTask);
// Rebind any listeners
if (Constants.DebugFlags.App.EnableTaskFiltering) {
mBarView.mApplicationIcon.setOnClickListener(this);
}
mBarView.mDismissButton.setOnClickListener(this);
- mLockToAppButtonView.setOnClickListener(this);
+ mFooterView.setOnClickListener(this);
if (Constants.DebugFlags.App.EnableDevAppInfoOnLongPress) {
if (mConfig.developerOptionsEnabled) {
mBarView.mApplicationIcon.setOnLongClickListener(this);
@@ -720,7 +587,7 @@
mBarView.mApplicationIcon.setOnClickListener(null);
}
mBarView.mDismissButton.setOnClickListener(null);
- mLockToAppButtonView.setOnClickListener(null);
+ mFooterView.setOnClickListener(null);
if (Constants.DebugFlags.App.EnableDevAppInfoOnLongPress) {
mBarView.mApplicationIcon.setOnLongClickListener(null);
}
@@ -733,8 +600,23 @@
setOnClickListener(enabled ? this : null);
}
+ /**** TaskFooterView.TaskFooterViewCallbacks ****/
+
@Override
- public void onClick(final View v) {
+ public void onTaskFooterHeightChanged(int height, int maxHeight) {
+ if (mIsFullScreenView) {
+ // Disable the bottom outline clip when fullscreen
+ mViewBounds.setOutlineClipBottom(0);
+ } else {
+ // Update the bottom clip in our outline provider
+ mViewBounds.setOutlineClipBottom(maxHeight - height);
+ }
+ }
+
+ /**** View.OnClickListener Implementation ****/
+
+ @Override
+ public void onClick(final View v) {
// We purposely post the handler delayed to allow for the touch feedback to draw
final TaskView tv = this;
postDelayed(new Runnable() {
@@ -752,13 +634,15 @@
});
// Hide the footer
tv.animateFooterVisibility(false, mConfig.taskViewRemoveAnimDuration);
- } else if (v == tv || v == mLockToAppButtonView) {
- mCb.onTaskViewClicked(tv, tv.getTask(), (v == mLockToAppButtonView));
+ } else if (v == tv || v == mFooterView) {
+ mCb.onTaskViewClicked(tv, tv.getTask(), (v == mFooterView));
}
}
}, 125);
}
+ /**** View.OnLongClickListener Implementation ****/
+
@Override
public boolean onLongClick(View v) {
if (v == mBarView.mApplicationIcon) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
index b351b03..aeb4fe4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -16,7 +16,12 @@
package com.android.systemui.recents.views;
+import android.animation.ValueAnimator;
import android.graphics.Rect;
+import android.view.View;
+import android.view.ViewPropertyAnimator;
+import android.view.animation.Interpolator;
+import com.android.systemui.recents.Constants;
/* The transform state for a task view */
@@ -77,6 +82,72 @@
return (Float.compare(translationZ, v) != 0);
}
+ /** Applies this transform to a view. */
+ public void applyToTaskView(View v, int duration, Interpolator interp, boolean allowLayers,
+ ValueAnimator.AnimatorUpdateListener scaleUpdateListener) {
+ // Check to see if any properties have changed, and update the task view
+ if (duration > 0) {
+ ViewPropertyAnimator anim = v.animate();
+ boolean requiresLayers = false;
+
+ // Animate to the final state
+ if (hasTranslationYChangedFrom(v.getTranslationY())) {
+ anim.translationY(translationY);
+ }
+ if (Constants.DebugFlags.App.EnableShadows &&
+ hasTranslationZChangedFrom(v.getTranslationZ())) {
+ anim.translationZ(translationZ);
+ }
+ if (hasScaleChangedFrom(v.getScaleX())) {
+ anim.scaleX(scale)
+ .scaleY(scale)
+ .setUpdateListener(scaleUpdateListener);
+ requiresLayers = true;
+ }
+ if (hasAlphaChangedFrom(v.getAlpha())) {
+ // Use layers if we animate alpha
+ anim.alpha(alpha);
+ requiresLayers = true;
+ }
+ if (requiresLayers && allowLayers) {
+ anim.withLayer();
+ }
+ anim.setStartDelay(startDelay)
+ .setDuration(duration)
+ .setInterpolator(interp)
+ .start();
+ } else {
+ // Set the changed properties
+ if (hasTranslationYChangedFrom(v.getTranslationY())) {
+ v.setTranslationY(translationY);
+ }
+ if (Constants.DebugFlags.App.EnableShadows &&
+ hasTranslationZChangedFrom(v.getTranslationZ())) {
+ v.setTranslationZ(translationZ);
+ }
+ if (hasScaleChangedFrom(v.getScaleX())) {
+ v.setScaleX(scale);
+ v.setScaleY(scale);
+ scaleUpdateListener.onAnimationUpdate(null);
+ }
+ if (hasAlphaChangedFrom(v.getAlpha())) {
+ v.setAlpha(alpha);
+ }
+ }
+ }
+
+ /** Reset the transform on a view. */
+ public static void reset(View v) {
+ v.setTranslationX(0f);
+ v.setTranslationY(0f);
+ if (Constants.DebugFlags.App.EnableShadows) {
+ v.setTranslationZ(0f);
+ }
+ v.setScaleX(1f);
+ v.setScaleY(1f);
+ v.setAlpha(1f);
+ }
+
@Override
public String toString() {
return "TaskViewTransform delay: " + startDelay + " y: " + translationY + " z: " + translationZ +
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
index e50a5cf..3705cb5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
@@ -16,6 +16,7 @@
package com.android.systemui.recents.views;
+import android.graphics.Rect;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
/* Common code related to view animations */
@@ -23,27 +24,22 @@
/* The animation context for a task view animation into Recents */
public static class TaskViewEnterContext {
- // The full screenshot view that we are animating down
- FullscreenTransitionOverlayView fullScreenshotView;
- // The transform of the target task view that we are animating into
- TaskViewTransform targetTaskTransform;
// A trigger to run some logic when all the animations complete. This works around the fact
// that it is difficult to coordinate ViewPropertyAnimators
ReferenceCountedTrigger postAnimationTrigger;
// These following properties are updated for each task view we start the enter animation on
+ // The task rect for the current stack
+ Rect currentTaskRect;
// The transform of the current task view
TaskViewTransform currentTaskTransform;
- // Whether this is the front most task view
- boolean isCurrentTaskLaunchTarget;
// The view index of the current task view
int currentStackViewIndex;
// The total number of task views
int currentStackViewCount;
- public TaskViewEnterContext(FullscreenTransitionOverlayView fss, ReferenceCountedTrigger t) {
- fullScreenshotView = fss;
+ public TaskViewEnterContext(ReferenceCountedTrigger t) {
postAnimationTrigger = t;
}
}
@@ -53,6 +49,7 @@
// A trigger to run some logic when all the animations complete. This works around the fact
// that it is difficult to coordinate ViewPropertyAnimators
ReferenceCountedTrigger postAnimationTrigger;
+
// The translationY to apply to a TaskView to move it off the bottom of the task stack
int offscreenTranslationY;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index a41ec22..303454b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -44,6 +44,7 @@
public static final int MODE_TRANSLUCENT = 2;
public static final int MODE_LIGHTS_OUT = 3;
public static final int MODE_TRANSPARENT = 4;
+ public static final int MODE_WARNING = 5;
public static final int LIGHTS_IN_DURATION = 250;
public static final int LIGHTS_OUT_DURATION = 750;
@@ -100,6 +101,7 @@
if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT";
if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
+ if (mode == MODE_WARNING) return "MODE_WARNING";
throw new IllegalArgumentException("Unknown mode " + mode);
}
@@ -115,6 +117,7 @@
private final int mOpaque;
private final int mSemiTransparent;
private final int mTransparent;
+ private final int mWarning;
private final Drawable mGradient;
private final TimeInterpolator mInterpolator;
@@ -135,10 +138,12 @@
mOpaque = 0xff0000ff;
mSemiTransparent = 0x7f0000ff;
mTransparent = 0x2f0000ff;
+ mWarning = 0xffff0000;
} else {
mOpaque = res.getColor(R.color.system_bar_background_opaque);
mSemiTransparent = res.getColor(R.color.system_bar_background_semi_transparent);
mTransparent = res.getColor(R.color.system_bar_background_transparent);
+ mWarning = res.getColor(R.color.system_bar_background_warning);
}
mGradient = res.getDrawable(gradientResourceId);
mInterpolator = new LinearInterpolator();
@@ -189,7 +194,9 @@
@Override
public void draw(Canvas canvas) {
int targetGradientAlpha = 0, targetColor = 0;
- if (mMode == MODE_TRANSLUCENT) {
+ if (mMode == MODE_WARNING) {
+ targetColor = mWarning;
+ } else if (mMode == MODE_TRANSLUCENT) {
targetColor = mSemiTransparent;
} else if (mMode == MODE_SEMI_TRANSPARENT) {
targetColor = mSemiTransparent;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index b5f38ae..74bc698 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -38,6 +38,7 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.FlashlightController;
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
@@ -63,6 +64,7 @@
private ActivityStarter mActivityStarter;
private UnlockMethodCache mUnlockMethodCache;
private LockPatternUtils mLockPatternUtils;
+ private FlashlightController mFlashlightController;
public KeyguardBottomAreaView(Context context) {
super(context);
@@ -102,6 +104,10 @@
mActivityStarter = activityStarter;
}
+ public void setFlashlightController(FlashlightController flashlightController) {
+ mFlashlightController = flashlightController;
+ }
+
private Intent getCameraIntent() {
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
boolean currentUserHasTrust = updateMonitor.getUserHasTrust(
@@ -189,6 +195,7 @@
}
public void launchCamera() {
+ mFlashlightController.killFlashlight();
Intent intent = getCameraIntent();
if (intent == SECURE_CAMERA_INTENT) {
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
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 fb0f1c1..e4e67c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -28,6 +28,7 @@
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -71,7 +72,6 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
@@ -127,11 +127,14 @@
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
import com.android.systemui.statusbar.policy.CastControllerImpl;
import com.android.systemui.statusbar.policy.FlashlightController;
import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
+import com.android.systemui.statusbar.policy.HotspotControllerImpl;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.LocationControllerImpl;
import com.android.systemui.statusbar.policy.NetworkControllerImpl;
@@ -205,6 +208,7 @@
BatteryController mBatteryController;
LocationControllerImpl mLocationController;
NetworkControllerImpl mNetworkController;
+ HotspotControllerImpl mHotspotController;
RotationLockControllerImpl mRotationLockController;
UserInfoController mUserInfoController;
ZenModeController mZenModeController;
@@ -213,6 +217,7 @@
KeyguardUserSwitcher mKeyguardUserSwitcher;
FlashlightController mFlashlightController;
UserSwitcherController mUserSwitcherController;
+ KeyguardMonitor mKeyguardMonitor;
int mNaturalBarHeight = -1;
int mIconSize = -1;
@@ -703,7 +708,18 @@
// Other icons
mLocationController = new LocationControllerImpl(mContext); // will post a notification
mBatteryController = new BatteryController(mContext);
+ mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
+ @Override
+ public void onPowerSaveChanged() {
+ mHandler.post(mCheckBarModes);
+ }
+ @Override
+ public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ // noop
+ }
+ });
mNetworkController = new NetworkControllerImpl(mContext);
+ mHotspotController = new HotspotControllerImpl(mContext);
mBluetoothController = new BluetoothControllerImpl(mContext);
if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
mRotationLockController = new RotationLockControllerImpl(mContext);
@@ -749,16 +765,18 @@
}
mFlashlightController = new FlashlightController(mContext);
+ mKeyguardBottomArea.setFlashlightController(mFlashlightController);
mUserSwitcherController = new UserSwitcherController(mContext);
+ mKeyguardMonitor = new KeyguardMonitor();
// Set up the quick settings tile panel
mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel);
if (mQSPanel != null) {
final QSTileHost qsh = new QSTileHost(mContext, this,
mBluetoothController, mLocationController, mRotationLockController,
- mNetworkController, mZenModeController, null /*tethering*/,
- mCastController, mVolumeComponent, mFlashlightController,
- mUserSwitcherController);
+ mNetworkController, mZenModeController, mHotspotController,
+ mCastController, mFlashlightController,
+ mUserSwitcherController, mKeyguardMonitor);
mQSPanel.setHost(qsh);
for (QSTile<?> tile : qsh.getTiles()) {
mQSPanel.addTile(tile);
@@ -1598,24 +1616,8 @@
updateMediaMetaData(metaDataChanged);
}
- private void removeAndRecycleImageViewDrawable(ImageView iv) {
- Bitmap oldBitmap = null;
- final Drawable drawable = iv.getDrawable();
- if (drawable != null && drawable instanceof BitmapDrawable) {
- oldBitmap = ((BitmapDrawable) drawable).getBitmap();
- }
- iv.animate().cancel();
- iv.setImageDrawable(null);
- if (oldBitmap != null) {
- if (DEBUG_MEDIA) {
- Log.v(TAG, "DEBUG_MEDIA: recycling bitmap " + oldBitmap + " from ImageView " + iv);
- }
- oldBitmap.recycle();
- }
- }
-
/**
- * Hide the album artwork that is fading out and release its memory.
+ * Hide the album artwork that is fading out and release its bitmap.
*/
private Runnable mHideBackdropFront = new Runnable() {
@Override
@@ -1624,7 +1626,8 @@
Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
}
mBackdropFront.setVisibility(View.INVISIBLE);
- removeAndRecycleImageViewDrawable(mBackdropFront);
+ mBackdropFront.animate().cancel();
+ mBackdropFront.setImageDrawable(null);
}
};
@@ -2320,7 +2323,12 @@
}
private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
- final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN;
+ final boolean powerSave = mBatteryController.isPowerSave();
+ final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN
+ && !powerSave;
+ if (powerSave && getBarState() != StatusBarState.KEYGUARD) {
+ mode = MODE_WARNING;
+ }
transitions.transitionTo(mode, anim);
}
@@ -2335,7 +2343,8 @@
@Override
public void run() {
checkBarModes();
- }};
+ }
+ };
@Override
public void setInteracting(int barWindow, boolean interacting) {
@@ -2654,6 +2663,9 @@
if (mUserSwitcherController != null) {
mUserSwitcherController.dump(fd, pw, args);
}
+ if (mBatteryController != null) {
+ mBatteryController.dump(fd, pw, args);
+ }
}
private String hunStateToString(Entry entry) {
@@ -3121,6 +3133,8 @@
int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
"translucent".equals(mode) ? MODE_TRANSLUCENT :
"semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
+ "transparent".equals(mode) ? MODE_TRANSPARENT :
+ "warning".equals(mode) ? MODE_WARNING :
-1;
if (barMode != -1) {
boolean animate = true;
@@ -3223,6 +3237,8 @@
checkBarModes();
updateCarrierLabelVisibility(false);
updateMediaMetaData(false);
+ mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
+ mStatusBarKeyguardViewManager.isSecure());
}
private void updateDozingState() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index a599070..c2fd24c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -36,13 +36,13 @@
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.FlashlightController;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RotationLockController;
-import com.android.systemui.statusbar.policy.TetheringController;
+import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.volume.VolumeComponent;
import java.util.ArrayList;
import java.util.List;
@@ -57,21 +57,21 @@
private final RotationLockController mRotation;
private final NetworkController mNetwork;
private final ZenModeController mZen;
- private final TetheringController mTethering;
+ private final HotspotController mHotspot;
private final CastController mCast;
private final Looper mLooper;
private final CurrentUserTracker mUserTracker;
- private final VolumeComponent mVolume;
private final ArrayList<QSTile<?>> mTiles = new ArrayList<QSTile<?>>();
private final FlashlightController mFlashlight;
private final UserSwitcherController mUserSwitcherController;
+ private final KeyguardMonitor mKeyguard;
public QSTileHost(Context context, PhoneStatusBar statusBar,
BluetoothController bluetooth, LocationController location,
RotationLockController rotation, NetworkController network,
- ZenModeController zen, TetheringController tethering,
- CastController cast, VolumeComponent volume, FlashlightController flashlight,
- UserSwitcherController userSwitcher) {
+ ZenModeController zen, HotspotController hotspot,
+ CastController cast, FlashlightController flashlight,
+ UserSwitcherController userSwitcher, KeyguardMonitor keyguard) {
mContext = context;
mStatusBar = statusBar;
mBluetooth = bluetooth;
@@ -79,11 +79,11 @@
mRotation = rotation;
mNetwork = network;
mZen = zen;
- mTethering = tethering;
+ mHotspot = hotspot;
mCast = cast;
- mVolume = volume;
mFlashlight = flashlight;
mUserSwitcherController = userSwitcher;
+ mKeyguard = keyguard;
final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName());
ht.start();
@@ -95,10 +95,10 @@
mTiles.add(new CellularTile(this));
mTiles.add(new AirplaneModeTile(this));
mTiles.add(new RotationLockTile(this));
+ mTiles.add(new FlashlightTile(this));
mTiles.add(new LocationTile(this));
mTiles.add(new CastTile(this));
mTiles.add(new HotspotTile(this));
- mTiles.add(new FlashlightTile(this));
mUserTracker = new CurrentUserTracker(mContext) {
@Override
@@ -167,8 +167,8 @@
}
@Override
- public TetheringController getTetheringController() {
- return mTethering;
+ public HotspotController getHotspotController() {
+ return mHotspot;
}
@Override
@@ -177,13 +177,13 @@
}
@Override
- public VolumeComponent getVolumeComponent() {
- return mVolume;
+ public FlashlightController getFlashlightController() {
+ return mFlashlight;
}
@Override
- public FlashlightController getFlashlightController() {
- return mFlashlight;
+ public KeyguardMonitor getKeyguardMonitor() {
+ return mKeyguard;
}
public UserSwitcherController getUserSwitcherController() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index b2709bc..ffb4dc1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -363,6 +363,11 @@
}
}
+ @Override
+ public void onPowerSaveChanged() {
+ // could not care less
+ }
+
private void updateClickTargets() {
setClickable(!mKeyguardShowing || mExpanded);
mDateTime.setClickable(mExpanded);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index ccfe18d..1e65543 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -16,41 +16,49 @@
package com.android.systemui.statusbar.policy;
-import com.android.internal.app.IBatteryStats;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.StatusBarHeaderView;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
-import android.os.BatteryStats;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.text.format.Formatter;
+import android.os.PowerManager;
import android.util.Log;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
public class BatteryController extends BroadcastReceiver {
- private static final String TAG = "StatusBar.BatteryController";
+ private static final String TAG = "BatteryController";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
+ private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
+ private final PowerManager mPowerManager;
private int mLevel;
private boolean mPluggedIn;
private boolean mCharging;
private boolean mCharged;
-
- public interface BatteryStateChangeCallback {
- public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
- }
+ private boolean mPowerSave;
public BatteryController(Context context) {
+ mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
context.registerReceiver(this, filter);
+
+ updatePowerSave();
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("BatteryController state:");
+ pw.print(" mLevel="); pw.println(mLevel);
+ pw.print(" mPluggedIn="); pw.println(mPluggedIn);
+ pw.print(" mCharging="); pw.println(mCharging);
+ pw.print(" mCharged="); pw.println(mCharged);
+ pw.print(" mPowerSave="); pw.println(mPowerSave);
}
public void addStateChangedCallback(BatteryStateChangeCallback cb) {
@@ -75,9 +83,40 @@
mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
mCharging = mCharged || status == BatteryManager.BATTERY_STATUS_CHARGING;
- for (BatteryStateChangeCallback cb : mChangeCallbacks) {
- cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
- }
+ fireBatteryLevelChanged();
+ } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
+ updatePowerSave();
}
}
+
+ public boolean isPowerSave() {
+ return mPowerSave;
+ }
+
+ private void updatePowerSave() {
+ final boolean powerSave = mPowerManager.isPowerSaveMode();
+ if (powerSave == mPowerSave) return;
+ mPowerSave = powerSave;
+ if (DEBUG) Log.d(TAG, "Power save is " + (mPowerSave ? "on" : "off"));
+ firePowerSaveChanged();
+ }
+
+ private void fireBatteryLevelChanged() {
+ final int N = mChangeCallbacks.size();
+ for (int i = 0; i < N; i++) {
+ mChangeCallbacks.get(i).onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
+ }
+ }
+
+ private void firePowerSaveChanged() {
+ final int N = mChangeCallbacks.size();
+ for (int i = 0; i < N; i++) {
+ mChangeCallbacks.get(i).onPowerSaveChanged();
+ }
+ }
+
+ public interface BatteryStateChangeCallback {
+ void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
+ void onPowerSaveChanged();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
index b059043..e05e34b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
@@ -28,6 +28,7 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
+import android.os.SystemProperties;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
@@ -41,6 +42,14 @@
public class FlashlightController {
private static final String TAG = "FlashlightController";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private static final boolean ENFORCE_AVAILABILITY_LISTENER =
+ SystemProperties.getBoolean("persist.sysui.flash.listener", false);
+
+ private static final int DISPATCH_ERROR = 0;
+ private static final int DISPATCH_OFF = 1;
+ private static final int DISPATCH_AVAILABILITY_CHANGED = 2;
private final CameraManager mCameraManager;
/** Call {@link #ensureHandler()} before using */
@@ -52,6 +61,8 @@
/** Lock on {@code this} when accessing */
private boolean mFlashlightEnabled;
+ private String mCameraId;
+ private boolean mCameraAvailable;
private CameraDevice mCameraDevice;
private CaptureRequest mFlashlightRequest;
private CameraCaptureSession mSession;
@@ -60,6 +71,20 @@
public FlashlightController(Context mContext) {
mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
+ initialize();
+ }
+
+ public void initialize() {
+ try {
+ mCameraId = getCameraId();
+ } catch (CameraAccessException e) {
+ Log.e(TAG, "Couldn't initialize.", e);
+ return;
+ }
+
+ ensureHandler();
+ mCameraAvailable = true;
+ mCameraManager.addAvailabilityListener(mAvailabilityListener, mHandler);
}
public synchronized void setFlashlight(boolean enabled) {
@@ -69,12 +94,18 @@
}
}
- public boolean isAvailable() {
- try {
- return getCameraId() != null;
- } catch (CameraAccessException e) {
- return false;
+ public void killFlashlight() {
+ boolean enabled;
+ synchronized (this) {
+ enabled = mFlashlightEnabled;
}
+ if (enabled) {
+ mHandler.post(mKillFlashlightRunnable);
+ }
+ }
+
+ public synchronized boolean isAvailable() {
+ return ENFORCE_AVAILABILITY_LISTENER ? mCameraAvailable : (mCameraId != null);
}
public void addListener(FlashlightListener l) {
@@ -207,24 +238,30 @@
}
private void dispatchOff() {
- dispatchListeners(false, true /* off */);
+ dispatchListeners(DISPATCH_OFF, false /* argument (ignored) */);
}
private void dispatchError() {
- dispatchListeners(true /* error */, false);
+ dispatchListeners(DISPATCH_ERROR, false /* argument (ignored) */);
}
- private void dispatchListeners(boolean error, boolean off) {
+ private void dispatchAvailabilityChanged(boolean available) {
+ dispatchListeners(DISPATCH_AVAILABILITY_CHANGED, available);
+ }
+
+ private void dispatchListeners(int message, boolean argument) {
synchronized (mListeners) {
final int N = mListeners.size();
boolean cleanup = false;
for (int i = 0; i < N; i++) {
FlashlightListener l = mListeners.get(i).get();
if (l != null) {
- if (error) {
+ if (message == DISPATCH_ERROR) {
l.onFlashlightError();
- } else if (off) {
+ } else if (message == DISPATCH_OFF) {
l.onFlashlightOff();
+ } else if (message == DISPATCH_AVAILABILITY_CHANGED) {
+ l.onFlashlightAvailabilityChanged(argument);
}
} else {
cleanup = true;
@@ -293,6 +330,48 @@
}
};
+ private final Runnable mKillFlashlightRunnable = new Runnable() {
+ @Override
+ public void run() {
+ synchronized (this) {
+ mFlashlightEnabled = false;
+ }
+ updateFlashlight(true /* forceDisable */);
+ dispatchOff();
+ }
+ };
+
+ private final CameraManager.AvailabilityListener mAvailabilityListener =
+ new CameraManager.AvailabilityListener() {
+ @Override
+ public void onCameraAvailable(String cameraId) {
+ if (DEBUG) Log.d(TAG, "onCameraAvailable(" + cameraId + ")");
+ if (cameraId.equals(mCameraId)) {
+ setCameraAvailable(true);
+ }
+ }
+
+ @Override
+ public void onCameraUnavailable(String cameraId) {
+ if (DEBUG) Log.d(TAG, "onCameraUnavailable(" + cameraId + ")");
+ if (cameraId.equals(mCameraId)) {
+ setCameraAvailable(false);
+ }
+ }
+
+ private void setCameraAvailable(boolean available) {
+ boolean changed;
+ synchronized (FlashlightController.this) {
+ changed = mCameraAvailable != available;
+ mCameraAvailable = available;
+ }
+ if (changed) {
+ if (DEBUG) Log.d(TAG, "dispatchAvailabilityChanged(" + available + ")");
+ dispatchAvailabilityChanged(available);
+ }
+ }
+ };
+
public interface FlashlightListener {
/**
@@ -304,5 +383,11 @@
* Called when there is an error that turns the flashlight off.
*/
void onFlashlightError();
+
+ /**
+ * Called when there is a change in availability of the flashlight functionality
+ * @param available true if the flashlight is currently available.
+ */
+ void onFlashlightAvailabilityChanged(boolean available);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TetheringController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/TetheringController.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
index 143ebaa..7ca91a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TetheringController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
@@ -16,13 +16,14 @@
package com.android.systemui.statusbar.policy;
-public interface TetheringController {
+public interface HotspotController {
void addCallback(Callback callback);
void removeCallback(Callback callback);
boolean isHotspotEnabled();
boolean isHotspotSupported();
+ void setHotspotEnabled(boolean enabled);
public interface Callback {
- void onHotspotChanged(boolean hotspot);
+ void onHotspotChanged(boolean enabled);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
new file mode 100644
index 0000000..eea8396
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import java.util.ArrayList;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.os.UserHandle;
+import android.util.Log;
+
+public class HotspotControllerImpl implements HotspotController {
+
+ private static final String TAG = "HotspotController";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
+ private final Receiver mReceiver = new Receiver();
+ private final Context mContext;
+ private final WifiManager mWifiManager;
+ private final ConnectivityManager mConnectivityManager;
+
+ public HotspotControllerImpl(Context context) {
+ mContext = context;
+ mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ mConnectivityManager = (ConnectivityManager)
+ mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ }
+
+ public void addCallback(Callback callback) {
+ if (callback == null || mCallbacks.contains(callback)) return;
+ if (DEBUG) Log.d(TAG, "addCallback " + callback);
+ mCallbacks.add(callback);
+ mReceiver.setListening(!mCallbacks.isEmpty());
+ }
+
+ public void removeCallback(Callback callback) {
+ if (callback == null) return;
+ if (DEBUG) Log.d(TAG, "removeCallback " + callback);
+ mCallbacks.remove(callback);
+ mReceiver.setListening(!mCallbacks.isEmpty());
+ }
+
+ @Override
+ public boolean isHotspotEnabled() {
+ return mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED;
+ }
+
+ @Override
+ public boolean isHotspotSupported() {
+ final boolean isSecondaryUser = ActivityManager.getCurrentUser() != UserHandle.USER_OWNER;
+ return !isSecondaryUser && mConnectivityManager.isTetheringSupported();
+ }
+
+ @Override
+ public void setHotspotEnabled(boolean enabled) {
+ mWifiManager.setWifiApEnabled(null, enabled);
+ }
+
+ private void fireCallback(boolean isEnabled) {
+ for (Callback callback : mCallbacks) {
+ callback.onHotspotChanged(isEnabled);
+ }
+ }
+
+ private final class Receiver extends BroadcastReceiver {
+ private boolean mRegistered;
+
+ public void setListening(boolean listening) {
+ if (listening && !mRegistered) {
+ if (DEBUG) Log.d(TAG, "Registering receiver");
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
+ mContext.registerReceiver(this, filter);
+ mRegistered = true;
+ } else if (!listening && mRegistered) {
+ if (DEBUG) Log.d(TAG, "Unregistering receiver");
+ mContext.unregisterReceiver(this);
+ mRegistered = false;
+ }
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) Log.d(TAG, "onReceive " + intent.getAction());
+ fireCallback(isHotspotEnabled());
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
new file mode 100644
index 0000000..0b3575f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import java.util.ArrayList;
+
+public final class KeyguardMonitor {
+
+ private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
+
+ private boolean mShowing;
+ private boolean mSecure;
+
+ public void addCallback(Callback callback) {
+ mCallbacks.add(callback);
+ }
+
+ public void removeCallback(Callback callback) {
+ mCallbacks.remove(callback);
+ }
+
+ public boolean isShowing() {
+ return mShowing;
+ }
+
+ public boolean isSecure() {
+ return mSecure;
+ }
+
+ public void notifyKeyguardState(boolean showing, boolean secure) {
+ if (mShowing == showing && mSecure == secure) return;
+ mShowing = showing;
+ mSecure = secure;
+ for (Callback callback : mCallbacks) {
+ callback.onKeyguardChanged();
+ }
+ }
+
+ public interface Callback {
+ void onKeyguardChanged();
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 49e7c67..7bf2c34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -66,6 +66,7 @@
private ArrayList<UserRecord> mUsers = new ArrayList<>();
private Dialog mExitGuestDialog;
+ private int mLastNonGuestUser = UserHandle.USER_OWNER;
public UserSwitcherController(Context context) {
mContext = context;
@@ -204,7 +205,14 @@
}
private void exitGuest(int id) {
- switchToUserId(UserHandle.USER_OWNER);
+ int newId = UserHandle.USER_OWNER;
+ if (mLastNonGuestUser != UserHandle.USER_OWNER) {
+ UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
+ if (info != null && info.isEnabled() && info.supportsSwitchTo()) {
+ newId = info.id;
+ }
+ }
+ switchToUserId(newId);
mUserManager.removeUser(id);
}
@@ -230,6 +238,9 @@
if (record.isCurrent != shouldBeCurrent) {
mUsers.set(i, record.copyWithIsCurrent(shouldBeCurrent));
}
+ if (shouldBeCurrent && !record.isGuest) {
+ mLastNonGuestUser = record.info.id;
+ }
}
notifyAdapters();
}
@@ -244,6 +255,7 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("UserSwitcherController state:");
+ pw.println(" mLastNonGuestUser=" + mLastNonGuestUser);
pw.print(" mUsers.size="); pw.println(mUsers.size());
for (int i = 0; i < mUsers.size(); i++) {
final UserRecord u = mUsers.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index ee7206f..fe2733b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -171,7 +171,10 @@
for (int i = 0; i < childCount; i++) {
View child = algorithmState.visibleChildren.get(i);
StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
- childViewState.belowSpeedBump = speedBumpIndex != -1 && i > speedBumpIndex;
+
+ // The speed bump can also be gone, so equality needs to be taken when comparing
+ // indices.
+ childViewState.belowSpeedBump = speedBumpIndex != -1 && i >= speedBumpIndex;
}
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 17a5263..56b8c92 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -6409,54 +6409,61 @@
mIsSystemRestore = isFullSystemRestore;
mFinished = false;
- if (filterSet == null) {
- // We want everything and a pony
- List<PackageInfo> apps
- = PackageManagerBackupAgent.getStorableApplications(mPackageManager);
- filterSet = packagesToNames(apps);
- if (DEBUG) {
- Slog.i(TAG, "Full restore; asking for " + filterSet.length + " apps");
- }
- }
-
- mAcceptSet = new ArrayList<PackageInfo>(filterSet.length);
-
- // Pro tem, we insist on moving the settings provider package to last place.
- // Keep track of whether it's in the list, and bump it down if so. We also
- // want to do the system package itself first if it's called for.
- boolean hasSystem = false;
- boolean hasSettings = false;
- for (int i = 0; i < filterSet.length; i++) {
- try {
- PackageInfo info = mPackageManager.getPackageInfo(filterSet[i], 0);
- if ("android".equals(info.packageName)) {
- hasSystem = true;
- continue;
+ if (targetPackage != null) {
+ // Single package restore
+ mAcceptSet = new ArrayList<PackageInfo>();
+ mAcceptSet.add(targetPackage);
+ } else {
+ // Everything possible, or a target set
+ if (filterSet == null) {
+ // We want everything and a pony
+ List<PackageInfo> apps =
+ PackageManagerBackupAgent.getStorableApplications(mPackageManager);
+ filterSet = packagesToNames(apps);
+ if (DEBUG) {
+ Slog.i(TAG, "Full restore; asking for " + filterSet.length + " apps");
}
- if (SETTINGS_PACKAGE.equals(info.packageName)) {
- hasSettings = true;
- continue;
- }
+ }
- if (appIsEligibleForBackup(info.applicationInfo)) {
- mAcceptSet.add(info);
+ mAcceptSet = new ArrayList<PackageInfo>(filterSet.length);
+
+ // Pro tem, we insist on moving the settings provider package to last place.
+ // Keep track of whether it's in the list, and bump it down if so. We also
+ // want to do the system package itself first if it's called for.
+ boolean hasSystem = false;
+ boolean hasSettings = false;
+ for (int i = 0; i < filterSet.length; i++) {
+ try {
+ PackageInfo info = mPackageManager.getPackageInfo(filterSet[i], 0);
+ if ("android".equals(info.packageName)) {
+ hasSystem = true;
+ continue;
+ }
+ if (SETTINGS_PACKAGE.equals(info.packageName)) {
+ hasSettings = true;
+ continue;
+ }
+
+ if (appIsEligibleForBackup(info.applicationInfo)) {
+ mAcceptSet.add(info);
+ }
+ } catch (NameNotFoundException e) {
+ // requested package name doesn't exist; ignore it
}
- } catch (NameNotFoundException e) {
- // requested package name doesn't exist; ignore it
}
- }
- if (hasSystem) {
- try {
- mAcceptSet.add(0, mPackageManager.getPackageInfo("android", 0));
- } catch (NameNotFoundException e) {
- // won't happen; we know a priori that it's valid
+ if (hasSystem) {
+ try {
+ mAcceptSet.add(0, mPackageManager.getPackageInfo("android", 0));
+ } catch (NameNotFoundException e) {
+ // won't happen; we know a priori that it's valid
+ }
}
- }
- if (hasSettings) {
- try {
- mAcceptSet.add(mPackageManager.getPackageInfo(SETTINGS_PACKAGE, 0));
- } catch (NameNotFoundException e) {
- // this one is always valid too
+ if (hasSettings) {
+ try {
+ mAcceptSet.add(mPackageManager.getPackageInfo(SETTINGS_PACKAGE, 0));
+ } catch (NameNotFoundException e) {
+ // this one is always valid too
+ }
}
}
@@ -6558,117 +6565,77 @@
private void startRestore() {
sendStartRestore(mAcceptSet.size());
- UnifiedRestoreState nextState = UnifiedRestoreState.RESTORE_FINISHED;
try {
- // If we don't yet have PM metadata for this token, synthesize an
- // entry for the PM pseudopackage and make it the first to be
- // restored.
String transportDir = mTransport.transportDirName();
mStateDir = new File(mBaseStateDir, transportDir);
- File metadataDir = new File(mStateDir, "_metadata");
- metadataDir.mkdirs();
- File metadataFile = new File(metadataDir, Long.toHexString(mToken));
- try {
- // PM info is cached in $BASE/transport/_metadata/$TOKEN
- mPmAgent = new PackageManagerBackupAgent(metadataFile);
- } catch (IOException e) {
- // Nope, we need to get it via restore
- if (MORE_DEBUG) Slog.v(TAG, "Need to restore @pm@");
- PackageInfo pmPackage = new PackageInfo();
- pmPackage.packageName = PACKAGE_MANAGER_SENTINEL;
- mAcceptSet.add(0, pmPackage);
- }
+
+ // Fetch the current metadata from the dataset first
+ PackageInfo pmPackage = new PackageInfo();
+ pmPackage.packageName = PACKAGE_MANAGER_SENTINEL;
+ mAcceptSet.add(0, pmPackage);
PackageInfo[] packages = mAcceptSet.toArray(new PackageInfo[0]);
mStatus = mTransport.startRestore(mToken, packages);
if (mStatus != BackupTransport.TRANSPORT_OK) {
Slog.e(TAG, "Transport error " + mStatus + "; no restore possible");
mStatus = BackupTransport.TRANSPORT_ERROR;
- nextState = UnifiedRestoreState.FINAL;
+ executeNextState(UnifiedRestoreState.FINAL);
return;
}
- if (mPmAgent == null) {
- if (DEBUG) {
- Slog.v(TAG, "Need to fetch metadata for token "
- + Long.toHexString(mToken));
- }
- RestoreDescription desc = mTransport.nextRestorePackage();
- if (desc == null) {
- Slog.e(TAG, "No restore metadata available; halting");
- mStatus = BackupTransport.TRANSPORT_ERROR;
- nextState = UnifiedRestoreState.FINAL;
- return;
- }
- if (!PACKAGE_MANAGER_SENTINEL.equals(desc.getPackageName())) {
- Slog.e(TAG, "Required metadata but got " + desc.getPackageName());
- mStatus = BackupTransport.TRANSPORT_ERROR;
- nextState = UnifiedRestoreState.FINAL;
- return;
- }
-
- // Pull the Package Manager metadata from the restore set first
- mCurrentPackage = new PackageInfo();
- mCurrentPackage.packageName = PACKAGE_MANAGER_SENTINEL;
- mPmAgent = new PackageManagerBackupAgent(mPackageManager, null);
- mAgent = IBackupAgent.Stub.asInterface(mPmAgent.onBind());
- if (MORE_DEBUG) {
- Slog.v(TAG, "initiating restore for PMBA");
- }
- initiateOneRestore(mCurrentPackage, 0);
- // The PM agent called operationComplete() already, because our invocation
- // of it is process-local and therefore synchronous. That means that a
- // RUNNING_QUEUE message is already enqueued. Only if we're unable to
- // proceed with running the queue do we remove that pending message and
- // jump straight to the FINAL state.
-
- // Verify that the backup set includes metadata. If not, we can't do
- // signature/version verification etc, so we simply do not proceed with
- // the restore operation.
- if (!mPmAgent.hasMetadata()) {
- Slog.e(TAG, "No restore metadata available, so not restoring settings");
- EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
- PACKAGE_MANAGER_SENTINEL,
- "Package manager restore metadata missing");
- mStatus = BackupTransport.TRANSPORT_ERROR;
- mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this);
- nextState = UnifiedRestoreState.FINAL;
- return;
- }
-
- // Success; cache the metadata and continue as expected with the
- // RUNNING_QUEUE step already enqueued.
- if (DEBUG) {
- Slog.v(TAG, "Got metadata; caching and proceeding to restore");
- }
- try {
- mPmAgent.saveToDisk(metadataFile);
- } catch (IOException e) {
- // Something bad; we need to abort
- Slog.e(TAG, "Unable to write restored metadata");
- EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
- PACKAGE_MANAGER_SENTINEL,
- "Unable to write restored metadata");
- mStatus = BackupTransport.TRANSPORT_ERROR;
- mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this);
- nextState = UnifiedRestoreState.FINAL;
- return;
- }
- } else {
- // We have the PMBA already, so we can proceed directly to
- // the RUNNING_QUEUE state ourselves.
- if (MORE_DEBUG) Slog.v(TAG, "PMBA from cache; proceeding to run queue");
- nextState = UnifiedRestoreState.RUNNING_QUEUE;
+ RestoreDescription desc = mTransport.nextRestorePackage();
+ if (desc == null) {
+ Slog.e(TAG, "No restore metadata available; halting");
+ mStatus = BackupTransport.TRANSPORT_ERROR;
+ executeNextState(UnifiedRestoreState.FINAL);
+ return;
}
+ if (!PACKAGE_MANAGER_SENTINEL.equals(desc.getPackageName())) {
+ Slog.e(TAG, "Required metadata but got " + desc.getPackageName());
+ mStatus = BackupTransport.TRANSPORT_ERROR;
+ executeNextState(UnifiedRestoreState.FINAL);
+ return;
+ }
+
+ // Pull the Package Manager metadata from the restore set first
+ mCurrentPackage = new PackageInfo();
+ mCurrentPackage.packageName = PACKAGE_MANAGER_SENTINEL;
+ mPmAgent = new PackageManagerBackupAgent(mPackageManager, null);
+ mAgent = IBackupAgent.Stub.asInterface(mPmAgent.onBind());
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "initiating restore for PMBA");
+ }
+ initiateOneRestore(mCurrentPackage, 0);
+ // The PM agent called operationComplete() already, because our invocation
+ // of it is process-local and therefore synchronous. That means that the
+ // next-state message (RUNNING_QUEUE) is already enqueued. Only if we're
+ // unable to proceed with running the queue do we remove that pending
+ // message and jump straight to the FINAL state.
+
+ // Verify that the backup set includes metadata. If not, we can't do
+ // signature/version verification etc, so we simply do not proceed with
+ // the restore operation.
+ if (!mPmAgent.hasMetadata()) {
+ Slog.e(TAG, "No restore metadata available, so not restoring");
+ EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+ PACKAGE_MANAGER_SENTINEL,
+ "Package manager restore metadata missing");
+ mStatus = BackupTransport.TRANSPORT_ERROR;
+ mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this);
+ executeNextState(UnifiedRestoreState.FINAL);
+ return;
+ }
+
+ // Success; cache the metadata and continue as expected with the
+ // next state already enqueued
+
} catch (RemoteException e) {
// If we lost the transport at any time, halt
Slog.e(TAG, "Unable to contact transport for restore");
mStatus = BackupTransport.TRANSPORT_ERROR;
mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this);
- nextState = UnifiedRestoreState.FINAL;
+ executeNextState(UnifiedRestoreState.FINAL);
return;
- } finally {
- executeNextState(nextState);
}
}
@@ -7267,6 +7234,13 @@
final UnifiedRestoreState nextState;
switch (mState) {
+ case INITIAL:
+ // We've just (manually) restored the PMBA. It doesn't need the
+ // additional restore-finished callback so we bypass that and go
+ // directly to running the queue.
+ nextState = UnifiedRestoreState.RUNNING_QUEUE;
+ break;
+
case RESTORE_KEYVALUE:
case RESTORE_FULL: {
// Okay, we've just heard back from the agent that it's done with
@@ -8187,6 +8161,9 @@
pkg.packageName = packageName;
mWakelock.acquire();
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Restore at install of " + packageName);
+ }
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
msg.obj = new RestoreParams(transport, dirName, null,
restoreSet, pkg, token);
@@ -8368,6 +8345,9 @@
if (token == mRestoreSets[i].token) {
long oldId = Binder.clearCallingIdentity();
mWakelock.acquire();
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "restoreAll() kicking off");
+ }
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
msg.obj = new RestoreParams(mRestoreTransport, dirName,
observer, token);
@@ -8439,6 +8419,9 @@
if (token == mRestoreSets[i].token) {
long oldId = Binder.clearCallingIdentity();
mWakelock.acquire();
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "restoreSome() of " + packages.length + " packages");
+ }
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token,
packages, packages.length > 1);
@@ -8518,6 +8501,9 @@
// Ready to go: enqueue the restore request and claim success
long oldId = Binder.clearCallingIdentity();
mWakelock.acquire();
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "restorePackage() : " + packageName);
+ }
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
msg.obj = new RestoreParams(mRestoreTransport, dirName,
observer, token, app, 0);
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index f64e97f..fcca788 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -37,7 +37,6 @@
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
-import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -48,9 +47,6 @@
import java.util.Set;
import java.util.Objects;
-import java.util.Map.Entry;
-
-import libcore.io.IoUtils;
/**
* We back up the signatures of each package so that during a system restore,
@@ -132,93 +128,6 @@
mStoredIncrementalVersion = Build.VERSION.INCREMENTAL;
}
- /**
- * Reconstitute a PMBA from its on-disk format. This is used for persistence
- * of the ancestral dataset's metadata. See {@link #saveToDisk()} for
- * details of the file format.
- */
- PackageManagerBackupAgent(File cache) throws IOException {
- FileInputStream fin = new FileInputStream(cache);
- BufferedInputStream bin = new BufferedInputStream(fin, 32 * 1024);
- DataInputStream in = new DataInputStream(bin);
-
- int version = in.readInt();
- // We can currently only handle the initial version format
- if (version == ANCESTRAL_RECORD_VERSION) {
- mStoredSdkVersion = in.readInt();
- mStoredIncrementalVersion = in.readUTF();
-
- int nPackages = in.readInt();
- if (nPackages > 0) {
- HashMap<String, Metadata> restoredMetadata =
- new HashMap<String, Metadata>(nPackages);
- ArrayList<byte[]> hashes = null;
- for (int pack = 0; pack < nPackages; pack++) {
- final String name = in.readUTF();
- final int versionCode = in.readInt();
- final int nHashes = in.readInt();
- if (nHashes > 0) {
- hashes = new ArrayList<byte[]>(nHashes);
- for (int i = 0; i < nHashes; i++) {
- int len = in.readInt();
- byte[] hash = new byte[len];
- in.read(hash);
- hashes.add(hash);
- }
- }
- restoredMetadata.put(name, new Metadata(versionCode, hashes));
- }
- mRestoredSignatures = restoredMetadata;
- }
- }
- }
-
- public void saveToDisk(File cache) throws IOException {
- // On disk format is very similar to the key/value format:
- //
- // Int: disk format version, currently 1
- // Int: VERSION.SDK_INT of source device
- // UTF: VERSION.INCREMENTAL string, for reference
- //
- // Int: number of packages represented in this file
- //
- // Per package if number > 0:
- // UTF: package name
- // Int: versionCode of the package
- // Int: number of signature hash blocks for this package
- // Per signature hash block:
- // Int: size of block
- // byte[]: block itself if size of block > 0
- FileOutputStream of = new FileOutputStream(cache);
- BufferedOutputStream bout = new BufferedOutputStream(of, 32*1024);
- DataOutputStream out = new DataOutputStream(bout);
-
- out.writeInt(ANCESTRAL_RECORD_VERSION);
- out.writeInt(mStoredSdkVersion);
- out.writeUTF(mStoredIncrementalVersion);
-
- out.writeInt(mRestoredSignatures.size());
- if (mRestoredSignatures.size() > 0) {
- Set<Entry<String, Metadata>> entries = mRestoredSignatures.entrySet();
- for (Entry<String, Metadata> i : entries) {
- final Metadata m = i.getValue();
- final int nHashes = (m.sigHashes != null) ? m.sigHashes.size() : 0;
- out.writeUTF(i.getKey());
- out.writeInt(m.versionCode);
- out.writeInt(nHashes);
- for (int h = 0; h < nHashes; h++) {
- byte[] hash = m.sigHashes.get(h);
- out.writeInt(hash.length);
- if (hash.length > 0) {
- out.write(hash);
- }
- }
- }
- }
- out.flush();
- IoUtils.closeQuietly(out);
- }
-
// We will need to refresh our understanding of what is eligible for
// backup periodically; this entry point serves that purpose.
public void evaluateStorablePackages() {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 9945909..abee0c6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -41,7 +41,6 @@
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
import android.app.AlarmManager;
-import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -52,9 +51,7 @@
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -185,8 +182,8 @@
public class ConnectivityService extends IConnectivityManager.Stub {
private static final String TAG = "ConnectivityService";
- private static final boolean DBG = true;
- private static final boolean VDBG = true; // STOPSHIP
+ private static final boolean DBG = false;
+ private static final boolean VDBG = false; // STOPSHIP
// network sampling debugging
private static final boolean SAMPLE_DBG = false;
@@ -224,10 +221,6 @@
AlarmManager mAlarmManager;
- // used in recursive route setting to add gateways for the host for which
- // a host route was requested.
- private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
-
private Tethering mTethering;
private KeyStore mKeyStore;
@@ -261,11 +254,6 @@
private CaptivePortalTracker mCaptivePortalTracker;
/**
- * The link properties that define the current links
- */
- private LinkProperties mCurrentLinkProperties[];
-
- /**
* A per Net list of the PID's that requested access to the net
* used both as a refcount and for per-PID DNS selection
*/
@@ -297,15 +285,6 @@
private static final int ENABLED = 1;
private static final int DISABLED = 0;
- private static final boolean ADD = true;
- private static final boolean REMOVE = false;
-
- private static final boolean TO_DEFAULT_TABLE = true;
- private static final boolean TO_SECONDARY_TABLE = false;
-
- private static final boolean EXEMPT = true;
- private static final boolean UNEXEMPT = false;
-
/**
* used internally as a delayed event to make us switch back to the
* default network
@@ -450,19 +429,6 @@
private InetAddress mDefaultDns;
- // Lock for protecting access to mAddedRoutes and mExemptAddresses
- private final Object mRoutesLock = new Object();
-
- // this collection is used to refcount the added routes - if there are none left
- // it's time to remove the route from the route table
- @GuardedBy("mRoutesLock")
- private Collection<RouteInfo> mAddedRoutes = new ArrayList<RouteInfo>();
-
- // this collection corresponds to the entries of mAddedRoutes that have routing exemptions
- // used to handle cleanup of exempt rules
- @GuardedBy("mRoutesLock")
- private Collection<LinkAddress> mExemptAddresses = new ArrayList<LinkAddress>();
-
// used in DBG mode to track inet condition reports
private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
private ArrayList mInetLog;
@@ -479,8 +445,6 @@
private SettingsObserver mSettingsObserver;
- private AppOpsManager mAppOpsManager;
-
private UserManager mUserManager;
NetworkConfig[] mNetConfigs;
@@ -514,8 +478,6 @@
// sequence number of NetworkRequests
private int mNextNetworkRequestId = 1;
- private static final int UID_UNUSED = -1;
-
/**
* Implements support for the legacy "one network per network type" model.
*
@@ -701,7 +663,6 @@
mNetTrackers = new NetworkStateTracker[
ConnectivityManager.MAX_NETWORK_TYPE+1];
- mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
mRadioAttributes = new RadioAttributes[ConnectivityManager.MAX_RADIO_TYPE+1];
mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
@@ -884,8 +845,6 @@
filter.addAction(CONNECTED_TO_PROVISIONING_NETWORK_ACTION);
mContext.registerReceiver(mProvisioningReceiver, filter);
- mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
}
@@ -1710,42 +1669,6 @@
}
/**
- * Check if the address falls into any of currently running VPN's route's.
- */
- private boolean isAddressUnderVpn(InetAddress address) {
- synchronized (mVpns) {
- synchronized (mRoutesLock) {
- int uid = UserHandle.getCallingUserId();
- Vpn vpn = mVpns.get(uid);
- if (vpn == null) {
- return false;
- }
-
- // Check if an exemption exists for this address.
- for (LinkAddress destination : mExemptAddresses) {
- if (!NetworkUtils.addressTypeMatches(address, destination.getAddress())) {
- continue;
- }
-
- int prefix = destination.getPrefixLength();
- InetAddress addrMasked = NetworkUtils.getNetworkPart(address, prefix);
- InetAddress destMasked = NetworkUtils.getNetworkPart(destination.getAddress(),
- prefix);
-
- if (addrMasked.equals(destMasked)) {
- return false;
- }
- }
-
- // Finally check if the address is covered by the VPN.
- return vpn.isAddressCovered(address);
- }
- }
- }
-
- /**
- * @deprecated use requestRouteToHostAddress instead
- *
* Ensure that a network route exists to deliver traffic to the specified
* host via the specified network interface.
* @param networkType the type of the network over which traffic to the
@@ -1754,32 +1677,12 @@
* desired
* @return {@code true} on success, {@code false} on failure
*/
- public boolean requestRouteToHost(int networkType, int hostAddress, String packageName) {
- InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
-
- if (inetAddress == null) {
- return false;
- }
-
- return requestRouteToHostAddress(networkType, inetAddress.getAddress(), packageName);
- }
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the specified network interface.
- * @param networkType the type of the network over which traffic to the
- * specified host is to be routed
- * @param hostAddress the IP address of the host to which the route is
- * desired
- * @return {@code true} on success, {@code false} on failure
- */
- public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
- String packageName) {
+ public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
enforceChangePermission();
if (mProtectedNetworks.contains(networkType)) {
enforceConnectivityInternalPermission();
}
- boolean exempt;
+
InetAddress addr;
try {
addr = InetAddress.getByAddress(hostAddress);
@@ -1787,26 +1690,6 @@
if (DBG) log("requestRouteToHostAddress got " + e.toString());
return false;
}
- // System apps may request routes bypassing the VPN to keep other networks working.
- if (Binder.getCallingUid() == Process.SYSTEM_UID) {
- exempt = true;
- } else {
- mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
- try {
- ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(packageName,
- 0);
- exempt = (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
- } catch (NameNotFoundException e) {
- throw new IllegalArgumentException("Failed to find calling package details", e);
- }
- }
-
- // Non-exempt routeToHost's can only be added if the host is not covered by the VPN.
- // This can be either because the VPN's routes do not cover the destination or a
- // system application added an exemption that covers this destination.
- if (!exempt && isAddressUnderVpn(addr)) {
- return false;
- }
if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
@@ -1822,13 +1705,13 @@
}
return false;
}
+
DetailedState netState;
synchronized (nai) {
netState = nai.networkInfo.getDetailedState();
}
- if ((netState != DetailedState.CONNECTED &&
- netState != DetailedState.CAPTIVE_PORTAL_CHECK)) {
+ if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) {
if (VDBG) {
log("requestRouteToHostAddress on down network "
+ "(" + networkType + ") - dropped"
@@ -1836,6 +1719,7 @@
}
return false;
}
+
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
@@ -1845,7 +1729,7 @@
lp = nai.linkProperties;
netId = nai.network.netId;
}
- boolean ok = modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE, exempt, netId, uid);
+ boolean ok = addLegacyRouteToHost(lp, addr, netId, uid);
if (DBG) log("requestRouteToHostAddress ok=" + ok);
return ok;
} finally {
@@ -1853,17 +1737,7 @@
}
}
- private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable,
- boolean exempt, int netId) {
- return modifyRoute(p, r, 0, ADD, toDefaultTable, exempt, netId, false, UID_UNUSED);
- }
-
- private boolean removeRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable, int netId) {
- return modifyRoute(p, r, 0, REMOVE, toDefaultTable, UNEXEMPT, netId, false, UID_UNUSED);
- }
-
- private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd,
- boolean toDefaultTable, boolean exempt, int netId, int uid) {
+ private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) {
RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
if (bestRoute == null) {
bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
@@ -1878,125 +1752,14 @@
bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
}
}
- return modifyRoute(lp, bestRoute, 0, doAdd, toDefaultTable, exempt, netId, true, uid);
- }
-
- /*
- * TODO: Clean all this stuff up. Once we have UID-based routing, stuff will break due to
- * incorrect tracking of mAddedRoutes, so a cleanup becomes necessary and urgent. But at
- * the same time, there'll be no more need to track mAddedRoutes or mExemptAddresses,
- * or even have the concept of an exempt address, or do things like "selectBestRoute", or
- * determine "default" vs "secondary" table, etc., so the cleanup becomes possible.
- */
- private boolean modifyRoute(LinkProperties lp, RouteInfo r, int cycleCount, boolean doAdd,
- boolean toDefaultTable, boolean exempt, int netId, boolean legacy, int uid) {
- if ((lp == null) || (r == null)) {
- if (DBG) log("modifyRoute got unexpected null: " + lp + ", " + r);
+ if (VDBG) log("Adding " + bestRoute + " for interface " + bestRoute.getInterface());
+ try {
+ mNetd.addLegacyRouteForNetId(netId, bestRoute, uid);
+ } catch (Exception e) {
+ // never crash - catch them all
+ if (DBG) loge("Exception trying to add a route: " + e);
return false;
}
-
- if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
- loge("Error modifying route - too much recursion");
- return false;
- }
-
- String ifaceName = r.getInterface();
- if(ifaceName == null) {
- loge("Error modifying route - no interface name");
- return false;
- }
- if (r.hasGateway()) {
- RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), r.getGateway());
- if (bestRoute != null) {
- if (bestRoute.getGateway().equals(r.getGateway())) {
- // if there is no better route, add the implied hostroute for our gateway
- bestRoute = RouteInfo.makeHostRoute(r.getGateway(), ifaceName);
- } else {
- // if we will connect to our gateway through another route, add a direct
- // route to it's gateway
- bestRoute = RouteInfo.makeHostRoute(r.getGateway(),
- bestRoute.getGateway(),
- ifaceName);
- }
- modifyRoute(lp, bestRoute, cycleCount+1, doAdd, toDefaultTable, exempt, netId,
- legacy, uid);
- }
- }
- if (doAdd) {
- if (VDBG) log("Adding " + r + " for interface " + ifaceName);
- try {
- if (toDefaultTable) {
- synchronized (mRoutesLock) {
- // only track default table - only one apps can effect
- mAddedRoutes.add(r);
- if (legacy) {
- mNetd.addLegacyRouteForNetId(netId, r, uid);
- } else {
- mNetd.addRoute(netId, r);
- }
- if (exempt) {
- LinkAddress dest = r.getDestinationLinkAddress();
- if (!mExemptAddresses.contains(dest)) {
- mNetd.setHostExemption(dest);
- mExemptAddresses.add(dest);
- }
- }
- }
- } else {
- if (legacy) {
- mNetd.addLegacyRouteForNetId(netId, r, uid);
- } else {
- mNetd.addRoute(netId, r);
- }
- }
- } catch (Exception e) {
- // never crash - catch them all
- if (DBG) loge("Exception trying to add a route: " + e);
- return false;
- }
- } else {
- // if we remove this one and there are no more like it, then refcount==0 and
- // we can remove it from the table
- if (toDefaultTable) {
- synchronized (mRoutesLock) {
- mAddedRoutes.remove(r);
- if (mAddedRoutes.contains(r) == false) {
- if (VDBG) log("Removing " + r + " for interface " + ifaceName);
- try {
- if (legacy) {
- mNetd.removeLegacyRouteForNetId(netId, r, uid);
- } else {
- mNetd.removeRoute(netId, r);
- }
- LinkAddress dest = r.getDestinationLinkAddress();
- if (mExemptAddresses.contains(dest)) {
- mNetd.clearHostExemption(dest);
- mExemptAddresses.remove(dest);
- }
- } catch (Exception e) {
- // never crash - catch them all
- if (VDBG) loge("Exception trying to remove a route: " + e);
- return false;
- }
- } else {
- if (VDBG) log("not removing " + r + " as it's still in use");
- }
- }
- } else {
- if (VDBG) log("Removing " + r + " for interface " + ifaceName);
- try {
- if (legacy) {
- mNetd.removeLegacyRouteForNetId(netId, r, uid);
- } else {
- mNetd.removeRoute(netId, r);
- }
- } catch (Exception e) {
- // never crash - catch them all
- if (VDBG) loge("Exception trying to remove a route: " + e);
- return false;
- }
- }
- }
return true;
}
@@ -2607,6 +2370,7 @@
*
* TODO - delete when we're sure all this functionallity is captured.
*/
+ /*
private void handleConnectivityChange(int netType, LinkProperties curLp, boolean doReset) {
int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0;
boolean exempt = ConnectivityManager.isNetworkTypeExempt(netType);
@@ -2615,10 +2379,8 @@
+ " resetMask=" + resetMask);
}
- /*
- * If a non-default network is enabled, add the host routes that
- * will allow it's DNS servers to be accessed.
- */
+ // If a non-default network is enabled, add the host routes that
+ // will allow it's DNS servers to be accessed.
handleDnsConfigurationChange(netType);
LinkProperties newLp = null;
@@ -2719,7 +2481,7 @@
// TODO: Temporary notifying upstread change to Tethering.
// @see bug/4455071
- /** Notify TetheringService if interface name has been changed. */
+ // Notify TetheringService if interface name has been changed.
if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
if (isTetheringSupported()) {
@@ -2727,6 +2489,7 @@
}
}
}
+ */
/**
* Add and remove routes using the old properties (null if not previously connected),
@@ -2736,6 +2499,7 @@
* host routes should be set to the dns servers
* returns a boolean indicating the routes changed
*/
+ /*
private boolean updateRoutes(LinkProperties newLp, LinkProperties curLp,
boolean isLinkDefault, boolean exempt, int netId) {
Collection<RouteInfo> routesToAdd = null;
@@ -2789,6 +2553,7 @@
return routesChanged;
}
+ */
/**
* Reads the network specific MTU size from reources.
@@ -3264,10 +3029,12 @@
// any activity by applications trying to use this
// connection will fail until the provisioning network
// is enabled.
+ /*
for (RouteInfo r : lp.getRoutes()) {
removeRoute(lp, r, TO_DEFAULT_TABLE,
mNetTrackers[info.getType()].getNetwork().netId);
}
+ */
} else if (state == NetworkInfo.State.DISCONNECTED) {
} else if (state == NetworkInfo.State.SUSPENDED) {
} else if (state == NetworkInfo.State.CONNECTED) {
@@ -3283,8 +3050,10 @@
// TODO: Temporary allowing network configuration
// change not resetting sockets.
// @see bug/4455071
+ /*
handleConnectivityChange(info.getType(), mCurrentLinkProperties[info.getType()],
false);
+ */
break;
}
case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED: {
@@ -4683,7 +4452,7 @@
// Make a route to host so we check the specific interface.
if (mCs.requestRouteToHostAddress(ConnectivityManager.TYPE_MOBILE_HIPRI,
- hostAddr.getAddress(), null)) {
+ hostAddr.getAddress())) {
// Wait a short time to be sure the route is established ??
log("isMobileOk:"
+ " wait to establish route to hostAddr=" + hostAddr);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 2434f712..db423b0 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -108,15 +108,6 @@
private static final String NETD_TAG = "NetdConnector";
private static final String NETD_SOCKET_NAME = "netd";
- private static final String ADD = "add";
- private static final String REMOVE = "remove";
-
- private static final String ALLOW = "allow";
- private static final String DENY = "deny";
-
- private static final String DEFAULT = "default";
- private static final String SECONDARY = "secondary";
-
private static final int MAX_UID_RANGES_PER_COMMAND = 10;
/**
@@ -126,7 +117,7 @@
public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
class NetdResponseCode {
- /* Keep in sync with system/netd/ResponseCode.h */
+ /* Keep in sync with system/netd/server/ResponseCode.h */
public static final int InterfaceListResult = 110;
public static final int TetherInterfaceListResult = 111;
public static final int TetherDnsFwdTgtListResult = 112;
@@ -946,15 +937,15 @@
@Override
public void addRoute(int netId, RouteInfo route) {
- modifyRoute(netId, ADD, route);
+ modifyRoute("add", "" + netId, route);
}
@Override
public void removeRoute(int netId, RouteInfo route) {
- modifyRoute(netId, REMOVE, route);
+ modifyRoute("remove", "" + netId, route);
}
- private void modifyRoute(int netId, String action, RouteInfo route) {
+ private void modifyRoute(String action, String netId, RouteInfo route) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
final Command cmd = new Command("network", "route", action, netId);
@@ -1175,6 +1166,11 @@
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
+ List<RouteInfo> routes = new ArrayList<RouteInfo>();
+ // The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it
+ // suitable to use as a route destination.
+ routes.add(new RouteInfo(getInterfaceConfig(iface).getLinkAddress(), null, iface));
+ addInterfaceToLocalNetwork(iface, routes);
}
@Override
@@ -1185,6 +1181,7 @@
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
+ removeInterfaceFromLocalNetwork(iface);
}
@Override
@@ -1748,36 +1745,6 @@
}
@Override
- public void setHostExemption(LinkAddress host) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- try {
- mConnector.execute("interface", "fwmark", "exempt", "add", host);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
- }
- }
-
- @Override
- public void clearHostExemption(LinkAddress host) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- try {
- mConnector.execute("interface", "fwmark", "exempt", "remove", host);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
- }
- }
-
- @Override
- public void flushNetworkDnsCache(int netId) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- try {
- mConnector.execute("resolver", "flushnet", netId);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
- }
- }
-
- @Override
public void setFirewallEnabled(boolean enabled) {
enforceSystemUid();
try {
@@ -1798,7 +1765,7 @@
public void setFirewallInterfaceRule(String iface, boolean allow) {
enforceSystemUid();
Preconditions.checkState(mFirewallEnabled);
- final String rule = allow ? ALLOW : DENY;
+ final String rule = allow ? "allow" : "deny";
try {
mConnector.execute("firewall", "set_interface_rule", iface, rule);
} catch (NativeDaemonConnectorException e) {
@@ -1810,7 +1777,7 @@
public void setFirewallEgressSourceRule(String addr, boolean allow) {
enforceSystemUid();
Preconditions.checkState(mFirewallEnabled);
- final String rule = allow ? ALLOW : DENY;
+ final String rule = allow ? "allow" : "deny";
try {
mConnector.execute("firewall", "set_egress_source_rule", addr, rule);
} catch (NativeDaemonConnectorException e) {
@@ -1822,7 +1789,7 @@
public void setFirewallEgressDestRule(String addr, int port, boolean allow) {
enforceSystemUid();
Preconditions.checkState(mFirewallEnabled);
- final String rule = allow ? ALLOW : DENY;
+ final String rule = allow ? "allow" : "deny";
try {
mConnector.execute("firewall", "set_egress_dest_rule", addr, port, rule);
} catch (NativeDaemonConnectorException e) {
@@ -1834,7 +1801,7 @@
public void setFirewallUidRule(int uid, boolean allow) {
enforceSystemUid();
Preconditions.checkState(mFirewallEnabled);
- final String rule = allow ? ALLOW : DENY;
+ final String rule = allow ? "allow" : "deny";
try {
mConnector.execute("firewall", "set_uid_rule", uid, rule);
} catch (NativeDaemonConnectorException e) {
@@ -2003,21 +1970,18 @@
@Override
public void addInterfaceToNetwork(String iface, int netId) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
- try {
- mConnector.execute("network", "addiface", netId, iface);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
- }
+ modifyInterfaceInNetwork("add", "" + netId, iface);
}
@Override
public void removeInterfaceFromNetwork(String iface, int netId) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+ modifyInterfaceInNetwork("remove", "" + netId, iface);
+ }
+ private void modifyInterfaceInNetwork(String action, String netId, String iface) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- mConnector.execute("network", "removeiface", netId, iface);
+ mConnector.execute("network", "interface", action, netId, iface);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
@@ -2025,18 +1989,9 @@
@Override
public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
- modifyLegacyRouteForNetId(netId, routeInfo, uid, ADD);
- }
-
- @Override
- public void removeLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
- modifyLegacyRouteForNetId(netId, routeInfo, uid, REMOVE);
- }
-
- private void modifyLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid, String action) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- final Command cmd = new Command("network", "route", "legacy", uid, action, netId);
+ final Command cmd = new Command("network", "route", "legacy", uid, "add", netId);
// create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
final LinkAddress la = routeInfo.getDestinationLinkAddress();
@@ -2131,4 +2086,19 @@
}
}
+ @Override
+ public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) {
+ modifyInterfaceInNetwork("add", "local", iface);
+
+ for (RouteInfo route : routes) {
+ if (!route.isDefaultRoute()) {
+ modifyRoute("add", "local", route);
+ }
+ }
+ }
+
+ @Override
+ public void removeInterfaceFromLocalNetwork(String iface) {
+ modifyInterfaceInNetwork("remove", "local", iface);
+ }
}
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index fe97c71..cf7e65c 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -603,7 +603,7 @@
return mUniqueId;
}
- /* These should be in sync with system/netd/mDnsResponseCode.h */
+ /* These should be in sync with system/netd/server/ResponseCode.h */
class NativeResponseCode {
public static final int SERVICE_DISCOVERY_FAILED = 602;
public static final int SERVICE_FOUND = 603;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3aaa402..2d6d09b 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18,6 +18,7 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -3545,6 +3546,23 @@
}
}
+ @Override
+ public final int startActivityFromRecents(int taskId, Bundle options) {
+ if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
+ String msg = "Permission Denial: startActivityFromRecents called without " +
+ START_TASKS_FROM_RECENTS;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task == null) {
+ throw new ActivityNotFoundException("Task " + taskId + " not found.");
+ }
+ return startActivityInPackage(task.mCallingUid, task.mCallingPackage,
+ task.intent, null, null, null, 0, 0, options, task.userId,
+ null);
+ }
+
final int startActivityInPackage(int uid, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, Bundle options, int userId,
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 061053a..69949a4 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -68,6 +68,8 @@
private static final String ATTR_TASK_AFFILIATION = "task_affiliation";
private static final String ATTR_PREV_AFFILIATION = "prev_affiliation";
private static final String ATTR_NEXT_AFFILIATION = "next_affiliation";
+ private static final String ATTR_CALLING_UID = "calling_uid";
+ private static final String ATTR_CALLING_PACKAGE = "calling_package";
private static final String LAST_ACTIVITY_ICON_SUFFIX = "_last_activity_icon_";
private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
@@ -144,6 +146,10 @@
TaskRecord mNextAffiliate; // next task in affiliated chain.
int mNextAffiliateTaskId = -1; // next id for persistence.
+ // For relaunching the task from recents as though it was launched by the original launcher.
+ int mCallingUid;
+ String mCallingPackage;
+
final ActivityManagerService mService;
TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
@@ -167,7 +173,7 @@
String _lastDescription, ArrayList<ActivityRecord> activities, long _firstActiveTime,
long _lastActiveTime, long lastTimeMoved, boolean neverRelinquishIdentity,
ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation,
- int prevTaskId, int nextTaskId) {
+ int prevTaskId, int nextTaskId, int callingUid, String callingPackage) {
mService = service;
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
@@ -196,17 +202,19 @@
mAffiliatedTaskId = taskAffiliation;
mPrevAffiliateTaskId = prevTaskId;
mNextAffiliateTaskId = nextTaskId;
+ mCallingUid = callingUid;
+ mCallingPackage = callingPackage;
}
void touchActiveTime() {
- lastActiveTime = android.os.SystemClock.elapsedRealtime();
+ lastActiveTime = System.currentTimeMillis();
if (firstActiveTime == 0) {
firstActiveTime = lastActiveTime;
}
}
long getInactiveDuration() {
- return android.os.SystemClock.elapsedRealtime() - lastActiveTime;
+ return System.currentTimeMillis() - lastActiveTime;
}
void setIntent(Intent _intent, ActivityInfo info) {
@@ -458,6 +466,8 @@
if (mActivities.isEmpty()) {
taskType = r.mActivityType;
isPersistable = r.isPersistable();
+ mCallingUid = r.launchedFromUid;
+ mCallingPackage = r.launchedFromPackage;
// Clamp to [1, 100].
maxRecents = Math.min(Math.max(r.info.maxRecents, 1), 100);
} else {
@@ -765,6 +775,8 @@
out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId));
+ out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
+ out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
if (affinityIntent != null) {
out.startTag(null, TAG_AFFINITYINTENT);
@@ -816,6 +828,8 @@
int taskAffiliation = -1;
int prevTaskId = -1;
int nextTaskId = -1;
+ int callingUid = -1;
+ String callingPackage = "";
for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
final String attrName = in.getAttributeName(attrNdx);
@@ -858,6 +872,10 @@
prevTaskId = Integer.valueOf(attrValue);
} else if (ATTR_NEXT_AFFILIATION.equals(attrName)) {
nextTaskId = Integer.valueOf(attrValue);
+ } else if (ATTR_CALLING_UID.equals(attrName)) {
+ callingUid = Integer.valueOf(attrValue);
+ } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
+ callingPackage = attrValue;
} else {
Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
}
@@ -898,7 +916,8 @@
affinityIntent, affinity, realActivity, origActivity, rootHasReset,
autoRemoveRecents, askedCompatMode, taskType, userId, lastDescription, activities,
firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
- taskDescription, taskAffiliation, prevTaskId, nextTaskId);
+ taskDescription, taskAffiliation, prevTaskId, nextTaskId, callingUid,
+ callingPackage);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
activities.get(activityNdx).task = task;
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 01a2fc2..d948942 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -724,14 +724,6 @@
return retVal;
}
- //TODO: Temporary handling upstream change triggered without
- // CONNECTIVITY_ACTION. Only to accomodate interface
- // switch during HO.
- // @see bug/4455071
- public void handleTetherIfaceChange() {
- mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
- }
-
class TetherInterfaceSM extends StateMachine {
// notification from the master SM that it's not in tether mode
static final int CMD_TETHER_MODE_DEAD = 1;
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index d15254b..7b68d55 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -488,18 +488,6 @@
return tun;
}
- /**
- * Check if a given address is covered by the VPN's routing rules.
- */
- public boolean isAddressCovered(InetAddress address) {
- synchronized (Vpn.this) {
- if (!isRunningLocked()) {
- return false;
- }
- return RouteInfo.selectBestRoute(mConfig.routes, address) != null;
- }
- }
-
private boolean isRunningLocked() {
return mVpnUsers != null;
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 1279c6e..64d3dc5 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -719,10 +719,16 @@
@Override
public void setMasterSyncAutomatically(boolean flag) {
+ setMasterSyncAutomaticallyAsUser(flag, UserHandle.getCallingUserId());
+ }
+
+ @Override
+ public void setMasterSyncAutomaticallyAsUser(boolean flag, int userId) {
+ enforceCrossUserPermission(userId,
+ "no permission to set the sync status for user " + userId);
mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
"no permission to write the sync settings");
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
SyncManager syncManager = getSyncManager();
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 4740cae..45d3771 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -26,7 +26,6 @@
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
-import android.hardware.display.DisplayManagerInternal;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -199,9 +198,10 @@
return mScreenAutoBrightness;
}
- public void updatePowerState(DisplayManagerInternal.DisplayPowerRequest request) {
- if (setScreenAutoBrightnessAdjustment(request.screenAutoBrightnessAdjustment)
- | setLightSensorEnabled(request.wantLightSensorEnabled())) {
+ public void configure(boolean enable, float adjustment) {
+ boolean changed = setLightSensorEnabled(enable);
+ changed |= setScreenAutoBrightnessAdjustment(adjustment);
+ if (changed) {
updateAutoBrightness(false /*sendUpdate*/);
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index a361e10..09221a3e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -213,9 +213,11 @@
// The elapsed real time when the screen on was blocked.
private long mScreenOnBlockStartRealTime;
- // True if the screen auto-brightness value is actually being used to
- // set the display brightness.
- private boolean mUsingScreenAutoBrightness;
+ // Remembers whether certain kinds of brightness adjustments
+ // were recently applied so that we can decide how to transition.
+ private boolean mAppliedAutoBrightness;
+ private boolean mAppliedDimming;
+ private boolean mAppliedLowPower;
// The controller for the automatic brightness level.
private AutomaticBrightnessController mAutomaticBrightnessController;
@@ -428,7 +430,6 @@
// Update the power state request.
final boolean mustNotify;
boolean mustInitialize = false;
- boolean wasDimOrDoze = false;
boolean autoBrightnessAdjustmentChanged = false;
synchronized (mLock) {
@@ -444,8 +445,6 @@
mPendingRequestChangedLocked = false;
mustInitialize = true;
} else if (mPendingRequestChangedLocked) {
- wasDimOrDoze = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM
- || mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE);
autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
!= mPendingRequestLocked.screenAutoBrightnessAdjustment);
mPowerRequest.copyFrom(mPendingRequestLocked);
@@ -463,10 +462,32 @@
initialize();
}
+ // Compute the basic display state using the policy.
+ // We might override this below based on other factors.
+ int state;
+ int brightness = PowerManager.BRIGHTNESS_DEFAULT;
+ switch (mPowerRequest.policy) {
+ case DisplayPowerRequest.POLICY_OFF:
+ state = Display.STATE_OFF;
+ break;
+ case DisplayPowerRequest.POLICY_DOZE:
+ if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
+ state = mPowerRequest.dozeScreenState;
+ } else {
+ state = Display.STATE_DOZE;
+ }
+ brightness = mPowerRequest.dozeScreenBrightness;
+ break;
+ case DisplayPowerRequest.POLICY_DIM:
+ case DisplayPowerRequest.POLICY_BRIGHT:
+ default:
+ state = Display.STATE_ON;
+ break;
+ }
+
// Apply the proximity sensor.
if (mProximitySensor != null) {
- if (mPowerRequest.useProximitySensor
- && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
+ if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
setProximitySensorEnabled(true);
if (!mScreenOffBecauseOfProximity
&& mProximity == PROXIMITY_POSITIVE) {
@@ -476,7 +497,7 @@
} else if (mWaitingForNegativeProximity
&& mScreenOffBecauseOfProximity
&& mProximity == PROXIMITY_POSITIVE
- && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
+ && state != Display.STATE_OFF) {
setProximitySensorEnabled(true);
} else {
setProximitySensorEnabled(false);
@@ -490,63 +511,89 @@
} else {
mWaitingForNegativeProximity = false;
}
-
- // Turn on the light sensor if needed.
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.updatePowerState(mPowerRequest);
+ if (mScreenOffBecauseOfProximity) {
+ state = Display.STATE_OFF;
}
- // Set the screen brightness.
- if (mPowerRequest.wantScreenOnAny()) {
- int target;
- boolean slow;
- int screenAutoBrightness = mAutomaticBrightnessController != null ?
- mAutomaticBrightnessController.getAutomaticScreenBrightness() : -1;
- if (screenAutoBrightness >= 0 && mPowerRequest.useAutoBrightness) {
- // Use current auto-brightness value.
- target = screenAutoBrightness;
- slow = mUsingScreenAutoBrightness && !autoBrightnessAdjustmentChanged;
- mUsingScreenAutoBrightness = true;
+ // Use zero brightness when screen is off.
+ if (state == Display.STATE_OFF) {
+ brightness = PowerManager.BRIGHTNESS_OFF;
+ }
+
+ // Use default brightness when dozing unless overridden.
+ if (brightness < 0 && (state == Display.STATE_DOZE
+ || state == Display.STATE_DOZE_SUSPEND)) {
+ brightness = mScreenBrightnessDozeConfig;
+ }
+
+ // Configure auto-brightness.
+ boolean autoBrightnessEnabled = false;
+ if (mAutomaticBrightnessController != null) {
+ autoBrightnessEnabled = mPowerRequest.useAutoBrightness
+ && state == Display.STATE_ON && brightness < 0;
+ mAutomaticBrightnessController.configure(autoBrightnessEnabled,
+ mPowerRequest.screenAutoBrightnessAdjustment);
+ }
+
+ // Apply auto-brightness.
+ boolean slowChange = false;
+ if (brightness < 0) {
+ if (autoBrightnessEnabled) {
+ brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
+ }
+ if (brightness >= 0) {
+ // Use current auto-brightness value and slowly adjust to changes.
+ brightness = clampScreenBrightness(brightness);
+ if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
+ slowChange = true; // slowly adapt to auto-brightness
+ }
+ mAppliedAutoBrightness = true;
} else {
- // Light sensor is disabled or not ready yet.
- // Use the current brightness setting from the request, which is expected
- // provide a nominal default value for the case where auto-brightness
- // is not ready yet.
- target = mPowerRequest.screenBrightness;
- slow = false;
- mUsingScreenAutoBrightness = false;
+ mAppliedAutoBrightness = false;
}
- if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) {
- // Dim quickly to the doze state.
- target = mScreenBrightnessDozeConfig;
- slow = false;
- } else if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {
- // Dim quickly by at least some minimum amount.
- target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION,
- mScreenBrightnessDimConfig);
- slow = false;
- } else if (wasDimOrDoze) {
- // Brighten quickly.
- slow = false;
- }
- // If low power mode is enabled, brightness level
- // would be scaled down to half
- if (mPowerRequest.lowPowerMode) {
- target = target/2;
- }
- animateScreenBrightness(clampScreenBrightness(target),
- slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
} else {
- // Screen is off. Don't bother changing the brightness.
- mUsingScreenAutoBrightness = false;
+ mAppliedAutoBrightness = false;
+ }
+
+ // Apply manual brightness.
+ // Use the current brightness setting from the request, which is expected
+ // provide a nominal default value for the case where auto-brightness
+ // is not ready yet.
+ if (brightness < 0) {
+ brightness = clampScreenBrightness(mPowerRequest.screenBrightness);
+ }
+
+ // Apply dimming by at least some minimum amount when user activity
+ // timeout is about to expire.
+ if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
+ brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
+ mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
+ if (!mAppliedDimming) {
+ slowChange = false;
+ }
+ mAppliedDimming = true;
+ }
+
+ // If low power mode is enabled, cut the brightness level by half
+ // as long as it is above the minimum threshold.
+ if (mPowerRequest.lowPowerMode) {
+ if (brightness > mScreenBrightnessRangeMinimum) {
+ brightness = Math.max(brightness / 2, mScreenBrightnessRangeMinimum);
+ }
+ if (!mAppliedLowPower) {
+ slowChange = false;
+ }
+ mAppliedLowPower = true;
+ }
+
+ // Animate the screen brightness when the screen is on.
+ if (state != Display.STATE_OFF) {
+ animateScreenBrightness(brightness, slowChange
+ ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
}
// Animate the screen on or off unless blocked.
- if (mScreenOffBecauseOfProximity) {
- // Screen off due to proximity.
- setScreenState(Display.STATE_OFF);
- unblockScreenOn();
- } else if (mPowerRequest.wantScreenOnAny()) {
+ if (state == Display.STATE_ON) {
// Want screen on.
// Wait for previous off animation to complete beforehand.
// It is relatively short but if we cancel it and switch to the
@@ -555,21 +602,14 @@
// Turn the screen on. The contents of the screen may not yet
// be visible if the electron beam has not been dismissed because
// its last frame of animation is solid black.
-
- if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) {
- if (!mScreenBrightnessRampAnimator.isAnimating()) {
- setScreenState(Display.STATE_DOZE);
- }
- } else {
- setScreenState(Display.STATE_ON);
- }
-
+ setScreenState(Display.STATE_ON);
if (mPowerRequest.blockScreenOn
&& mPowerState.getElectronBeamLevel() == 0.0f) {
blockScreenOn();
} else {
unblockScreenOn();
- if (USE_ELECTRON_BEAM_ON_ANIMATION) {
+ if (USE_ELECTRON_BEAM_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {
+ // Perform screen on animation.
if (!mElectronBeamOnAnimator.isStarted()) {
if (mPowerState.getElectronBeamLevel() == 1.0f) {
mPowerState.dismissElectronBeam();
@@ -583,28 +623,59 @@
}
}
} else {
+ // Skip screen on animation.
mPowerState.setElectronBeamLevel(1.0f);
mPowerState.dismissElectronBeam();
}
}
}
+ } else if (state == Display.STATE_DOZE) {
+ // Want screen dozing.
+ // Wait for brightness animation to complete beforehand when entering doze
+ // from screen on.
+ unblockScreenOn();
+ if (!mScreenBrightnessRampAnimator.isAnimating()
+ || mPowerState.getScreenState() != Display.STATE_ON) {
+ // Set screen state and dismiss the black surface without fanfare.
+ setScreenState(state);
+ mPowerState.setElectronBeamLevel(1.0f);
+ mPowerState.dismissElectronBeam();
+ }
+ } else if (state == Display.STATE_DOZE_SUSPEND) {
+ // Want screen dozing and suspended.
+ // Wait for brightness animation to complete beforehand unless already
+ // suspended because we may not be able to change it after suspension.
+ unblockScreenOn();
+ if (!mScreenBrightnessRampAnimator.isAnimating()
+ || mPowerState.getScreenState() == Display.STATE_DOZE_SUSPEND) {
+ // Set screen state and dismiss the black surface without fanfare.
+ setScreenState(state);
+ mPowerState.setElectronBeamLevel(1.0f);
+ mPowerState.dismissElectronBeam();
+ }
} else {
// Want screen off.
// Wait for previous on animation to complete beforehand.
unblockScreenOn();
if (!mElectronBeamOnAnimator.isStarted()) {
- if (!mElectronBeamOffAnimator.isStarted()) {
- if (mPowerState.getElectronBeamLevel() == 0.0f) {
- setScreenState(Display.STATE_OFF);
- } else if (mPowerState.prepareElectronBeam(
- mElectronBeamFadesConfig ?
- ElectronBeam.MODE_FADE :
- ElectronBeam.MODE_COOL_DOWN)
- && mPowerState.getScreenState() != Display.STATE_OFF) {
- mElectronBeamOffAnimator.start();
- } else {
- mElectronBeamOffAnimator.end();
+ if (mPowerRequest.policy == DisplayPowerRequest.POLICY_OFF) {
+ // Perform screen off animation.
+ if (!mElectronBeamOffAnimator.isStarted()) {
+ if (mPowerState.getElectronBeamLevel() == 0.0f) {
+ setScreenState(Display.STATE_OFF);
+ } else if (mPowerState.prepareElectronBeam(
+ mElectronBeamFadesConfig ?
+ ElectronBeam.MODE_FADE :
+ ElectronBeam.MODE_COOL_DOWN)
+ && mPowerState.getScreenState() != Display.STATE_OFF) {
+ mElectronBeamOffAnimator.start();
+ } else {
+ mElectronBeamOffAnimator.end();
+ }
}
+ } else {
+ // Skip screen off animation.
+ setScreenState(Display.STATE_OFF);
}
}
}
@@ -856,7 +927,9 @@
pw.println(" mPendingProximityDebounceTime="
+ TimeUtils.formatUptime(mPendingProximityDebounceTime));
pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
- pw.println(" mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness);
+ pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
+ pw.println(" mAppliedDimming=" + mAppliedDimming);
+ pw.println(" mAppliedLowPower=" + mAppliedLowPower);
pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
mScreenBrightnessRampAnimator.isAnimating());
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index a5f8849..4821e74 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -402,13 +402,14 @@
Slog.d(TAG, "Updating screen state: state="
+ Display.stateToString(state) + ", backlight=" + backlight);
}
- if (stateChanged && state != Display.STATE_OFF) {
+ boolean suspending = Display.isSuspendedState(state);
+ if (stateChanged && !suspending) {
mBlanker.requestDisplayState(state);
}
if (backlightChanged) {
mBacklight.setBrightness(backlight);
}
- if (stateChanged && state == Display.STATE_OFF) {
+ if (stateChanged && suspending) {
mBlanker.requestDisplayState(state);
}
}
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 4ccf73b..107a6f6 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -38,6 +38,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
+import android.os.PowerManagerInternal;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -48,6 +49,7 @@
import android.service.dreams.IDreamManager;
import android.text.TextUtils;
import android.util.Slog;
+import android.view.Display;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -71,6 +73,7 @@
private final DreamHandler mHandler;
private final DreamController mController;
private final PowerManager mPowerManager;
+ private final PowerManagerInternal mPowerManagerInternal;
private final PowerManager.WakeLock mDozeWakeLock;
private final McuHal mMcuHal; // synchronized on self
@@ -81,6 +84,8 @@
private boolean mCurrentDreamCanDoze;
private boolean mCurrentDreamIsDozing;
private boolean mCurrentDreamIsWaking;
+ private int mCurrentDreamDozeScreenState = Display.STATE_UNKNOWN;
+ private int mCurrentDreamDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
private DozeHardwareWrapper mCurrentDreamDozeHardware;
public DreamManagerService(Context context) {
@@ -90,6 +95,7 @@
mController = new DreamController(context, mHandler, mControllerListener);
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ mPowerManagerInternal = getLocalService(PowerManagerInternal.class);
mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, TAG);
mMcuHal = McuHal.open();
@@ -134,6 +140,9 @@
pw.println("mCurrentDreamCanDoze=" + mCurrentDreamCanDoze);
pw.println("mCurrentDreamIsDozing=" + mCurrentDreamIsDozing);
pw.println("mCurrentDreamIsWaking=" + mCurrentDreamIsWaking);
+ pw.println("mCurrentDreamDozeScreenState="
+ + Display.stateToString(mCurrentDreamDozeScreenState));
+ pw.println("mCurrentDreamDozeScreenBrightness=" + mCurrentDreamDozeScreenBrightness);
pw.println("mCurrentDreamDozeHardware=" + mCurrentDreamDozeHardware);
pw.println("getDozeComponent()=" + getDozeComponent());
pw.println();
@@ -213,16 +222,24 @@
}
}
- private void startDozingInternal(IBinder token) {
+ private void startDozingInternal(IBinder token, int screenState,
+ int screenBrightness) {
if (DEBUG) {
- Slog.d(TAG, "Dream requested to start dozing: " + token);
+ Slog.d(TAG, "Dream requested to start dozing: " + token
+ + ", screenState=" + screenState
+ + ", screenBrightness=" + screenBrightness);
}
synchronized (mLock) {
- if (mCurrentDreamToken == token && mCurrentDreamCanDoze
- && !mCurrentDreamIsDozing) {
- mCurrentDreamIsDozing = true;
- mDozeWakeLock.acquire();
+ if (mCurrentDreamToken == token && mCurrentDreamCanDoze) {
+ mCurrentDreamDozeScreenState = screenState;
+ mCurrentDreamDozeScreenBrightness = screenBrightness;
+ mPowerManagerInternal.setDozeOverrideFromDreamManager(
+ screenState, screenBrightness);
+ if (!mCurrentDreamIsDozing) {
+ mCurrentDreamIsDozing = true;
+ mDozeWakeLock.acquire();
+ }
}
}
}
@@ -236,6 +253,8 @@
if (mCurrentDreamToken == token && mCurrentDreamIsDozing) {
mCurrentDreamIsDozing = false;
mDozeWakeLock.release();
+ mPowerManagerInternal.setDozeOverrideFromDreamManager(
+ Display.STATE_UNKNOWN, PowerManager.BRIGHTNESS_DEFAULT);
}
}
}
@@ -399,6 +418,8 @@
mCurrentDreamIsDozing = false;
mDozeWakeLock.release();
}
+ mCurrentDreamDozeScreenState = Display.STATE_UNKNOWN;
+ mCurrentDreamDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
if (mCurrentDreamDozeHardware != null) {
mCurrentDreamDozeHardware.release();
mCurrentDreamDozeHardware = null;
@@ -593,7 +614,7 @@
}
@Override // Binder call
- public void startDozing(IBinder token) {
+ public void startDozing(IBinder token, int screenState, int screenBrightness) {
// Requires no permission, called by Dream from an arbitrary process.
if (token == null) {
throw new IllegalArgumentException("token must not be null");
@@ -601,7 +622,7 @@
final long ident = Binder.clearCallingIdentity();
try {
- startDozingInternal(token);
+ startDozingInternal(token, screenState, screenBrightness);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 85c7747..946d4ce 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -16,6 +16,8 @@
package com.android.server.hdmi;
+import android.hardware.hdmi.HdmiCecDeviceInfo;
+
/**
* Defines constants related to HDMI-CEC protocol internal implementation.
* If a constant will be used in the public api, it should be located in
@@ -78,7 +80,7 @@
public static final int ADDR_INVALID = -1;
/** Logical address used to indicate the source comes from internal device. */
- public static final int ADDR_INTERNAL = 0xFFFF;
+ public static final int ADDR_INTERNAL = HdmiCecDeviceInfo.ADDR_INTERNAL;
static final int MESSAGE_FEATURE_ABORT = 0x00;
static final int MESSAGE_IMAGE_VIEW_ON = 0x04;
@@ -179,10 +181,11 @@
static final int INVALID_PORT_ID = -1;
static final int INVALID_PHYSICAL_ADDRESS = 0xFFFF;
- // Send result codes.
+ // Send result codes. It should be consistent with hdmi_cec.h's send_message error code.
static final int SEND_RESULT_SUCCESS = 0;
- static final int SEND_RESULT_NAK = -1;
- static final int SEND_RESULT_FAILURE = -2;
+ static final int SEND_RESULT_NAK = 1;
+ static final int SEND_RESULT_BUSY = 2;
+ static final int SEND_RESULT_FAILURE = 3;
// Strategy for device polling.
// Should use "OR(|) operation of POLL_STRATEGY_XXX and POLL_ITERATION_XXX.
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index a66f473..e985e35 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -556,6 +556,9 @@
@ServiceThreadOnly
private void clearDeviceInfoList() {
assertRunOnServiceThread();
+ for (HdmiCecDeviceInfo info : mSafeExternalInputs) {
+ mService.invokeDeviceEventListeners(info, false);
+ }
mDeviceInfos.clear();
updateSafeDeviceInfoList();
}
@@ -1129,6 +1132,7 @@
disableSystemAudioIfExist();
disableArcIfExist();
+ clearDeviceInfoList();
checkIfPendingActionsCleared();
}
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index b3419c1..09873c7 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -322,7 +322,7 @@
private GpsStatusListenerHelper mListenerHelper = new GpsStatusListenerHelper() {
@Override
protected boolean isSupported() {
- return native_is_measurement_supported();
+ return GpsLocationProvider.isSupported();
}
};
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index a2dd15e..b0ccd62 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -776,8 +776,8 @@
if ((flags & AudioManager.FLAG_ACTIVE_MEDIA_ONLY) != 0) {
if (DEBUG) {
Log.d(TAG, "No active session to adjust, skipping media only volume event");
- return;
}
+ return;
}
try {
mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream, flags,
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f69c066..a6711c3 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.notification;
+import static android.service.notification.NotificationListenerService.FLAG_DISABLE_HOST_ALERTS;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -71,6 +72,7 @@
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.Log;
import android.util.Slog;
@@ -121,6 +123,7 @@
static final int MESSAGE_RECONSIDER_RANKING = 4;
static final int MESSAGE_RANKING_CONFIG_CHANGE = 5;
static final int MESSAGE_SEND_RANKING_UPDATE = 6;
+ static final int MESSAGE_LISTENER_FLAGS_CHANGED = 7;
static final int LONG_DELAY = 3500; // 3.5 seconds
static final int SHORT_DELAY = 2000; // 2 seconds
@@ -169,6 +172,9 @@
NotificationRecord mSoundNotification;
NotificationRecord mVibrateNotification;
+ private final ArraySet<ManagedServiceInfo> mListenersDisablingAlerts = new ArraySet<>();
+ private int mListenerFlags; // right now, all flags are global
+
// for enabling and disabling notification pulse behavior
private boolean mScreenOn = true;
private boolean mInCall = false;
@@ -463,7 +469,7 @@
public void onSetDisabled(int status) {
synchronized (mNotificationList) {
mDisableNotificationAlerts = (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
- if (mDisableNotificationAlerts) {
+ if (disableNotificationAlerts()) {
// cancel whatever's going on
long identity = Binder.clearCallingIdentity();
try {
@@ -904,6 +910,13 @@
}
}
+ private void updateListenerFlagsLocked() {
+ final int flags = mListenersDisablingAlerts.isEmpty() ? 0 : FLAG_DISABLE_HOST_ALERTS;
+ if (flags == mListenerFlags) return;
+ mListenerFlags = flags;
+ scheduleListenerFlagsChanged(flags);
+ }
+
private final IBinder mService = new INotificationManager.Stub() {
// Toasts
// ============================================================================
@@ -1249,6 +1262,27 @@
}
@Override
+ public void requestFlagsFromListener(INotificationListener token, int flags) {
+ synchronized (mNotificationList) {
+ final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
+ final boolean disableAlerts = (flags & FLAG_DISABLE_HOST_ALERTS) != 0;
+ if (disableAlerts) {
+ mListenersDisablingAlerts.add(info);
+ } else {
+ mListenersDisablingAlerts.remove(info);
+ }
+ updateListenerFlagsLocked();
+ }
+ }
+
+ @Override
+ public int getFlagsFromListener(INotificationListener token) {
+ synchronized (mNotificationList) {
+ return mListenerFlags;
+ }
+ }
+
+ @Override
public ZenModeConfig getZenModeConfig() {
enforceSystemOrSystemUI("INotificationManager.getZenModeConfig");
return mZenModeHelper.getConfig();
@@ -1339,6 +1373,10 @@
return keys.toArray(new String[keys.size()]);
}
+ private boolean disableNotificationAlerts() {
+ return mDisableNotificationAlerts || (mListenerFlags & FLAG_DISABLE_HOST_ALERTS) != 0;
+ }
+
void dumpImpl(PrintWriter pw, DumpFilter filter) {
pw.print("Current Notification Manager state");
if (filter != null) {
@@ -1422,6 +1460,15 @@
pw.println("\n Notification listeners:");
mListeners.dump(pw, filter);
+ pw.print(" mListenerFlags: "); pw.println(mListenerFlags);
+ pw.print(" mListenersDisablingAlerts: (");
+ N = mListenersDisablingAlerts.size();
+ for (int i = 0; i < N; i++) {
+ final ManagedServiceInfo listener = mListenersDisablingAlerts.valueAt(i);
+ if (i > 0) pw.print(',');
+ pw.print(listener.component);
+ }
+ pw.println(')');
}
pw.println("\n Condition providers:");
@@ -1618,7 +1665,7 @@
}
// If we're not supposed to beep, vibrate, etc. then don't.
- if (!mDisableNotificationAlerts
+ if (!disableNotificationAlerts()
&& (!(record.isUpdate
&& (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
&& (record.getUserId() == UserHandle.USER_ALL ||
@@ -1920,6 +1967,17 @@
}
}
+ private void scheduleListenerFlagsChanged(int state) {
+ mHandler.removeMessages(MESSAGE_LISTENER_FLAGS_CHANGED);
+ mHandler.obtainMessage(MESSAGE_LISTENER_FLAGS_CHANGED, state, 0).sendToTarget();
+ }
+
+ private void handleListenerFlagsChanged(int state) {
+ synchronized (mNotificationList) {
+ mListeners.notifyListenerFlagsChangedLocked(state);
+ }
+ }
+
private final class WorkerHandler extends Handler
{
@Override
@@ -1936,6 +1994,9 @@
case MESSAGE_SEND_RANKING_UPDATE:
handleSendRankingUpdate();
break;
+ case MESSAGE_LISTENER_FLAGS_CHANGED:
+ handleListenerFlagsChanged(msg.arg1);
+ break;
}
}
@@ -2445,6 +2506,13 @@
}
}
+ @Override
+ protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
+ if (mListenersDisablingAlerts.remove(removed)) {
+ updateListenerFlagsLocked();
+ }
+ }
+
/**
* asynchronously notify all listeners about a new notification
*/
@@ -2509,6 +2577,20 @@
}
}
+ public void notifyListenerFlagsChangedLocked(final int flags) {
+ for (final ManagedServiceInfo serviceInfo : mServices) {
+ if (!serviceInfo.isEnabledForCurrentProfiles()) {
+ continue;
+ }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ notifyListenerFlagsChanged(serviceInfo, flags);
+ }
+ });
+ }
+ }
+
private void notifyPostedIfUserMatch(final ManagedServiceInfo info,
final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate) {
if (!info.enabledAndUserMatches(sbn.getUserId())) {
@@ -2544,6 +2626,15 @@
Log.e(TAG, "unable to notify listener (ranking update): " + listener, ex);
}
}
+
+ private void notifyListenerFlagsChanged(ManagedServiceInfo info, int state) {
+ final INotificationListener listener = (INotificationListener) info.service;
+ try {
+ listener.onListenerFlagsChanged(state);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "unable to notify listener (listener flags): " + listener, ex);
+ }
+ }
}
public static final class DumpFilter {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a70dd1b..69f2f32 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -474,6 +474,9 @@
final SparseArray<PackageVerificationState> mPendingVerification
= new SparseArray<PackageVerificationState>();
+ /** Set of packages associated with each app op permission. */
+ final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
+
final PackageInstallerService mInstallerService;
HashSet<PackageParser.Package> mDeferredDexOpt = null;
@@ -2917,6 +2920,17 @@
}
@Override
+ public String[] getAppOpPermissionPackages(String permissionName) {
+ synchronized (mPackages) {
+ ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
+ if (pkgs == null) {
+ return null;
+ }
+ return pkgs.toArray(new String[pkgs.size()]);
+ }
+ }
+
+ @Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
@@ -6312,10 +6326,32 @@
* @param apkName the name of the installed package.
*/
private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
- // This is of the form "/system/lib64/<packagename>", "/vendor/lib64/<packagename>"
- // or similar.
- final boolean has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
- final boolean has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
+ final File codeFile = new File(pkg.codePath);
+
+ final boolean has64BitLibs;
+ final boolean has32BitLibs;
+ if (isApkFile(codeFile)) {
+ // Monolithic install
+ has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
+ has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
+ } else {
+ // Cluster install
+ final File rootDir = new File(codeFile, LIB_DIR_NAME);
+ if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
+ && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
+ final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
+ has64BitLibs = (new File(rootDir, isa)).exists();
+ } else {
+ has64BitLibs = false;
+ }
+ if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
+ && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
+ final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
+ has32BitLibs = (new File(rootDir, isa)).exists();
+ } else {
+ has32BitLibs = false;
+ }
+ }
if (has64BitLibs && !has32BitLibs) {
// The package has 64 bit libs, but not 32 bit libs. Its primary
@@ -6569,6 +6605,31 @@
r.append(p.info.name);
}
}
+ if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
+ ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
+ if (appOpPerms != null) {
+ appOpPerms.remove(pkg.packageName);
+ }
+ }
+ }
+ if (r != null) {
+ if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
+ }
+
+ N = pkg.requestedPermissions.size();
+ r = null;
+ for (i=0; i<N; i++) {
+ String perm = pkg.requestedPermissions.get(i);
+ BasePermission bp = mSettings.mPermissions.get(perm);
+ if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
+ ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
+ if (appOpPerms != null) {
+ appOpPerms.remove(pkg.packageName);
+ if (appOpPerms.isEmpty()) {
+ mAppOpPermissionPackages.remove(perm);
+ }
+ }
+ }
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
@@ -6753,6 +6814,15 @@
final String perm = bp.name;
boolean allowed;
boolean allowedSig = false;
+ if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
+ // Keep track of app op permissions.
+ ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
+ if (pkgs == null) {
+ pkgs = new ArraySet<>();
+ mAppOpPermissionPackages.put(bp.name, pkgs);
+ }
+ pkgs.add(pkg.packageName);
+ }
final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
if (level == PermissionInfo.PROTECTION_NORMAL
|| level == PermissionInfo.PROTECTION_DANGEROUS) {
@@ -6815,7 +6885,9 @@
+ " (protectionLevel=" + bp.protectionLevel
+ " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
+ ")");
- } else {
+ } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
+ // Don't print warning for app op permissions, since it is fine for them
+ // not to be granted, there is a UI for the user to decide.
Slog.w(TAG, "Not granting permission " + perm
+ " to package " + pkg.packageName
+ " (protectionLevel=" + bp.protectionLevel
@@ -7860,7 +7932,7 @@
}
@Override
- public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
+ public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
int userId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
PackageSetting pkgSetting;
@@ -7868,11 +7940,11 @@
if (UserHandle.getUserId(uid) != userId) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
- "setApplicationBlockedSetting for user " + userId);
+ "setApplicationHiddenSetting for user " + userId);
}
- if (blocked && isPackageDeviceAdmin(packageName, userId)) {
- Slog.w(TAG, "Not blocking package " + packageName + ": has active device admin");
+ if (hidden && isPackageDeviceAdmin(packageName, userId)) {
+ Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
return false;
}
@@ -7886,10 +7958,10 @@
if (pkgSetting == null) {
return false;
}
- if (pkgSetting.getBlocked(userId) != blocked) {
- pkgSetting.setBlocked(blocked, userId);
+ if (pkgSetting.getHidden(userId) != hidden) {
+ pkgSetting.setHidden(hidden, userId);
mSettings.writePackageRestrictionsLPr(userId);
- if (blocked) {
+ if (hidden) {
sendRemoved = true;
} else {
sendAdded = true;
@@ -7902,8 +7974,8 @@
}
if (sendRemoved) {
killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
- "blocking pkg");
- sendPackageBlockedForUser(packageName, pkgSetting, userId);
+ "hiding pkg");
+ sendApplicationHiddenForUser(packageName, pkgSetting, userId);
}
} finally {
Binder.restoreCallingIdentity(callingId);
@@ -7911,7 +7983,7 @@
return false;
}
- private void sendPackageBlockedForUser(String packageName, PackageSetting pkgSetting,
+ private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
int userId) {
final PackageRemovedInfo info = new PackageRemovedInfo();
info.removedPackage = packageName;
@@ -7922,13 +7994,13 @@
/**
* Returns true if application is not found or there was an error. Otherwise it returns
- * the blocked state of the package for the given user.
+ * the hidden state of the package for the given user.
*/
@Override
- public boolean getApplicationBlockedSettingAsUser(String packageName, int userId) {
+ public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
- "getApplicationBlocked for user " + userId);
+ "getApplicationHidden for user " + userId);
PackageSetting pkgSetting;
long callingId = Binder.clearCallingIdentity();
try {
@@ -7938,7 +8010,7 @@
if (pkgSetting == null) {
return true;
}
- return pkgSetting.getBlocked(userId);
+ return pkgSetting.getHidden(userId);
}
} finally {
Binder.restoreCallingIdentity(callingId);
@@ -7972,7 +8044,7 @@
}
if (!pkgSetting.getInstalled(userId)) {
pkgSetting.setInstalled(true, userId);
- pkgSetting.setBlocked(false, userId);
+ pkgSetting.setHidden(false, userId);
mSettings.writePackageRestrictionsLPr(userId);
sendAdded = true;
}
@@ -10571,19 +10643,19 @@
return;
}
- boolean blocked = false;
+ boolean uninstallBlocked = false;
if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
int[] users = sUserManager.getUserIds();
for (int i = 0; i < users.length; ++i) {
if (getBlockUninstallForUser(packageName, users[i])) {
- blocked = true;
+ uninstallBlocked = true;
break;
}
}
} else {
- blocked = getBlockUninstallForUser(packageName, userId);
+ uninstallBlocked = getBlockUninstallForUser(packageName, userId);
}
- if (blocked) {
+ if (uninstallBlocked) {
try {
observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED);
} catch (RemoteException re) {
@@ -10591,7 +10663,9 @@
return;
}
- if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
+ if (DEBUG_REMOVE) {
+ Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
+ }
// Queue up an async operation since the package deletion may take a little while.
mHandler.post(new Runnable() {
public void run() {
@@ -11010,7 +11084,7 @@
false, //installed
true, //stopped
true, //notLaunched
- false, //blocked
+ false, //hidden
null, null, null,
false // blockUninstall
);
@@ -12402,6 +12476,22 @@
if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
+ if (packageName == null) {
+ for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
+ if (iperm == 0) {
+ if (dumpState.onTitlePrinted())
+ pw.println();
+ pw.println("AppOp Permissions:");
+ }
+ pw.print(" AppOp Permission ");
+ pw.print(mAppOpPermissionPackages.keyAt(iperm));
+ pw.println(":");
+ ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
+ for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
+ pw.print(" "); pw.println(pkgs.valueAt(ipkg));
+ }
+ }
+ }
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index e164f5f..e29332c 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -281,12 +281,12 @@
modifyUserState(userId).notLaunched = stop;
}
- boolean getBlocked(int userId) {
- return readUserState(userId).blocked;
+ boolean getHidden(int userId) {
+ return readUserState(userId).hidden;
}
- void setBlocked(boolean blocked, int userId) {
- modifyUserState(userId).blocked = blocked;
+ void setHidden(boolean hidden, int userId) {
+ modifyUserState(userId).hidden = hidden;
}
boolean getBlockUninstall(int userId) {
@@ -298,7 +298,7 @@
}
void setUserState(int userId, int enabled, boolean installed, boolean stopped,
- boolean notLaunched, boolean blocked,
+ boolean notLaunched, boolean hidden,
String lastDisableAppCaller, HashSet<String> enabledComponents,
HashSet<String> disabledComponents, boolean blockUninstall) {
PackageUserState state = modifyUserState(userId);
@@ -306,7 +306,7 @@
state.installed = installed;
state.stopped = stopped;
state.notLaunched = notLaunched;
- state.blocked = blocked;
+ state.hidden = hidden;
state.lastDisableAppCaller = lastDisableAppCaller;
state.enabledComponents = enabledComponents;
state.disabledComponents = disabledComponents;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index e16894e..d1ea3e1 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -153,7 +153,10 @@
private static final String ATTR_ENABLED = "enabled";
private static final String ATTR_ENABLED_CALLER = "enabledCaller";
private static final String ATTR_STOPPED = "stopped";
+ // Legacy, here for reading older versions of the package-restrictions.
private static final String ATTR_BLOCKED = "blocked";
+ // New name for the above attribute.
+ private static final String ATTR_HIDDEN = "hidden";
private static final String ATTR_INSTALLED = "inst";
private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
@@ -606,7 +609,7 @@
installed,
true, // stopped,
true, // notLaunched
- false, // blocked
+ false, // hidden
null, null, null,
false // blockUninstall
);
@@ -1177,7 +1180,7 @@
true, // installed
false, // stopped
false, // notLaunched
- false, // blocked
+ false, // hidden
null, null, null,
false // blockUninstall
);
@@ -1233,9 +1236,14 @@
final String stoppedStr = parser.getAttributeValue(null, ATTR_STOPPED);
final boolean stopped = stoppedStr == null
? false : Boolean.parseBoolean(stoppedStr);
+ // For backwards compatibility with the previous name of "blocked", which
+ // now means hidden, read the old attribute as well.
final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED);
- final boolean blocked = blockedStr == null
+ boolean hidden = blockedStr == null
? false : Boolean.parseBoolean(blockedStr);
+ final String hiddenStr = parser.getAttributeValue(null, ATTR_HIDDEN);
+ hidden = hiddenStr == null
+ ? hidden : Boolean.parseBoolean(hiddenStr);
final String notLaunchedStr = parser.getAttributeValue(null, ATTR_NOT_LAUNCHED);
final boolean notLaunched = stoppedStr == null
? false : Boolean.parseBoolean(notLaunchedStr);
@@ -1263,7 +1271,7 @@
}
}
- ps.setUserState(userId, enabled, installed, stopped, notLaunched, blocked,
+ ps.setUserState(userId, enabled, installed, stopped, notLaunched, hidden,
enabledCaller, enabledComponents, disabledComponents, blockUninstall);
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLPw(parser, userId);
@@ -1432,7 +1440,7 @@
PackageUserState ustate = pkg.readUserState(userId);
if (ustate.stopped || ustate.notLaunched || !ustate.installed
|| ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT
- || ustate.blocked
+ || ustate.hidden
|| (ustate.enabledComponents != null
&& ustate.enabledComponents.size() > 0)
|| (ustate.disabledComponents != null
@@ -1451,8 +1459,8 @@
if (ustate.notLaunched) {
serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
}
- if (ustate.blocked) {
- serializer.attribute(null, ATTR_BLOCKED, "true");
+ if (ustate.hidden) {
+ serializer.attribute(null, ATTR_HIDDEN, "true");
}
if (ustate.blockUninstall) {
serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");
@@ -3443,7 +3451,7 @@
pw.print(user.id);
pw.print(",");
pw.print(ps.getInstalled(user.id) ? "I" : "i");
- pw.print(ps.getBlocked(user.id) ? "B" : "b");
+ pw.print(ps.getHidden(user.id) ? "B" : "b");
pw.print(ps.getStopped(user.id) ? "S" : "s");
pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
pw.print(",");
@@ -3583,8 +3591,8 @@
pw.print(prefix); pw.print(" User "); pw.print(user.id); pw.print(": ");
pw.print(" installed=");
pw.print(ps.getInstalled(user.id));
- pw.print(" blocked=");
- pw.print(ps.getBlocked(user.id));
+ pw.print(" hidden=");
+ pw.print(ps.getHidden(user.id));
pw.print(" stopped=");
pw.print(ps.getStopped(user.id));
pw.print(" notLaunched=");
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b4cc252..33ecc4d 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1428,7 +1428,7 @@
removeRestrictionsForUser(userHandle, true);
}
- private void removeRestrictionsForUser(final int userHandle, boolean unblockApps) {
+ private void removeRestrictionsForUser(final int userHandle, boolean unhideApps) {
synchronized (mPackagesLock) {
// Remove all user restrictions
setUserRestrictions(new Bundle(), userHandle);
@@ -1437,12 +1437,12 @@
// Remove any app restrictions
cleanAppRestrictions(userHandle);
}
- if (unblockApps) {
- unblockAllAppsForUser(userHandle);
+ if (unhideApps) {
+ unhideAllInstalledAppsForUser(userHandle);
}
}
- private void unblockAllAppsForUser(final int userHandle) {
+ private void unhideAllInstalledAppsForUser(final int userHandle) {
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -1453,8 +1453,8 @@
try {
for (ApplicationInfo appInfo : apps) {
if ((appInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0
- && (appInfo.flags & ApplicationInfo.FLAG_BLOCKED) != 0) {
- mPm.setApplicationBlockedSettingAsUser(appInfo.packageName, false,
+ && (appInfo.flags & ApplicationInfo.FLAG_HIDDEN) != 0) {
+ mPm.setApplicationHiddenSettingAsUser(appInfo.packageName, false,
userHandle);
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 4b1e8eb..8c52fad 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -404,6 +404,12 @@
// Use NaN to disable.
private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
+ // The screen state to use while dozing.
+ private int mDozeScreenStateOverrideFromDreamManager = Display.STATE_UNKNOWN;
+
+ // The screen brightness to use while dozing.
+ private int mDozeScreenBrightnessOverrideFromDreamManager = PowerManager.BRIGHTNESS_DEFAULT;
+
// Time when we last logged a warning about calling userActivity() without permission.
private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
@@ -1370,11 +1376,12 @@
if (mUserActivitySummary == 0
&& mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
- if (now < nextTimeout
- && mDisplayPowerRequest.wantScreenOnNormal()) {
- mUserActivitySummary = mDisplayPowerRequest.screenState
- == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
- USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
+ if (now < nextTimeout) {
+ if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT) {
+ mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
+ } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
+ mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
+ }
}
}
if (mUserActivitySummary != 0) {
@@ -1631,7 +1638,7 @@
if (mWakefulness != WAKEFULNESS_DREAMING
|| !mDreamsSupportedConfig
|| !mDreamsEnabledSetting
- || !mDisplayPowerRequest.wantScreenOnNormal()
+ || !mDisplayPowerRequest.isBrightOrDim()
|| !mBootCompleted) {
return false;
}
@@ -1672,8 +1679,7 @@
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
| DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
- final int newScreenState = getDesiredScreenPowerStateLocked();
- mDisplayPowerRequest.screenState = newScreenState;
+ mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
int screenBrightness = mScreenBrightnessSettingDefault;
float screenAutoBrightnessAdjustment = 0.0f;
@@ -1713,13 +1719,22 @@
mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
+ if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
+ mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
+ mDisplayPowerRequest.dozeScreenBrightness =
+ mDozeScreenBrightnessOverrideFromDreamManager;
+ } else {
+ mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
+ mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
+ }
+
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
if (DEBUG_SPEW) {
Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady
- + ", newScreenState=" + newScreenState
+ + ", policy=" + mDisplayPowerRequest.policy
+ ", mWakefulness=" + mWakefulness
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
@@ -1737,22 +1752,22 @@
return value >= -1.0f && value <= 1.0f;
}
- private int getDesiredScreenPowerStateLocked() {
+ private int getDesiredScreenPolicyLocked() {
if (mWakefulness == WAKEFULNESS_ASLEEP) {
- return DisplayPowerRequest.SCREEN_STATE_OFF;
+ return DisplayPowerRequest.POLICY_OFF;
}
if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
- return DisplayPowerRequest.SCREEN_STATE_DOZE;
+ return DisplayPowerRequest.POLICY_DOZE;
}
if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
|| (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
|| !mBootCompleted) {
- return DisplayPowerRequest.SCREEN_STATE_BRIGHT;
+ return DisplayPowerRequest.POLICY_BRIGHT;
}
- return DisplayPowerRequest.SCREEN_STATE_DIM;
+ return DisplayPowerRequest.POLICY_DIM;
}
private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks =
@@ -1895,7 +1910,7 @@
if (!mDisplayReady) {
return true;
}
- if (mDisplayPowerRequest.wantScreenOnNormal()) {
+ if (mDisplayPowerRequest.isBrightOrDim()) {
// If we asked for the screen to be on but it is off due to the proximity
// sensor then we may suspend but only if the configuration allows it.
// On some hardware it may not be safe to suspend because the proximity
@@ -2103,6 +2118,19 @@
}
}
+ private void setDozeOverrideFromDreamManagerInternal(
+ int screenState, int screenBrightness) {
+ synchronized (mLock) {
+ if (mDozeScreenStateOverrideFromDreamManager != screenState
+ || mDozeScreenBrightnessOverrideFromDreamManager != screenBrightness) {
+ mDozeScreenStateOverrideFromDreamManager = screenState;
+ mDozeScreenBrightnessOverrideFromDreamManager = screenBrightness;
+ mDirty |= DIRTY_SETTINGS;
+ updatePowerStateLocked();
+ }
+ }
+ }
+
private void powerHintInternal(int hintId, int data) {
nativeSendPowerHint(hintId, data);
}
@@ -2257,6 +2285,10 @@
+ mTemporaryScreenBrightnessSettingOverride);
pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
+ mTemporaryScreenAutoBrightnessAdjustmentSettingOverride);
+ pw.println(" mDozeScreenStateOverrideFromDreamManager="
+ + mDozeScreenStateOverrideFromDreamManager);
+ pw.println(" mDozeScreenBrightnessOverrideFromDreamManager="
+ + mDozeScreenBrightnessOverrideFromDreamManager);
pw.println(" mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum);
pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
@@ -3026,63 +3058,44 @@
}
private final class LocalService extends PowerManagerInternal {
- /**
- * Used by the window manager to override the screen brightness based on the
- * current foreground activity.
- *
- * This method must only be called by the window manager.
- *
- * @param brightness The overridden brightness, or -1 to disable the override.
- */
@Override
- public void setScreenBrightnessOverrideFromWindowManager(int brightness) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.DEVICE_POWER, null);
-
- final long ident = Binder.clearCallingIdentity();
- try {
- setScreenBrightnessOverrideFromWindowManagerInternal(brightness);
- } finally {
- Binder.restoreCallingIdentity(ident);
+ public void setScreenBrightnessOverrideFromWindowManager(int screenBrightness) {
+ if (screenBrightness < PowerManager.BRIGHTNESS_DEFAULT
+ || screenBrightness > PowerManager.BRIGHTNESS_ON) {
+ screenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
}
+ setScreenBrightnessOverrideFromWindowManagerInternal(screenBrightness);
}
- /**
- * Used by the window manager to override the button brightness based on the
- * current foreground activity.
- *
- * This method must only be called by the window manager.
- *
- * @param brightness The overridden brightness, or -1 to disable the override.
- */
@Override
- public void setButtonBrightnessOverrideFromWindowManager(int brightness) {
+ public void setButtonBrightnessOverrideFromWindowManager(int screenBrightness) {
// Do nothing.
// Button lights are not currently supported in the new implementation.
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.DEVICE_POWER, null);
}
- /**
- * Used by the window manager to override the user activity timeout based on the
- * current foreground activity. It can only be used to make the timeout shorter
- * than usual, not longer.
- *
- * This method must only be called by the window manager.
- *
- * @param timeoutMillis The overridden timeout, or -1 to disable the override.
- */
+ @Override
+ public void setDozeOverrideFromDreamManager(int screenState, int screenBrightness) {
+ switch (screenState) {
+ case Display.STATE_UNKNOWN:
+ case Display.STATE_OFF:
+ case Display.STATE_DOZE:
+ case Display.STATE_DOZE_SUSPEND:
+ case Display.STATE_ON:
+ break;
+ default:
+ screenState = Display.STATE_UNKNOWN;
+ break;
+ }
+ if (screenBrightness < PowerManager.BRIGHTNESS_DEFAULT
+ || screenBrightness > PowerManager.BRIGHTNESS_ON) {
+ screenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
+ }
+ setDozeOverrideFromDreamManagerInternal(screenState, screenBrightness);
+ }
+
@Override
public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.DEVICE_POWER, null);
-
- final long ident = Binder.clearCallingIdentity();
- try {
- setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
}
@Override
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 8854869..ea19012 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -211,9 +211,6 @@
}
public void addHardwareTvInput(int deviceId, TvInputInfo info) {
- if (info.getType() == TvInputInfo.TYPE_VIRTUAL) {
- throw new IllegalArgumentException("info (" + info + ") has virtual type.");
- }
synchronized (mLock) {
String oldInputId = mHardwareInputIdMap.get(deviceId);
if (oldInputId != null) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index fa22ded..29ef9c1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4852,8 +4852,11 @@
// Where to start adding?
for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
- int pos = findAppWindowInsertionPointLocked(tokens.get(0));
final int numTokens = tokens.size();
+ if (numTokens == 0) {
+ continue;
+ }
+ int pos = findAppWindowInsertionPointLocked(tokens.get(0));
for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
final AppWindowToken wtoken = tokens.get(tokenNdx);
if (wtoken != null) {
@@ -11173,17 +11176,14 @@
public void waitForAllWindowsDrawn(Runnable callback, long timeout) {
synchronized (mWindowMap) {
mWaitingForDrawnCallback = callback;
- for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
- final WindowList windows =
- mDisplayContents.valueAt(displayNdx).getWindowList();
- for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState win = windows.get(winNdx);
- if (win.mHasSurface && win.isWinVisibleLw() && !win.mIsWallpaper) {
- win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
- // Force add to mResizingWindows.
- win.mLastContentInsets.set(-1, -1, -1, -1);
- mWaitingForDrawn.add(win);
- }
+ final WindowList windows = getDefaultWindowListLocked();
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = windows.get(winNdx);
+ if (win.mHasSurface) {
+ win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
+ // Force add to mResizingWindows.
+ win.mLastContentInsets.set(-1, -1, -1, -1);
+ mWaitingForDrawn.add(win);
}
}
requestTraversalLocked();
diff --git a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
index 87626d0..8bb6e8a 100644
--- a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -861,6 +861,7 @@
static jobject translate_gps_clock(JNIEnv* env, GpsClock* clock) {
const char* doubleSignature = "(D)V";
+ const char* longSignature = "(J)V";
jclass gpsClockClass = env->FindClass("android/location/GpsClock");
jmethodID gpsClockCtor = env->GetMethodID(gpsClockClass, "<init>", "()V");
@@ -873,53 +874,51 @@
env->CallObjectMethod(gpsClockObject, setterMethod, clock->leap_second);
}
- jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setTimeInNs", "(J)V");
+ jmethodID typeSetterMethod = env->GetMethodID(gpsClockClass, "setType", "(B)V");
+ env->CallObjectMethod(gpsClockObject, typeSetterMethod, clock->type);
+
+ jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setTimeInNs", longSignature);
env->CallObjectMethod(gpsClockObject, setterMethod, clock->time_ns);
if (flags & GPS_CLOCK_HAS_TIME_UNCERTAINTY) {
- jmethodID setterMethod = env->GetMethodID(
- gpsClockClass,
- "setTimeUncertaintyInNs",
- doubleSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsClockClass, "setTimeUncertaintyInNs", doubleSignature);
env->CallObjectMethod(gpsClockObject, setterMethod, clock->time_uncertainty_ns);
}
+ if (flags & GPS_CLOCK_HAS_FULL_BIAS) {
+ jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setFullBiasInNs", longSignature);
+ env->CallObjectMethod(gpsClockObject, setterMethod, clock->full_bias_ns);
+ }
+
if (flags & GPS_CLOCK_HAS_BIAS) {
jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setBiasInNs", doubleSignature);
env->CallObjectMethod(gpsClockObject, setterMethod, clock->bias_ns);
}
if (flags & GPS_CLOCK_HAS_BIAS_UNCERTAINTY) {
- jmethodID setterMethod = env->GetMethodID(
- gpsClockClass,
- "setBiasUncertaintyInNs",
- doubleSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsClockClass, "setBiasUncertaintyInNs", doubleSignature);
env->CallObjectMethod(gpsClockObject, setterMethod, clock->bias_uncertainty_ns);
}
if (flags & GPS_CLOCK_HAS_DRIFT) {
- jmethodID setterMethod = env->GetMethodID(
- gpsClockClass,
- "setDriftInNsPerSec",
- doubleSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsClockClass, "setDriftInNsPerSec", doubleSignature);
env->CallObjectMethod(gpsClockObject, setterMethod, clock->drift_nsps);
}
if (flags & GPS_CLOCK_HAS_DRIFT_UNCERTAINTY) {
- jmethodID setterMethod = env->GetMethodID(
- gpsClockClass,
- "setDriftUncertaintyInNsPerSec",
- doubleSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsClockClass, "setDriftUncertaintyInNsPerSec", doubleSignature);
env->CallObjectMethod(gpsClockObject, setterMethod, clock->drift_uncertainty_nsps);
}
return gpsClockObject;
}
-static jobject translate_gps_measurement(
- JNIEnv* env,
- GpsMeasurement* measurement,
- uint32_t time_ns) {
+static jobject translate_gps_measurement(JNIEnv* env, GpsMeasurement* measurement) {
+ const char* byteSignature = "(B)V";
const char* shortSignature = "(S)V";
const char* longSignature = "(J)V";
const char* floatSignature = "(F)V";
@@ -931,16 +930,18 @@
jobject gpsMeasurementObject = env->NewObject(gpsMeasurementClass, gpsMeasurementCtor);
GpsMeasurementFlags flags = measurement->flags;
-
- jmethodID prnSetterMethod = env->GetMethodID(gpsMeasurementClass, "setPrn", "(B)V");
+ jmethodID prnSetterMethod = env->GetMethodID(gpsMeasurementClass, "setPrn", byteSignature);
env->CallObjectMethod(gpsMeasurementObject, prnSetterMethod, measurement->prn);
- jmethodID localTimeSetterMethod =
- env->GetMethodID(gpsMeasurementClass, "setLocalTimeInNs", longSignature);
+ jmethodID timeOffsetSetterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setTimeOffsetInNs", doubleSignature);
env->CallObjectMethod(
gpsMeasurementObject,
- localTimeSetterMethod,
- time_ns + measurement->time_offset_ns);
+ timeOffsetSetterMethod,
+ measurement->time_offset_ns);
+
+ jmethodID stateSetterMethod = env->GetMethodID(gpsMeasurementClass, "setState", shortSignature);
+ env->CallObjectMethod(gpsMeasurementObject, stateSetterMethod, measurement->state);
jmethodID receivedGpsTowSetterMethod =
env->GetMethodID(gpsMeasurementClass, "setReceivedGpsTowInNs", longSignature);
@@ -949,10 +950,17 @@
receivedGpsTowSetterMethod,
measurement->received_gps_tow_ns);
- jmethodID cn0SetterMethod = env->GetMethodID(
+ jmethodID receivedGpsTowUncertaintySetterMethod = env->GetMethodID(
gpsMeasurementClass,
- "setCn0InDbHz",
- doubleSignature);
+ "setReceivedGpsTowUncertaintyInNs",
+ longSignature);
+ env->CallVoidMethod(
+ gpsMeasurementObject,
+ receivedGpsTowUncertaintySetterMethod,
+ measurement->received_gps_tow_uncertainty_ns);
+
+ jmethodID cn0SetterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setCn0InDbHz", doubleSignature);
env->CallObjectMethod(gpsMeasurementObject, cn0SetterMethod, measurement->c_n0_dbhz);
jmethodID pseudorangeRateSetterMethod = env->GetMethodID(
@@ -962,7 +970,7 @@
env->CallObjectMethod(
gpsMeasurementObject,
pseudorangeRateSetterMethod,
- measurement->pseudorange_rate_mpersec);
+ measurement->pseudorange_rate_mps);
jmethodID pseudorangeRateUncertaintySetterMethod = env->GetMethodID(
gpsMeasurementClass,
@@ -971,7 +979,14 @@
env->CallObjectMethod(
gpsMeasurementObject,
pseudorangeRateUncertaintySetterMethod,
- measurement->pseudorange_rate_uncertainty_mpersec);
+ measurement->pseudorange_rate_uncertainty_mps);
+
+ jmethodID accumulatedDeltaRangeStateSetterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setAccumulatedDeltaRangeState", shortSignature);
+ env->CallObjectMethod(
+ gpsMeasurementObject,
+ accumulatedDeltaRangeStateSetterMethod,
+ measurement->accumulated_delta_range_state);
jmethodID accumulatedDeltaRangeSetterMethod = env->GetMethodID(
gpsMeasurementClass,
@@ -991,12 +1006,9 @@
accumulatedDeltaRangeUncertaintySetterMethod,
measurement->accumulated_delta_range_uncertainty_m);
-
if (flags & GPS_MEASUREMENT_HAS_PSEUDORANGE) {
- jmethodID setterMethod = env->GetMethodID(
- gpsMeasurementClass,
- "setPseudorangeInMeters",
- doubleSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setPseudorangeInMeters", doubleSignature);
env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->pseudorange_m);
}
@@ -1012,10 +1024,8 @@
}
if (flags & GPS_MEASUREMENT_HAS_CODE_PHASE) {
- jmethodID setterMethod = env->GetMethodID(
- gpsMeasurementClass,
- "setCodePhaseInChips",
- doubleSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setCodePhaseInChips", doubleSignature);
env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->code_phase_chips);
}
@@ -1031,10 +1041,8 @@
}
if (flags & GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY) {
- jmethodID setterMethod = env->GetMethodID(
- gpsMeasurementClass,
- "setCarrierFrequencyInHz",
- floatSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setCarrierFrequencyInHz", floatSignature);
env->CallObjectMethod(
gpsMeasurementObject,
setterMethod,
@@ -1065,33 +1073,27 @@
}
jmethodID lossOfLockSetterMethod =
- env->GetMethodID(gpsMeasurementClass, "setLossOfLock", shortSignature);
+ env->GetMethodID(gpsMeasurementClass, "setLossOfLock", byteSignature);
env->CallObjectMethod(gpsMeasurementObject, lossOfLockSetterMethod, measurement->loss_of_lock);
if (flags & GPS_MEASUREMENT_HAS_BIT_NUMBER) {
- jmethodID setterMethod = env->GetMethodID(
- gpsMeasurementClass,
- "setBitNumber",
- shortSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setBitNumber", shortSignature);
env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->bit_number);
}
if (flags & GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT) {
- jmethodID setterMethod = env->GetMethodID(
- gpsMeasurementClass,
- "setTimeFromLastBitInNs",
- longSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setTimeFromLastBitInMs", shortSignature);
env->CallObjectMethod(
gpsMeasurementObject,
setterMethod,
- measurement->time_from_last_bit_ns);
+ measurement->time_from_last_bit_ms);
}
if (flags & GPS_MEASUREMENT_HAS_DOPPLER_SHIFT) {
- jmethodID setterMethod = env->GetMethodID(
- gpsMeasurementClass,
- "setDopplerShiftInHz",
- doubleSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setDopplerShiftInHz", doubleSignature);
env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->doppler_shift_hz);
}
@@ -1106,10 +1108,8 @@
measurement->doppler_shift_uncertainty_hz);
}
- jmethodID multipathIndicatorSetterMethod = env->GetMethodID(
- gpsMeasurementClass,
- "setMultipathIndicator",
- shortSignature);
+ jmethodID multipathIndicatorSetterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setMultipathIndicator", byteSignature);
env->CallObjectMethod(
gpsMeasurementObject,
multipathIndicatorSetterMethod,
@@ -1122,18 +1122,14 @@
}
if (flags & GPS_MEASUREMENT_HAS_ELEVATION) {
- jmethodID setterMethod = env->GetMethodID(
- gpsMeasurementClass,
- "setElevationInDeg",
- doubleSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setElevationInDeg", doubleSignature);
env->CallObjectMethod(gpsMeasurementObject, setterMethod, measurement->elevation_deg);
}
if (flags & GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY) {
- jmethodID setterMethod = env->GetMethodID(
- gpsMeasurementClass,
- "setElevationUncertaintyInDeg",
- doubleSignature);
+ jmethodID setterMethod =
+ env->GetMethodID(gpsMeasurementClass, "setElevationUncertaintyInDeg", doubleSignature);
env->CallObjectMethod(
gpsMeasurementObject,
setterMethod,
@@ -1180,10 +1176,7 @@
GpsMeasurement* gpsMeasurements = data->measurements;
for (uint16_t i = 0; i < measurementCount; ++i) {
- jobject gpsMeasurement = translate_gps_measurement(
- env,
- &gpsMeasurements[i],
- data->clock.time_ns);
+ jobject gpsMeasurement = translate_gps_measurement(env, &gpsMeasurements[i]);
env->SetObjectArrayElement(gpsMeasurementArray, i, gpsMeasurement);
env->DeleteLocalRef(gpsMeasurement);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 12ed920..5f876ff 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1103,6 +1103,8 @@
type = parser.next();
int outerDepth = parser.getDepth();
policy.mLockTaskPackages.clear();
+ policy.mAdminList.clear();
+ policy.mAdminMap.clear();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -1124,7 +1126,6 @@
ActiveAdmin ap = new ActiveAdmin(dai);
ap.readFromXml(parser);
policy.mAdminMap.put(ap.info.getComponent(), ap);
- policy.mAdminList.add(ap);
}
} catch (RuntimeException e) {
Slog.w(LOG_TAG, "Failed loading admin " + name, e);
@@ -1184,6 +1185,9 @@
// Ignore
}
+ // Generate a list of admins from the admin map
+ policy.mAdminList.addAll(policy.mAdminMap.values());
+
// Validate that what we stored for the password quality matches
// sufficiently what is currently set. Note that this is only
// a sanity check in case the two get out of sync; this should
@@ -1268,10 +1272,8 @@
if (!mHasFeature) {
return;
}
- synchronized (this) {
- loadSettingsLocked(getUserData(UserHandle.USER_OWNER), UserHandle.USER_OWNER);
- loadDeviceOwner();
- }
+ getUserData(UserHandle.USER_OWNER);
+ loadDeviceOwner();
cleanUpOldUsers();
mAppOpsService = IAppOpsService.Stub.asInterface(
ServiceManager.getService(Context.APP_OPS_SERVICE));
@@ -1436,14 +1438,12 @@
ActiveAdmin newAdmin = new ActiveAdmin(info);
policy.mAdminMap.put(adminReceiver, newAdmin);
int replaceIndex = -1;
- if (refreshing) {
- final int N = policy.mAdminList.size();
- for (int i=0; i < N; i++) {
- ActiveAdmin oldAdmin = policy.mAdminList.get(i);
- if (oldAdmin.info.getComponent().equals(adminReceiver)) {
- replaceIndex = i;
- break;
- }
+ final int N = policy.mAdminList.size();
+ for (int i=0; i < N; i++) {
+ ActiveAdmin oldAdmin = policy.mAdminList.get(i);
+ if (oldAdmin.info.getComponent().equals(adminReceiver)) {
+ replaceIndex = i;
+ break;
}
}
if (replaceIndex == -1) {
@@ -3708,8 +3708,8 @@
}
@Override
- public boolean setApplicationBlocked(ComponentName who, String packageName,
- boolean blocked) {
+ public boolean setApplicationHidden(ComponentName who, String packageName,
+ boolean hidden) {
int callingUserId = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
@@ -3720,10 +3720,10 @@
long id = Binder.clearCallingIdentity();
try {
IPackageManager pm = AppGlobals.getPackageManager();
- return pm.setApplicationBlockedSettingAsUser(packageName, blocked, callingUserId);
+ return pm.setApplicationHiddenSettingAsUser(packageName, hidden, callingUserId);
} catch (RemoteException re) {
// shouldn't happen
- Slog.e(LOG_TAG, "Failed to setApplicationBlockedSetting", re);
+ Slog.e(LOG_TAG, "Failed to setApplicationHiddenSetting", re);
} finally {
restoreCallingIdentity(id);
}
@@ -3732,7 +3732,7 @@
}
@Override
- public int setApplicationsBlocked(ComponentName who, Intent intent, boolean blocked) {
+ public int setApplicationsHidden(ComponentName who, Intent intent, boolean hidden) {
int callingUserId = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
@@ -3750,20 +3750,20 @@
callingUserId);
if (DBG) Slog.d(LOG_TAG, "Enabling activities: " + activitiesToEnable);
- int numberOfAppsUnblocked = 0;
+ int numberOfAppsUnhidden = 0;
if (activitiesToEnable != null) {
for (ResolveInfo info : activitiesToEnable) {
if (info.activityInfo != null) {
- numberOfAppsUnblocked++;
- pm.setApplicationBlockedSettingAsUser(info.activityInfo.packageName,
- blocked, callingUserId);
+ numberOfAppsUnhidden++;
+ pm.setApplicationHiddenSettingAsUser(info.activityInfo.packageName,
+ hidden, callingUserId);
}
}
}
- return numberOfAppsUnblocked;
+ return numberOfAppsUnhidden;
} catch (RemoteException re) {
// shouldn't happen
- Slog.e(LOG_TAG, "Failed to setApplicationsBlockedSettingsWithIntent", re);
+ Slog.e(LOG_TAG, "Failed to setApplicationsHiddenSettingsWithIntent", re);
} finally {
restoreCallingIdentity(id);
}
@@ -3772,7 +3772,7 @@
}
@Override
- public boolean isApplicationBlocked(ComponentName who, String packageName) {
+ public boolean isApplicationHidden(ComponentName who, String packageName) {
int callingUserId = UserHandle.getCallingUserId();
synchronized (this) {
if (who == null) {
@@ -3783,10 +3783,10 @@
long id = Binder.clearCallingIdentity();
try {
IPackageManager pm = AppGlobals.getPackageManager();
- return pm.getApplicationBlockedSettingAsUser(packageName, callingUserId);
+ return pm.getApplicationHiddenSettingAsUser(packageName, callingUserId);
} catch (RemoteException re) {
// shouldn't happen
- Slog.e(LOG_TAG, "Failed to getApplicationBlockedSettingAsUser", re);
+ Slog.e(LOG_TAG, "Failed to getApplicationHiddenSettingAsUser", re);
} finally {
restoreCallingIdentity(id);
}
@@ -4030,7 +4030,8 @@
@Override
public boolean getCrossProfileCallerIdDisabledForUser(int userId) {
- enforceSystemProcess("getCrossProfileCallerIdDisabled can only be called by system");
+ // TODO: Should there be a check to make sure this relationship is within a profile group?
+ //enforceSystemProcess("getCrossProfileCallerIdDisabled can only be called by system");
synchronized (this) {
ActiveAdmin admin = getProfileOwnerAdmin(userId);
return (admin != null) ? admin.disableCallerId : false;
diff --git a/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java b/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java
index 4fe30e6..fb29b6a 100644
--- a/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java
+++ b/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java
@@ -40,6 +40,7 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.IUserManager;
+import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -103,7 +104,8 @@
@Override
public void requestPermission(final String packageName, final String requestType,
- final Bundle requestData) throws RemoteException {
+ final String requestId,
+ final PersistableBundle requestData) throws RemoteException {
if (DEBUG) {
Log.i(LOG_TAG, "requestPermission");
}
@@ -127,6 +129,7 @@
intent.setComponent(restrictionsProvider);
intent.putExtra(RestrictionsManager.EXTRA_PACKAGE_NAME, packageName);
intent.putExtra(RestrictionsManager.EXTRA_REQUEST_TYPE, requestType);
+ intent.putExtra(RestrictionsManager.EXTRA_REQUEST_ID, requestId);
intent.putExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE, requestData);
mContext.sendBroadcastAsUser(intent, new UserHandle(userHandle));
} finally {
@@ -136,7 +139,40 @@
}
@Override
- public void notifyPermissionResponse(String packageName, Bundle response)
+ public Intent getLocalApprovalIntent() throws RemoteException {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "requestPermission");
+ }
+ final int userHandle = UserHandle.getCallingUserId();
+ if (mDpm != null) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ ComponentName restrictionsProvider =
+ mDpm.getRestrictionsProvider(userHandle);
+ // Check if there is a restrictions provider
+ if (restrictionsProvider == null) {
+ throw new IllegalStateException(
+ "Cannot request permission without a restrictions provider registered");
+ }
+ String providerPackageName = restrictionsProvider.getPackageName();
+ Intent intent = new Intent(RestrictionsManager.ACTION_REQUEST_LOCAL_APPROVAL);
+ intent.setPackage(providerPackageName);
+ ResolveInfo ri = AppGlobals.getPackageManager().resolveIntent(intent,
+ null /* resolvedType */, 0 /* flags */, userHandle);
+ if (ri != null && ri.activityInfo != null && ri.activityInfo.exported) {
+ intent.setComponent(new ComponentName(ri.activityInfo.packageName,
+ ri.activityInfo.name));
+ return intent;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void notifyPermissionResponse(String packageName, PersistableBundle response)
throws RemoteException {
// Check caller
int callingUid = Binder.getCallingUid();
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 88aaafc..9e3dec8 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -162,12 +162,10 @@
mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
nextConnBroadcast.get();
- // verify that both routes were added and DNS was flushed
+ // verify that both routes were added
int mobileNetId = mMobile.tracker.getNetwork().netId;
verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
- verify(mNetManager).flushNetworkDnsCache(mobileNetId);
-
}
public void testMobileWifiHandoff() throws Exception {
@@ -204,7 +202,6 @@
int wifiNetId = mWifi.tracker.getNetwork().netId;
verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V4));
verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V6));
- verify(mNetManager).flushNetworkDnsCache(wifiNetId);
verify(mMobile.tracker).teardown();
int mobileNetId = mMobile.tracker.getNetwork().netId;
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 13cbf8a..475824a 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -16,6 +16,7 @@
package com.android.server.usage;
+import android.Manifest;
import android.app.AppOpsManager;
import android.app.usage.IUsageStatsManager;
import android.app.usage.PackageUsageStats;
@@ -25,6 +26,7 @@
import android.app.usage.UsageStatsManagerInternal;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
@@ -381,10 +383,21 @@
private class BinderService extends IUsageStatsManager.Stub {
+ private boolean hasPermission(String callingPackage) {
+ final int mode = mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS,
+ Binder.getCallingUid(), callingPackage);
+ if (mode == AppOpsManager.MODE_IGNORED) {
+ // If AppOpsManager ignores this, still allow if we have the system level
+ // permission.
+ return getContext().checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+ return mode == AppOpsManager.MODE_ALLOWED;
+ }
+
@Override
public UsageStats[] getStatsSince(int bucketType, long time, String callingPackage) {
- if (mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS, Binder.getCallingUid(),
- callingPackage) != AppOpsManager.MODE_ALLOWED) {
+ if (!hasPermission(callingPackage)) {
return UsageStats.EMPTY_STATS;
}
@@ -398,8 +411,7 @@
@Override
public UsageStats.Event[] getEventsSince(long time, String callingPackage) {
- if (mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS, Binder.getCallingUid(),
- callingPackage) != AppOpsManager.MODE_ALLOWED) {
+ if (!hasPermission(callingPackage)) {
return UsageStats.Event.EMPTY_EVENTS;
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java
index 50be1dc..1e0d6de 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java
@@ -100,29 +100,32 @@
}
public boolean addOrUpdateKeyphraseSoundModel(KeyphraseSoundModel soundModel) {
- SQLiteDatabase db = getWritableDatabase();
- ContentValues values = new ContentValues();
- // Generate a random ID for the model.
- values.put(SoundModelContract.KEY_ID, soundModel.uuid.toString());
- values.put(SoundModelContract.KEY_DATA, soundModel.data);
- values.put(SoundModelContract.KEY_TYPE, SoundTrigger.SoundModel.TYPE_KEYPHRASE);
-
- boolean status = true;
- if (db.insertWithOnConflict(
- SoundModelContract.TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE) != -1) {
- for (Keyphrase keyphrase : soundModel.keyphrases) {
- status &= addOrUpdateKeyphrase(db, soundModel.uuid, keyphrase);
+ synchronized(this) {
+ SQLiteDatabase db = getWritableDatabase();
+ ContentValues values = new ContentValues();
+ // Generate a random ID for the model.
+ values.put(SoundModelContract.KEY_ID, soundModel.uuid.toString());
+ values.put(SoundModelContract.KEY_DATA, soundModel.data);
+ values.put(SoundModelContract.KEY_TYPE, SoundTrigger.SoundModel.TYPE_KEYPHRASE);
+
+ boolean status = true;
+ if (db.insertWithOnConflict(SoundModelContract.TABLE, null, values,
+ SQLiteDatabase.CONFLICT_REPLACE) != -1) {
+ for (Keyphrase keyphrase : soundModel.keyphrases) {
+ status &= addOrUpdateKeyphraseLocked(db, soundModel.uuid, keyphrase);
+ }
+ db.close();
+ return status;
+ } else {
+ Slog.w(TAG, "Failed to persist sound model to database");
+ db.close();
+ return false;
}
- db.close();
- return status;
- } else {
- Slog.w(TAG, "Failed to persist sound model to database");
- db.close();
- return false;
}
}
- private boolean addOrUpdateKeyphrase(SQLiteDatabase db, UUID modelId, Keyphrase keyphrase) {
+ private boolean addOrUpdateKeyphraseLocked(
+ SQLiteDatabase db, UUID modelId, Keyphrase keyphrase) {
ContentValues values = new ContentValues();
values.put(KeyphraseContract.KEY_ID, keyphrase.id);
values.put(KeyphraseContract.KEY_RECOGNITION_MODES, keyphrase.recognitionModes);
@@ -143,62 +146,66 @@
* Deletes the sound model and associated keyphrases.
*/
public boolean deleteKeyphraseSoundModel(UUID uuid) {
- SQLiteDatabase db = getWritableDatabase();
- String modelId = uuid.toString();
- String soundModelClause = SoundModelContract.KEY_ID + "=" + modelId;
- boolean status = true;
- if (db.delete(SoundModelContract.TABLE, soundModelClause, null) == 0) {
- Slog.w(TAG, "No sound models deleted from the database");
- status = false;
+ synchronized(this) {
+ SQLiteDatabase db = getWritableDatabase();
+ String modelId = uuid.toString();
+ String soundModelClause = SoundModelContract.KEY_ID + "=" + modelId;
+ boolean status = true;
+ if (db.delete(SoundModelContract.TABLE, soundModelClause, null) == 0) {
+ Slog.w(TAG, "No sound models deleted from the database");
+ status = false;
+ }
+ String keyphraseClause = KeyphraseContract.KEY_SOUND_MODEL_ID + "=" + modelId;
+ if (db.delete(KeyphraseContract.TABLE, keyphraseClause, null) == 0) {
+ Slog.w(TAG, "No keyphrases deleted from the database");
+ status = false;
+ }
+ db.close();
+ return status;
}
- String keyphraseClause = KeyphraseContract.KEY_SOUND_MODEL_ID + "=" + modelId;
- if (db.delete(KeyphraseContract.TABLE, keyphraseClause, null) == 0) {
- Slog.w(TAG, "No keyphrases deleted from the database");
- status = false;
- }
- db.close();
- return status;
}
/**
* Lists all the keyphrase sound models currently registered with the system.
*/
public List<KeyphraseSoundModel> getKephraseSoundModels() {
- List<KeyphraseSoundModel> models = new ArrayList<>();
- String selectQuery = "SELECT * FROM " + SoundModelContract.TABLE;
- SQLiteDatabase db = getReadableDatabase();
- Cursor c = db.rawQuery(selectQuery, null);
-
- // looping through all rows and adding to list
- if (c.moveToFirst()) {
- do {
- int type = c.getInt(c.getColumnIndex(SoundModelContract.KEY_TYPE));
- if (type != SoundTrigger.SoundModel.TYPE_KEYPHRASE) {
- // Ignore non-keyphrase sound models.
- continue;
- }
- String id = c.getString(c.getColumnIndex(SoundModelContract.KEY_ID));
- byte[] data = c.getBlob(c.getColumnIndex(SoundModelContract.KEY_DATA));
- // Get all the keyphrases for this this sound model.
- // Validate the sound model.
- if (id == null) {
- Slog.w(TAG, "Ignoring sound model since it doesn't specify an ID");
- continue;
- }
- KeyphraseSoundModel model = new KeyphraseSoundModel(
- UUID.fromString(id), data, getKeyphrasesForSoundModel(db, id));
- if (DBG) {
- Slog.d(TAG, "Adding model: " + model);
- }
- models.add(model);
- } while (c.moveToNext());
+ synchronized(this) {
+ List<KeyphraseSoundModel> models = new ArrayList<>();
+ String selectQuery = "SELECT * FROM " + SoundModelContract.TABLE;
+ SQLiteDatabase db = getReadableDatabase();
+ Cursor c = db.rawQuery(selectQuery, null);
+
+ // looping through all rows and adding to list
+ if (c.moveToFirst()) {
+ do {
+ int type = c.getInt(c.getColumnIndex(SoundModelContract.KEY_TYPE));
+ if (type != SoundTrigger.SoundModel.TYPE_KEYPHRASE) {
+ // Ignore non-keyphrase sound models.
+ continue;
+ }
+ String id = c.getString(c.getColumnIndex(SoundModelContract.KEY_ID));
+ byte[] data = c.getBlob(c.getColumnIndex(SoundModelContract.KEY_DATA));
+ // Get all the keyphrases for this this sound model.
+ // Validate the sound model.
+ if (id == null) {
+ Slog.w(TAG, "Ignoring sound model since it doesn't specify an ID");
+ continue;
+ }
+ KeyphraseSoundModel model = new KeyphraseSoundModel(
+ UUID.fromString(id), data, getKeyphrasesForSoundModelLocked(db, id));
+ if (DBG) {
+ Slog.d(TAG, "Adding model: " + model);
+ }
+ models.add(model);
+ } while (c.moveToNext());
+ }
+ c.close();
+ db.close();
+ return models;
}
- c.close();
- db.close();
- return models;
}
- private Keyphrase[] getKeyphrasesForSoundModel(SQLiteDatabase db, String modelId) {
+ private Keyphrase[] getKeyphrasesForSoundModelLocked(SQLiteDatabase db, String modelId) {
List<Keyphrase> keyphrases = new ArrayList<>();
String selectQuery = "SELECT * FROM " + KeyphraseContract.TABLE
+ " WHERE " + KeyphraseContract.KEY_SOUND_MODEL_ID + " = '" + modelId + "'";
@@ -243,7 +250,7 @@
}
- private String getCommaSeparatedString(int[] users) {
+ private static String getCommaSeparatedString(int[] users) {
if (users == null || users.length == 0) {
return "";
}
@@ -255,7 +262,7 @@
return csv.substring(0, csv.length() - 1);
}
- private int[] getArrayForCommaSeparatedString(String text) {
+ private static int[] getArrayForCommaSeparatedString(String text) {
if (TextUtils.isEmpty(text)) {
return null;
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 2ce4971..5d9e107 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -266,13 +266,13 @@
+ Manifest.permission.MANAGE_VOICE_KEYPHRASES);
}
}
+ }
- final long caller = Binder.clearCallingIdentity();
- try {
- return mDbHelper.getKephraseSoundModels();
- } finally {
- Binder.restoreCallingIdentity(caller);
- }
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ return mDbHelper.getKephraseSoundModels();
+ } finally {
+ Binder.restoreCallingIdentity(caller);
}
}
@@ -287,26 +287,31 @@
if (model == null) {
throw new IllegalArgumentException("Model must not be null");
}
+ }
- final long caller = Binder.clearCallingIdentity();
- try {
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ boolean success = false;
+ if (model.keyphrases == null) {
// If the keyphrases are not present in the model, delete the model.
- if (model.keyphrases == null) {
- if (mDbHelper.deleteKeyphraseSoundModel(model.uuid)) {
- return SoundTriggerHelper.STATUS_OK;
- } else {
- return SoundTriggerHelper.STATUS_ERROR;
- }
- } else {
- if (mDbHelper.addOrUpdateKeyphraseSoundModel(model)) {
- return SoundTriggerHelper.STATUS_OK;
- } else {
- return SoundTriggerHelper.STATUS_ERROR;
+ success = mDbHelper.deleteKeyphraseSoundModel(model.uuid);
+ } else {
+ // Else update the model.
+ success = mDbHelper.addOrUpdateKeyphraseSoundModel(model);
+ }
+ if (success) {
+ synchronized (this) {
+ // Notify the voice interaction service of a change in sound models.
+ if (mImpl != null && mImpl.mService != null) {
+ mImpl.notifySoundModelsChangedLocked();
}
}
- } finally {
- Binder.restoreCallingIdentity(caller);
+ return SoundTriggerHelper.STATUS_OK;
+ } else {
+ return SoundTriggerHelper.STATUS_ERROR;
}
+ } finally {
+ Binder.restoreCallingIdentity(caller);
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 54af5d4..94f227c 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -96,6 +96,13 @@
@Override
public void onServiceDisconnected(ComponentName name) {
+ try {
+ if (mService != null) {
+ mService.shutdown();
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "RemoteException in shutdown", e);
+ }
mService = null;
}
};
@@ -308,4 +315,15 @@
mContext.unregisterReceiver(mBroadcastReceiver);
}
}
+
+ void notifySoundModelsChangedLocked() {
+ if (mService == null) {
+ Slog.w(TAG, "Not bound to voice interaction service " + mComponent);
+ }
+ try {
+ mService.soundModelsChanged();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "RemoteException while calling soundModelsChanged", e);
+ }
+ }
}
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index f751826..d5b39cf 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -432,14 +432,20 @@
public void onSuccess(ConnectionRequest request, Connection connection) {
Log.d(this, "adapter handleCreateConnectionSuccessful %s",
request.getCallId());
- mAdapter.handleCreateConnectionSuccessful(request);
addConnection(request.getCallId(), connection);
-
- // TODO: onSuccess should pass through the entire state of the connection instead of
- // having to set it like this afterwards. Also, it would eliminate the hack of
- // having to change the request object that we pass back.
- mConnectionListener.onCallCapabilitiesChanged(
- connection, connection.getCallCapabilities());
+ mAdapter.handleCreateConnectionSuccessful(
+ request,
+ new ParcelableConnection(
+ request.getAccountHandle(),
+ connection.getState(),
+ connection.getCallCapabilities(),
+ connection.getHandle(),
+ connection.getHandlePresentation(),
+ connection.getCallerDisplayName(),
+ connection.getCallerDisplayNamePresentation(),
+ connection.getCallVideoProvider() == null ?
+ null : connection.getCallVideoProvider().getInterface(),
+ connection.getVideoState()));
}
@Override
@@ -720,12 +726,6 @@
mIdByConnection.put(connection, callId);
connection.addConnectionListener(mConnectionListener);
onConnectionAdded(connection);
-
- // Trigger listeners for properties set before connection listener was added.
- CallVideoProvider callVideoProvider = connection.getCallVideoProvider();
- if (callVideoProvider != null) {
- connection.setCallVideoProvider(callVideoProvider);
- }
}
private void removeConnection(Connection connection) {
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
index 0b8d93d..66e9925 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
@@ -74,10 +74,11 @@
}
}
- void handleCreateConnectionSuccessful(ConnectionRequest request) {
+ void handleCreateConnectionSuccessful(
+ ConnectionRequest request, ParcelableConnection connection) {
for (IConnectionServiceAdapter adapter : mAdapters) {
try {
- adapter.handleCreateConnectionSuccessful(request);
+ adapter.handleCreateConnectionSuccessful(request, connection);
} catch (RemoteException e) {
}
}
@@ -277,7 +278,9 @@
void setCallVideoProvider(String callId, CallVideoProvider callVideoProvider) {
for (IConnectionServiceAdapter adapter : mAdapters) {
try {
- adapter.setCallVideoProvider(callId, callVideoProvider.getInterface());
+ adapter.setCallVideoProvider(
+ callId,
+ callVideoProvider == null ? null : callVideoProvider.getInterface());
} catch (RemoteException e) {
}
}
diff --git a/telecomm/java/android/telecomm/ParcelableConnection.aidl b/telecomm/java/android/telecomm/ParcelableConnection.aidl
new file mode 100644
index 0000000..e3c3bd2
--- /dev/null
+++ b/telecomm/java/android/telecomm/ParcelableConnection.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecomm;
+
+parcelable ParcelableConnection;
diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java
new file mode 100644
index 0000000..f730fef
--- /dev/null
+++ b/telecomm/java/android/telecomm/ParcelableConnection.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecomm;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.telecomm.ICallVideoProvider;
+
+/**
+ * Information about a connection that is used between Telecomm and the ConnectionService.
+ * This is used to send initial Connection information to Telecomm when the connection is
+ * first created.
+ * @hide
+ */
+public final class ParcelableConnection implements Parcelable {
+ private PhoneAccountHandle mPhoneAccount;
+ private int mState;
+ private int mCapabilities;
+ private Uri mHandle;
+ private int mHandlePresentation;
+ private String mCallerDisplayName;
+ private int mCallerDisplayNamePresentation;
+ private ICallVideoProvider mCallVideoProvider;
+ private int mVideoState;
+
+ /** @hide */
+ public ParcelableConnection(
+ PhoneAccountHandle phoneAccount,
+ int state,
+ int capabilities,
+ Uri handle,
+ int handlePresentation,
+ String callerDisplayName,
+ int callerDisplayNamePresentation,
+ ICallVideoProvider callVideoProvider,
+ int videoState) {
+ mPhoneAccount = phoneAccount;
+ mState = state;
+ mCapabilities = capabilities;
+ mHandle = handle;
+ mHandlePresentation = handlePresentation;
+ mCallerDisplayName = callerDisplayName;
+ mCallerDisplayNamePresentation = callerDisplayNamePresentation;
+ mCallVideoProvider = callVideoProvider;
+ mVideoState = videoState;
+ }
+
+ public PhoneAccountHandle getPhoneAccount() {
+ return mPhoneAccount;
+ }
+
+ public int getState() {
+ return mState;
+ }
+
+ // Bit mask of actions a call supports, values are defined in {@link CallCapabilities}.
+ public int getCapabilities() {
+ return mCapabilities;
+ }
+
+ public Uri getHandle() {
+ return mHandle;
+ }
+
+ public int getHandlePresentation() {
+ return mHandlePresentation;
+ }
+
+ public String getCallerDisplayName() {
+ return mCallerDisplayName;
+ }
+
+ public int getCallerDisplayNamePresentation() {
+ return mCallerDisplayNamePresentation;
+ }
+
+ public ICallVideoProvider getCallVideoProvider() {
+ return mCallVideoProvider;
+ }
+
+ public int getVideoState() {
+ return mVideoState;
+ }
+
+ public static final Parcelable.Creator<ParcelableConnection> CREATOR =
+ new Parcelable.Creator<ParcelableConnection> () {
+ @Override
+ public ParcelableConnection createFromParcel(Parcel source) {
+ ClassLoader classLoader = ParcelableConnection.class.getClassLoader();
+
+ PhoneAccountHandle phoneAccount = source.readParcelable(classLoader);
+ int state = source.readInt();
+ int capabilities = source.readInt();
+ Uri handle = source.readParcelable(classLoader);
+ int handlePresentation = source.readInt();
+ String callerDisplayName = source.readString();
+ int callerDisplayNamePresentation = source.readInt();
+ ICallVideoProvider callVideoProvider =
+ ICallVideoProvider.Stub.asInterface(source.readStrongBinder());
+ int videoState = source.readInt();
+
+ return new ParcelableConnection(
+ phoneAccount,
+ state,
+ capabilities,
+ handle,
+ handlePresentation,
+ callerDisplayName,
+ callerDisplayNamePresentation,
+ callVideoProvider,
+ videoState);
+ }
+
+ @Override
+ public ParcelableConnection[] newArray(int size) {
+ return new ParcelableConnection[size];
+ }
+ };
+
+ /** {@inheritDoc} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Writes ParcelableConnection object into a Parcel. */
+ @Override
+ public void writeToParcel(Parcel destination, int flags) {
+ destination.writeParcelable(mPhoneAccount, 0);
+ destination.writeInt(mState);
+ destination.writeInt(mCapabilities);
+ destination.writeParcelable(mHandle, 0);
+ destination.writeInt(mHandlePresentation);
+ destination.writeString(mCallerDisplayName);
+ destination.writeInt(mCallerDisplayNamePresentation);
+ destination.writeStrongBinder(
+ mCallVideoProvider != null ? mCallVideoProvider.asBinder() : null);
+ destination.writeInt(mVideoState);
+ }
+}
diff --git a/telecomm/java/android/telecomm/PhoneAccount.java b/telecomm/java/android/telecomm/PhoneAccount.java
index 0570d18..5a7753c 100644
--- a/telecomm/java/android/telecomm/PhoneAccount.java
+++ b/telecomm/java/android/telecomm/PhoneAccount.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.Resources.NotFoundException;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Parcel;
@@ -181,7 +182,7 @@
}
try {
return packageContext.getResources().getDrawable(resId);
- } catch (MissingResourceException e) {
+ } catch (NotFoundException|MissingResourceException e) {
Log.e(this, e, "Cannot find icon %d in package %s",
resId, mAccountHandle.getComponentName().getPackageName());
return null;
diff --git a/telecomm/java/android/telecomm/RemoteCallVideoClient.java b/telecomm/java/android/telecomm/RemoteCallVideoClient.java
index 8024831..08d1391 100644
--- a/telecomm/java/android/telecomm/RemoteCallVideoClient.java
+++ b/telecomm/java/android/telecomm/RemoteCallVideoClient.java
@@ -26,17 +26,20 @@
/**
* Remote class to invoke callbacks in InCallUI related to supporting video in calls.
*/
-public class RemoteCallVideoClient implements IBinder.DeathRecipient {
+public class RemoteCallVideoClient {
private final ICallVideoClient mCallVideoClient;
+ private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ mCallVideoClient.asBinder().unlinkToDeath(this, 0);
+ }
+ };
+
+ /** {@hide} */
RemoteCallVideoClient(ICallVideoClient callVideoProvider) throws RemoteException {
mCallVideoClient = callVideoProvider;
- mCallVideoClient.asBinder().linkToDeath(this, 0);
- }
-
- @Override
- public void binderDied() {
- mCallVideoClient.asBinder().unlinkToDeath(this, 0);
+ mCallVideoClient.asBinder().linkToDeath(mDeathRecipient, 0);
}
/**
@@ -49,9 +52,11 @@
*
* @param videoCallProfile The requested video call profile.
*/
- public void receiveSessionModifyRequest(VideoCallProfile videoCallProfile)
- throws RemoteException {
- mCallVideoClient.receiveSessionModifyRequest(videoCallProfile);
+ public void receiveSessionModifyRequest(VideoCallProfile videoCallProfile) {
+ try {
+ mCallVideoClient.receiveSessionModifyRequest(videoCallProfile);
+ } catch (RemoteException e) {
+ }
}
/**
@@ -66,9 +71,13 @@
* @param requestedProfile The original request which was sent to the remote device.
* @param responseProfile The actual profile changes made by the remote device.
*/
- public void receiveSessionModifyResponse(int status, VideoCallProfile requestedProfile,
- VideoCallProfile responseProfile) throws RemoteException {
- mCallVideoClient.receiveSessionModifyResponse(status, requestedProfile, responseProfile);
+ public void receiveSessionModifyResponse(
+ int status, VideoCallProfile requestedProfile, VideoCallProfile responseProfile) {
+ try {
+ mCallVideoClient.receiveSessionModifyResponse(
+ status, requestedProfile, responseProfile);
+ } catch (RemoteException e) {
+ }
}
/**
@@ -81,8 +90,11 @@
*
* @param event The event.
*/
- public void handleCallSessionEvent(int event) throws RemoteException {
- mCallVideoClient.handleCallSessionEvent(event);
+ public void handleCallSessionEvent(int event) {
+ try {
+ mCallVideoClient.handleCallSessionEvent(event);
+ } catch (RemoteException e) {
+ }
}
/**
@@ -92,8 +104,11 @@
* @param width The updated peer video width.
* @param height The updated peer video height.
*/
- public void updatePeerDimensions(int width, int height) throws RemoteException {
- mCallVideoClient.updatePeerDimensions(width, height);
+ public void updatePeerDimensions(int width, int height) {
+ try {
+ mCallVideoClient.updatePeerDimensions(width, height);
+ } catch (RemoteException e) {
+ }
}
/**
@@ -101,8 +116,11 @@
*
* @param dataUsage The updated data usage.
*/
- public void updateCallDataUsage(int dataUsage) throws RemoteException {
- mCallVideoClient.updateCallDataUsage(dataUsage);
+ public void updateCallDataUsage(int dataUsage) {
+ try {
+ mCallVideoClient.updateCallDataUsage(dataUsage);
+ } catch (RemoteException e) {
+ }
}
/**
@@ -110,8 +128,10 @@
*
* @param callCameraCapabilities The changed camera capabilities.
*/
- public void handleCameraCapabilitiesChange(CallCameraCapabilities callCameraCapabilities)
- throws RemoteException {
- mCallVideoClient.handleCameraCapabilitiesChange(callCameraCapabilities);
+ public void handleCameraCapabilitiesChange(CallCameraCapabilities callCameraCapabilities) {
+ try {
+ mCallVideoClient.handleCameraCapabilitiesChange(callCameraCapabilities);
+ } catch (RemoteException e) {
+ }
}
-}
+}
\ No newline at end of file
diff --git a/telecomm/java/android/telecomm/RemoteCallVideoProvider.java b/telecomm/java/android/telecomm/RemoteCallVideoProvider.java
index 170cf04..b8b8b9d 100644
--- a/telecomm/java/android/telecomm/RemoteCallVideoProvider.java
+++ b/telecomm/java/android/telecomm/RemoteCallVideoProvider.java
@@ -59,8 +59,11 @@
*
* @param cameraId The id of the camera.
*/
- public void setCamera(String cameraId) throws RemoteException {
- mCallVideoProvider.setCamera(cameraId);
+ public void setCamera(String cameraId) {
+ try {
+ mCallVideoProvider.setCamera(cameraId);
+ } catch (RemoteException e) {
+ }
}
/**
@@ -107,8 +110,11 @@
*
* @param value The camera zoom ratio.
*/
- public void setZoom(float value) throws RemoteException {
- mCallVideoProvider.setZoom(value);
+ public void setZoom(float value) {
+ try {
+ mCallVideoProvider.setZoom(value);
+ } catch (RemoteException e) {
+ }
}
/**
diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java
index 29461af..10569ab 100644
--- a/telecomm/java/android/telecomm/RemoteConnectionService.java
+++ b/telecomm/java/android/telecomm/RemoteConnectionService.java
@@ -19,18 +19,17 @@
import android.app.PendingIntent;
import android.content.ComponentName;
import android.net.Uri;
-import android.os.IBinder.DeathRecipient;
import android.os.Handler;
+import android.os.IBinder.DeathRecipient;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.DisconnectCause;
-
import android.text.TextUtils;
import com.android.internal.os.SomeArgs;
+import com.android.internal.telecomm.ICallVideoProvider;
import com.android.internal.telecomm.IConnectionService;
import com.android.internal.telecomm.IConnectionServiceAdapter;
-import com.android.internal.telecomm.ICallVideoProvider;
import com.android.internal.telecomm.RemoteServiceCallback;
import java.util.LinkedList;
@@ -80,11 +79,27 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL: {
- ConnectionRequest request = (ConnectionRequest) msg.obj;
- if (isPendingConnection(request.getCallId())) {
- mConnection = new RemoteConnection(mConnectionService, request.getCallId());
- mPendingResponse.onSuccess(request, mConnection);
- clearPendingInformation();
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ ConnectionRequest request = (ConnectionRequest) args.arg1;
+ if (isPendingConnection(request.getCallId())) {
+ ParcelableConnection parcel = (ParcelableConnection) args.arg2;
+ mConnection = new RemoteConnection(
+ mConnectionService, request.getCallId());
+ mConnection.setState(parcel.getState());
+ mConnection.setCallCapabilities(parcel.getCapabilities());
+ mConnection.setHandle(
+ parcel.getHandle(), parcel.getHandlePresentation());
+ mConnection.setCallerDisplayName(
+ parcel.getCallerDisplayName(),
+ parcel.getCallerDisplayNamePresentation());
+ // TODO: Do we need to support video providers for remote connections?
+
+ mPendingResponse.onSuccess(request, mConnection);
+ clearPendingInformation();
+ }
+ } finally {
+ args.recycle();
}
break;
}
@@ -242,8 +257,12 @@
private final IConnectionServiceAdapter mAdapter = new IConnectionServiceAdapter.Stub() {
@Override
- public void handleCreateConnectionSuccessful(ConnectionRequest request) {
- mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, request).sendToTarget();
+ public void handleCreateConnectionSuccessful(
+ ConnectionRequest request, ParcelableConnection connection) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = request;
+ args.arg2 = connection;
+ mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, args).sendToTarget();
}
@Override
diff --git a/telecomm/java/android/telecomm/TelecommManager.java b/telecomm/java/android/telecomm/TelecommManager.java
index c76d670..ea89a53 100644
--- a/telecomm/java/android/telecomm/TelecommManager.java
+++ b/telecomm/java/android/telecomm/TelecommManager.java
@@ -56,6 +56,12 @@
"android.intent.action.CONNECTION_SERVICE_CONFIGURE";
/**
+ * The {@link android.content.Intent} action used to show the call settings page.
+ */
+ public static final String ACTION_SHOW_CALL_SETTINGS =
+ "android.telecomm.intent.action.SHOW_CALL_SETTINGS";
+
+ /**
* Optional extra for {@link android.content.Intent#ACTION_CALL} containing a boolean that
* determines whether the speakerphone should be automatically turned on for an outgoing call.
*/
diff --git a/telecomm/java/android/telecomm/VideoCallProfile.java b/telecomm/java/android/telecomm/VideoCallProfile.java
index fc7b2c3..5b15e4a 100644
--- a/telecomm/java/android/telecomm/VideoCallProfile.java
+++ b/telecomm/java/android/telecomm/VideoCallProfile.java
@@ -77,6 +77,15 @@
* Creates an instance of the VideoCallProfile
*
* @param videoState The video state.
+ */
+ public VideoCallProfile(int videoState) {
+ this(videoState, QUALITY_DEFAULT);
+ }
+
+ /**
+ * Creates an instance of the VideoCallProfile
+ *
+ * @param videoState The video state.
* @param quality The video quality.
*/
public VideoCallProfile(int videoState, int quality) {
diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
index 1abdf7c..552993f 100644
--- a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
@@ -19,6 +19,7 @@
import android.app.PendingIntent;
import android.net.Uri;
import android.telecomm.ConnectionRequest;
+import android.telecomm.ParcelableConnection;
import android.telecomm.StatusHints;
import com.android.internal.telecomm.ICallVideoProvider;
@@ -32,7 +33,8 @@
* {@hide}
*/
oneway interface IConnectionServiceAdapter {
- void handleCreateConnectionSuccessful(in ConnectionRequest request);
+ void handleCreateConnectionSuccessful(
+ in ConnectionRequest request, in ParcelableConnection connection);
void handleCreateConnectionFailed(
in ConnectionRequest request, int errorCode, String errorMessage);
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index e388480..36c90f2 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -661,7 +661,7 @@
* @hide
*/
@Override
- public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
+ public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
UserHandle user) {
return false;
}
@@ -670,7 +670,7 @@
* @hide
*/
@Override
- public boolean getApplicationBlockedSettingAsUser(String packageName, UserHandle user) {
+ public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
return false;
}
diff --git a/tests/DozeTest/AndroidManifest.xml b/tests/DozeTest/AndroidManifest.xml
index c199f69..03778d6 100644
--- a/tests/DozeTest/AndroidManifest.xml
+++ b/tests/DozeTest/AndroidManifest.xml
@@ -22,7 +22,8 @@
android:name="DozeTestDream"
android:exported="true"
android:icon="@drawable/ic_app"
- android:label="@string/doze_dream_name">
+ android:label="@string/doze_dream_name"
+ android:permission="android.permission.BIND_DREAM_SERVICE">
<!-- Commented out to prevent this dream from appearing in the list of
dreams that the user can select via the Settings application.
<intent-filter>
diff --git a/tests/DozeTest/res/layout/dream.xml b/tests/DozeTest/res/layout/dream.xml
index 1c8fd3f..bced230 100644
--- a/tests/DozeTest/res/layout/dream.xml
+++ b/tests/DozeTest/res/layout/dream.xml
@@ -18,7 +18,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:background="#bb2288">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java b/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java
index a0b2d1a..f72e331 100644
--- a/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java
+++ b/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java
@@ -22,11 +22,13 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.Handler;
import android.os.PowerManager;
import android.service.dreams.DozeHardware;
import android.service.dreams.DreamService;
import android.text.format.DateFormat;
import android.util.Log;
+import android.view.Display;
import android.widget.TextView;
import java.util.Date;
@@ -51,10 +53,16 @@
// Doesn't mean anything. Real hardware won't handle it.
private static final String TEST_PING_MESSAGE = "test.ping";
+ // Not all hardware supports dozing. We should use Display.STATE_DOZE but
+ // for testing purposes it is convenient to use Display.STATE_ON so the
+ // test still works on hardware that does not support dozing.
+ private static final int DISPLAY_STATE_WHEN_DOZING = Display.STATE_ON;
+
private PowerManager mPowerManager;
private PowerManager.WakeLock mWakeLock;
private AlarmManager mAlarmManager;
private PendingIntent mAlarmIntent;
+ private Handler mHandler = new Handler();
private TextView mAlarmClock;
@@ -64,6 +72,8 @@
private boolean mDreaming;
private DozeHardware mDozeHardware;
+ private long mLastTime = Long.MIN_VALUE;
+
@Override
public void onCreate() {
super.onCreate();
@@ -80,6 +90,8 @@
registerReceiver(mAlarmReceiver, filter);
mAlarmIntent = PendingIntent.getBroadcast(this, 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
+
+ setDozeScreenState(DISPLAY_STATE_WHEN_DOZING);
}
@Override
@@ -143,13 +155,33 @@
if (mDreaming) {
long now = System.currentTimeMillis();
now -= now % 60000; // back up to last minute boundary
+ if (mLastTime == now) {
+ return;
+ }
+ mLastTime = now;
mTime.setTime(now);
mAlarmClock.setText(mTimeFormat.format(mTime));
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, now + 60000, mAlarmIntent);
- mWakeLock.acquire(UPDATE_TIME_TIMEOUT);
+ mWakeLock.acquire(UPDATE_TIME_TIMEOUT + 5000 /*for testing brightness*/);
+
+ // flash the screen a bit to test these functions
+ setDozeScreenState(DISPLAY_STATE_WHEN_DOZING);
+ setDozeScreenBrightness(200);
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ setDozeScreenBrightness(50);
+ }
+ }, 2000);
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ setDozeScreenState(Display.STATE_OFF);
+ }
+ }, 5000);
}
}
diff --git a/tests/MusicBrowserDemo/Android.mk b/tests/MusicBrowserDemo/Android.mk
new file mode 100644
index 0000000..207774b
--- /dev/null
+++ b/tests/MusicBrowserDemo/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := MusicBrowserDemo
+#LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-v4 \
+ android-support-v7-appcompat
+
+LOCAL_RESOURCE_DIR := \
+ $(LOCAL_PATH)/res \
+ frameworks/support/v7/appcompat/res
+LOCAL_PROGUARD_ENABLED := disabled
+#LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+LOCAL_AAPT_FLAGS := \
+ --auto-add-overlay \
+ --extra-packages android.support.v7.appcompat
+include $(BUILD_PACKAGE)
diff --git a/tests/MusicBrowserDemo/AndroidManifest.xml b/tests/MusicBrowserDemo/AndroidManifest.xml
new file mode 100644
index 0000000..d2acfe2
--- /dev/null
+++ b/tests/MusicBrowserDemo/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.musicbrowserdemo"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="9"
+ android:targetSdkVersion="19" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme"
+ >
+
+ <activity
+ android:name="com.example.android.musicbrowserdemo.MainActivity"
+ android:label="@string/app_name"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/tests/MusicBrowserDemo/res/drawable-hdpi/ic_launcher.png b/tests/MusicBrowserDemo/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..47d6854
--- /dev/null
+++ b/tests/MusicBrowserDemo/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MusicBrowserDemo/res/drawable-mdpi/ic_launcher.png b/tests/MusicBrowserDemo/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..01b53fd
--- /dev/null
+++ b/tests/MusicBrowserDemo/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MusicBrowserDemo/res/drawable-xhdpi/ic_launcher.png b/tests/MusicBrowserDemo/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..af762f2
--- /dev/null
+++ b/tests/MusicBrowserDemo/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MusicBrowserDemo/res/drawable-xxhdpi/ic_launcher.png b/tests/MusicBrowserDemo/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..eef47aa
--- /dev/null
+++ b/tests/MusicBrowserDemo/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MusicBrowserDemo/res/values/strings.xml b/tests/MusicBrowserDemo/res/values/strings.xml
new file mode 100644
index 0000000..858f278f
--- /dev/null
+++ b/tests/MusicBrowserDemo/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<resources>
+
+ <string name="app_name">Music Browser</string>
+
+</resources>
diff --git a/tests/MusicBrowserDemo/res/values/styles.xml b/tests/MusicBrowserDemo/res/values/styles.xml
new file mode 100644
index 0000000..b83662d
--- /dev/null
+++ b/tests/MusicBrowserDemo/res/values/styles.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+
+</resources>
diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java
new file mode 100644
index 0000000..c0f3a7f
--- /dev/null
+++ b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java
@@ -0,0 +1,149 @@
+/*
+ * 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.example.android.musicbrowserdemo;
+
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.media.browse.MediaBrowserService;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.app.ListFragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// TODO: Include an icon.
+
+public class AppListFragment extends ListFragment {
+
+ private Adapter mAdapter;
+ private List<Item> mItems;
+
+ public AppListFragment() {
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ mAdapter = new Adapter();
+ setListAdapter(mAdapter);
+ }
+
+ @Override
+ public void onListItemClick(ListView l, View v, int position, long id) {
+ final Item item = mItems.get(position);
+
+ Log.i("AppListFragment", "Item clicked: " + position + " -- " + item.component);
+
+ final BrowserListFragment fragment = new BrowserListFragment();
+
+ final Bundle args = new Bundle();
+ args.putParcelable(BrowserListFragment.ARG_COMPONENT, item.component);
+ fragment.setArguments(args);
+
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, fragment)
+ .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
+ .addToBackStack(null)
+ .commit();
+ }
+
+ private static class Item {
+ final String label;
+ final ComponentName component;
+
+ Item(String l, ComponentName c) {
+ this.label = l;
+ this.component = c;
+ }
+ }
+
+ private class Adapter extends BaseAdapter {
+ private final LayoutInflater mInflater;
+
+ Adapter() {
+ super();
+
+ final Context context = getActivity();
+ mInflater = LayoutInflater.from(context);
+
+ // Load the data
+ final PackageManager pm = context.getPackageManager();
+ final Intent intent = new Intent(MediaBrowserService.SERVICE_ACTION);
+ final List<ResolveInfo> list = pm.queryIntentServices(intent, 0);
+ final int N = list.size();
+ mItems = new ArrayList(N);
+ for (int i=0; i<N; i++) {
+ final ResolveInfo ri = list.get(i);
+ mItems.add(new Item(ri.loadLabel(pm).toString(), new ComponentName(
+ ri.serviceInfo.applicationInfo.packageName,
+ ri.serviceInfo.name)));
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return mItems.size();
+ }
+
+ @Override
+ public Item getItem(int position) {
+ return mItems.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return 1;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
+ }
+
+ final TextView tv = (TextView)convertView;
+ final Item item = mItems.get(position);
+ tv.setText(item.label);
+
+ return convertView;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 1;
+ }
+ }
+}
+
+
diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java
new file mode 100644
index 0000000..3fc468d
--- /dev/null
+++ b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java
@@ -0,0 +1,212 @@
+/*
+ * 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.example.android.musicbrowserdemo;
+
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.media.browse.MediaBrowser;
+import android.media.browse.MediaBrowserItem;
+import android.media.browse.MediaBrowserService;
+import android.os.Bundle;
+import android.net.Uri;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.app.ListFragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BrowserListFragment extends ListFragment {
+ private static final String TAG = "BrowserListFragment";
+
+ // Hints
+ public static final String HINT_DISPLAY = "com.example.android.musicbrowserdemo.DISPLAY";
+
+ // For args
+ public static final String ARG_COMPONENT = "component";
+ public static final String ARG_URI = "uri";
+
+ private Adapter mAdapter;
+ private List<Item> mItems = new ArrayList();
+ private ComponentName mComponent;
+ private Uri mUri;
+ private MediaBrowser mBrowser;
+
+ private static class Item {
+ final MediaBrowserItem media;
+
+ Item(MediaBrowserItem m) {
+ this.media = m;
+ }
+ }
+
+ public BrowserListFragment() {
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ Log.d(TAG, "onActivityCreated -- " + hashCode());
+ mAdapter = new Adapter();
+ setListAdapter(mAdapter);
+
+ // Get our arguments
+ final Bundle args = getArguments();
+ mComponent = args.getParcelable(ARG_COMPONENT);
+ mUri = args.getParcelable(ARG_URI);
+
+ // A hint about who we are, so the service can customize the results if it wants to.
+ final Bundle rootHints = new Bundle();
+ rootHints.putBoolean(HINT_DISPLAY, true);
+
+ mBrowser = new MediaBrowser(getActivity(), mComponent, mConnectionCallbacks, rootHints);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mBrowser.connect();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mBrowser.disconnect();
+ }
+
+ @Override
+ public void onListItemClick(ListView l, View v, int position, long id) {
+ final Item item = mItems.get(position);
+
+ Log.i("BrowserListFragment", "Item clicked: " + position + " -- "
+ + mAdapter.getItem(position).media.getUri());
+
+ final BrowserListFragment fragment = new BrowserListFragment();
+
+ final Bundle args = new Bundle();
+ args.putParcelable(BrowserListFragment.ARG_COMPONENT, mComponent);
+ args.putParcelable(BrowserListFragment.ARG_URI, item.media.getUri());
+ fragment.setArguments(args);
+
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, fragment)
+ .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
+ .addToBackStack(null)
+ .commit();
+
+ }
+
+ final MediaBrowser.ConnectionCallback mConnectionCallbacks
+ = new MediaBrowser.ConnectionCallback() {
+ @Override
+ public void onConnected() {
+ Log.d(TAG, "mConnectionCallbacks.onConnected");
+ if (mUri == null) {
+ mUri = mBrowser.getRoot();
+ }
+ mBrowser.subscribe(mUri, new MediaBrowser.SubscriptionCallback() {
+ @Override
+ public void onChildrenLoaded(Uri parentUri, List<MediaBrowserItem> children) {
+ Log.d(TAG, "onChildrenLoaded parentUri=" + parentUri
+ + " children= " + children);
+ mItems.clear();
+ final int N = children.size();
+ for (int i=0; i<N; i++) {
+ mItems.add(new Item(children.get(i)));
+ }
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onError(Uri parentUri) {
+ Log.d(TAG, "onError parentUri=" + parentUri);
+ }
+ });
+ }
+
+ @Override
+ public void onConnectionSuspended() {
+ Log.d(TAG, "mConnectionCallbacks.onConnectionSuspended");
+ }
+
+ @Override
+ public void onConnectionFailed() {
+ Log.d(TAG, "mConnectionCallbacks.onConnectionFailed");
+ }
+ };
+
+ private class Adapter extends BaseAdapter {
+ private final LayoutInflater mInflater;
+
+ Adapter() {
+ super();
+
+ final Context context = getActivity();
+ mInflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public int getCount() {
+ return mItems.size();
+ }
+
+ @Override
+ public Item getItem(int position) {
+ return mItems.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return 1;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
+ }
+
+ final TextView tv = (TextView)convertView;
+ final Item item = mItems.get(position);
+ tv.setText(item.media.getTitle());
+
+ return convertView;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 1;
+ }
+ }
+}
+
+
diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java
new file mode 100644
index 0000000..ed91aad
--- /dev/null
+++ b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java
@@ -0,0 +1,48 @@
+/*
+ * 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.example.android.musicbrowserdemo;
+
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * Main activity class.
+ */
+public class MainActivity extends FragmentActivity {
+
+ private static final String BROWSER_FRAGMENT_TAG = "browser";
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ Log.d("MainActivity", "-------------------------------------------------------");
+
+ // If we are starting afresh, start at the app list.
+ final FragmentManager fm = getSupportFragmentManager();
+ if (fm.findFragmentById(android.R.id.content) == null) {
+ fm.beginTransaction().add(android.R.id.content, new AppListFragment()).commit();
+ }
+ }
+}
+
diff --git a/tests/MusicServiceDemo/Android.mk b/tests/MusicServiceDemo/Android.mk
new file mode 100644
index 0000000..feef67a
--- /dev/null
+++ b/tests/MusicServiceDemo/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := MusicServiceDemo
+#LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-v4 \
+ android-support-v7-appcompat
+
+LOCAL_RESOURCE_DIR := \
+ $(LOCAL_PATH)/res \
+ frameworks/support/v7/appcompat/res
+LOCAL_PROGUARD_ENABLED := disabled
+#LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+LOCAL_AAPT_FLAGS := \
+ --auto-add-overlay \
+ --extra-packages android.support.v7.appcompat
+include $(BUILD_PACKAGE)
diff --git a/tests/MusicServiceDemo/AndroidManifest.xml b/tests/MusicServiceDemo/AndroidManifest.xml
new file mode 100644
index 0000000..4178a80
--- /dev/null
+++ b/tests/MusicServiceDemo/AndroidManifest.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.musicservicedemo"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+ <uses-sdk
+ android:minSdkVersion="9"
+ android:targetSdkVersion="19" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme"
+ >
+
+ <activity
+ android:name="com.example.android.automotive.musicplayer.MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <service
+ android:name=".BrowserService"
+ android:exported="true"
+ >
+ <intent-filter>
+ <action android:name="android.media.browse.MediaBrowseService" />
+ </intent-filter>
+ </service>
+ </application>
+
+</manifest>
diff --git a/tests/MusicServiceDemo/proguard-project.txt b/tests/MusicServiceDemo/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/tests/MusicServiceDemo/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/tests/MusicServiceDemo/res/drawable-hdpi/ic_launcher.png b/tests/MusicServiceDemo/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..47d6854
--- /dev/null
+++ b/tests/MusicServiceDemo/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MusicServiceDemo/res/drawable-mdpi/ic_launcher.png b/tests/MusicServiceDemo/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..01b53fd
--- /dev/null
+++ b/tests/MusicServiceDemo/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MusicServiceDemo/res/drawable-xhdpi/ic_launcher.png b/tests/MusicServiceDemo/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..af762f2
--- /dev/null
+++ b/tests/MusicServiceDemo/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MusicServiceDemo/res/drawable-xxhdpi/ic_launcher.png b/tests/MusicServiceDemo/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..eef47aa
--- /dev/null
+++ b/tests/MusicServiceDemo/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MusicServiceDemo/res/drawable-xxhdpi/thumbsup.png b/tests/MusicServiceDemo/res/drawable-xxhdpi/thumbsup.png
new file mode 100644
index 0000000..ea98c95
--- /dev/null
+++ b/tests/MusicServiceDemo/res/drawable-xxhdpi/thumbsup.png
Binary files differ
diff --git a/tests/MusicServiceDemo/res/layout/activity_main.xml b/tests/MusicServiceDemo/res/layout/activity_main.xml
new file mode 100644
index 0000000..71753e3
--- /dev/null
+++ b/tests/MusicServiceDemo/res/layout/activity_main.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context="com.example.android.automotive.musicplayer.MainActivity"
+ tools:ignore="MergeRootFrame" />
diff --git a/tests/MusicServiceDemo/res/layout/fragment_main.xml b/tests/MusicServiceDemo/res/layout/fragment_main.xml
new file mode 100644
index 0000000..8796e86
--- /dev/null
+++ b/tests/MusicServiceDemo/res/layout/fragment_main.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ tools:context="com.example.android.automotive.musicplayer.MainActivity$PlaceholderFragment" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/app_name" />
+
+</RelativeLayout>
diff --git a/tests/MusicServiceDemo/res/values/colors.xml b/tests/MusicServiceDemo/res/values/colors.xml
new file mode 100644
index 0000000..44dd05d
--- /dev/null
+++ b/tests/MusicServiceDemo/res/values/colors.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <color name="yellow">#ffffff00</color>
+ <color name="green">#ff00ff00</color>
+ <color name="blue">#ff0000ff</color>
+ <color name="red">#ffff0000</color>
+</resources>
diff --git a/tests/MusicServiceDemo/res/values/dimens.xml b/tests/MusicServiceDemo/res/values/dimens.xml
new file mode 100644
index 0000000..9f63ef2
--- /dev/null
+++ b/tests/MusicServiceDemo/res/values/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<resources>
+
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
diff --git a/tests/MusicServiceDemo/res/values/strings.xml b/tests/MusicServiceDemo/res/values/strings.xml
new file mode 100644
index 0000000..14c0171
--- /dev/null
+++ b/tests/MusicServiceDemo/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<resources>
+
+ <string name="app_name">Music Service Demo</string>
+ <string name="action_settings">Settings</string>
+ <string name="thumbs_up">Thumbs Up</string>
+ <string name="music_error">No music found</string>
+ <string name="now_playing">Now Playing</string>
+
+</resources>
diff --git a/tests/MusicServiceDemo/res/values/styles.xml b/tests/MusicServiceDemo/res/values/styles.xml
new file mode 100644
index 0000000..b83662d
--- /dev/null
+++ b/tests/MusicServiceDemo/res/values/styles.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+
+</resources>
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java
new file mode 100644
index 0000000..e5216b5
--- /dev/null
+++ b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * 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.example.android.musicservicedemo;
+
+import android.app.SearchManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.UriMatcher;
+import android.content.res.Resources.NotFoundException;
+import android.database.MatrixCursor;
+import android.graphics.Bitmap;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaPlayer.OnErrorListener;
+import android.media.MediaPlayer.OnPreparedListener;
+import android.media.browse.MediaBrowserItem;
+import android.media.browse.MediaBrowserService;
+import android.media.browse.MediaBrowserService.BrowserRoot;
+import android.media.session.MediaSession;
+import android.net.Uri;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.WifiLock;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.example.android.musicservicedemo.browser.MusicProvider;
+import com.example.android.musicservicedemo.browser.MusicProviderTask;
+import com.example.android.musicservicedemo.browser.MusicProviderTaskListener;
+import com.example.android.musicservicedemo.browser.MusicTrack;
+
+import org.json.JSONException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Service that implements MediaBrowserService and returns our menu hierarchy.
+ */
+public class BrowserService extends MediaBrowserService {
+ private static final String TAG = "BrowserService";
+
+ // URI paths for browsing music
+ public static final String BROWSE_ROOT_BASE_PATH = "browse";
+ public static final String NOW_PLAYING_PATH = "now_playing";
+ public static final String PIANO_BASE_PATH = "piano";
+ public static final String VOICE_BASE_PATH = "voice";
+
+ // Content URIs
+ public static final String AUTHORITY = "com.example.android.automotive.musicplayer";
+ public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY);
+ public static final Uri BROWSE_URI = Uri.withAppendedPath(BASE_URI, BROWSE_ROOT_BASE_PATH);
+
+ // URI matcher constants for browsing paths
+ public static final int BROWSE_ROOT = 1;
+ public static final int NOW_PLAYING = 2;
+ public static final int PIANO = 3;
+ public static final int VOICE = 4;
+
+ // Map the the URI paths with the URI matcher constants
+ private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ static {
+ sUriMatcher.addURI(AUTHORITY, BROWSE_ROOT_BASE_PATH, BROWSE_ROOT);
+ sUriMatcher.addURI(AUTHORITY, NOW_PLAYING_PATH, NOW_PLAYING);
+ sUriMatcher.addURI(AUTHORITY, PIANO_BASE_PATH, PIANO);
+ sUriMatcher.addURI(AUTHORITY, VOICE_BASE_PATH, VOICE);
+ }
+
+ // Media metadata that will be provided for a media container
+ public static final String[] MEDIA_CONTAINER_PROJECTION = {
+ "uri",
+ "title",
+ "subtitle",
+ "image_uri",
+ "supported_actions"
+ };
+
+ // MusicProvider will download the music catalog
+ private MusicProvider mMusicProvider;
+
+ private MediaSession mSession;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ mSession = new MediaSession(this, "com.example.android.musicservicedemo.BrowserService");
+ setSessionToken(mSession.getSessionToken());
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ }
+
+ @Override
+ protected BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
+ return new BrowserRoot(BROWSE_URI, null);
+ }
+
+ @Override
+ protected List<MediaBrowserItem> onLoadChildren(Uri parentUri) {
+ final ArrayList<MediaBrowserItem> results = new ArrayList();
+
+ for (int i=0; i<10; i++) {
+ results.add(new MediaBrowserItem.Builder(
+ Uri.withAppendedPath(BASE_URI, Integer.toString(i)),
+ MediaBrowserItem.FLAG_BROWSABLE, "Title " + i)
+ .setSummary("Summary " + i)
+ .build());
+ }
+
+ return results;
+ }
+
+ @Override
+ protected Bitmap onGetThumbnail(Uri uri, int width, int height) {
+ return null;
+ }
+
+ /*
+ @Override
+ public void query(final Query query, final IMetadataResultHandler metadataResultHandler,
+ final IErrorHandler errorHandler)
+ throws RemoteException {
+ Log.d(TAG, "query: " + query);
+ Utils.checkNotNull(query);
+ Utils.checkNotNull(metadataResultHandler);
+ Utils.checkNotNull(errorHandler);
+
+ // Handle async response
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ // Pre-load the list of music
+ List<MusicTrack> musicTracks = getMusicList();
+ if (musicTracks == null) {
+ notifyListenersOnPlaybackStateUpdate(getCurrentPlaybackState());
+ errorHandler.onError(new Error(Error.UNKNOWN,
+ getString(R.string.music_error)));
+ return;
+ }
+
+ final Uri uri = query.getUri();
+ int match = sUriMatcher.match(uri);
+ Log.d(TAG, "Queried: " + uri + "; match: " + match);
+ switch (match) {
+ case BROWSE_ROOT:
+ {
+ Log.d(TAG, "Browse_root");
+
+ try {
+ MatrixCursor matrixCursor = mMusicProvider
+ .getRootContainerCurser();
+ DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
+ matrixCursor, null);
+
+ Log.d(TAG, "on metadata response called " + holder.getCount());
+ metadataResultHandler.onMetadataResponse(holder);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error delivering metadata in the callback.", e);
+ }
+ break;
+ }
+ case NOW_PLAYING:
+ {
+ try {
+ Log.d(TAG, "query NOW_PLAYING");
+ MatrixCursor matrixCursor = mMusicProvider
+ .getRootItemCursor(
+ PIANO);
+ DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
+ matrixCursor, null);
+ Log.d(TAG, "on metadata response called " + holder.getCount());
+ metadataResultHandler.onMetadataResponse(holder);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error querying NOW_PLAYING");
+ }
+ break;
+ }
+ case PIANO:
+ {
+ try {
+ Log.d(TAG, "query PIANO");
+ MatrixCursor matrixCursor = mMusicProvider
+ .getRootItemCursor(
+ PIANO);
+ DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
+ matrixCursor, null);
+ Log.d(TAG, "on metadata response called " + holder.getCount());
+ metadataResultHandler.onMetadataResponse(holder);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error querying PIANO");
+ }
+ break;
+ }
+ case VOICE:
+ {
+ try {
+ Log.d(TAG, "query VOICE");
+ MatrixCursor matrixCursor = mMusicProvider
+ .getRootItemCursor(
+ VOICE);
+ DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
+ matrixCursor, null);
+ Log.d(TAG, "on metadata response called " + holder.getCount());
+ metadataResultHandler.onMetadataResponse(holder);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error querying VOICE");
+ }
+ break;
+ }
+ default:
+ {
+ Log.w(TAG, "Skipping unmatched URI: " + uri);
+ }
+ }
+ } catch (NotFoundException e) {
+ Log.e(TAG, "::run:", e);
+ } catch (RemoteException e) {
+ Log.e(TAG, "::run:", e);
+ }
+ } // end run
+ }).start();
+ }
+
+ */
+}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java
new file mode 100644
index 0000000..db45b9d
--- /dev/null
+++ b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java
@@ -0,0 +1,101 @@
+/* Copyright 2014 Google Inc. All Rights Reserved.
+ *
+ * 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.example.android.musicservicedemo;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v7.app.ActionBarActivity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.example.android.musicservicedemo.R;
+
+// TODO Local UI
+
+/**
+ * Main activity of the app.
+ */
+public class MainActivity extends ActionBarActivity {
+
+ private static final String LOG = "MainActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (savedInstanceState == null) {
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.container, new PlaceholderFragment())
+ .commit();
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
+ */
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+
+ // Inflate the menu; this adds items to the action bar if it is present.
+ //getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
+ */
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+ // if (id == R.id.action_settings) {
+ // return true;
+ // }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * A placeholder fragment containing a simple view.
+ */
+ public static class PlaceholderFragment extends Fragment {
+
+ public PlaceholderFragment() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater
+ * , android.view.ViewGroup, android.os.Bundle)
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View rootView = inflater.inflate(R.layout.fragment_main, container, false);
+ return rootView;
+ }
+ }
+
+}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/Utils.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/Utils.java
new file mode 100644
index 0000000..3589761
--- /dev/null
+++ b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/Utils.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * 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.example.android.musicservicedemo;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class Utils {
+
+ private static final String TAG = "Utils";
+
+ /**
+ * Utility method to check that parameters are not null
+ *
+ * @param object
+ */
+ public static final void checkNotNull(Object object) {
+ if (object == null) {
+ throw new NullPointerException();
+ }
+ }
+
+ /**
+ * Utility to download a bitmap
+ *
+ * @param source
+ * @return
+ */
+ public static Bitmap getBitmapFromURL(String source) {
+ try {
+ URL url = new URL(source);
+ HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
+ httpConnection.setDoInput(true);
+ httpConnection.connect();
+ InputStream inputStream = httpConnection.getInputStream();
+ return BitmapFactory.decodeStream(inputStream);
+ } catch (IOException e) {
+ Log.e(TAG, "getBitmapFromUrl: " + source, e);
+ }
+ return null;
+ }
+
+ /**
+ * Utility method to wrap an index
+ *
+ * @param i
+ * @param size
+ * @return
+ */
+ public static int wrapIndex(int i, int size) {
+ int m = i % size;
+ if (m < 0) { // java modulus can be negative
+ m += size;
+ }
+ return m;
+ }
+}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProvider.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProvider.java
new file mode 100644
index 0000000..15038d7
--- /dev/null
+++ b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProvider.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * 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.example.android.musicservicedemo.browser;
+
+import android.database.MatrixCursor;
+import android.media.session.PlaybackState;
+import android.net.Uri;
+import android.util.Log;
+
+import com.example.android.musicservicedemo.BrowserService;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class to get a list of MusicTrack's based on a server-side JSON
+ * configuration.
+ */
+public class MusicProvider {
+
+ private static final String TAG = "MusicProvider";
+
+ private static final String MUSIC_URL = "http://storage.googleapis.com/automotive-media/music.json";
+
+ private static String MUSIC = "music";
+ private static String TITLE = "title";
+ private static String ALBUM = "album";
+ private static String ARTIST = "artist";
+ private static String GENRE = "genre";
+ private static String SOURCE = "source";
+ private static String IMAGE = "image";
+ private static String TRACK_NUMBER = "trackNumber";
+ private static String TOTAL_TRACK_COUNT = "totalTrackCount";
+ private static String DURATION = "duration";
+
+ // Cache for music track data
+ private static List<MusicTrack> mMusicList;
+
+ /**
+ * Get the cached list of music tracks
+ *
+ * @return
+ * @throws JSONException
+ */
+ public List<MusicTrack> getMedia() throws JSONException {
+ if (null != mMusicList && mMusicList.size() > 0) {
+ return mMusicList;
+ }
+ return null;
+ }
+
+ /**
+ * Get the list of music tracks from a server and return the list of
+ * MusicTrack objects.
+ *
+ * @return
+ * @throws JSONException
+ */
+ public List<MusicTrack> retreiveMedia() throws JSONException {
+ if (null != mMusicList) {
+ return mMusicList;
+ }
+ int slashPos = MUSIC_URL.lastIndexOf('/');
+ String path = MUSIC_URL.substring(0, slashPos + 1);
+ JSONObject jsonObj = parseUrl(MUSIC_URL);
+
+ try {
+ JSONArray videos = jsonObj.getJSONArray(MUSIC);
+ if (null != videos) {
+ mMusicList = new ArrayList<MusicTrack>();
+ for (int j = 0; j < videos.length(); j++) {
+ JSONObject music = videos.getJSONObject(j);
+ String title = music.getString(TITLE);
+ String album = music.getString(ALBUM);
+ String artist = music.getString(ARTIST);
+ String genre = music.getString(GENRE);
+ String source = music.getString(SOURCE);
+ // Media is stored relative to JSON file
+ if (!source.startsWith("http")) {
+ source = path + source;
+ }
+ String image = music.getString(IMAGE);
+ if (!image.startsWith("http")) {
+ image = path + image;
+ }
+ int trackNumber = music.getInt(TRACK_NUMBER);
+ int totalTrackCount = music.getInt(TOTAL_TRACK_COUNT);
+ int duration = music.getInt(DURATION) * 1000; // ms
+
+ mMusicList.add(new MusicTrack(title, album, artist, genre, source,
+ image, trackNumber, totalTrackCount, duration));
+ }
+ }
+ } catch (NullPointerException e) {
+ Log.e(TAG, "retreiveMedia", e);
+ }
+ return mMusicList;
+ }
+
+ /**
+ * Download a JSON file from a server, parse the content and return the JSON
+ * object.
+ *
+ * @param urlString
+ * @return
+ */
+ private JSONObject parseUrl(String urlString) {
+ InputStream is = null;
+ try {
+ java.net.URL url = new java.net.URL(urlString);
+ URLConnection urlConnection = url.openConnection();
+ is = new BufferedInputStream(urlConnection.getInputStream());
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ urlConnection.getInputStream(), "iso-8859-1"), 8);
+ StringBuilder sb = new StringBuilder();
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+ return new JSONObject(sb.toString());
+ } catch (Exception e) {
+ Log.d(TAG, "Failed to parse the json for media list", e);
+ return null;
+ } finally {
+ if (null != is) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ public MatrixCursor getRootContainerCurser() {
+ MatrixCursor matrixCursor = new MatrixCursor(BrowserService.MEDIA_CONTAINER_PROJECTION);
+ Uri.Builder pianoBuilder = new Uri.Builder();
+ pianoBuilder.authority(BrowserService.AUTHORITY);
+ pianoBuilder.appendPath(BrowserService.PIANO_BASE_PATH);
+ matrixCursor.addRow(new Object[] {
+ pianoBuilder.build(),
+ BrowserService.PIANO_BASE_PATH,
+ "subtitle",
+ null,
+ 0
+ });
+
+ Uri.Builder voiceBuilder = new Uri.Builder();
+ voiceBuilder.authority(BrowserService.AUTHORITY);
+ voiceBuilder.appendPath(BrowserService.VOICE_BASE_PATH);
+ matrixCursor.addRow(new Object[] {
+ voiceBuilder.build(),
+ BrowserService.VOICE_BASE_PATH,
+ "subtitle",
+ null,
+ 0
+ });
+ return matrixCursor;
+ }
+
+ public MatrixCursor getRootItemCursor(int type) {
+ if (type == BrowserService.NOW_PLAYING) {
+ MatrixCursor matrixCursor = new MatrixCursor(BrowserService.MEDIA_CONTAINER_PROJECTION);
+
+ try {
+ // Just return all of the tracks for now
+ List<MusicTrack> musicTracks = retreiveMedia();
+ for (MusicTrack musicTrack : musicTracks) {
+ Uri.Builder builder = new Uri.Builder();
+ builder.authority(BrowserService.AUTHORITY);
+ builder.appendPath(BrowserService.NOW_PLAYING_PATH);
+ builder.appendPath(musicTrack.getTitle());
+ matrixCursor.addRow(new Object[] {
+ builder.build(),
+ musicTrack.getTitle(),
+ musicTrack.getArtist(),
+ musicTrack.getImage(),
+ PlaybackState.ACTION_PLAY
+ });
+ Log.d(TAG, "Uri " + builder.build());
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, "::getRootItemCursor:", e);
+ }
+
+ Log.d(TAG, "cursor: " + matrixCursor.getCount());
+ return matrixCursor;
+ } else if (type == BrowserService.PIANO) {
+ MatrixCursor matrixCursor = new MatrixCursor(BrowserService.MEDIA_CONTAINER_PROJECTION);
+
+ try {
+ List<MusicTrack> musicTracks = retreiveMedia();
+ for (MusicTrack musicTrack : musicTracks) {
+ Uri.Builder builder = new Uri.Builder();
+ builder.authority(BrowserService.AUTHORITY);
+ builder.appendPath(BrowserService.PIANO_BASE_PATH);
+ builder.appendPath(musicTrack.getTitle());
+ matrixCursor.addRow(new Object[] {
+ builder.build(),
+ musicTrack.getTitle(),
+ musicTrack.getArtist(),
+ musicTrack.getImage(),
+ PlaybackState.ACTION_PLAY
+ });
+ Log.d(TAG, "Uri " + builder.build());
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, "::getRootItemCursor:", e);
+ }
+
+ Log.d(TAG, "cursor: " + matrixCursor.getCount());
+ return matrixCursor;
+ } else if (type == BrowserService.VOICE) {
+ MatrixCursor matrixCursor = new MatrixCursor(BrowserService.MEDIA_CONTAINER_PROJECTION);
+
+ try {
+ List<MusicTrack> musicTracks = retreiveMedia();
+ for (MusicTrack musicTrack : musicTracks) {
+ Uri.Builder builder = new Uri.Builder();
+ builder.authority(BrowserService.AUTHORITY);
+ builder.appendPath(BrowserService.VOICE_BASE_PATH);
+ builder.appendPath(musicTrack.getTitle());
+ matrixCursor.addRow(new Object[] {
+ builder.build(),
+ musicTrack.getTitle(),
+ musicTrack.getArtist(),
+ musicTrack.getImage(),
+ PlaybackState.ACTION_PLAY
+ });
+ Log.d(TAG, "Uri " + builder.build());
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, "::getRootItemCursor:", e);
+ }
+
+ Log.d(TAG, "cursor: " + matrixCursor.getCount());
+ return matrixCursor;
+
+ }
+ return null;
+ }
+}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTask.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTask.java
new file mode 100644
index 0000000..ffda110
--- /dev/null
+++ b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTask.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.musicservicedemo.browser;
+
+import android.os.AsyncTask;
+import android.util.Log;
+
+import org.json.JSONException;
+
+/**
+ * Asynchronous task to retrieve the music data using MusicProvider.
+ */
+public class MusicProviderTask extends AsyncTask<Void, Void, Void> {
+
+ private static final String TAG = "MusicProviderTask";
+
+ MusicProvider mMusicProvider;
+ MusicProviderTaskListener mMusicProviderTaskListener;
+
+ /**
+ * Initialize the task with the provider to download the music data and the
+ * listener to be informed when the task is done.
+ *
+ * @param musicProvider
+ * @param listener
+ */
+ public MusicProviderTask(MusicProvider musicProvider,
+ MusicProviderTaskListener listener) {
+ mMusicProvider = musicProvider;
+ mMusicProviderTaskListener = listener;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see android.os.AsyncTask#doInBackground(java.lang.Object[])
+ */
+ @Override
+ protected Void doInBackground(Void... arg0) {
+ try {
+ mMusicProvider.retreiveMedia();
+ } catch (JSONException e) {
+ Log.e(TAG, "::doInBackground:", e);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
+ */
+ @Override
+ protected void onPostExecute(Void result) {
+ mMusicProviderTaskListener.onMusicProviderTaskCompleted();
+ }
+
+}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTaskListener.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTaskListener.java
new file mode 100644
index 0000000..b1d168f
--- /dev/null
+++ b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTaskListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * 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.example.android.musicservicedemo.browser;
+
+/**
+ * Callback listener for completion of MusicProviderTask
+ */
+public interface MusicProviderTaskListener {
+ public void onMusicProviderTaskCompleted();
+}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicTrack.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicTrack.java
new file mode 100644
index 0000000..02ea899
--- /dev/null
+++ b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicTrack.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * 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.example.android.musicservicedemo.browser;
+
+/**
+ * A class to model music track metadata.
+ */
+public class MusicTrack {
+
+ private static final String TAG = "MusicTrack";
+
+ private String mTitle;
+ private String mAlbum;
+ private String mArtist;
+ private String mGenre;
+ private String mSource;
+ private String mImage;
+ private int mTrackNumber;
+ private int mTotalTrackCount;
+ private int mDuration;
+
+ /**
+ * Constructor creating a MusicTrack instance.
+ *
+ * @param title
+ * @param album
+ * @param artist
+ * @param genre
+ * @param source
+ * @param image
+ * @param trackNumber
+ * @param totalTrackCount
+ * @param duration
+ */
+ public MusicTrack(String title, String album, String artist, String genre, String source,
+ String image, int trackNumber, int totalTrackCount, int duration) {
+ this.mTitle = title;
+ this.mAlbum = album;
+ this.mArtist = artist;
+ this.mGenre = genre;
+ this.mSource = source;
+ this.mImage = image;
+ this.mTrackNumber = trackNumber;
+ this.mTotalTrackCount = totalTrackCount;
+ this.mDuration = duration;
+ }
+
+ public String getTitle() {
+ return mTitle;
+ }
+
+ public void setTitle(String mTitle) {
+ this.mTitle = mTitle;
+ }
+
+ public String getAlbum() {
+ return mAlbum;
+ }
+
+ public void setAlbum(String mAlbum) {
+ this.mAlbum = mAlbum;
+ }
+
+ public String getArtist() {
+ return mArtist;
+ }
+
+ public void setArtist(String mArtist) {
+ this.mArtist = mArtist;
+ }
+
+ public String getGenre() {
+ return mGenre;
+ }
+
+ public void setGenre(String mGenre) {
+ this.mGenre = mGenre;
+ }
+
+ public String getSource() {
+ return mSource;
+ }
+
+ public void setSource(String mSource) {
+ this.mSource = mSource;
+ }
+
+ public String getImage() {
+ return mImage;
+ }
+
+ public void setImage(String mImage) {
+ this.mImage = mImage;
+ }
+
+ public int getTrackNumber() {
+ return mTrackNumber;
+ }
+
+ public void setTrackNumber(int mTrackNumber) {
+ this.mTrackNumber = mTrackNumber;
+ }
+
+ public int getTotalTrackCount() {
+ return mTotalTrackCount;
+ }
+
+ public void setTotalTrackCount(int mTotalTrackCount) {
+ this.mTotalTrackCount = mTotalTrackCount;
+ }
+
+ public int getDuration() {
+ return mDuration;
+ }
+
+ public void setDuration(int mDuration) {
+ this.mDuration = mDuration;
+ }
+
+ public String toString() {
+ return mTitle;
+ }
+
+}
diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml
index 33f000d..c328b3c 100644
--- a/tests/VoiceInteraction/AndroidManifest.xml
+++ b/tests/VoiceInteraction/AndroidManifest.xml
@@ -1,6 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.test.voiceinteraction">
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+
<application>
<activity android:name="VoiceInteractionMain" android:label="Voice Interaction"
android:theme="@android:style/Theme.Material">
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index e74307f..cc710f9 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -30,6 +30,12 @@
private final Callback mHotwordCallback = new Callback() {
@Override
+ public void onAvailabilityChanged(int status) {
+ Log.i(TAG, "onAvailabilityChanged(" + status + ")");
+ hotwordAvailabilityChangeHelper(status);
+ }
+
+ @Override
public void onDetected(byte[] data) {
Log.i(TAG, "onDetected");
}
@@ -50,30 +56,7 @@
Log.i(TAG, "Keyphrase enrollment meta-data: "
+ Arrays.toString(getKeyphraseEnrollmentInfo().listKeyphraseMetadata()));
- mHotwordDetector = getAlwaysOnHotwordDetector("Hello There", "en-US", mHotwordCallback);
- int availability = mHotwordDetector.getAvailability();
- Log.i(TAG, "Hotword availability = " + availability);
-
- switch (availability) {
- case AlwaysOnHotwordDetector.KEYPHRASE_HARDWARE_UNAVAILABLE:
- Log.i(TAG, "KEYPHRASE_HARDWARE_UNAVAILABLE");
- break;
- case AlwaysOnHotwordDetector.KEYPHRASE_UNSUPPORTED:
- Log.i(TAG, "KEYPHRASE_UNSUPPORTED");
- break;
- case AlwaysOnHotwordDetector.KEYPHRASE_UNENROLLED:
- Log.i(TAG, "KEYPHRASE_UNENROLLED");
- Intent enroll = mHotwordDetector.getManageIntent(
- AlwaysOnHotwordDetector.MANAGE_ACTION_ENROLL);
- Log.i(TAG, "Need to enroll with " + enroll);
- break;
- case AlwaysOnHotwordDetector.KEYPHRASE_ENROLLED:
- Log.i(TAG, "KEYPHRASE_ENROLLED");
- int status = mHotwordDetector.startRecognition(
- AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE);
- Log.i(TAG, "startRecognition status = " + status);
- break;
- }
+ mHotwordDetector = createAlwaysOnHotwordDetector("Hello There", "en-US", mHotwordCallback);
}
@Override
@@ -84,4 +67,33 @@
stopSelf(startId);
return START_NOT_STICKY;
}
+
+ private void hotwordAvailabilityChangeHelper(int availability) {
+ Log.i(TAG, "Hotword availability = " + availability);
+ switch (availability) {
+ case AlwaysOnHotwordDetector.STATE_INVALID:
+ Log.i(TAG, "STATE_INVALID");
+ mHotwordDetector =
+ createAlwaysOnHotwordDetector("Hello There", "en-US", mHotwordCallback);
+ break;
+ case AlwaysOnHotwordDetector.STATE_HARDWARE_UNAVAILABLE:
+ Log.i(TAG, "STATE_HARDWARE_UNAVAILABLE");
+ break;
+ case AlwaysOnHotwordDetector.STATE_KEYPHRASE_UNSUPPORTED:
+ Log.i(TAG, "STATE_KEYPHRASE_UNSUPPORTED");
+ break;
+ case AlwaysOnHotwordDetector.STATE_KEYPHRASE_UNENROLLED:
+ Log.i(TAG, "STATE_KEYPHRASE_UNENROLLED");
+ Intent enroll = mHotwordDetector.getManageIntent(
+ AlwaysOnHotwordDetector.MANAGE_ACTION_ENROLL);
+ Log.i(TAG, "Need to enroll with " + enroll);
+ break;
+ case AlwaysOnHotwordDetector.STATE_KEYPHRASE_ENROLLED:
+ Log.i(TAG, "STATE_KEYPHRASE_ENROLLED");
+ int status = mHotwordDetector.startRecognition(
+ AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE);
+ Log.i(TAG, "startRecognition status = " + status);
+ break;
+ }
+ }
}
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
index ead3b13..9300401 100644
--- a/tools/layoutlib/Android.mk
+++ b/tools/layoutlib/Android.mk
@@ -27,8 +27,8 @@
# We need to process the framework classes.jar file, but we can't
# depend directly on it (private vars won't be inherited correctly).
# So, we depend on framework's BUILT file.
-built_framework_dep := $(call java-lib-deps,framework-base)
-built_framework_classes := $(call java-lib-files,framework-base)
+built_framework_dep := $(call java-lib-deps,framework)
+built_framework_classes := $(call java-lib-files,framework)
built_core_dep := $(call java-lib-deps,core-libart)
built_core_classes := $(call java-lib-files,core-libart)
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index 7153a90..776398f 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -608,6 +608,9 @@
* @param y The y-coordinate of the end of a line
*/
private void lineTo(float x, float y) {
+ if (isEmpty()) {
+ mPath.moveTo(mLastX = 0, mLastY = 0);
+ }
mPath.lineTo(mLastX = x, mLastY = y);
}