Merge "Fixed SSB. Correct broadcast of removed spans' positions"
diff --git a/Android.mk b/Android.mk
index 3b2d32d..a98b1c2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -61,6 +61,7 @@
LOCAL_SRC_FILES += \
core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
+ core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl \
core/java/android/accounts/IAccountManager.aidl \
core/java/android/accounts/IAccountManagerResponse.aidl \
core/java/android/accounts/IAccountAuthenticator.aidl \
diff --git a/api/current.txt b/api/current.txt
index 7698924..2025aa7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -294,6 +294,7 @@
field public static final int cacheColorHint = 16843009; // 0x1010101
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
+ field public static final int canHandleGestures = 16843699; // 0x10103b3
field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
field public static final deprecated int capitalize = 16843113; // 0x1010169
@@ -1993,23 +1994,39 @@
public abstract class AccessibilityService extends android.app.Service {
ctor public AccessibilityService();
+ method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
method public abstract void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
method public final android.os.IBinder onBind(android.content.Intent);
- method protected void onGesture(int);
+ method protected boolean onGesture(int);
method public abstract void onInterrupt();
method protected void onServiceConnected();
+ method public final boolean performGlobalAction(int);
method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
field public static final int GESTURE_CLOCKWISE_CIRCLE = 9; // 0x9
field public static final int GESTURE_COUNTER_CLOCKWISE_CIRCLE = 10; // 0xa
field public static final int GESTURE_SWIPE_DOWN = 2; // 0x2
+ field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 17; // 0x11
+ field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18; // 0x12
field public static final int GESTURE_SWIPE_DOWN_AND_UP = 8; // 0x8
field public static final int GESTURE_SWIPE_LEFT = 3; // 0x3
+ field public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 12; // 0xc
field public static final int GESTURE_SWIPE_LEFT_AND_RIGHT = 5; // 0x5
+ field public static final int GESTURE_SWIPE_LEFT_AND_UP = 11; // 0xb
field public static final int GESTURE_SWIPE_RIGHT = 4; // 0x4
+ field public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 14; // 0xe
field public static final int GESTURE_SWIPE_RIGHT_AND_LEFT = 6; // 0x6
+ field public static final int GESTURE_SWIPE_RIGHT_AND_UP = 13; // 0xd
field public static final int GESTURE_SWIPE_UP = 1; // 0x1
field public static final int GESTURE_SWIPE_UP_AND_DOWN = 7; // 0x7
+ field public static final int GESTURE_SWIPE_UP_AND_LEFT = 15; // 0xf
+ field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 16; // 0x10
+ field public static final int GESTURE_TWO_FINGER_LONG_PRESS = 20; // 0x14
+ field public static final int GESTURE_TWO_FINGER_TAP = 19; // 0x13
+ field public static final int GLOBAL_ACTION_BACK = 1; // 0x1
+ field public static final int GLOBAL_ACTION_HOME = 2; // 0x2
+ field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4
+ field public static final int GLOBAL_ACTION_RECENTS = 3; // 0x3
field public static final java.lang.String SERVICE_INTERFACE = "android.accessibilityservice.AccessibilityService";
field public static final java.lang.String SERVICE_META_DATA = "android.accessibilityservice";
}
@@ -2019,6 +2036,7 @@
method public int describeContents();
method public static java.lang.String feedbackTypeToString(int);
method public static java.lang.String flagToString(int);
+ method public boolean getCanHandleGestures();
method public boolean getCanRetrieveWindowContent();
method public deprecated java.lang.String getDescription();
method public java.lang.String getId();
@@ -3754,7 +3772,6 @@
method public android.app.Notification.Builder setDefaults(int);
method public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent);
method public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
- method public android.app.Notification.Builder setIntruderActionsShowText(boolean);
method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
method public android.app.Notification.Builder setLights(int, int, int);
method public android.app.Notification.Builder setNumber(int);
@@ -3770,11 +3787,16 @@
method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
method public android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
method public android.app.Notification.Builder setUsesChronometer(boolean);
- method public android.app.Notification.Builder setUsesIntruderAlert(boolean);
method public android.app.Notification.Builder setVibrate(long[]);
method public android.app.Notification.Builder setWhen(long);
}
+ public static class Notification.InboxStyle {
+ ctor public Notification.InboxStyle(android.app.Notification.Builder);
+ method public android.app.Notification.InboxStyle addLine(java.lang.CharSequence);
+ method public android.app.Notification build();
+ }
+
public class NotificationManager {
method public void cancel(int);
method public void cancel(java.lang.String, int);
@@ -3977,6 +3999,7 @@
method public android.app.TaskStackBuilder addNextIntent(android.content.Intent);
method public android.app.TaskStackBuilder addParentStack(android.app.Activity);
method public android.app.TaskStackBuilder addParentStack(java.lang.Class<?>);
+ method public android.app.TaskStackBuilder addParentStack(android.content.ComponentName);
method public static android.app.TaskStackBuilder from(android.content.Context);
method public android.content.Intent getIntent(int);
method public int getIntentCount();
@@ -4051,10 +4074,12 @@
method public void setWallpaperOffsetSteps(float, float);
method public void setWallpaperOffsets(android.os.IBinder, float, float);
method public void suggestDesiredDimensions(int, int);
+ field public static final java.lang.String ACTION_CHANGE_LIVE_WALLPAPER = "android.service.wallpaper.CHANGE_LIVE_WALLPAPER";
field public static final java.lang.String ACTION_LIVE_WALLPAPER_CHOOSER = "android.service.wallpaper.LIVE_WALLPAPER_CHOOSER";
field public static final java.lang.String COMMAND_DROP = "android.home.drop";
field public static final java.lang.String COMMAND_SECONDARY_TAP = "android.wallpaper.secondaryTap";
field public static final java.lang.String COMMAND_TAP = "android.wallpaper.tap";
+ field public static final java.lang.String EXTRA_LIVE_WALLPAPER_COMPONENT = "android.service.wallpaper.extra.LIVE_WALLPAPER_COMPONENT";
field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
}
@@ -4283,10 +4308,13 @@
method protected void prepareView(android.view.View);
method public void setAppWidget(int, android.appwidget.AppWidgetProviderInfo);
method public void updateAppWidget(android.widget.RemoteViews);
+ method public void updateAppWidgetExtras(android.os.Bundle);
+ method public void updateAppWidgetSize(android.os.Bundle, int, int, int, int);
}
public class AppWidgetManager {
method public void bindAppWidgetId(int, android.content.ComponentName);
+ method public android.os.Bundle getAppWidgetExtras(int);
method public int[] getAppWidgetIds(android.content.ComponentName);
method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo(int);
method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProviders();
@@ -4298,14 +4326,21 @@
method public void updateAppWidget(int[], android.widget.RemoteViews);
method public void updateAppWidget(int, android.widget.RemoteViews);
method public void updateAppWidget(android.content.ComponentName, android.widget.RemoteViews);
+ method public void updateAppWidgetExtras(int, android.os.Bundle);
field public static final java.lang.String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE";
field public static final java.lang.String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
field public static final java.lang.String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
field public static final java.lang.String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
+ field public static final java.lang.String ACTION_APPWIDGET_EXTRAS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_EXTRAS";
field public static final java.lang.String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
field public static final java.lang.String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
+ field public static final java.lang.String EXTRA_APPWIDGET_EXTRAS = "appWidgetExtras";
field public static final java.lang.String EXTRA_APPWIDGET_ID = "appWidgetId";
field public static final java.lang.String EXTRA_APPWIDGET_IDS = "appWidgetIds";
+ field public static final java.lang.String EXTRA_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight";
+ field public static final java.lang.String EXTRA_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth";
+ field public static final java.lang.String EXTRA_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight";
+ field public static final java.lang.String EXTRA_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth";
field public static final java.lang.String EXTRA_CUSTOM_EXTRAS = "customExtras";
field public static final java.lang.String EXTRA_CUSTOM_INFO = "customInfo";
field public static final int INVALID_APPWIDGET_ID = 0; // 0x0
@@ -4314,6 +4349,7 @@
public class AppWidgetProvider extends android.content.BroadcastReceiver {
ctor public AppWidgetProvider();
+ method public void onAppWidgetExtrasChanged(android.content.Context, android.appwidget.AppWidgetManager, int, android.os.Bundle);
method public void onDeleted(android.content.Context, int[]);
method public void onDisabled(android.content.Context);
method public void onEnabled(android.content.Context);
@@ -10706,6 +10742,7 @@
public class AudioRecord {
ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
method public int getAudioFormat();
+ method public int getAudioSessionId();
method public int getAudioSource();
method public int getChannelConfiguration();
method public int getChannelCount();
@@ -10724,6 +10761,7 @@
method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener);
method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener, android.os.Handler);
method public void startRecording() throws java.lang.IllegalStateException;
+ method public void startRecording(android.media.MediaSyncEvent) throws java.lang.IllegalStateException;
method public void stop() throws java.lang.IllegalStateException;
field public static final int ERROR = -1; // 0xffffffff
field public static final int ERROR_BAD_VALUE = -2; // 0xfffffffe
@@ -10953,8 +10991,8 @@
method public java.nio.ByteBuffer[] getInputBuffers();
method public java.nio.ByteBuffer[] getOutputBuffers();
method public final java.util.Map<java.lang.String, java.lang.Object> getOutputFormat();
- method public final void queueInputBuffer(int, int, int, long, int);
- method public final void queueSecureInputBuffer(int, int, int[], int[], int, byte[], byte[], int, long, int);
+ method public final void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException;
+ method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException;
method public final void release();
method public final void releaseOutputBuffer(int, boolean);
method public final void start();
@@ -10979,6 +11017,22 @@
field public int size;
}
+ public static final class MediaCodec.CryptoException extends java.lang.RuntimeException {
+ ctor public MediaCodec.CryptoException(int, java.lang.String);
+ method public int getErrorCode();
+ }
+
+ public static final class MediaCodec.CryptoInfo {
+ ctor public MediaCodec.CryptoInfo();
+ method public void set(int, int[], int[], byte[], byte[], int);
+ field public byte[] iv;
+ field public byte[] key;
+ field public int mode;
+ field public int[] numBytesOfClearData;
+ field public int[] numBytesOfEncryptedData;
+ field public int numSubSamples;
+ }
+
public final class MediaCodecList {
method public static final int countCodecs();
method public static final android.media.MediaCodecList.CodecCapabilities getCodecCapabilities(int, java.lang.String);
@@ -11010,10 +11064,13 @@
ctor public MediaExtractor();
method public boolean advance();
method public int countTracks();
+ method public long getCachedDuration();
+ method public boolean getSampleCryptoInfo(android.media.MediaCodec.CryptoInfo);
method public int getSampleFlags();
method public long getSampleTime();
method public int getSampleTrackIndex();
method public java.util.Map<java.lang.String, java.lang.Object> getTrackFormat(int);
+ method public boolean hasCacheReachedEndOfStream();
method public int readSampleData(java.nio.ByteBuffer, int);
method public final void release();
method public void seekTo(long);
@@ -11257,6 +11314,15 @@
method public abstract void onScanCompleted(java.lang.String, android.net.Uri);
}
+ public class MediaSyncEvent {
+ method public static android.media.MediaSyncEvent createEvent(int) throws java.lang.IllegalArgumentException;
+ method public int getAudioSessionId();
+ method public int getType();
+ method public android.media.MediaSyncEvent setAudioSessionId(int) throws java.lang.IllegalArgumentException;
+ field public static final int SYNC_EVENT_NONE = 0; // 0x0
+ field public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1; // 0x1
+ }
+
public class RemoteControlClient {
ctor public RemoteControlClient(android.app.PendingIntent);
ctor public RemoteControlClient(android.app.PendingIntent, android.os.Looper);
@@ -11374,6 +11440,7 @@
public class ToneGenerator {
ctor public ToneGenerator(int, int);
+ method public final int getAudioSessionId();
method public void release();
method public boolean startTone(int);
method public boolean startTone(int, int);
@@ -11485,6 +11552,11 @@
package android.media.audiofx {
+ public class AcousticEchoCanceler extends android.media.audiofx.AudioEffect {
+ method public static android.media.audiofx.AcousticEchoCanceler create(int);
+ method public static boolean isAvailable();
+ }
+
public class AudioEffect {
method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
method public boolean getEnabled() throws java.lang.IllegalStateException;
@@ -11535,6 +11607,11 @@
method public abstract void onEnableStatusChange(android.media.audiofx.AudioEffect, boolean);
}
+ public class AutomaticGainControl extends android.media.audiofx.AudioEffect {
+ method public static android.media.audiofx.AutomaticGainControl create(int);
+ method public static boolean isAvailable();
+ }
+
public class BassBoost extends android.media.audiofx.AudioEffect {
ctor public BassBoost(int, int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.RuntimeException, java.lang.UnsupportedOperationException;
method public android.media.audiofx.BassBoost.Settings getProperties() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
@@ -11653,6 +11730,11 @@
field public short numBands;
}
+ public class NoiseSuppressor extends android.media.audiofx.AudioEffect {
+ method public static android.media.audiofx.NoiseSuppressor create(int);
+ method public static boolean isAvailable();
+ }
+
public class PresetReverb extends android.media.audiofx.AudioEffect {
ctor public PresetReverb(int, int) throws java.lang.IllegalArgumentException, java.lang.RuntimeException, java.lang.UnsupportedOperationException;
method public short getPreset() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
@@ -11710,11 +11792,13 @@
method public int getFft(byte[]) throws java.lang.IllegalStateException;
method public static int getMaxCaptureRate();
method public int getSamplingRate() throws java.lang.IllegalStateException;
+ method public int getScalingMode() throws java.lang.IllegalStateException;
method public int getWaveForm(byte[]) throws java.lang.IllegalStateException;
method public void release();
method public int setCaptureSize(int) throws java.lang.IllegalStateException;
method public int setDataCaptureListener(android.media.audiofx.Visualizer.OnDataCaptureListener, int, boolean, boolean);
method public int setEnabled(boolean) throws java.lang.IllegalStateException;
+ method public int setScalingMode(int) throws java.lang.IllegalStateException;
field public static final int ALREADY_EXISTS = -2; // 0xfffffffe
field public static final int ERROR = -1; // 0xffffffff
field public static final int ERROR_BAD_VALUE = -4; // 0xfffffffc
@@ -11722,6 +11806,8 @@
field public static final int ERROR_INVALID_OPERATION = -5; // 0xfffffffb
field public static final int ERROR_NO_INIT = -3; // 0xfffffffd
field public static final int ERROR_NO_MEMORY = -6; // 0xfffffffa
+ field public static final int SCALING_MODE_AS_PLAYED = 1; // 0x1
+ field public static final int SCALING_MODE_NORMALIZED = 0; // 0x0
field public static final int STATE_ENABLED = 2; // 0x2
field public static final int STATE_INITIALIZED = 1; // 0x1
field public static final int STATE_UNINITIALIZED = 0; // 0x0
@@ -12439,10 +12525,14 @@
method public void resolveService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, android.net.nsd.NsdManager.DnsSdResolveListener);
method public void stopServiceDiscovery(android.net.nsd.NsdManager.Channel, android.net.nsd.NsdManager.ActionListener);
method public void unregisterService(android.net.nsd.NsdManager.Channel, int, android.net.nsd.NsdManager.ActionListener);
+ field public static final java.lang.String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
field public static final int ALREADY_ACTIVE = 3; // 0x3
field public static final int BUSY = 2; // 0x2
field public static final int ERROR = 0; // 0x0
+ field public static final java.lang.String EXTRA_NSD_STATE = "nsd_state";
field public static final int MAX_REGS_REACHED = 4; // 0x4
+ field public static final int NSD_STATE_DISABLED = 1; // 0x1
+ field public static final int NSD_STATE_ENABLED = 2; // 0x2
field public static final int UNSUPPORTED = 1; // 0x1
}
@@ -13011,6 +13101,7 @@
field public static final java.lang.String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
field public static final java.lang.String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_p2p_state";
+ field public static final int NO_SERVICE_REQUESTS = 3; // 0x3
field public static final int P2P_UNSUPPORTED = 1; // 0x1
field public static final java.lang.String WIFI_P2P_CONNECTION_CHANGED_ACTION = "android.net.wifi.p2p.CONNECTION_STATE_CHANGE";
field public static final java.lang.String WIFI_P2P_DISCOVERY_CHANGED_ACTION = "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE";
@@ -16250,9 +16341,11 @@
public final class CalendarContract {
field public static final java.lang.String ACCOUNT_TYPE_LOCAL = "LOCAL";
field public static final java.lang.String ACTION_EVENT_REMINDER = "android.intent.action.EVENT_REMINDER";
+ field public static final java.lang.String ACTION_HANDLE_CUSTOM_EVENT = "android.provider.calendar.action.HANDLE_CUSTOM_EVENT";
field public static final java.lang.String AUTHORITY = "com.android.calendar";
field public static final java.lang.String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String EXTRA_CUSTOM_APP_URI = "customAppUri";
field public static final java.lang.String EXTRA_EVENT_ALL_DAY = "allDay";
field public static final java.lang.String EXTRA_EVENT_BEGIN_TIME = "beginTime";
field public static final java.lang.String EXTRA_EVENT_END_TIME = "endTime";
@@ -16265,6 +16358,8 @@
protected static abstract interface CalendarContract.AttendeesColumns {
field public static final java.lang.String ATTENDEE_EMAIL = "attendeeEmail";
+ field public static final java.lang.String ATTENDEE_IDENTITY = "attendeeIdentity";
+ field public static final java.lang.String ATTENDEE_ID_NAMESPACE = "attendeeIdNamespace";
field public static final java.lang.String ATTENDEE_NAME = "attendeeName";
field public static final java.lang.String ATTENDEE_RELATIONSHIP = "attendeeRelationship";
field public static final java.lang.String ATTENDEE_STATUS = "attendeeStatus";
@@ -16412,6 +16507,8 @@
field public static final int AVAILABILITY_TENTATIVE = 2; // 0x2
field public static final java.lang.String CALENDAR_ID = "calendar_id";
field public static final java.lang.String CAN_INVITE_OTHERS = "canInviteOthers";
+ field public static final java.lang.String CUSTOM_APP_PACKAGE = "customAppPackage";
+ field public static final java.lang.String CUSTOM_APP_URI = "customAppUri";
field public static final java.lang.String DESCRIPTION = "description";
field public static final java.lang.String DISPLAY_COLOR = "displayColor";
field public static final java.lang.String DTEND = "dtend";
@@ -17811,9 +17908,11 @@
field public static final java.lang.String DATE_ADDED = "date_added";
field public static final java.lang.String DATE_MODIFIED = "date_modified";
field public static final java.lang.String DISPLAY_NAME = "_display_name";
+ field public static final java.lang.String HEIGHT = "height";
field public static final java.lang.String MIME_TYPE = "mime_type";
field public static final java.lang.String SIZE = "_size";
field public static final java.lang.String TITLE = "title";
+ field public static final java.lang.String WIDTH = "width";
}
public static final class MediaStore.Video {
@@ -18246,104 +18345,95 @@
package android.renderscript {
- public class Allocation extends android.renderscript.BaseObj {
- method public void copy1DRangeFrom(int, int, int[]);
- method public void copy1DRangeFrom(int, int, short[]);
- method public void copy1DRangeFrom(int, int, byte[]);
- method public void copy1DRangeFrom(int, int, float[]);
- method public void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
- method public void copy1DRangeFromUnchecked(int, int, int[]);
- method public void copy1DRangeFromUnchecked(int, int, short[]);
- method public void copy1DRangeFromUnchecked(int, int, byte[]);
- method public void copy1DRangeFromUnchecked(int, int, float[]);
- method public void copy2DRangeFrom(int, int, int, int, byte[]);
- method public void copy2DRangeFrom(int, int, int, int, short[]);
- method public void copy2DRangeFrom(int, int, int, int, int[]);
- method public void copy2DRangeFrom(int, int, int, int, float[]);
- method public void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
- method public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
- method public void copyFrom(android.renderscript.BaseObj[]);
- method public void copyFrom(int[]);
- method public void copyFrom(short[]);
- method public void copyFrom(byte[]);
- method public void copyFrom(float[]);
- method public void copyFrom(android.graphics.Bitmap);
- method public void copyFromUnchecked(int[]);
- method public void copyFromUnchecked(short[]);
- method public void copyFromUnchecked(byte[]);
- method public void copyFromUnchecked(float[]);
- method public void copyTo(android.graphics.Bitmap);
- method public void copyTo(byte[]);
- method public void copyTo(short[]);
- method public void copyTo(int[]);
- method public void copyTo(float[]);
- method public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
- method public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap);
- method public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
- method public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int);
- method public static android.renderscript.Allocation createFromString(android.renderscript.RenderScript, java.lang.String, int);
- method public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int, int);
- method public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int);
- method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, int);
- method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type);
- method public void generateMipmaps();
- method public int getBytesSize();
- method public android.renderscript.Element getElement();
- method public android.view.Surface getSurface();
- method public android.renderscript.Type getType();
- method public int getUsage();
- method public void ioReceive();
- method public void ioSend();
- method public synchronized void resize(int);
- method public void setFromFieldPacker(int, android.renderscript.FieldPacker);
- method public void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
- method public void setSurface(android.view.Surface);
- method public void syncAll(int);
- field public static final int USAGE_GRAPHICS_CONSTANTS = 8; // 0x8
- field public static final int USAGE_GRAPHICS_RENDER_TARGET = 16; // 0x10
- field public static final int USAGE_GRAPHICS_TEXTURE = 2; // 0x2
- field public static final int USAGE_GRAPHICS_VERTEX = 4; // 0x4
- field public static final int USAGE_IO_INPUT = 32; // 0x20
- field public static final int USAGE_IO_OUTPUT = 64; // 0x40
- field public static final int USAGE_SCRIPT = 1; // 0x1
+ public deprecated class Allocation extends android.renderscript.BaseObj {
+ method public deprecated void copy1DRangeFrom(int, int, int[]);
+ method public deprecated void copy1DRangeFrom(int, int, short[]);
+ method public deprecated void copy1DRangeFrom(int, int, byte[]);
+ method public deprecated void copy1DRangeFrom(int, int, float[]);
+ method public deprecated void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
+ method public deprecated void copy1DRangeFromUnchecked(int, int, int[]);
+ method public deprecated void copy1DRangeFromUnchecked(int, int, short[]);
+ method public deprecated void copy1DRangeFromUnchecked(int, int, byte[]);
+ method public deprecated void copy1DRangeFromUnchecked(int, int, float[]);
+ method public deprecated void copy2DRangeFrom(int, int, int, int, byte[]);
+ method public deprecated void copy2DRangeFrom(int, int, int, int, short[]);
+ method public deprecated void copy2DRangeFrom(int, int, int, int, int[]);
+ method public deprecated void copy2DRangeFrom(int, int, int, int, float[]);
+ method public deprecated void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
+ method public deprecated void copy2DRangeFrom(int, int, android.graphics.Bitmap);
+ method public deprecated void copyFrom(android.renderscript.BaseObj[]);
+ method public deprecated void copyFrom(int[]);
+ method public deprecated void copyFrom(short[]);
+ method public deprecated void copyFrom(byte[]);
+ method public deprecated void copyFrom(float[]);
+ method public deprecated void copyFrom(android.graphics.Bitmap);
+ method public deprecated void copyFromUnchecked(int[]);
+ method public deprecated void copyFromUnchecked(short[]);
+ method public deprecated void copyFromUnchecked(byte[]);
+ method public deprecated void copyFromUnchecked(float[]);
+ method public deprecated void copyTo(android.graphics.Bitmap);
+ method public deprecated void copyTo(byte[]);
+ method public deprecated void copyTo(short[]);
+ method public deprecated void copyTo(int[]);
+ method public deprecated void copyTo(float[]);
+ method public static deprecated android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+ method public static deprecated android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
+ method public static deprecated android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+ method public static deprecated android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap);
+ method public static deprecated android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+ method public static deprecated android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
+ method public static deprecated android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int, android.renderscript.Allocation.MipmapControl, int);
+ method public static deprecated android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int);
+ method public static deprecated android.renderscript.Allocation createFromString(android.renderscript.RenderScript, java.lang.String, int);
+ method public static deprecated android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int, int);
+ method public static deprecated android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int);
+ method public static deprecated android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, android.renderscript.Allocation.MipmapControl, int);
+ method public static deprecated android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, int);
+ method public static deprecated android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type);
+ method public deprecated void generateMipmaps();
+ method public deprecated android.renderscript.Type getType();
+ method public deprecated synchronized void resize(int);
+ method public deprecated void setFromFieldPacker(int, android.renderscript.FieldPacker);
+ method public deprecated void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
+ method public deprecated void syncAll(int);
+ field public static final deprecated int USAGE_GRAPHICS_CONSTANTS = 8; // 0x8
+ field public static final deprecated int USAGE_GRAPHICS_RENDER_TARGET = 16; // 0x10
+ field public static final deprecated int USAGE_GRAPHICS_TEXTURE = 2; // 0x2
+ field public static final deprecated int USAGE_GRAPHICS_VERTEX = 4; // 0x4
+ field public static final deprecated int USAGE_SCRIPT = 1; // 0x1
}
- public static final class Allocation.MipmapControl extends java.lang.Enum {
+ public static final deprecated class Allocation.MipmapControl extends java.lang.Enum {
method public static android.renderscript.Allocation.MipmapControl valueOf(java.lang.String);
method public static final android.renderscript.Allocation.MipmapControl[] values();
- enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_FULL;
- enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_NONE;
- enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
+ enum_constant public static final deprecated android.renderscript.Allocation.MipmapControl MIPMAP_FULL;
+ enum_constant public static final deprecated android.renderscript.Allocation.MipmapControl MIPMAP_NONE;
+ enum_constant public static final deprecated android.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
}
- public class AllocationAdapter extends android.renderscript.Allocation {
- method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
- method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
- method public void setFace(android.renderscript.Type.CubemapFace);
- method public void setLOD(int);
- method public void setY(int);
- method public void setZ(int);
+ public deprecated class AllocationAdapter extends android.renderscript.Allocation {
+ method public static deprecated android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
+ method public static deprecated android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
+ method public deprecated void setFace(android.renderscript.Type.CubemapFace);
+ method public deprecated void setLOD(int);
+ method public deprecated void setY(int);
+ method public deprecated void setZ(int);
}
- public class BaseObj {
- method public synchronized void destroy();
- method public java.lang.String getName();
- method public void setName(java.lang.String);
+ public deprecated class BaseObj {
+ method public deprecated synchronized void destroy();
+ method public deprecated java.lang.String getName();
+ method public deprecated void setName(java.lang.String);
}
- public class Byte2 {
+ public deprecated class Byte2 {
ctor public Byte2();
ctor public Byte2(byte, byte);
field public byte x;
field public byte y;
}
- public class Byte3 {
+ public deprecated class Byte3 {
ctor public Byte3();
ctor public Byte3(byte, byte, byte);
field public byte x;
@@ -18351,7 +18441,7 @@
field public byte z;
}
- public class Byte4 {
+ public deprecated class Byte4 {
ctor public Byte4();
ctor public Byte4(byte, byte, byte, byte);
field public byte w;
@@ -18360,14 +18450,14 @@
field public byte z;
}
- public class Double2 {
+ public deprecated class Double2 {
ctor public Double2();
ctor public Double2(double, double);
field public double x;
field public double y;
}
- public class Double3 {
+ public deprecated class Double3 {
ctor public Double3();
ctor public Double3(double, double, double);
field public double x;
@@ -18375,7 +18465,7 @@
field public double z;
}
- public class Double4 {
+ public deprecated class Double4 {
ctor public Double4();
ctor public Double4(double, double, double, double);
field public double w;
@@ -18384,92 +18474,82 @@
field public double z;
}
- public class Element extends android.renderscript.BaseObj {
- method public static android.renderscript.Element ALLOCATION(android.renderscript.RenderScript);
- method public static android.renderscript.Element A_8(android.renderscript.RenderScript);
- method public static android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
- method public static android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element FONT(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX4X4(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX_2X2(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX_3X3(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX_4X4(android.renderscript.RenderScript);
- method public static android.renderscript.Element MESH(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_FRAGMENT(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_RASTER(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_STORE(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_VERTEX(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGBA_4444(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGBA_5551(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGBA_8888(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGB_565(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGB_888(android.renderscript.RenderScript);
- method public static android.renderscript.Element SAMPLER(android.renderscript.RenderScript);
- method public static android.renderscript.Element SCRIPT(android.renderscript.RenderScript);
- method public static android.renderscript.Element TYPE(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
- method public static android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
- method public int getBytesSize();
- method public android.renderscript.Element.DataKind getDataKind();
- method public android.renderscript.Element.DataType getDataType();
- method public android.renderscript.Element getSubElement(int);
- method public int getSubElementArraySize(int);
- method public int getSubElementCount();
- method public java.lang.String getSubElementName(int);
- method public int getSubElementOffsetBytes(int);
- method public int getVectorSize();
- method public boolean isCompatible(android.renderscript.Element);
- method public boolean isComplex();
+ public deprecated class Element extends android.renderscript.BaseObj {
+ method public static deprecated android.renderscript.Element ALLOCATION(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element A_8(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element F32(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element F32_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element F32_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element F32_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element F64(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element F64_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element F64_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element F64_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I16(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I16_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I16_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I16_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I32(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I32_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I32_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I32_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I64(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I64_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I64_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I64_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I8(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I8_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I8_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element I8_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element MATRIX4X4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element MATRIX_2X2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element MATRIX_3X3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element MATRIX_4X4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element MESH(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element PROGRAM_FRAGMENT(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element PROGRAM_RASTER(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element PROGRAM_STORE(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element PROGRAM_VERTEX(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element RGBA_4444(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element RGBA_5551(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element RGBA_8888(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element RGB_565(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element RGB_888(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element SAMPLER(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element SCRIPT(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element TYPE(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U16(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U16_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U16_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U16_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U32(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U32_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U32_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U32_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U64(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U64_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U64_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U64_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U8(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U8_2(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U8_3(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element U8_4(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
+ method public static deprecated android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
+ method public deprecated boolean isCompatible(android.renderscript.Element);
+ method public deprecated boolean isComplex();
}
- public static class Element.Builder {
- ctor public Element.Builder(android.renderscript.RenderScript);
- method public android.renderscript.Element.Builder add(android.renderscript.Element, java.lang.String, int);
- method public android.renderscript.Element.Builder add(android.renderscript.Element, java.lang.String);
- method public android.renderscript.Element create();
+ public static deprecated class Element.Builder {
+ ctor public deprecated Element.Builder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.Element.Builder add(android.renderscript.Element, java.lang.String, int);
+ method public deprecated android.renderscript.Element.Builder add(android.renderscript.Element, java.lang.String);
+ method public deprecated android.renderscript.Element create();
}
- public static final class Element.DataKind extends java.lang.Enum {
+ public static final deprecated class Element.DataKind extends java.lang.Enum {
method public static android.renderscript.Element.DataKind valueOf(java.lang.String);
method public static final android.renderscript.Element.DataKind[] values();
enum_constant public static final android.renderscript.Element.DataKind PIXEL_A;
@@ -18481,7 +18561,7 @@
enum_constant public static final android.renderscript.Element.DataKind USER;
}
- public static final class Element.DataType extends java.lang.Enum {
+ public static final deprecated class Element.DataType extends java.lang.Enum {
method public static android.renderscript.Element.DataType valueOf(java.lang.String);
method public static final android.renderscript.Element.DataType[] values();
enum_constant public static final android.renderscript.Element.DataType BOOLEAN;
@@ -18490,10 +18570,8 @@
enum_constant public static final android.renderscript.Element.DataType MATRIX_2X2;
enum_constant public static final android.renderscript.Element.DataType MATRIX_3X3;
enum_constant public static final android.renderscript.Element.DataType MATRIX_4X4;
- enum_constant public static final android.renderscript.Element.DataType NONE;
enum_constant public static final android.renderscript.Element.DataType RS_ALLOCATION;
enum_constant public static final android.renderscript.Element.DataType RS_ELEMENT;
- enum_constant public static final android.renderscript.Element.DataType RS_FONT;
enum_constant public static final android.renderscript.Element.DataType RS_MESH;
enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_FRAGMENT;
enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_RASTER;
@@ -18515,7 +18593,7 @@
enum_constant public static final android.renderscript.Element.DataType UNSIGNED_8;
}
- public class FieldPacker {
+ public deprecated class FieldPacker {
ctor public FieldPacker(int);
method public void addBoolean(boolean);
method public void addF32(float);
@@ -18569,37 +18647,37 @@
method public void skip(int);
}
- public class FileA3D extends android.renderscript.BaseObj {
- method public static android.renderscript.FileA3D createFromAsset(android.renderscript.RenderScript, android.content.res.AssetManager, java.lang.String);
- method public static android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.lang.String);
- method public static android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.io.File);
- method public static android.renderscript.FileA3D createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int);
- method public android.renderscript.FileA3D.IndexEntry getIndexEntry(int);
- method public int getIndexEntryCount();
+ public deprecated class FileA3D extends android.renderscript.BaseObj {
+ method public static deprecated android.renderscript.FileA3D createFromAsset(android.renderscript.RenderScript, android.content.res.AssetManager, java.lang.String);
+ method public static deprecated android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.lang.String);
+ method public static deprecated android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.io.File);
+ method public static deprecated android.renderscript.FileA3D createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int);
+ method public deprecated android.renderscript.FileA3D.IndexEntry getIndexEntry(int);
+ method public deprecated int getIndexEntryCount();
}
- public static final class FileA3D.EntryType extends java.lang.Enum {
+ public static final deprecated class FileA3D.EntryType extends java.lang.Enum {
method public static android.renderscript.FileA3D.EntryType valueOf(java.lang.String);
method public static final android.renderscript.FileA3D.EntryType[] values();
- enum_constant public static final android.renderscript.FileA3D.EntryType MESH;
- enum_constant public static final android.renderscript.FileA3D.EntryType UNKNOWN;
+ enum_constant public static final deprecated android.renderscript.FileA3D.EntryType MESH;
+ enum_constant public static final deprecated android.renderscript.FileA3D.EntryType UNKNOWN;
}
- public static class FileA3D.IndexEntry {
- method public android.renderscript.FileA3D.EntryType getEntryType();
- method public android.renderscript.Mesh getMesh();
- method public java.lang.String getName();
- method public android.renderscript.BaseObj getObject();
+ public static deprecated class FileA3D.IndexEntry {
+ method public deprecated android.renderscript.FileA3D.EntryType getEntryType();
+ method public deprecated android.renderscript.Mesh getMesh();
+ method public deprecated java.lang.String getName();
+ method public deprecated android.renderscript.BaseObj getObject();
}
- public class Float2 {
+ public deprecated class Float2 {
ctor public Float2();
ctor public Float2(float, float);
field public float x;
field public float y;
}
- public class Float3 {
+ public deprecated class Float3 {
ctor public Float3();
ctor public Float3(float, float, float);
field public float x;
@@ -18607,7 +18685,7 @@
field public float z;
}
- public class Float4 {
+ public deprecated class Float4 {
ctor public Float4();
ctor public Float4(float, float, float, float);
field public float w;
@@ -18616,31 +18694,31 @@
field public float z;
}
- public class Font extends android.renderscript.BaseObj {
- method public static android.renderscript.Font create(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, android.renderscript.Font.Style, float);
- method public static android.renderscript.Font createFromAsset(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
- method public static android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
- method public static android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.io.File, float);
- method public static android.renderscript.Font createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int, float);
+ public deprecated class Font extends android.renderscript.BaseObj {
+ method public static deprecated android.renderscript.Font create(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, android.renderscript.Font.Style, float);
+ method public static deprecated android.renderscript.Font createFromAsset(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
+ method public static deprecated android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
+ method public static deprecated android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.io.File, float);
+ method public static deprecated android.renderscript.Font createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int, float);
}
- public static final class Font.Style extends java.lang.Enum {
+ public static final deprecated class Font.Style extends java.lang.Enum {
method public static android.renderscript.Font.Style valueOf(java.lang.String);
method public static final android.renderscript.Font.Style[] values();
- enum_constant public static final android.renderscript.Font.Style BOLD;
- enum_constant public static final android.renderscript.Font.Style BOLD_ITALIC;
- enum_constant public static final android.renderscript.Font.Style ITALIC;
- enum_constant public static final android.renderscript.Font.Style NORMAL;
+ enum_constant public static final deprecated android.renderscript.Font.Style BOLD;
+ enum_constant public static final deprecated android.renderscript.Font.Style BOLD_ITALIC;
+ enum_constant public static final deprecated android.renderscript.Font.Style ITALIC;
+ enum_constant public static final deprecated android.renderscript.Font.Style NORMAL;
}
- public class Int2 {
+ public deprecated class Int2 {
ctor public Int2();
ctor public Int2(int, int);
field public int x;
field public int y;
}
- public class Int3 {
+ public deprecated class Int3 {
ctor public Int3();
ctor public Int3(int, int, int);
field public int x;
@@ -18648,7 +18726,7 @@
field public int z;
}
- public class Int4 {
+ public deprecated class Int4 {
ctor public Int4();
ctor public Int4(int, int, int, int);
field public int w;
@@ -18657,14 +18735,14 @@
field public int z;
}
- public class Long2 {
+ public deprecated class Long2 {
ctor public Long2();
ctor public Long2(long, long);
field public long x;
field public long y;
}
- public class Long3 {
+ public deprecated class Long3 {
ctor public Long3();
ctor public Long3(long, long, long);
field public long x;
@@ -18672,7 +18750,7 @@
field public long z;
}
- public class Long4 {
+ public deprecated class Long4 {
ctor public Long4();
ctor public Long4(long, long, long, long);
field public long w;
@@ -18681,384 +18759,365 @@
field public long z;
}
- public class Matrix2f {
- ctor public Matrix2f();
- ctor public Matrix2f(float[]);
- method public float get(int, int);
- method public float[] getArray();
- method public void load(android.renderscript.Matrix2f);
- method public void loadIdentity();
- method public void loadMultiply(android.renderscript.Matrix2f, android.renderscript.Matrix2f);
- method public void loadRotate(float);
- method public void loadScale(float, float);
- method public void multiply(android.renderscript.Matrix2f);
- method public void rotate(float);
- method public void scale(float, float);
- method public void set(int, int, float);
- method public void transpose();
+ public deprecated class Matrix2f {
+ ctor public deprecated Matrix2f();
+ ctor public deprecated Matrix2f(float[]);
+ method public deprecated float get(int, int);
+ method public deprecated float[] getArray();
+ method public deprecated void load(android.renderscript.Matrix2f);
+ method public deprecated void loadIdentity();
+ method public deprecated void loadMultiply(android.renderscript.Matrix2f, android.renderscript.Matrix2f);
+ method public deprecated void loadRotate(float);
+ method public deprecated void loadScale(float, float);
+ method public deprecated void multiply(android.renderscript.Matrix2f);
+ method public deprecated void rotate(float);
+ method public deprecated void scale(float, float);
+ method public deprecated void set(int, int, float);
+ method public deprecated void transpose();
}
- public class Matrix3f {
- ctor public Matrix3f();
- ctor public Matrix3f(float[]);
- method public float get(int, int);
- method public float[] getArray();
- method public void load(android.renderscript.Matrix3f);
- method public void loadIdentity();
- method public void loadMultiply(android.renderscript.Matrix3f, android.renderscript.Matrix3f);
- method public void loadRotate(float, float, float, float);
- method public void loadRotate(float);
- method public void loadScale(float, float);
- method public void loadScale(float, float, float);
- method public void loadTranslate(float, float);
- method public void multiply(android.renderscript.Matrix3f);
- method public void rotate(float, float, float, float);
- method public void rotate(float);
- method public void scale(float, float);
- method public void scale(float, float, float);
- method public void set(int, int, float);
- method public void translate(float, float);
- method public void transpose();
+ public deprecated class Matrix3f {
+ ctor public deprecated Matrix3f();
+ ctor public deprecated Matrix3f(float[]);
+ method public deprecated float get(int, int);
+ method public deprecated float[] getArray();
+ method public deprecated void load(android.renderscript.Matrix3f);
+ method public deprecated void loadIdentity();
+ method public deprecated void loadMultiply(android.renderscript.Matrix3f, android.renderscript.Matrix3f);
+ method public deprecated void loadRotate(float, float, float, float);
+ method public deprecated void loadRotate(float);
+ method public deprecated void loadScale(float, float);
+ method public deprecated void loadScale(float, float, float);
+ method public deprecated void loadTranslate(float, float);
+ method public deprecated void multiply(android.renderscript.Matrix3f);
+ method public deprecated void rotate(float, float, float, float);
+ method public deprecated void rotate(float);
+ method public deprecated void scale(float, float);
+ method public deprecated void scale(float, float, float);
+ method public deprecated void set(int, int, float);
+ method public deprecated void translate(float, float);
+ method public deprecated void transpose();
}
- public class Matrix4f {
- ctor public Matrix4f();
- ctor public Matrix4f(float[]);
- method public float get(int, int);
- method public float[] getArray();
- method public boolean inverse();
- method public boolean inverseTranspose();
- method public void load(android.renderscript.Matrix4f);
- method public void loadFrustum(float, float, float, float, float, float);
- method public void loadIdentity();
- method public void loadMultiply(android.renderscript.Matrix4f, android.renderscript.Matrix4f);
- method public void loadOrtho(float, float, float, float, float, float);
- method public void loadOrthoWindow(int, int);
- method public void loadPerspective(float, float, float, float);
- method public void loadProjectionNormalized(int, int);
- method public void loadRotate(float, float, float, float);
- method public void loadScale(float, float, float);
- method public void loadTranslate(float, float, float);
- method public void multiply(android.renderscript.Matrix4f);
- method public void rotate(float, float, float, float);
- method public void scale(float, float, float);
- method public void set(int, int, float);
- method public void translate(float, float, float);
- method public void transpose();
+ public deprecated class Matrix4f {
+ ctor public deprecated Matrix4f();
+ ctor public deprecated Matrix4f(float[]);
+ method public deprecated float get(int, int);
+ method public deprecated float[] getArray();
+ method public deprecated boolean inverse();
+ method public deprecated boolean inverseTranspose();
+ method public deprecated void load(android.renderscript.Matrix4f);
+ method public deprecated void loadFrustum(float, float, float, float, float, float);
+ method public deprecated void loadIdentity();
+ method public deprecated void loadMultiply(android.renderscript.Matrix4f, android.renderscript.Matrix4f);
+ method public deprecated void loadOrtho(float, float, float, float, float, float);
+ method public deprecated void loadOrthoWindow(int, int);
+ method public deprecated void loadPerspective(float, float, float, float);
+ method public deprecated void loadProjectionNormalized(int, int);
+ method public deprecated void loadRotate(float, float, float, float);
+ method public deprecated void loadScale(float, float, float);
+ method public deprecated void loadTranslate(float, float, float);
+ method public deprecated void multiply(android.renderscript.Matrix4f);
+ method public deprecated void rotate(float, float, float, float);
+ method public deprecated void scale(float, float, float);
+ method public deprecated void set(int, int, float);
+ method public deprecated void translate(float, float, float);
+ method public deprecated void transpose();
}
- public class Mesh extends android.renderscript.BaseObj {
- method public android.renderscript.Allocation getIndexSetAllocation(int);
- method public android.renderscript.Mesh.Primitive getPrimitive(int);
- method public int getPrimitiveCount();
- method public android.renderscript.Allocation getVertexAllocation(int);
- method public int getVertexAllocationCount();
+ public deprecated class Mesh extends android.renderscript.BaseObj {
+ method public deprecated android.renderscript.Allocation getIndexSetAllocation(int);
+ method public deprecated android.renderscript.Mesh.Primitive getPrimitive(int);
+ method public deprecated int getPrimitiveCount();
+ method public deprecated android.renderscript.Allocation getVertexAllocation(int);
+ method public deprecated int getVertexAllocationCount();
}
- public static class Mesh.AllocationBuilder {
- ctor public Mesh.AllocationBuilder(android.renderscript.RenderScript);
- method public android.renderscript.Mesh.AllocationBuilder addIndexSetAllocation(android.renderscript.Allocation, android.renderscript.Mesh.Primitive);
- method public android.renderscript.Mesh.AllocationBuilder addIndexSetType(android.renderscript.Mesh.Primitive);
- method public android.renderscript.Mesh.AllocationBuilder addVertexAllocation(android.renderscript.Allocation) throws java.lang.IllegalStateException;
- method public android.renderscript.Mesh create();
- method public int getCurrentIndexSetIndex();
- method public int getCurrentVertexTypeIndex();
+ public static deprecated class Mesh.AllocationBuilder {
+ ctor public deprecated Mesh.AllocationBuilder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.Mesh.AllocationBuilder addIndexSetAllocation(android.renderscript.Allocation, android.renderscript.Mesh.Primitive);
+ method public deprecated android.renderscript.Mesh.AllocationBuilder addIndexSetType(android.renderscript.Mesh.Primitive);
+ method public deprecated android.renderscript.Mesh.AllocationBuilder addVertexAllocation(android.renderscript.Allocation) throws java.lang.IllegalStateException;
+ method public deprecated android.renderscript.Mesh create();
+ method public deprecated int getCurrentIndexSetIndex();
+ method public deprecated int getCurrentVertexTypeIndex();
}
- public static class Mesh.Builder {
- ctor public Mesh.Builder(android.renderscript.RenderScript, int);
- method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Type, android.renderscript.Mesh.Primitive);
- method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Mesh.Primitive);
- method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Element, int, android.renderscript.Mesh.Primitive);
- method public android.renderscript.Mesh.Builder addVertexType(android.renderscript.Type) throws java.lang.IllegalStateException;
- method public android.renderscript.Mesh.Builder addVertexType(android.renderscript.Element, int) throws java.lang.IllegalStateException;
- method public android.renderscript.Mesh create();
- method public int getCurrentIndexSetIndex();
- method public int getCurrentVertexTypeIndex();
+ public static deprecated class Mesh.Builder {
+ ctor public deprecated Mesh.Builder(android.renderscript.RenderScript, int);
+ method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Type, android.renderscript.Mesh.Primitive);
+ method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Mesh.Primitive);
+ method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Element, int, android.renderscript.Mesh.Primitive);
+ method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Type) throws java.lang.IllegalStateException;
+ method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Element, int) throws java.lang.IllegalStateException;
+ method public deprecated android.renderscript.Mesh create();
+ method public deprecated int getCurrentIndexSetIndex();
+ method public deprecated int getCurrentVertexTypeIndex();
}
- public static final class Mesh.Primitive extends java.lang.Enum {
+ public static final deprecated class Mesh.Primitive extends java.lang.Enum {
method public static android.renderscript.Mesh.Primitive valueOf(java.lang.String);
method public static final android.renderscript.Mesh.Primitive[] values();
- enum_constant public static final android.renderscript.Mesh.Primitive LINE;
- enum_constant public static final android.renderscript.Mesh.Primitive LINE_STRIP;
- enum_constant public static final android.renderscript.Mesh.Primitive POINT;
- enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE;
- enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE_FAN;
- enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE_STRIP;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE_STRIP;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive POINT;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_FAN;
+ enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_STRIP;
}
- public static class Mesh.TriangleMeshBuilder {
- ctor public Mesh.TriangleMeshBuilder(android.renderscript.RenderScript, int, int);
- method public android.renderscript.Mesh.TriangleMeshBuilder addTriangle(int, int, int);
- method public android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float);
- method public android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float, float);
- method public android.renderscript.Mesh create(boolean);
- method public android.renderscript.Mesh.TriangleMeshBuilder setColor(float, float, float, float);
- method public android.renderscript.Mesh.TriangleMeshBuilder setNormal(float, float, float);
- method public android.renderscript.Mesh.TriangleMeshBuilder setTexture(float, float);
- field public static final int COLOR = 1; // 0x1
- field public static final int NORMAL = 2; // 0x2
- field public static final int TEXTURE_0 = 256; // 0x100
+ public static deprecated class Mesh.TriangleMeshBuilder {
+ ctor public deprecated Mesh.TriangleMeshBuilder(android.renderscript.RenderScript, int, int);
+ method public deprecated android.renderscript.Mesh.TriangleMeshBuilder addTriangle(int, int, int);
+ method public deprecated android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float);
+ method public deprecated android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float, float);
+ method public deprecated android.renderscript.Mesh create(boolean);
+ method public deprecated android.renderscript.Mesh.TriangleMeshBuilder setColor(float, float, float, float);
+ method public deprecated android.renderscript.Mesh.TriangleMeshBuilder setNormal(float, float, float);
+ method public deprecated android.renderscript.Mesh.TriangleMeshBuilder setTexture(float, float);
+ field public static final deprecated int COLOR = 1; // 0x1
+ field public static final deprecated int NORMAL = 2; // 0x2
+ field public static final deprecated int TEXTURE_0 = 256; // 0x100
}
- public class Program extends android.renderscript.BaseObj {
- method public void bindConstants(android.renderscript.Allocation, int);
- method public void bindSampler(android.renderscript.Sampler, int) throws java.lang.IllegalArgumentException;
- method public void bindTexture(android.renderscript.Allocation, int) throws java.lang.IllegalArgumentException;
- method public android.renderscript.Type getConstant(int);
- method public int getConstantCount();
- method public int getTextureCount();
- method public java.lang.String getTextureName(int);
- method public android.renderscript.Program.TextureType getTextureType(int);
+ public deprecated class Program extends android.renderscript.BaseObj {
+ method public deprecated void bindConstants(android.renderscript.Allocation, int);
+ method public deprecated void bindSampler(android.renderscript.Sampler, int) throws java.lang.IllegalArgumentException;
+ method public deprecated void bindTexture(android.renderscript.Allocation, int) throws java.lang.IllegalArgumentException;
}
public static class Program.BaseProgramBuilder {
- ctor protected Program.BaseProgramBuilder(android.renderscript.RenderScript);
- method public android.renderscript.Program.BaseProgramBuilder addConstant(android.renderscript.Type) throws java.lang.IllegalStateException;
- method public android.renderscript.Program.BaseProgramBuilder addTexture(android.renderscript.Program.TextureType) throws java.lang.IllegalArgumentException;
- method public android.renderscript.Program.BaseProgramBuilder addTexture(android.renderscript.Program.TextureType, java.lang.String) throws java.lang.IllegalArgumentException;
- method public int getCurrentConstantIndex();
- method public int getCurrentTextureIndex();
- method protected void initProgram(android.renderscript.Program);
- method public android.renderscript.Program.BaseProgramBuilder setShader(java.lang.String);
- method public android.renderscript.Program.BaseProgramBuilder setShader(android.content.res.Resources, int);
+ ctor protected deprecated Program.BaseProgramBuilder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.Program.BaseProgramBuilder addConstant(android.renderscript.Type) throws java.lang.IllegalStateException;
+ method public deprecated android.renderscript.Program.BaseProgramBuilder addTexture(android.renderscript.Program.TextureType) throws java.lang.IllegalArgumentException;
+ method public deprecated int getCurrentConstantIndex();
+ method public deprecated int getCurrentTextureIndex();
+ method protected deprecated void initProgram(android.renderscript.Program);
+ method public deprecated android.renderscript.Program.BaseProgramBuilder setShader(java.lang.String);
+ method public deprecated android.renderscript.Program.BaseProgramBuilder setShader(android.content.res.Resources, int);
}
- public static final class Program.TextureType extends java.lang.Enum {
+ public static final deprecated class Program.TextureType extends java.lang.Enum {
method public static android.renderscript.Program.TextureType valueOf(java.lang.String);
method public static final android.renderscript.Program.TextureType[] values();
- enum_constant public static final android.renderscript.Program.TextureType TEXTURE_2D;
- enum_constant public static final android.renderscript.Program.TextureType TEXTURE_CUBE;
+ enum_constant public static final deprecated android.renderscript.Program.TextureType TEXTURE_2D;
+ enum_constant public static final deprecated android.renderscript.Program.TextureType TEXTURE_CUBE;
}
- public class ProgramFragment extends android.renderscript.Program {
+ public deprecated class ProgramFragment extends android.renderscript.Program {
}
public static class ProgramFragment.Builder extends android.renderscript.Program.BaseProgramBuilder {
- ctor public ProgramFragment.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramFragment create();
+ ctor public deprecated ProgramFragment.Builder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.ProgramFragment create();
}
- public class ProgramFragmentFixedFunction extends android.renderscript.ProgramFragment {
+ public deprecated class ProgramFragmentFixedFunction extends android.renderscript.ProgramFragment {
}
public static class ProgramFragmentFixedFunction.Builder {
- ctor public ProgramFragmentFixedFunction.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramFragmentFixedFunction create();
- method public android.renderscript.ProgramFragmentFixedFunction.Builder setPointSpriteTexCoordinateReplacement(boolean);
- method public android.renderscript.ProgramFragmentFixedFunction.Builder setTexture(android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode, android.renderscript.ProgramFragmentFixedFunction.Builder.Format, int) throws java.lang.IllegalArgumentException;
- method public android.renderscript.ProgramFragmentFixedFunction.Builder setVaryingColor(boolean);
- field public static final int MAX_TEXTURE = 2; // 0x2
+ ctor public deprecated ProgramFragmentFixedFunction.Builder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.ProgramFragmentFixedFunction create();
+ method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setPointSpriteTexCoordinateReplacement(boolean);
+ method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setTexture(android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode, android.renderscript.ProgramFragmentFixedFunction.Builder.Format, int) throws java.lang.IllegalArgumentException;
+ method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setVaryingColor(boolean);
+ field public static final deprecated int MAX_TEXTURE = 2; // 0x2
}
- public static final class ProgramFragmentFixedFunction.Builder.EnvMode extends java.lang.Enum {
+ public static final deprecated class ProgramFragmentFixedFunction.Builder.EnvMode extends java.lang.Enum {
method public static android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode valueOf(java.lang.String);
method public static final android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode[] values();
- enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode DECAL;
- enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode MODULATE;
- enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode REPLACE;
+ enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode DECAL;
+ enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode MODULATE;
+ enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode REPLACE;
}
- public static final class ProgramFragmentFixedFunction.Builder.Format extends java.lang.Enum {
+ public static final deprecated class ProgramFragmentFixedFunction.Builder.Format extends java.lang.Enum {
method public static android.renderscript.ProgramFragmentFixedFunction.Builder.Format valueOf(java.lang.String);
method public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format[] values();
- enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format ALPHA;
- enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format LUMINANCE_ALPHA;
- enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGB;
- enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGBA;
+ enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format LUMINANCE_ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGB;
+ enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGBA;
}
- public class ProgramRaster extends android.renderscript.BaseObj {
- method public static android.renderscript.ProgramRaster CULL_BACK(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramRaster CULL_FRONT(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramRaster CULL_NONE(android.renderscript.RenderScript);
- method public android.renderscript.ProgramRaster.CullMode getCullMode();
- method public boolean isPointSpriteEnabled();
+ public deprecated class ProgramRaster extends android.renderscript.BaseObj {
+ method public static deprecated android.renderscript.ProgramRaster CULL_BACK(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.ProgramRaster CULL_FRONT(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.ProgramRaster CULL_NONE(android.renderscript.RenderScript);
}
- public static class ProgramRaster.Builder {
- ctor public ProgramRaster.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramRaster create();
- method public android.renderscript.ProgramRaster.Builder setCullMode(android.renderscript.ProgramRaster.CullMode);
- method public android.renderscript.ProgramRaster.Builder setPointSpriteEnabled(boolean);
+ public static deprecated class ProgramRaster.Builder {
+ ctor public deprecated ProgramRaster.Builder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.ProgramRaster create();
+ method public deprecated android.renderscript.ProgramRaster.Builder setCullMode(android.renderscript.ProgramRaster.CullMode);
+ method public deprecated android.renderscript.ProgramRaster.Builder setPointSpriteEnabled(boolean);
}
- public static final class ProgramRaster.CullMode extends java.lang.Enum {
+ public static final deprecated class ProgramRaster.CullMode extends java.lang.Enum {
method public static android.renderscript.ProgramRaster.CullMode valueOf(java.lang.String);
method public static final android.renderscript.ProgramRaster.CullMode[] values();
- enum_constant public static final android.renderscript.ProgramRaster.CullMode BACK;
- enum_constant public static final android.renderscript.ProgramRaster.CullMode FRONT;
- enum_constant public static final android.renderscript.ProgramRaster.CullMode NONE;
+ enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode BACK;
+ enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode FRONT;
+ enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode NONE;
}
- public class ProgramStore extends android.renderscript.BaseObj {
- method public static android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_NONE(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_TEST(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramStore BLEND_NONE_DEPTH_NONE(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramStore BLEND_NONE_DEPTH_TEST(android.renderscript.RenderScript);
- method public android.renderscript.ProgramStore.BlendDstFunc getBlendDstFunc();
- method public android.renderscript.ProgramStore.BlendSrcFunc getBlendSrcFunc();
- method public android.renderscript.ProgramStore.DepthFunc getDepthFunc();
- method public boolean isColorMaskAlphaEnabled();
- method public boolean isColorMaskBlueEnabled();
- method public boolean isColorMaskGreenEnabled();
- method public boolean isColorMaskRedEnabled();
- method public boolean isDepthMaskEnabled();
- method public boolean isDitherEnabled();
+ public deprecated class ProgramStore extends android.renderscript.BaseObj {
+ method public static deprecated android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_NONE(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_TEST(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.ProgramStore BLEND_NONE_DEPTH_NONE(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.ProgramStore BLEND_NONE_DEPTH_TEST(android.renderscript.RenderScript);
}
- public static final class ProgramStore.BlendDstFunc extends java.lang.Enum {
+ public static final deprecated class ProgramStore.BlendDstFunc extends java.lang.Enum {
method public static android.renderscript.ProgramStore.BlendDstFunc valueOf(java.lang.String);
method public static final android.renderscript.ProgramStore.BlendDstFunc[] values();
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc DST_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_DST_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_COLOR;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc SRC_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc SRC_COLOR;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ZERO;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc DST_ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ONE;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_DST_ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_COLOR;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc SRC_ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc SRC_COLOR;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ZERO;
}
- public static final class ProgramStore.BlendSrcFunc extends java.lang.Enum {
+ public static final deprecated class ProgramStore.BlendSrcFunc extends java.lang.Enum {
method public static android.renderscript.ProgramStore.BlendSrcFunc valueOf(java.lang.String);
method public static final android.renderscript.ProgramStore.BlendSrcFunc[] values();
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc DST_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc DST_COLOR;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_COLOR;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_SRC_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA_SATURATE;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ZERO;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc DST_ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc DST_COLOR;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ONE;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_COLOR;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_SRC_ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA_SATURATE;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ZERO;
}
- public static class ProgramStore.Builder {
+ public static deprecated class ProgramStore.Builder {
ctor public ProgramStore.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramStore create();
- method public android.renderscript.ProgramStore.Builder setBlendFunc(android.renderscript.ProgramStore.BlendSrcFunc, android.renderscript.ProgramStore.BlendDstFunc);
- method public android.renderscript.ProgramStore.Builder setColorMaskEnabled(boolean, boolean, boolean, boolean);
- method public android.renderscript.ProgramStore.Builder setDepthFunc(android.renderscript.ProgramStore.DepthFunc);
- method public android.renderscript.ProgramStore.Builder setDepthMaskEnabled(boolean);
- method public android.renderscript.ProgramStore.Builder setDitherEnabled(boolean);
+ method public deprecated android.renderscript.ProgramStore create();
+ method public deprecated android.renderscript.ProgramStore.Builder setBlendFunc(android.renderscript.ProgramStore.BlendSrcFunc, android.renderscript.ProgramStore.BlendDstFunc);
+ method public deprecated android.renderscript.ProgramStore.Builder setColorMaskEnabled(boolean, boolean, boolean, boolean);
+ method public deprecated android.renderscript.ProgramStore.Builder setDepthFunc(android.renderscript.ProgramStore.DepthFunc);
+ method public deprecated android.renderscript.ProgramStore.Builder setDepthMaskEnabled(boolean);
+ method public deprecated android.renderscript.ProgramStore.Builder setDitherEnabled(boolean);
}
- public static final class ProgramStore.DepthFunc extends java.lang.Enum {
+ public static final deprecated class ProgramStore.DepthFunc extends java.lang.Enum {
method public static android.renderscript.ProgramStore.DepthFunc valueOf(java.lang.String);
method public static final android.renderscript.ProgramStore.DepthFunc[] values();
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc ALWAYS;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc EQUAL;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc GREATER;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc GREATER_OR_EQUAL;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc LESS;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc LESS_OR_EQUAL;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc NOT_EQUAL;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc ALWAYS;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc EQUAL;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc GREATER;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc GREATER_OR_EQUAL;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc LESS;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc LESS_OR_EQUAL;
+ enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc NOT_EQUAL;
}
- public class ProgramVertex extends android.renderscript.Program {
- method public android.renderscript.Element getInput(int);
- method public int getInputCount();
+ public deprecated class ProgramVertex extends android.renderscript.Program {
}
- public static class ProgramVertex.Builder extends android.renderscript.Program.BaseProgramBuilder {
- ctor public ProgramVertex.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramVertex.Builder addInput(android.renderscript.Element) throws java.lang.IllegalStateException;
- method public android.renderscript.ProgramVertex create();
+ public static deprecated class ProgramVertex.Builder extends android.renderscript.Program.BaseProgramBuilder {
+ ctor public deprecated ProgramVertex.Builder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.ProgramVertex.Builder addInput(android.renderscript.Element) throws java.lang.IllegalStateException;
+ method public deprecated android.renderscript.ProgramVertex create();
}
- public class ProgramVertexFixedFunction extends android.renderscript.ProgramVertex {
- method public void bindConstants(android.renderscript.ProgramVertexFixedFunction.Constants);
+ public deprecated class ProgramVertexFixedFunction extends android.renderscript.ProgramVertex {
+ method public deprecated void bindConstants(android.renderscript.ProgramVertexFixedFunction.Constants);
}
public static class ProgramVertexFixedFunction.Builder {
- ctor public ProgramVertexFixedFunction.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramVertexFixedFunction create();
- method public android.renderscript.ProgramVertexFixedFunction.Builder setTextureMatrixEnable(boolean);
+ ctor public deprecated ProgramVertexFixedFunction.Builder(android.renderscript.RenderScript);
+ method public deprecated android.renderscript.ProgramVertexFixedFunction create();
+ method public deprecated android.renderscript.ProgramVertexFixedFunction.Builder setTextureMatrixEnable(boolean);
}
- public static class ProgramVertexFixedFunction.Constants {
- ctor public ProgramVertexFixedFunction.Constants(android.renderscript.RenderScript);
- method public void destroy();
- method public void setModelview(android.renderscript.Matrix4f);
- method public void setProjection(android.renderscript.Matrix4f);
- method public void setTexture(android.renderscript.Matrix4f);
+ public static deprecated class ProgramVertexFixedFunction.Constants {
+ ctor public deprecated ProgramVertexFixedFunction.Constants(android.renderscript.RenderScript);
+ method public deprecated void destroy();
+ method public deprecated void setModelview(android.renderscript.Matrix4f);
+ method public deprecated void setProjection(android.renderscript.Matrix4f);
+ method public deprecated void setTexture(android.renderscript.Matrix4f);
}
- public class RSDriverException extends android.renderscript.RSRuntimeException {
+ public deprecated class RSDriverException extends android.renderscript.RSRuntimeException {
ctor public RSDriverException(java.lang.String);
}
- public class RSIllegalArgumentException extends android.renderscript.RSRuntimeException {
- ctor public RSIllegalArgumentException(java.lang.String);
+ public deprecated class RSIllegalArgumentException extends android.renderscript.RSRuntimeException {
+ ctor public deprecated RSIllegalArgumentException(java.lang.String);
}
- public class RSInvalidStateException extends android.renderscript.RSRuntimeException {
- ctor public RSInvalidStateException(java.lang.String);
+ public deprecated class RSInvalidStateException extends android.renderscript.RSRuntimeException {
+ ctor public deprecated RSInvalidStateException(java.lang.String);
}
- public class RSRuntimeException extends java.lang.RuntimeException {
- ctor public RSRuntimeException(java.lang.String);
+ public deprecated class RSRuntimeException extends java.lang.RuntimeException {
+ ctor public deprecated RSRuntimeException(java.lang.String);
}
- public class RSSurfaceView extends android.view.SurfaceView implements android.view.SurfaceHolder.Callback {
- ctor public RSSurfaceView(android.content.Context);
- ctor public RSSurfaceView(android.content.Context, android.util.AttributeSet);
+ public deprecated class RSSurfaceView extends android.view.SurfaceView implements android.view.SurfaceHolder.Callback {
+ ctor public deprecated RSSurfaceView(android.content.Context);
+ ctor public deprecated RSSurfaceView(android.content.Context, android.util.AttributeSet);
method public android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
method public void destroyRenderScriptGL();
method public android.renderscript.RenderScriptGL getRenderScriptGL();
- method public void pause();
- method public void resume();
+ method public deprecated void pause();
+ method public deprecated void resume();
method public void setRenderScriptGL(android.renderscript.RenderScriptGL);
- method public void surfaceChanged(android.view.SurfaceHolder, int, int, int);
- method public void surfaceCreated(android.view.SurfaceHolder);
- method public void surfaceDestroyed(android.view.SurfaceHolder);
+ method public deprecated void surfaceChanged(android.view.SurfaceHolder, int, int, int);
+ method public deprecated void surfaceCreated(android.view.SurfaceHolder);
+ method public deprecated void surfaceDestroyed(android.view.SurfaceHolder);
}
- public class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
- ctor public RSTextureView(android.content.Context);
- ctor public RSTextureView(android.content.Context, android.util.AttributeSet);
- method public android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
- method public void destroyRenderScriptGL();
- method public android.renderscript.RenderScriptGL getRenderScriptGL();
+ public deprecated class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
+ ctor public deprecated RSTextureView(android.content.Context);
+ ctor public deprecated RSTextureView(android.content.Context, android.util.AttributeSet);
+ method public deprecated android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
+ method public deprecated void destroyRenderScriptGL();
+ method public deprecated android.renderscript.RenderScriptGL getRenderScriptGL();
method public void onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int);
method public boolean onSurfaceTextureDestroyed(android.graphics.SurfaceTexture);
method public void onSurfaceTextureSizeChanged(android.graphics.SurfaceTexture, int, int);
method public void onSurfaceTextureUpdated(android.graphics.SurfaceTexture);
- method public void pause();
- method public void resume();
- method public void setRenderScriptGL(android.renderscript.RenderScriptGL);
+ method public deprecated void pause();
+ method public deprecated void resume();
+ method public deprecated void setRenderScriptGL(android.renderscript.RenderScriptGL);
}
- public class RenderScript {
- method public void contextDump();
- method public static android.renderscript.RenderScript create(android.content.Context);
- method public void destroy();
- method public void finish();
- method public final android.content.Context getApplicationContext();
+ public deprecated class RenderScript {
+ method public deprecated void contextDump();
+ method public static deprecated android.renderscript.RenderScript create(android.content.Context);
+ method public deprecated void destroy();
+ method public deprecated void finish();
+ method public final deprecated android.content.Context getApplicationContext();
method public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
method public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
method public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
- method public void setPriority(android.renderscript.RenderScript.Priority);
+ method public deprecated void setPriority(android.renderscript.RenderScript.Priority);
}
- public static final class RenderScript.Priority extends java.lang.Enum {
+ public static final deprecated class RenderScript.Priority extends java.lang.Enum {
method public static android.renderscript.RenderScript.Priority valueOf(java.lang.String);
method public static final android.renderscript.RenderScript.Priority[] values();
enum_constant public static final android.renderscript.RenderScript.Priority LOW;
enum_constant public static final android.renderscript.RenderScript.Priority NORMAL;
}
- public static class RenderScript.RSErrorHandler implements java.lang.Runnable {
+ public static deprecated class RenderScript.RSErrorHandler implements java.lang.Runnable {
ctor public RenderScript.RSErrorHandler();
method public void run();
field protected java.lang.String mErrorMessage;
field protected int mErrorNum;
}
- public static class RenderScript.RSMessageHandler implements java.lang.Runnable {
+ public static deprecated class RenderScript.RSMessageHandler implements java.lang.Runnable {
ctor public RenderScript.RSMessageHandler();
method public void run();
field protected int[] mData;
@@ -19066,45 +19125,40 @@
field protected int mLength;
}
- public class RenderScriptGL extends android.renderscript.RenderScript {
- ctor public RenderScriptGL(android.content.Context, android.renderscript.RenderScriptGL.SurfaceConfig);
- method public void bindProgramFragment(android.renderscript.ProgramFragment);
- method public void bindProgramRaster(android.renderscript.ProgramRaster);
- method public void bindProgramStore(android.renderscript.ProgramStore);
- method public void bindProgramVertex(android.renderscript.ProgramVertex);
- method public void bindRootScript(android.renderscript.Script);
- method public int getHeight();
- method public int getWidth();
- method public void pause();
- method public void resume();
- method public void setSurface(android.view.SurfaceHolder, int, int);
- method public void setSurfaceTexture(android.graphics.SurfaceTexture, int, int);
+ public deprecated class RenderScriptGL extends android.renderscript.RenderScript {
+ ctor public deprecated RenderScriptGL(android.content.Context, android.renderscript.RenderScriptGL.SurfaceConfig);
+ method public deprecated void bindProgramFragment(android.renderscript.ProgramFragment);
+ method public deprecated void bindProgramRaster(android.renderscript.ProgramRaster);
+ method public deprecated void bindProgramStore(android.renderscript.ProgramStore);
+ method public deprecated void bindProgramVertex(android.renderscript.ProgramVertex);
+ method public deprecated void bindRootScript(android.renderscript.Script);
+ method public deprecated int getHeight();
+ method public deprecated int getWidth();
+ method public deprecated void pause();
+ method public deprecated void resume();
+ method public deprecated void setSurface(android.view.SurfaceHolder, int, int);
+ method public deprecated void setSurfaceTexture(android.graphics.SurfaceTexture, int, int);
}
- public static class RenderScriptGL.SurfaceConfig {
+ public static deprecated class RenderScriptGL.SurfaceConfig {
ctor public RenderScriptGL.SurfaceConfig();
ctor public RenderScriptGL.SurfaceConfig(android.renderscript.RenderScriptGL.SurfaceConfig);
- method public void setAlpha(int, int);
- method public void setColor(int, int);
- method public void setDepth(int, int);
- method public void setSamples(int, int, float);
+ method public deprecated void setAlpha(int, int);
+ method public deprecated void setColor(int, int);
+ method public deprecated void setDepth(int, int);
+ method public deprecated void setSamples(int, int, float);
}
- public class Sampler extends android.renderscript.BaseObj {
- method public static android.renderscript.Sampler CLAMP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler CLAMP_NEAREST(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler WRAP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler WRAP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler WRAP_NEAREST(android.renderscript.RenderScript);
- method public float getAnisotropy();
- method public android.renderscript.Sampler.Value getMagnification();
- method public android.renderscript.Sampler.Value getMinification();
- method public android.renderscript.Sampler.Value getWrapS();
- method public android.renderscript.Sampler.Value getWrapT();
+ public deprecated class Sampler extends android.renderscript.BaseObj {
+ method public static deprecated android.renderscript.Sampler CLAMP_LINEAR(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Sampler CLAMP_NEAREST(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Sampler WRAP_LINEAR(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Sampler WRAP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+ method public static deprecated android.renderscript.Sampler WRAP_NEAREST(android.renderscript.RenderScript);
}
- public static class Sampler.Builder {
+ public static deprecated class Sampler.Builder {
ctor public Sampler.Builder(android.renderscript.RenderScript);
method public android.renderscript.Sampler create();
method public void setAnisotropy(float);
@@ -19114,30 +19168,30 @@
method public void setWrapT(android.renderscript.Sampler.Value);
}
- public static final class Sampler.Value extends java.lang.Enum {
+ public static final deprecated class Sampler.Value extends java.lang.Enum {
method public static android.renderscript.Sampler.Value valueOf(java.lang.String);
method public static final android.renderscript.Sampler.Value[] values();
- enum_constant public static final android.renderscript.Sampler.Value CLAMP;
- enum_constant public static final android.renderscript.Sampler.Value LINEAR;
- enum_constant public static final android.renderscript.Sampler.Value LINEAR_MIP_LINEAR;
- enum_constant public static final android.renderscript.Sampler.Value LINEAR_MIP_NEAREST;
- enum_constant public static final android.renderscript.Sampler.Value NEAREST;
- enum_constant public static final android.renderscript.Sampler.Value WRAP;
+ enum_constant public static final deprecated android.renderscript.Sampler.Value CLAMP;
+ enum_constant public static final deprecated android.renderscript.Sampler.Value LINEAR;
+ enum_constant public static final deprecated android.renderscript.Sampler.Value LINEAR_MIP_LINEAR;
+ enum_constant public static final deprecated android.renderscript.Sampler.Value LINEAR_MIP_NEAREST;
+ enum_constant public static final deprecated android.renderscript.Sampler.Value NEAREST;
+ enum_constant public static final deprecated android.renderscript.Sampler.Value WRAP;
}
- public class Script extends android.renderscript.BaseObj {
- method public void bindAllocation(android.renderscript.Allocation, int);
- method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
- method protected void invoke(int);
- method protected void invoke(int, android.renderscript.FieldPacker);
- method public void setTimeZone(java.lang.String);
- method public void setVar(int, float);
- method public void setVar(int, double);
- method public void setVar(int, int);
- method public void setVar(int, long);
- method public void setVar(int, boolean);
- method public void setVar(int, android.renderscript.BaseObj);
- method public void setVar(int, android.renderscript.FieldPacker);
+ public deprecated class Script extends android.renderscript.BaseObj {
+ method public deprecated void bindAllocation(android.renderscript.Allocation, int);
+ method protected deprecated void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
+ method protected deprecated void invoke(int);
+ method protected deprecated void invoke(int, android.renderscript.FieldPacker);
+ method public deprecated void setTimeZone(java.lang.String);
+ method public deprecated void setVar(int, float);
+ method public deprecated void setVar(int, double);
+ method public deprecated void setVar(int, int);
+ method public deprecated void setVar(int, long);
+ method public deprecated void setVar(int, boolean);
+ method public deprecated void setVar(int, android.renderscript.BaseObj);
+ method public deprecated void setVar(int, android.renderscript.FieldPacker);
}
public static class Script.Builder {
@@ -19155,19 +19209,19 @@
field protected android.renderscript.Element mElement;
}
- public class ScriptC extends android.renderscript.Script {
- ctor protected ScriptC(int, android.renderscript.RenderScript);
- ctor protected ScriptC(android.renderscript.RenderScript, android.content.res.Resources, int);
+ public deprecated class ScriptC extends android.renderscript.Script {
+ ctor protected deprecated ScriptC(int, android.renderscript.RenderScript);
+ ctor protected deprecated ScriptC(android.renderscript.RenderScript, android.content.res.Resources, int);
}
- public class Short2 {
+ public deprecated class Short2 {
ctor public Short2();
ctor public Short2(short, short);
field public short x;
field public short y;
}
- public class Short3 {
+ public deprecated class Short3 {
ctor public Short3();
ctor public Short3(short, short, short);
field public short x;
@@ -19175,7 +19229,7 @@
field public short z;
}
- public class Short4 {
+ public deprecated class Short4 {
ctor public Short4();
ctor public Short4(short, short, short, short);
field public short w;
@@ -19184,22 +19238,22 @@
field public short z;
}
- public class Type extends android.renderscript.BaseObj {
- method public int getCount();
- method public android.renderscript.Element getElement();
- method public int getX();
- method public int getY();
- method public int getZ();
- method public boolean hasFaces();
- method public boolean hasMipmaps();
+ public deprecated class Type extends android.renderscript.BaseObj {
+ method public deprecated int getCount();
+ method public deprecated android.renderscript.Element getElement();
+ method public deprecated int getX();
+ method public deprecated int getY();
+ method public deprecated int getZ();
+ method public deprecated boolean hasFaces();
+ method public deprecated boolean hasMipmaps();
}
- public static class Type.Builder {
- ctor public Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
- method public android.renderscript.Type create();
+ public static deprecated class Type.Builder {
+ ctor public deprecated Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
+ method public deprecated android.renderscript.Type create();
method public android.renderscript.Type.Builder setFaces(boolean);
method public android.renderscript.Type.Builder setMipmaps(boolean);
- method public android.renderscript.Type.Builder setX(int);
+ method public deprecated android.renderscript.Type.Builder setX(int);
method public android.renderscript.Type.Builder setY(int);
}
@@ -22468,6 +22522,7 @@
}
public class Display {
+ method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
method public int getDisplayId();
method public deprecated int getHeight();
method public void getMetrics(android.util.DisplayMetrics);
@@ -22664,6 +22719,7 @@
method public int describeContents();
method public final android.view.InputDevice getDevice();
method public abstract int getDeviceId();
+ method public abstract long getEventTime();
method public abstract int getSource();
field public static final android.os.Parcelable.Creator CREATOR;
}
@@ -23874,7 +23930,7 @@
method public void onWindowSystemUiVisibilityChanged(int);
method protected void onWindowVisibilityChanged(int);
method protected boolean overScrollBy(int, int, int, int, int, int, int, int, boolean);
- method public boolean performAccessibilityAction(int);
+ method public boolean performAccessibilityAction(int, android.os.Bundle);
method public boolean performClick();
method public boolean performHapticFeedback(int);
method public boolean performHapticFeedback(int, int);
@@ -24026,7 +24082,9 @@
field public static final int ACCESSIBILITY_FOCUS_FORWARD = 4098; // 0x1002
field public static final int ACCESSIBILITY_FOCUS_IN = 4100; // 0x1004
field public static final int ACCESSIBILITY_FOCUS_LEFT = 4113; // 0x1011
+ field public static final int ACCESSIBILITY_FOCUS_NEXT = 4112; // 0x1010
field public static final int ACCESSIBILITY_FOCUS_OUT = 4104; // 0x1008
+ field public static final int ACCESSIBILITY_FOCUS_PREVIOUS = 4128; // 0x1020
field public static final int ACCESSIBILITY_FOCUS_RIGHT = 4162; // 0x1042
field public static final int ACCESSIBILITY_FOCUS_UP = 4129; // 0x1021
field public static final android.util.Property ALPHA;
@@ -24943,6 +25001,7 @@
method public int getChildCount();
method public java.lang.CharSequence getClassName();
method public java.lang.CharSequence getContentDescription();
+ method public java.lang.CharSequence[] getGranularities();
method public java.lang.CharSequence getPackageName();
method public android.view.accessibility.AccessibilityNodeInfo getParent();
method public java.lang.CharSequence getText();
@@ -24963,6 +25022,7 @@
method public static android.view.accessibility.AccessibilityNodeInfo obtain();
method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.accessibility.AccessibilityNodeInfo);
method public boolean performAction(int);
+ method public boolean performAction(int, android.os.Bundle);
method public void recycle();
method public void setAccessibilityFocused(boolean);
method public void setBoundsInParent(android.graphics.Rect);
@@ -24975,6 +25035,7 @@
method public void setEnabled(boolean);
method public void setFocusable(boolean);
method public void setFocused(boolean);
+ method public void setGranularities(java.lang.CharSequence[]);
method public void setLongClickable(boolean);
method public void setPackageName(java.lang.CharSequence);
method public void setParent(android.view.View);
@@ -24986,12 +25047,16 @@
method public void setSource(android.view.View, int);
method public void setText(java.lang.CharSequence);
method public void writeToParcel(android.os.Parcel, int);
- field public static final int ACTION_ACCESSIBILITY_FOCUS = 16; // 0x10
- field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 32; // 0x20
+ field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
+ field public static final java.lang.String ACTION_ARGUMENT_GRANULARITY = "ACTION_ARGUMENT_GRANULARITY";
+ field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
- field public static final int ACTION_CLICK = 64; // 0x40
+ field public static final int ACTION_CLICK = 16; // 0x10
field public static final int ACTION_FOCUS = 1; // 0x1
+ field public static final int ACTION_LONG_CLICK = 32; // 0x20
+ field public static final int ACTION_NEXT_AT_GRANULARITY = 256; // 0x100
+ field public static final int ACTION_PREVIOUS_AT_GRANULARITY = 512; // 0x200
field public static final int ACTION_SELECT = 4; // 0x4
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
@@ -25004,7 +25069,7 @@
method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int);
method public android.view.accessibility.AccessibilityNodeInfo findAccessibilitiyFocus(int);
method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
- method public boolean performAccessibilityAction(int, int);
+ method public boolean performAction(int, int, android.os.Bundle);
}
public class AccessibilityRecord {
@@ -25952,10 +26017,12 @@
method public void setMimeType(java.lang.String);
}
- public class WebSettings {
+ public abstract class WebSettings {
method public boolean enableSmoothTransition();
method public boolean getAllowContentAccess();
method public boolean getAllowFileAccess();
+ method public abstract boolean getAllowFileAccessFromFileURLs();
+ method public abstract boolean getAllowUniversalAccessFromFileURLs();
method public synchronized boolean getBlockNetworkImage();
method public synchronized boolean getBlockNetworkLoads();
method public boolean getBuiltInZoomControls();
@@ -25997,6 +26064,8 @@
method public synchronized java.lang.String getUserAgentString();
method public void setAllowContentAccess(boolean);
method public void setAllowFileAccess(boolean);
+ method public abstract void setAllowFileAccessFromFileURLs(boolean);
+ method public abstract void setAllowUniversalAccessFromFileURLs(boolean);
method public synchronized void setAppCacheEnabled(boolean);
method public synchronized void setAppCacheMaxSize(long);
method public synchronized void setAppCachePath(java.lang.String);
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 53a0186..8cd8900 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -194,6 +194,12 @@
String key = nextArgRequired();
String value = nextArgRequired();
intent.putExtra(key, Uri.parse(value));
+ } else if (opt.equals("--ecn")) {
+ String key = nextArgRequired();
+ String value = nextArgRequired();
+ ComponentName cn = ComponentName.unflattenFromString(value);
+ if (cn == null) throw new IllegalArgumentException("Bad component name: " + value);
+ intent.putExtra(key, cn);
} else if (opt.equals("--eia")) {
String key = nextArgRequired();
String value = nextArgRequired();
@@ -1366,6 +1372,7 @@
" [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]\n" +
" [--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]\n" +
" [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]\n" +
+ " [--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]\n" +
" [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
" [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
" [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 3da35d3..c858e3c 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -19,22 +19,17 @@
import android.app.Service;
import android.content.Context;
import android.content.Intent;
-import android.content.res.Configuration;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
-import android.util.LocaleUtil;
import android.util.Log;
-import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.os.HandlerCaller;
-import java.util.Locale;
-
/**
* An accessibility service runs in the background and receives callbacks by the system
* when {@link AccessibilityEvent}s are fired. Such events denote some state transition
@@ -259,13 +254,61 @@
public static final int GESTURE_COUNTER_CLOCKWISE_CIRCLE = 10;
/**
+ * The user has performed a left and up gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_LEFT_AND_UP = 11;
+
+ /**
+ * The user has performed a left and down gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 12;
+
+ /**
+ * The user has performed a right and up gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_RIGHT_AND_UP = 13;
+
+ /**
+ * The user has performed a right and down gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 14;
+
+ /**
+ * The user has performed an up and left gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_UP_AND_LEFT = 15;
+
+ /**
+ * The user has performed an up and right gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_UP_AND_RIGHT = 16;
+
+ /**
+ * The user has performed an down and left gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 17;
+
+ /**
+ * The user has performed an down and right gesture on the touch screen.
+ */
+ public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18;
+
+ /**
+ * The user has performed a two finger tap gesture on the touch screen.
+ */
+ public static final int GESTURE_TWO_FINGER_TAP = 19;
+
+ /**
+ * The user has performed a two finger long press gesture on the touch screen.
+ */
+ public static final int GESTURE_TWO_FINGER_LONG_PRESS = 20;
+
+ /**
* The {@link Intent} that must be declared as handled by the service.
*/
public static final String SERVICE_INTERFACE =
"android.accessibilityservice.AccessibilityService";
- private static final int UNDEFINED = -1;
-
/**
* Name under which an AccessibilityService component publishes information
* about itself. This meta-data must reference an XML resource containing an
@@ -284,6 +327,26 @@
*/
public static final String SERVICE_META_DATA = "android.accessibilityservice";
+ /**
+ * Action to go back.
+ */
+ public static final int GLOBAL_ACTION_BACK = 1;
+
+ /**
+ * Action to go home.
+ */
+ public static final int GLOBAL_ACTION_HOME = 2;
+
+ /**
+ * Action to open the recents.
+ */
+ public static final int GLOBAL_ACTION_RECENTS = 3;
+
+ /**
+ * Action to open the notifications.
+ */
+ public static final int GLOBAL_ACTION_NOTIFICATIONS = 4;
+
private static final String LOG_TAG = "AccessibilityService";
interface Callbacks {
@@ -291,15 +354,13 @@
public void onInterrupt();
public void onServiceConnected();
public void onSetConnectionId(int connectionId);
- public void onGesture(int gestureId);
+ public boolean onGesture(int gestureId);
}
private int mConnectionId;
private AccessibilityServiceInfo mInfo;
- private int mLayoutDirection;
-
/**
* Callback for {@link android.view.accessibility.AccessibilityEvent}s.
*
@@ -326,79 +387,80 @@
/**
* Called by the system when the user performs a specific gesture on the
- * touch screen.
+ * touch screen. If the gesture is not handled in this callback the system
+ * may provide default handing. Therefore, one should return true from this
+ * function if overriding of default behavior is desired.
+ *
+ * <strong>Note:</strong> To receive gestures an accessibility service
+ * must declare that it can handle such by specifying the
+ * <code><{@link android.R.styleable#AccessibilityService_canHandleGestures
+ * canHandleGestures}></code> attribute.
*
* @param gestureId The unique id of the performed gesture.
*
+ * @return Whether the gesture was handled.
+ *
* @see #GESTURE_SWIPE_UP
- * @see #GESTURE_SWIPE_DOWN
- * @see #GESTURE_SWIPE_LEFT
- * @see #GESTURE_SWIPE_RIGHT
+ * @see #GESTURE_SWIPE_UP_AND_LEFT
* @see #GESTURE_SWIPE_UP_AND_DOWN
+ * @see #GESTURE_SWIPE_UP_AND_RIGHT
+ * @see #GESTURE_SWIPE_DOWN
+ * @see #GESTURE_SWIPE_DOWN_AND_LEFT
* @see #GESTURE_SWIPE_DOWN_AND_UP
+ * @see #GESTURE_SWIPE_DOWN_AND_RIGHT
+ * @see #GESTURE_SWIPE_LEFT
+ * @see #GESTURE_SWIPE_LEFT_AND_UP
* @see #GESTURE_SWIPE_LEFT_AND_RIGHT
+ * @see #GESTURE_SWIPE_LEFT_AND_DOWN
+ * @see #GESTURE_SWIPE_RIGHT
+ * @see #GESTURE_SWIPE_RIGHT_AND_UP
* @see #GESTURE_SWIPE_RIGHT_AND_LEFT
+ * @see #GESTURE_SWIPE_RIGHT_AND_DOWN
* @see #GESTURE_CLOCKWISE_CIRCLE
* @see #GESTURE_COUNTER_CLOCKWISE_CIRCLE
+ * @see #GESTURE_TWO_FINGER_TAP
+ * @see #GESTURE_TWO_FINGER_LONG_PRESS
*/
- protected void onGesture(int gestureId) {
+ protected boolean onGesture(int gestureId) {
// TODO: Describe the default gesture processing in the javaDoc once it is finalized.
+ return false;
+ }
- // Cache the id to avoid locking
- final int connectionId = mConnectionId;
- if (connectionId == UNDEFINED) {
- throw new IllegalStateException("AccessibilityService not connected."
- + " Did you receive a call of onServiceConnected()?");
+ /**
+ * Gets the root node in the currently active window if this service
+ * can retrieve window content.
+ *
+ * @return The root node if this service can retrieve window content.
+ */
+ public AccessibilityNodeInfo getRootInActiveWindow() {
+ return AccessibilityInteractionClient.getInstance().getRootInActiveWindow(mConnectionId);
+ }
+
+ /**
+ * Performs a global action. Such an action can be performed
+ * at any moment regardless of the current application or user
+ * location in that application. For example going back, going
+ * home, opening recents, etc.
+ *
+ * @param action The action to perform.
+ * @return Whether the action was successfully performed.
+ *
+ * @see #GLOBAL_ACTION_BACK
+ * @see #GLOBAL_ACTION_HOME
+ * @see #GLOBAL_ACTION_NOTIFICATIONS
+ * @see #GLOBAL_ACTION_RECENTS
+ */
+ public final boolean performGlobalAction(int action) {
+ IAccessibilityServiceConnection connection =
+ AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+ if (connection != null) {
+ try {
+ return connection.performGlobalAction(action);
+ } catch (RemoteException re) {
+ Log.w(LOG_TAG, "Error while calling performGlobalAction", re);
+ }
}
- AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance()
- .findAccessibilityNodeInfoByAccessibilityId(connectionId,
- AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
- if (root == null) {
- return;
- }
- AccessibilityNodeInfo current = root.findFocus(View.FOCUS_ACCESSIBILITY);
- if (current == null) {
- current = root;
- }
- AccessibilityNodeInfo next = null;
- switch (gestureId) {
- case GESTURE_SWIPE_UP: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_OUT);
- } break;
- case GESTURE_SWIPE_DOWN: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_IN);
- } break;
- case GESTURE_SWIPE_LEFT: {
- if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD);
- } else { // LAYOUT_DIRECTION_RTL
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD);
- }
- } break;
- case GESTURE_SWIPE_RIGHT: {
- if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD);
- } else { // LAYOUT_DIRECTION_RTL
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD);
- }
- } break;
- case GESTURE_SWIPE_UP_AND_DOWN: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_UP);
- } break;
- case GESTURE_SWIPE_DOWN_AND_UP: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_DOWN);
- } break;
- case GESTURE_SWIPE_LEFT_AND_RIGHT: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_LEFT);
- } break;
- case GESTURE_SWIPE_RIGHT_AND_LEFT: {
- next = current.focusSearch(View.ACCESSIBILITY_FOCUS_RIGHT);
- } break;
- }
- if (next != null && !next.equals(current)) {
- next.performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
- }
+ return false;
}
/**
@@ -456,18 +518,6 @@
}
}
- @Override
- public void onCreate() {
- Locale locale = getResources().getConfiguration().locale;
- mLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale);
- }
-
- @Override
- public void onConfigurationChanged(Configuration configuration) {
- super.onConfigurationChanged(configuration);
- mLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(configuration.locale);
- }
-
/**
* Implement to return the implementation of the internal accessibility
* service interface.
@@ -496,8 +546,8 @@
}
@Override
- public void onGesture(int gestureId) {
- AccessibilityService.this.onGesture(gestureId);
+ public boolean onGesture(int gestureId) {
+ return AccessibilityService.this.onGesture(gestureId);
}
});
}
@@ -542,8 +592,10 @@
mCaller.sendMessage(message);
}
- public void onGesture(int gestureId) {
- Message message = mCaller.obtainMessageI(DO_ON_GESTURE, gestureId);
+ public void onGesture(int gestureId, IAccessibilityServiceClientCallback callback,
+ int interactionId) {
+ Message message = mCaller.obtainMessageIIO(DO_ON_GESTURE, gestureId, interactionId,
+ callback);
mCaller.sendMessage(message);
}
@@ -576,7 +628,15 @@
return;
case DO_ON_GESTURE :
final int gestureId = message.arg1;
- mCallback.onGesture(gestureId);
+ final int interactionId = message.arg2;
+ IAccessibilityServiceClientCallback callback =
+ (IAccessibilityServiceClientCallback) message.obj;
+ final boolean handled = mCallback.onGesture(gestureId);
+ try {
+ callback.setGestureResult(gestureId, handled, interactionId);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error calling back with the gesture resut.", re);
+ }
return;
default :
Log.w(LOG_TAG, "Unknown message type " + message.what);
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index e77ed9a..7e6786b 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -224,6 +224,11 @@
private boolean mCanRetrieveWindowContent;
/**
+ * Flag whether this accessibility service can handle gestures.
+ */
+ private boolean mCanHandleGestures;
+
+ /**
* Resource id of the description of the accessibility service.
*/
private int mDescriptionResId;
@@ -303,6 +308,8 @@
mCanRetrieveWindowContent = asAttributes.getBoolean(
com.android.internal.R.styleable.AccessibilityService_canRetrieveWindowContent,
false);
+ mCanHandleGestures = asAttributes.getBoolean(
+ com.android.internal.R.styleable.AccessibilityService_canHandleGestures, false);
TypedValue peekedValue = asAttributes.peekValue(
com.android.internal.R.styleable.AccessibilityService_description);
if (peekedValue != null) {
@@ -378,13 +385,25 @@
* <strong>Statically set from
* {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
* </p>
- * @return True window content can be retrieved.
+ * @return True if window content can be retrieved.
*/
public boolean getCanRetrieveWindowContent() {
return mCanRetrieveWindowContent;
}
/**
+ * Whether this service can handle gestures.
+ * <p>
+ * <strong>Statically set from
+ * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
+ * </p>
+ * @return True if the service can handle gestures.
+ */
+ public boolean getCanHandleGestures() {
+ return mCanHandleGestures;
+ }
+
+ /**
* Gets the non-localized description of the accessibility service.
* <p>
* <strong>Statically set from
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
index 588728c..0257aa4 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
@@ -16,6 +16,7 @@
package android.accessibilityservice;
+import android.accessibilityservice.IAccessibilityServiceClientCallback;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.view.accessibility.AccessibilityEvent;
@@ -32,5 +33,5 @@
void onInterrupt();
- void onGesture(int gestureId);
+ void onGesture(int gesture, in IAccessibilityServiceClientCallback callback, int interactionId);
}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl
new file mode 100644
index 0000000..9061398
--- /dev/null
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl
@@ -0,0 +1,30 @@
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.accessibilityservice;
+
+import android.accessibilityservice.IAccessibilityServiceConnection;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * Callback for IAccessibilityServiceClient.
+ *
+ * @hide
+ */
+ oneway interface IAccessibilityServiceClientCallback {
+
+ void setGestureResult(int gestureId, boolean handled, int interactionId);
+}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 30da9db..dd50f3c 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -16,6 +16,7 @@
package android.accessibilityservice;
+import android.os.Bundle;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
@@ -147,17 +148,26 @@
* {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
* to start from the root.
* @param action The action to perform.
+ * @param arguments Optional action arguments.
* @param interactionId The id of the interaction for matching with the callback result.
* @param callback Callback which to receive the result.
* @param threadId The id of the calling thread.
* @return Whether the action was performed.
*/
boolean performAccessibilityAction(int accessibilityWindowId, long accessibilityNodeId,
- int action, int interactionId, IAccessibilityInteractionConnectionCallback callback,
- long threadId);
+ int action, in Bundle arguments, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long threadId);
/**
* @return The associated accessibility service info.
*/
AccessibilityServiceInfo getServiceInfo();
+
+ /**
+ * Performs a global action, such as going home, going back, etc.
+ *
+ * @param action The action to perform.
+ * @return Whether the action was performed.
+ */
+ boolean performGlobalAction(int action);
}
diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
index c840bd6..4d4bfeb 100644
--- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java
+++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
@@ -19,6 +19,7 @@
import android.accessibilityservice.AccessibilityService.Callbacks;
import android.accessibilityservice.AccessibilityService.IAccessibilityServiceClientWrapper;
import android.content.Context;
+import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.RemoteException;
@@ -177,8 +178,8 @@
}
@Override
- public void onGesture(int gestureId) {
- /* do nothing */
+ public boolean onGesture(int gestureId) {
+ return false;
}
});
@@ -444,10 +445,12 @@
*
* @param accessibilityNodeId A unique node id (accessibility and virtual descendant id).
* @param action The action to perform.
+ * @param arguments Optional action arguments.
* @return Whether the action was performed.
*/
- public boolean performAccessibilityActionInActiveWindow(long accessibilityNodeId, int action) {
- return performAccessibilityAction(ACTIVE_WINDOW_ID, accessibilityNodeId, action);
+ public boolean performAccessibilityActionInActiveWindow(long accessibilityNodeId, int action,
+ Bundle arguments) {
+ return performAccessibilityAction(ACTIVE_WINDOW_ID, accessibilityNodeId, action, arguments);
}
/**
@@ -457,15 +460,16 @@
* {@link #ACTIVE_WINDOW_ID} to query the currently active window.
* @param accessibilityNodeId A unique node id (accessibility and virtual descendant id).
* @param action The action to perform.
+ * @param arguments Optional action arguments.
* @return Whether the action was performed.
*/
public boolean performAccessibilityAction(int accessibilityWindowId, long accessibilityNodeId,
- int action) {
+ int action, Bundle arguments) {
// Cache the id to avoid locking
final int connectionId = mConnectionId;
ensureValidConnection(connectionId);
return AccessibilityInteractionClient.getInstance().performAccessibilityAction(connectionId,
- accessibilityWindowId, accessibilityNodeId, action);
+ accessibilityWindowId, accessibilityNodeId, action, arguments);
}
/**
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 871bb2c..c643137 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -1005,6 +1005,8 @@
anim.start();
anim.end();
}
+ // listeners should clean up the currentChangingAnimations list, but just in case...
+ currentChangingAnimations.clear();
}
/**
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index fade20c..2154b14 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -150,6 +150,13 @@
private boolean mStarted = false;
/**
+ * Tracks whether we've notified listeners of the onAnimationSTart() event. This can be
+ * complex to keep track of since we notify listeners at different times depending on
+ * startDelay and whether start() was called before end().
+ */
+ private boolean mStartListenersCalled = false;
+
+ /**
* Flag that denotes whether the animation is set up and ready to go. Used to
* set up animation that has not yet been started.
*/
@@ -885,6 +892,18 @@
}
}
+ private void notifyStartListeners() {
+ if (mListeners != null && !mStartListenersCalled) {
+ ArrayList<AnimatorListener> tmpListeners =
+ (ArrayList<AnimatorListener>) mListeners.clone();
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationStart(this);
+ }
+ }
+ mStartListenersCalled = true;
+ }
+
/**
* Start the animation playing. This version of start() takes a boolean flag that indicates
* whether the animation should play in reverse. The flag is usually false, but may be set
@@ -914,15 +933,7 @@
setCurrentPlayTime(getCurrentPlayTime());
mPlayingState = STOPPED;
mRunning = true;
-
- if (mListeners != null) {
- ArrayList<AnimatorListener> tmpListeners =
- (ArrayList<AnimatorListener>) mListeners.clone();
- int numListeners = tmpListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- tmpListeners.get(i).onAnimationStart(this);
- }
- }
+ notifyStartListeners();
}
animationHandler.sendEmptyMessage(ANIMATION_START);
}
@@ -941,7 +952,11 @@
|| handler.mPendingAnimations.contains(this)
|| handler.mDelayedAnims.contains(this)) {
// Only notify listeners if the animator has actually started
- if (mRunning && mListeners != null) {
+ if ((mStarted || mRunning) && mListeners != null) {
+ if (!mRunning) {
+ // If it's not yet running, then start listeners weren't called. Call them now.
+ notifyStartListeners();
+ }
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
for (AnimatorListener listener : tmpListeners) {
@@ -959,6 +974,7 @@
// Special case if the animation has not yet started; get it ready for ending
mStartedDelay = false;
startAnimation(handler);
+ mStarted = true;
} else if (!mInitialized) {
initAnimation();
}
@@ -1010,7 +1026,11 @@
handler.mPendingAnimations.remove(this);
handler.mDelayedAnims.remove(this);
mPlayingState = STOPPED;
- if (mRunning && mListeners != null) {
+ if ((mStarted || mRunning) && mListeners != null) {
+ if (!mRunning) {
+ // If it's not yet running, then start listeners weren't called. Call them now.
+ notifyStartListeners();
+ }
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
int numListeners = tmpListeners.size();
@@ -1020,6 +1040,7 @@
}
mRunning = false;
mStarted = false;
+ mStartListenersCalled = false;
}
/**
@@ -1032,12 +1053,7 @@
if (mStartDelay > 0 && mListeners != null) {
// Listeners were already notified in start() if startDelay is 0; this is
// just for delayed animations
- ArrayList<AnimatorListener> tmpListeners =
- (ArrayList<AnimatorListener>) mListeners.clone();
- int numListeners = tmpListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- tmpListeners.get(i).onAnimationStart(this);
- }
+ notifyStartListeners();
}
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 1c820dc..35bc7ff 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -549,7 +549,7 @@
* super.onCreate(savedInstanceState);
*
* SharedPreferences mPrefs = getSharedPreferences();
- * mCurViewMode = mPrefs.getInt("view_mode" DAY_VIEW_MODE);
+ * mCurViewMode = mPrefs.getInt("view_mode", DAY_VIEW_MODE);
* }
*
* protected void onPause() {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1489b2c..e2e791b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3765,9 +3765,11 @@
final void handleTrimMemory(int level) {
if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
- WindowManagerImpl.getDefault().trimMemory(level);
- ArrayList<ComponentCallbacks2> callbacks;
+ final WindowManagerImpl windowManager = WindowManagerImpl.getDefault();
+ windowManager.startTrimMemory(level);
+
+ ArrayList<ComponentCallbacks2> callbacks;
synchronized (mPackages) {
callbacks = collectComponentCallbacksLocked(true, null);
}
@@ -3776,7 +3778,8 @@
for (int i = 0; i < N; i++) {
callbacks.get(i).onTrimMemory(level);
}
- WindowManagerImpl.getDefault().terminateEgl();
+
+ windowManager.endTrimMemory();
}
private void setupGraphicsSupport(LoadedApk info) {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 8942135..64a05a8 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1480,7 +1480,9 @@
public Context createPackageContext(String packageName, int flags)
throws PackageManager.NameNotFoundException {
if (packageName.equals("system") || packageName.equals("android")) {
- return new ContextImpl(mMainThread.getSystemContext());
+ final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
+ context.mBasePackageName = mBasePackageName;
+ return context;
}
LoadedApk pi =
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 55f29e6..0713127 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -347,9 +347,9 @@
private CharSequence mTitle;
private CharSequence mDescription;
private String mMimeType;
- private boolean mRoamingAllowed = true;
private int mAllowedNetworkTypes = ~0; // default to all network types allowed
- private boolean mAllowedOverMetered = true;
+ private boolean mRoamingAllowed = true;
+ private boolean mMeteredAllowed = true;
private boolean mIsVisibleInDownloadsUi = true;
private boolean mScannable = false;
private boolean mUseSystemCache = false;
@@ -624,17 +624,6 @@
}
/**
- * Set whether this download may proceed over a metered network
- * connection. By default, metered networks are allowed.
- *
- * @see ConnectivityManager#isActiveNetworkMetered()
- */
- public Request setAllowedOverMetered(boolean allow) {
- mAllowedOverMetered = allow;
- return this;
- }
-
- /**
* Set whether this download may proceed over a roaming connection. By default, roaming is
* allowed.
* @param allowed whether to allow a roaming connection to be used
@@ -646,6 +635,17 @@
}
/**
+ * Set whether this download may proceed over a metered network
+ * connection. By default, metered networks are allowed.
+ *
+ * @see ConnectivityManager#isActiveNetworkMetered()
+ */
+ public Request setAllowedOverMetered(boolean allow) {
+ mMeteredAllowed = allow;
+ return this;
+ }
+
+ /**
* Set whether this download should be displayed in the system's Downloads UI. True by
* default.
* @param isVisible whether to display this download in the Downloads UI
@@ -687,10 +687,10 @@
putIfNonNull(values, Downloads.Impl.COLUMN_DESCRIPTION, mDescription);
putIfNonNull(values, Downloads.Impl.COLUMN_MIME_TYPE, mMimeType);
- // TODO: add COLUMN_ALLOW_METERED and persist
values.put(Downloads.Impl.COLUMN_VISIBILITY, mNotificationVisibility);
values.put(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES, mAllowedNetworkTypes);
values.put(Downloads.Impl.COLUMN_ALLOW_ROAMING, mRoamingAllowed);
+ values.put(Downloads.Impl.COLUMN_ALLOW_METERED, mMeteredAllowed);
values.put(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI, mIsVisibleInDownloadsUi);
return values;
@@ -1340,9 +1340,6 @@
case Downloads.Impl.STATUS_FILE_ALREADY_EXISTS_ERROR:
return ERROR_FILE_ALREADY_EXISTS;
- case Downloads.Impl.STATUS_BLOCKED:
- return ERROR_BLOCKED;
-
default:
return ERROR_UNKNOWN;
}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 4d5238c..6f95e26 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -34,5 +34,8 @@
void cancelToast(String pkg, ITransientNotification callback);
void enqueueNotificationWithTag(String pkg, String tag, int id, in Notification notification, inout int[] idReceived);
void cancelNotificationWithTag(String pkg, String tag, int id);
+
+ void setNotificationsEnabledForPackage(String pkg, boolean enabled);
+ boolean areNotificationsEnabledForPackage(String pkg);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 5cce25f..0a996df 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -190,12 +190,6 @@
public RemoteViews contentView;
/**
- * The view that will represent this notification in the pop-up "intruder alert" dialog.
- * @hide
- */
- public RemoteViews intruderView;
-
- /**
* A large-format version of {@link #contentView}, giving the Notification an
* opportunity to show more detail. The system UI may choose to show this
* instead of the normal content view at its discretion.
@@ -590,9 +584,6 @@
actions = parcel.createTypedArray(Action.CREATOR);
if (parcel.readInt() != 0) {
- intruderView = RemoteViews.CREATOR.createFromParcel(parcel);
- }
- if (parcel.readInt() != 0) {
bigContentView = RemoteViews.CREATOR.createFromParcel(parcel);
}
}
@@ -658,9 +649,6 @@
for(int i=0; i<this.actions.length; i++) {
that.actions[i] = this.actions[i].clone();
}
- if (this.intruderView != null) {
- that.intruderView = this.intruderView.clone();
- }
if (this.bigContentView != null) {
that.bigContentView = this.bigContentView.clone();
}
@@ -755,13 +743,6 @@
parcel.writeTypedArray(actions, 0);
- if (intruderView != null) {
- parcel.writeInt(1);
- intruderView.writeToParcel(parcel, 0);
- } else {
- parcel.writeInt(0);
- }
-
if (bigContentView != null) {
parcel.writeInt(1);
bigContentView.writeToParcel(parcel, 0);
@@ -942,8 +923,6 @@
private Bundle mExtras;
private int mPriority;
private ArrayList<Action> mActions = new ArrayList<Action>(3);
- private boolean mCanHasIntruder;
- private boolean mIntruderActionsShowText;
private boolean mUseChronometer;
/**
@@ -1349,38 +1328,6 @@
return this;
}
- /**
- * Specify whether this notification should pop up as an
- * "intruder alert" (a small window that shares the screen with the
- * current activity). This sort of notification is (as the name implies)
- * very intrusive, so use it sparingly for notifications that require
- * the user's attention.
- *
- * Notes:
- * <ul>
- * <li>Intruder alerts only show when the screen is on.</li>
- * <li>Intruder alerts take precedence over fullScreenIntents.</li>
- * </ul>
- *
- * @param intrude Whether to pop up an intruder alert (default false).
- */
- public Builder setUsesIntruderAlert(boolean intrude) {
- mCanHasIntruder = intrude;
- return this;
- }
-
- /**
- * Control text on intruder alert action buttons. By default, action
- * buttons in intruders do not show textual labels.
- *
- * @param showActionText Whether to show text labels beneath action
- * icons (default false).
- */
- public Builder setIntruderActionsShowText(boolean showActionText) {
- mIntruderActionsShowText = showActionText;
- return this;
- }
-
private void setFlag(int mask, boolean value) {
if (value) {
mFlags |= mask;
@@ -1503,46 +1450,7 @@
private RemoteViews makeBigContentView() {
if (mActions.size() == 0) return null;
- return applyStandardTemplateWithActions(R.layout.notification_template_base);
- }
-
- private RemoteViews makeIntruderView(boolean showLabels) {
- RemoteViews intruderView = new RemoteViews(mContext.getPackageName(),
- R.layout.notification_intruder_content);
- if (mLargeIcon != null) {
- intruderView.setImageViewBitmap(R.id.icon, mLargeIcon);
- intruderView.setViewVisibility(R.id.icon, View.VISIBLE);
- } else if (mSmallIcon != 0) {
- intruderView.setImageViewResource(R.id.icon, mSmallIcon);
- intruderView.setViewVisibility(R.id.icon, View.VISIBLE);
- } else {
- intruderView.setViewVisibility(R.id.icon, View.GONE);
- }
- if (mContentTitle != null) {
- intruderView.setTextViewText(R.id.title, mContentTitle);
- }
- if (mContentText != null) {
- intruderView.setTextViewText(R.id.text, mContentText);
- }
- if (mActions.size() > 0) {
- intruderView.setViewVisibility(R.id.actions, View.VISIBLE);
- int N = mActions.size();
- if (N>3) N=3;
- final int[] BUTTONS = { R.id.action0, R.id.action1, R.id.action2 };
- for (int i=0; i<N; i++) {
- final Action action = mActions.get(i);
- final int buttonId = BUTTONS[i];
-
- intruderView.setViewVisibility(buttonId, View.VISIBLE);
- intruderView.setTextViewText(buttonId, showLabels ? action.title : null);
- intruderView.setTextViewCompoundDrawables(buttonId, 0, action.icon, 0, 0);
- intruderView.setContentDescription(buttonId, action.title);
- intruderView.setOnClickPendingIntent(buttonId, action.actionIntent);
- }
- } else {
- intruderView.setViewVisibility(R.id.actions, View.GONE);
- }
- return intruderView;
+ return applyStandardTemplateWithActions(R.layout.notification_template_big_base);
}
private RemoteViews generateActionButton(Action action) {
@@ -1579,9 +1487,6 @@
n.ledOffMS = mLedOffMs;
n.defaults = mDefaults;
n.flags = mFlags;
- if (mCanHasIntruder) {
- n.intruderView = makeIntruderView(mIntruderActionsShowText);
- }
n.bigContentView = makeBigContentView();
if (mLedOnMs != 0 && mLedOffMs != 0) {
n.flags |= FLAG_SHOW_LIGHTS;
@@ -1681,7 +1586,7 @@
}
private RemoteViews makeBigContentView() {
- RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(R.layout.notification_template_base);
+ RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(R.layout.notification_template_big_text);
contentView.setTextViewText(R.id.big_text, mBigText);
contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
@@ -1696,4 +1601,60 @@
return wip;
}
}
+
+ /**
+ * Helper class for generating large-format notifications that include a list of (up to 5) strings.
+ *
+ * This class is a "rebuilder": It consumes a Builder object and modifies its behavior, like so:
+ * <pre class="prettyprint">
+ * Notification noti = new Notification.DigestStyle(
+ * new Notification.Builder()
+ * .setContentTitle("New mail from " + sender.toString())
+ * .setContentText(subject)
+ * .setSmallIcon(R.drawable.new_mail)
+ * .setLargeIcon(aBitmap))
+ * .addLine(str1)
+ * .addLine(str2)
+ * .build();
+ * </pre>
+ *
+ * @see Notification#bigContentView
+ */
+ public static class InboxStyle {
+ private Builder mBuilder;
+ private ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(5);
+
+ public InboxStyle(Builder builder) {
+ mBuilder = builder;
+ }
+
+ public InboxStyle addLine(CharSequence cs) {
+ mTexts.add(cs);
+ return this;
+ }
+
+ private RemoteViews makeBigContentView() {
+ RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(R.layout.notification_template_inbox);
+
+ int[] rowIds = {R.id.inbox_text0, R.id.inbox_text1, R.id.inbox_text2, R.id.inbox_text3, R.id.inbox_text4};
+
+ int i=0;
+ while (i < mTexts.size() && i < rowIds.length) {
+ CharSequence str = mTexts.get(i);
+ if (str != null && !str.equals("")) {
+ contentView.setViewVisibility(rowIds[i], View.VISIBLE);
+ contentView.setTextViewText(rowIds[i], str);
+ }
+ i++;
+ }
+
+ return contentView;
+ }
+
+ public Notification build() {
+ Notification wip = mBuilder.getNotification();
+ wip.bigContentView = makeBigContentView();
+ return wip;
+ }
+ }
}
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
index 7fd4747..e2d28dd 100644
--- a/core/java/android/app/TaskStackBuilder.java
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -91,8 +91,10 @@
/**
* Add the activity parent chain as specified by the
- * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
- * (or activity-alias) element in the application's manifest to the task stack builder.
+ * {@link Activity#getParentActivityIntent() getParentActivityIntent()} method of the activity
+ * specified and the {@link android.R.attr#parentActivityName parentActivityName} attributes
+ * of each successive activity (or activity-alias) element in the application's manifest
+ * to the task stack builder.
*
* @param sourceActivity All parents of this activity will be added
* @return This TaskStackBuilder for method chaining
@@ -156,6 +158,41 @@
}
/**
+ * Add the activity parent chain as specified by the
+ * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
+ * (or activity-alias) element in the application's manifest to the task stack builder.
+ *
+ * @param sourceActivityName Must specify an Activity component. All parents of
+ * this activity will be added
+ * @return This TaskStackBuilder for method chaining
+ */
+ public TaskStackBuilder addParentStack(ComponentName sourceActivityName) {
+ final int insertAt = mIntents.size();
+ PackageManager pm = mSourceContext.getPackageManager();
+ try {
+ ActivityInfo info = pm.getActivityInfo(sourceActivityName, 0);
+ String parentActivity = info.parentActivityName;
+ Intent parent = new Intent().setComponent(
+ new ComponentName(info.packageName, parentActivity));
+ while (parent != null) {
+ mIntents.add(insertAt, parent);
+ info = pm.getActivityInfo(parent.getComponent(), 0);
+ parentActivity = info.parentActivityName;
+ if (parentActivity != null) {
+ parent = new Intent().setComponent(
+ new ComponentName(info.packageName, parentActivity));
+ } else {
+ parent = null;
+ }
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
+ throw new IllegalArgumentException(e);
+ }
+ return this;
+ }
+
+ /**
* @return the number of intents added so far.
*/
public int getIntentCount() {
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index c057d66..6f19934 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -67,6 +67,23 @@
= "android.service.wallpaper.LIVE_WALLPAPER_CHOOSER";
/**
+ * Directly launch live wallpaper preview, allowing the user to immediately
+ * confirm to switch to a specific live wallpaper. You must specify
+ * {@link #EXTRA_LIVE_WALLPAPER_COMPONENT} with the ComponentName of
+ * a live wallpaper component that is to be shown.
+ */
+ public static final String ACTION_CHANGE_LIVE_WALLPAPER
+ = "android.service.wallpaper.CHANGE_LIVE_WALLPAPER";
+
+ /**
+ * Extra in {@link #ACTION_CHANGE_LIVE_WALLPAPER} that specifies the
+ * ComponentName of a live wallpaper that should be shown as a preview,
+ * for the user to confirm.
+ */
+ public static final String EXTRA_LIVE_WALLPAPER_COMPONENT
+ = "android.service.wallpaper.extra.LIVE_WALLPAPER_COMPONENT";
+
+ /**
* Manifest entry for activities that respond to {@link Intent#ACTION_SET_WALLPAPER}
* which allows them to provide a custom large icon associated with this action.
*/
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 61a9dce..c1b8e7c 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -28,6 +28,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -206,6 +207,45 @@
super.dispatchRestoreInstanceState(jail);
}
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int oldWidth = getMeasuredWidth();
+ int oldHeight = getMeasuredHeight();
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int newWidth = getMeasuredWidth();
+ int newHeight = getMeasuredHeight();
+
+ // TODO: this is just a hack for now -- we actually have the AppWidgetHost
+ // be responsible for updating the size of the widget.
+ if (oldWidth != newWidth || oldHeight != newHeight) {
+ final float density = mContext.getResources().getDisplayMetrics().density;
+ final int newWidthDips = (int) (newWidth / density);
+ final int newHeightDips = (int) (newHeight / density);
+ updateAppWidgetSize(null, newWidthDips, newHeightDips, newWidthDips, newHeightDips);
+ }
+ }
+
+ /**
+ * Provide guidance about the size of this widget to the AppWidgetManager. This information
+ * gets embedded into the AppWidgetExtras and causes a callback to the AppWidgetProvider.
+ *
+ * @see AppWidgetProvider#onAppWidgetExtrasChanged(Context, AppWidgetManager, int, Bundle)
+ */
+ public void updateAppWidgetSize(Bundle extras, int minWidth, int minHeight, int maxWidth, int maxHeight) {
+ if (extras == null) {
+ extras = new Bundle();
+ }
+ extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MIN_WIDTH, minWidth);
+ extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MIN_HEIGHT, minHeight);
+ extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MAX_WIDTH, maxWidth);
+ extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MAX_HEIGHT, maxHeight);
+ updateAppWidgetExtras(extras);
+ }
+
+ public void updateAppWidgetExtras(Bundle extras) {
+ AppWidgetManager.getInstance(mContext).updateAppWidgetExtras(mAppWidgetId, extras);
+ }
+
/** {@inheritDoc} */
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index a7f7792..83ab817 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -19,6 +19,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -109,6 +110,32 @@
public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
/**
+ * An bundle extra that contains the lower bound on the current width, in dips, of a widget instance.
+ */
+ public static final String EXTRA_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth";
+
+ /**
+ * An bundle extra that contains the lower bound on the current height, in dips, of a widget instance.
+ */
+ public static final String EXTRA_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight";
+
+ /**
+ * An bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
+ */
+ public static final String EXTRA_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth";
+
+ /**
+ * An bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
+ */
+ public static final String EXTRA_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight";
+
+ /**
+ * An intent extra which points to a bundle of extra information for a particular widget id.
+ * In particular this bundle can contain EXTRA_APPWIDGET_WIDTH and EXTRA_APPWIDGET_HEIGHT.
+ */
+ public static final String EXTRA_APPWIDGET_EXTRAS = "appWidgetExtras";
+
+ /**
* An intent extra that contains multiple appWidgetIds.
* <p>
* The value will be an int array that can be retrieved like this:
@@ -161,6 +188,14 @@
public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
/**
+ * Sent when the custom extras for an AppWidget change.
+ *
+ * @see AppWidgetProvider#onAppWidgetExtrasChanged AppWidgetProvider#onAppWidgetExtrasChanged(
+ * Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
+ */
+ public static final String ACTION_APPWIDGET_EXTRAS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_EXTRAS";
+
+ /**
* Sent when an instance of an AppWidget is deleted from its host.
*
* @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds)
@@ -252,6 +287,46 @@
}
/**
+ * Update the extras for a given widget instance.
+ *
+ * The extras can be used to embed additional information about this widget to be accessed
+ * by the associated widget's AppWidgetProvider.
+ *
+ * @see #getAppWidgetExtras(int)
+ *
+ * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
+ * @param extras The extras to associate with this widget
+ */
+ public void updateAppWidgetExtras(int appWidgetId, Bundle extras) {
+ try {
+ sService.updateAppWidgetExtras(appWidgetId, extras);
+ }
+ catch (RemoteException e) {
+ throw new RuntimeException("system server dead?", e);
+ }
+ }
+
+ /**
+ * Get the extras associated with a given widget instance.
+ *
+ * The extras can be used to embed additional information about this widget to be accessed
+ * by the associated widget's AppWidgetProvider.
+ *
+ * @see #updateAppWidgetExtras(int, Bundle)
+ *
+ * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
+ * @return The extras associated with the given widget instance.
+ */
+ public Bundle getAppWidgetExtras(int appWidgetId) {
+ try {
+ return sService.getAppWidgetExtras(appWidgetId);
+ }
+ catch (RemoteException e) {
+ throw new RuntimeException("system server dead?", e);
+ }
+ }
+
+ /**
* Set the RemoteViews to use for the specified appWidgetId.
*
* Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java
index 00a5f0c..3cf40ae 100755
--- a/core/java/android/appwidget/AppWidgetProvider.java
+++ b/core/java/android/appwidget/AppWidgetProvider.java
@@ -74,6 +74,16 @@
this.onDeleted(context, new int[] { appWidgetId });
}
}
+ else if (AppWidgetManager.ACTION_APPWIDGET_EXTRAS_CHANGED.equals(action)) {
+ Bundle extras = intent.getExtras();
+ if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
+ && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_EXTRAS)) {
+ int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
+ Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_EXTRAS);
+ this.onAppWidgetExtrasChanged(context, AppWidgetManager.getInstance(context),
+ appWidgetId, widgetExtras);
+ }
+ }
else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
this.onEnabled(context);
}
@@ -82,7 +92,7 @@
}
}
// END_INCLUDE(onReceive)
-
+
/**
* Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_UPDATE} broadcast when
* this AppWidget provider is being asked to provide {@link android.widget.RemoteViews RemoteViews}
@@ -102,7 +112,26 @@
*/
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
}
-
+
+ /**
+ * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_EXTRAS_CHANGED}
+ * broadcast when this widget has been layed out at a new size.
+ *
+ * {@more}
+ *
+ * @param context The {@link android.content.Context Context} in which this receiver is
+ * running.
+ * @param appWidgetManager A {@link AppWidgetManager} object you can call {@link
+ * AppWidgetManager#updateAppWidget} on.
+ * @param appWidgetId The appWidgetId of the widget who's size changed.
+ * @param newExtras The appWidgetId of the widget who's size changed.
+ *
+ * @see AppWidgetManager#ACTION_APPWIDGET_EXTRAS_CHANGED
+ */
+ public void onAppWidgetExtrasChanged(Context context, AppWidgetManager appWidgetManager,
+ int appWidgetId, Bundle newExtras) {
+ }
+
/**
* Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_DELETED} broadcast when
* one or more AppWidget instances have been deleted. Override this method to implement
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 04af5f7..56e1735 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -160,6 +160,18 @@
"android.bluetooth.device.action.NAME_CHANGED";
/**
+ * Broadcast Action: Indicates the alias of a remote device has been
+ * changed.
+ * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_ALIAS_CHANGED =
+ "android.bluetooth.device.action.ALIAS_CHANGED";
+
+ /**
* Broadcast Action: Indicates a change in the bond state of a remote
* device. For example, if a device is bonded (paired).
* <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index 800d0d2..dfd1820 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -77,7 +77,20 @@
}
};
+ /**
+ * Defines a listener callback that is invoked when the primary clip on the clipboard changes.
+ * Objects that want to register a listener call
+ * {@link android.content.ClipboardManager#addPrimaryClipChangedListener(OnPrimaryClipChangedListener)
+ * addPrimaryClipChangedListener()} with an
+ * object that implements OnPrimaryClipChangedListener.
+ *
+ */
public interface OnPrimaryClipChangedListener {
+
+ /**
+ * Callback that is invoked by {@link android.content.ClipboardManager} when the primary
+ * clip changes.
+ */
void onPrimaryClipChanged();
}
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 04f6377..acdc488 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -390,6 +390,8 @@
// Called by SQLiteConnectionPool only.
void reconfigure(SQLiteDatabaseConfiguration configuration) {
+ mOnlyAllowReadOnlyOperations = false;
+
// Register custom functions.
final int functionCount = configuration.customFunctions.size();
for (int i = 0; i < functionCount; i++) {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 640b47b..eb0a0c6 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -234,48 +234,6 @@
};
/**
- * Creates a new Camera object to access a particular hardware camera.
- *
- * <p>When <code>force</code> is set to false, this will throw an exception
- * if the same camera is already opened by other clients. If true, the other
- * client will be disconnected from the camera they opened. If the device
- * can only support one camera running at a time, all camera-using clients
- * will be disconnected from their cameras.
- *
- * <p>A camera being held by an application can be taken away by other
- * applications at any time. Before the camera is taken, applications will
- * get {@link #CAMERA_ERROR_RELEASED} and have some time to clean up. Apps
- * receiving this callback must immediately stop video recording and then
- * call {@link #release()} on their camera object. Otherwise, it will be
- * released by the frameworks in a short time. After receiving
- * CAMERA_ERROR_RELEASED, apps should not call any method except <code>
- * release</code> and {@link #isReleased()}. After a camera is taken away,
- * all methods will throw exceptions except <code>isReleased</code> and
- * <code>release</code>. Apps can use <code>isReleased</code> to see if the
- * camera has been taken away. If the camera is taken away, the apps can
- * silently finish themselves or show a dialog.
- *
- * <p>Applications with android.permission.KEEP_CAMERA can request to keep
- * the camera. That is, the camera will not be taken by other applications
- * while it is opened. The permission can only be obtained by trusted
- * platform applications, such as those implementing lock screen security
- * features.
- *
- * @param cameraId the hardware camera to access, between 0 and
- * {@link #getNumberOfCameras()}-1.
- * @param force true to take the ownership from the existing client if the
- * camera has been opened by other clients.
- * @param keep true if the applications do not want other apps to take the
- * camera. Only the apps with android.permission.KEEP_CAMERA can keep
- * the camera.
- * @return a new Camera object, connected, locked and ready for use.
- * @hide
- */
- public static Camera open(int cameraId, boolean force, boolean keep) {
- return new Camera(cameraId, force, keep);
- }
-
- /**
* Creates a new Camera object to access a particular hardware camera. If
* the same camera is opened by other applications, this will throw a
* RuntimeException.
@@ -305,7 +263,7 @@
* @see android.app.admin.DevicePolicyManager#getCameraDisabled(android.content.ComponentName)
*/
public static Camera open(int cameraId) {
- return new Camera(cameraId, false, false);
+ return new Camera(cameraId);
}
/**
@@ -320,13 +278,13 @@
for (int i = 0; i < numberOfCameras; i++) {
getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
- return new Camera(i, false, false);
+ return new Camera(i);
}
}
return null;
}
- Camera(int cameraId, boolean force, boolean keep) {
+ Camera(int cameraId) {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
@@ -343,7 +301,7 @@
mEventHandler = null;
}
- native_setup(new WeakReference<Camera>(this), cameraId, force, keep);
+ native_setup(new WeakReference<Camera>(this), cameraId);
}
/**
@@ -356,8 +314,7 @@
release();
}
- private native final void native_setup(Object camera_this, int cameraId,
- boolean force, boolean keep);
+ private native final void native_setup(Object camera_this, int cameraId);
private native final void native_release();
@@ -372,18 +329,6 @@
}
/**
- * Whether the camera is released. When any camera method throws an
- * exception, applications can use this to check whether the camera has been
- * taken by other clients. If true, it means other clients have taken the
- * camera. The applications can silently finish themselves or show a dialog.
- *
- * @return whether the camera is released.
- * @see #open(int, boolean, boolean)
- * @hide
- */
- public native final boolean isReleased();
-
- /**
* Unlocks the camera to allow another process to access it.
* Normally, the camera is locked to the process with an active Camera
* object until {@link #release()} is called. To allow rapid handoff
@@ -1377,17 +1322,6 @@
public static final int CAMERA_ERROR_UNKNOWN = 1;
/**
- * Camera was released because another client has opened the camera. The
- * application should call {@link #release()} after getting this. The apps
- * should not call any method except <code>release</code> and {@link #isReleased()}
- * after this.
- *
- * @see Camera.ErrorCallback
- * @hide
- */
- public static final int CAMERA_ERROR_RELEASED = 2;
-
- /**
* Media server died. In this case, the application must release the
* Camera object and instantiate a new one.
* @see Camera.ErrorCallback
@@ -2508,13 +2442,13 @@
}
/**
- * Sets the rotation angle in degrees relative to the orientation of
- * the camera. This affects the pictures returned from JPEG {@link
- * PictureCallback}. The camera driver may set orientation in the
- * EXIF header without rotating the picture. Or the driver may rotate
- * the picture and the EXIF thumbnail. If the Jpeg picture is rotated,
- * the orientation in the EXIF header will be missing or 1 (row #0 is
- * top and column #0 is left side).
+ * Sets the clockwise rotation angle in degrees relative to the
+ * orientation of the camera. This affects the pictures returned from
+ * JPEG {@link PictureCallback}. The camera driver may set orientation
+ * in the EXIF header without rotating the picture. Or the driver may
+ * rotate the picture and the EXIF thumbnail. If the Jpeg picture is
+ * rotated, the orientation in the EXIF header will be missing or 1
+ * (row #0 is top and column #0 is left side).
*
* <p>If applications want to rotate the picture to match the orientation
* of what users see, apps should use {@link
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index b39b823..5ba1850 100755
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -268,6 +268,8 @@
synchronized (mInputDevicesLock) {
int index = findInputDeviceListenerLocked(listener);
if (index >= 0) {
+ InputDeviceListenerDelegate d = mInputDeviceListeners.get(index);
+ d.removeCallbacksAndMessages(null);
mInputDeviceListeners.remove(index);
}
}
diff --git a/core/java/android/net/DhcpInfoInternal.java b/core/java/android/net/DhcpInfoInternal.java
index fa77bc5..c87c34b 100644
--- a/core/java/android/net/DhcpInfoInternal.java
+++ b/core/java/android/net/DhcpInfoInternal.java
@@ -19,9 +19,8 @@
import android.text.TextUtils;
import android.util.Log;
-import java.net.InetAddress;
import java.net.Inet4Address;
-import java.net.UnknownHostException;
+import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -42,6 +41,11 @@
public String serverAddress;
public int leaseDuration;
+ /**
+ * Vendor specific information (from RFC 2132).
+ */
+ public String vendorInfo;
+
private Collection<RouteInfo> mRoutes;
public DhcpInfoInternal() {
@@ -138,6 +142,14 @@
}
}
+ /**
+ * Test if this DHCP lease includes vendor hint that network link is
+ * metered, and sensitive to heavy data transfers.
+ */
+ public boolean hasMeteredHint() {
+ return "ANDROID_METERED".equals(vendorInfo);
+ }
+
public String toString() {
String routeString = "";
for (RouteInfo route : mRoutes) routeString += route.toString() + " | ";
diff --git a/core/java/android/net/nsd/INsdManager.aidl b/core/java/android/net/nsd/INsdManager.aidl
index 077a675..3361a7b 100644
--- a/core/java/android/net/nsd/INsdManager.aidl
+++ b/core/java/android/net/nsd/INsdManager.aidl
@@ -26,4 +26,5 @@
interface INsdManager
{
Messenger getMessenger();
+ void setEnabled(boolean enable);
}
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index dac8d20..77e97e1 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -16,6 +16,8 @@
package android.net.nsd;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
@@ -133,6 +135,40 @@
private static final String TAG = "NsdManager";
INsdManager mService;
+ /**
+ * Broadcast intent action to indicate whether network service discovery is
+ * enabled or disabled. An extra {@link #EXTRA_NSD_STATE} provides the state
+ * information as int.
+ *
+ * @see #EXTRA_NSD_STATE
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_NSD_STATE_CHANGED =
+ "android.net.nsd.STATE_CHANGED";
+
+ /**
+ * The lookup key for an int that indicates whether network service discovery is enabled
+ * or disabled. Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
+ *
+ * @see #NSD_STATE_DISABLED
+ * @see #NSD_STATE_ENABLED
+ */
+ public static final String EXTRA_NSD_STATE = "nsd_state";
+
+ /**
+ * Network service discovery is disabled
+ *
+ * @see #ACTION_NSD_STATE_CHANGED
+ */
+ public static final int NSD_STATE_DISABLED = 1;
+
+ /**
+ * Network service discovery is enabled
+ *
+ * @see #ACTION_NSD_STATE_CHANGED
+ */
+ public static final int NSD_STATE_ENABLED = 2;
+
private static final int BASE = Protocol.BASE_NSD_MANAGER;
/** @hide */
@@ -188,6 +224,12 @@
/** @hide */
public static final int STOP_RESOLVE_SUCCEEDED = BASE + 23;
+ /** @hide */
+ public static final int ENABLE = BASE + 24;
+ /** @hide */
+ public static final int DISABLE = BASE + 25;
+
+
/**
* Create a new Nsd instance. Applications use
* {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -312,8 +354,8 @@
private DnsSdResolveListener mDnsSdResolveListener;
private ActionListener mDnsSdStopResolveListener;
- AsyncChannel mAsyncChannel;
- ServiceHandler mHandler;
+ private AsyncChannel mAsyncChannel;
+ private ServiceHandler mHandler;
class ServiceHandler extends Handler {
ServiceHandler(Looper looper) {
super(looper);
@@ -594,6 +636,13 @@
c.mAsyncChannel.sendMessage(STOP_RESOLVE);
}
+ /** Internal use only @hide */
+ public void setEnabled(boolean enabled) {
+ try {
+ mService.setEnabled(enabled);
+ } catch (RemoteException e) { }
+ }
+
/**
* Get a reference to NetworkService handler. This is used to establish
* an AsyncChannel communication with the service
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index ddd00a4..39810ba 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -34,7 +34,7 @@
INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
int getState();
- boolean disable();
+ boolean disable(boolean saveState);
boolean enable();
boolean enableNdefPush();
boolean disableNdefPush();
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 90f5bef..7bf9feb 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -574,9 +574,10 @@
*
* @hide
*/
+
public boolean disable() {
try {
- return sService.disable();
+ return sService.disable(true);
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
return false;
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 20a731e..98fe06a 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1324,4 +1324,42 @@
return false;
}
}
+
+ /**
+ * Return a String describing the calling method and location at a particular stack depth.
+ * @param callStack the Thread stack
+ * @param depth the depth of stack to return information for.
+ * @return the String describing the caller at that depth.
+ */
+ private static String getCaller(StackTraceElement callStack[], int depth) {
+ // callStack[4] is the caller of the method that called getCallers()
+ if (4 + depth >= callStack.length) {
+ return "<bottom of call stack>";
+ }
+ StackTraceElement caller = callStack[4 + depth];
+ return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
+ }
+
+ /**
+ * Return a string consisting of methods and locations at multiple call stack levels.
+ * @param depth the number of levels to return, starting with the immediate caller.
+ * @return a string describing the call stack.
+ * {@hide}
+ */
+ public static String getCallers(final int depth) {
+ final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < depth; i++) {
+ sb.append(getCaller(callStack, i)).append(" ");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * @return a String describing the immediate caller of the calling function.
+ * {@hide}
+ */
+ public static String getCaller() {
+ return getCaller(Thread.currentThread().getStackTrace(), 0);
+ }
}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 11f9445..f7f0263 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -113,19 +113,16 @@
= getDirectory("ANDROID_SECURE_DATA", "/data/secure");
private static final File EXTERNAL_STORAGE_DIRECTORY
- = getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard");
+ = getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0");
- private static final File EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY
- = new File (new File(getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard"),
- "Android"), "data");
+ private static final File EXTERNAL_STORAGE_ANDROID_DATA_DIRECTORY = new File(new File(
+ getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0"), "Android"), "data");
- private static final File EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY
- = new File (new File(getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard"),
- "Android"), "media");
+ private static final File EXTERNAL_STORAGE_ANDROID_MEDIA_DIRECTORY = new File(new File(
+ getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0"), "Android"), "media");
- private static final File EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY
- = new File (new File(getDirectory("EXTERNAL_STORAGE", "/mnt/sdcard"),
- "Android"), "obb");
+ private static final File EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY = new File(new File(
+ getDirectory("EXTERNAL_STORAGE", "/storage/sdcard0"), "Android"), "obb");
private static final File DOWNLOAD_CACHE_DIRECTORY
= getDirectory("DOWNLOAD_CACHE", "/cache");
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 770bf1c..8e041bb 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -266,25 +266,38 @@
*/
public static final int SCHED_IDLE = 5;
- /**
- * Default thread group - gets a 'normal' share of the CPU
- * @hide
- */
- public static final int THREAD_GROUP_DEFAULT = 0;
+ // Keep in sync with SP_* constants of enum type SchedPolicy
+ // declared in system/core/include/cutils/sched_policy.h,
+ // except THREAD_GROUP_DEFAULT does not correspond to any SP_* value.
/**
- * Background non-interactive thread group - All threads in
+ * Default thread group -
+ * has meaning with setProcessGroup() only, cannot be used with setThreadGroup().
+ * When used with setProcessGroup(), the group of each thread in the process
+ * is conditionally changed based on that thread's current priority, as follows:
+ * threads with priority numerically less than THREAD_PRIORITY_BACKGROUND
+ * are moved to foreground thread group. All other threads are left unchanged.
+ * @hide
+ */
+ public static final int THREAD_GROUP_DEFAULT = -1;
+
+ /**
+ * Background thread group - All threads in
* this group are scheduled with a reduced share of the CPU.
+ * Value is same as constant SP_BACKGROUND of enum SchedPolicy.
+ * FIXME rename to THREAD_GROUP_BACKGROUND.
* @hide
*/
- public static final int THREAD_GROUP_BG_NONINTERACTIVE = 1;
+ public static final int THREAD_GROUP_BG_NONINTERACTIVE = 0;
/**
- * Foreground 'boost' thread group - All threads in
- * this group are scheduled with an increased share of the CPU
+ * Foreground thread group - All threads in
+ * this group are scheduled with a normal share of the CPU.
+ * Value is same as constant SP_FOREGROUND of enum SchedPolicy.
+ * Not used at this level.
* @hide
**/
- public static final int THREAD_GROUP_FG_BOOST = 2;
+ private static final int THREAD_GROUP_FOREGROUND = 1;
public static final int SIGNAL_QUIT = 3;
public static final int SIGNAL_KILL = 9;
@@ -672,28 +685,37 @@
/**
* Sets the scheduling group for a thread.
* @hide
- * @param tid The indentifier of the thread/process to change.
- * @param group The target group for this thread/process.
+ * @param tid The identifier of the thread to change.
+ * @param group The target group for this thread from THREAD_GROUP_*.
*
* @throws IllegalArgumentException Throws IllegalArgumentException if
* <var>tid</var> does not exist.
* @throws SecurityException Throws SecurityException if your process does
* not have permission to modify the given thread, or to use the given
* priority.
+ * If the thread is a thread group leader, that is it's gettid() == getpid(),
+ * then the other threads in the same thread group are _not_ affected.
*/
public static final native void setThreadGroup(int tid, int group)
throws IllegalArgumentException, SecurityException;
+
/**
* Sets the scheduling group for a process and all child threads
* @hide
- * @param pid The indentifier of the process to change.
- * @param group The target group for this process.
+ * @param pid The identifier of the process to change.
+ * @param group The target group for this process from THREAD_GROUP_*.
*
* @throws IllegalArgumentException Throws IllegalArgumentException if
* <var>tid</var> does not exist.
* @throws SecurityException Throws SecurityException if your process does
* not have permission to modify the given thread, or to use the given
* priority.
+ *
+ * group == THREAD_GROUP_DEFAULT means to move all non-background priority
+ * threads to the foreground scheduling group, but to leave background
+ * priority threads alone. group == THREAD_GROUP_BG_NONINTERACTIVE moves all
+ * threads, regardless of priority, to the background scheduling group.
+ * group == THREAD_GROUP_FOREGROUND is not allowed.
*/
public static final native void setProcessGroup(int pid, int group)
throws IllegalArgumentException, SecurityException;
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 83799c4..593762a 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -19,6 +19,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ContentProviderClient;
@@ -98,6 +99,32 @@
public static final String ACTION_EVENT_REMINDER = "android.intent.action.EVENT_REMINDER";
/**
+ * Activity Action: Display the event to the user in the custom app as
+ * specified in {@link EventsColumns#CUSTOM_APP_PACKAGE}. The custom app
+ * will be started via {@link Activity#startActivityForResult(Intent, int)}
+ * and it should call {@link Activity#setResult(int)} with
+ * {@link Activity#RESULT_OK} or {@link Activity#RESULT_CANCELED} to
+ * acknowledge whether the action was handled or not.
+ * <p>
+ * Input: {@link Intent#getData} has the event URI. The extra
+ * {@link #EXTRA_EVENT_BEGIN_TIME} has the start time of the instance. The
+ * extra {@link #EXTRA_CUSTOM_APP_URI} will have the
+ * {@link EventsColumns#CUSTOM_APP_URI}.
+ * <p>
+ * Output: {@link Activity#RESULT_OK} if this was handled; otherwise
+ * {@link Activity#RESULT_CANCELED}
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_HANDLE_CUSTOM_EVENT =
+ "android.provider.calendar.action.HANDLE_CUSTOM_EVENT";
+
+ /**
+ * Intent Extras key: {@link EventsColumns#CUSTOM_APP_URI} for the event in
+ * the {@link #ACTION_HANDLE_CUSTOM_EVENT} intent
+ */
+ public static final String EXTRA_CUSTOM_APP_URI = "customAppUri";
+
+ /**
* Intent Extras key: The start time of an event or an instance of a
* recurring event. (milliseconds since epoch)
*/
@@ -756,6 +783,22 @@
public static final int ATTENDEE_STATUS_DECLINED = 2;
public static final int ATTENDEE_STATUS_INVITED = 3;
public static final int ATTENDEE_STATUS_TENTATIVE = 4;
+
+ /**
+ * The identity of the attendee as referenced in
+ * {@link ContactsContract.CommonDataKinds.Identity#IDENTITY}.
+ * This is required only if {@link #ATTENDEE_ID_NAMESPACE} is present. Column name.
+ * <P>Type: STRING</P>
+ */
+ public static final String ATTENDEE_IDENTITY = "attendeeIdentity";
+
+ /**
+ * The identity name space of the attendee as referenced in
+ * {@link ContactsContract.CommonDataKinds.Identity#NAMESPACE}.
+ * This is required only if {@link #ATTENDEE_IDENTITY} is present. Column name.
+ * <P>Type: STRING</P>
+ */
+ public static final String ATTENDEE_ID_NAMESPACE = "attendeeIdNamespace";
}
/**
@@ -773,6 +816,8 @@
* <li>{@link #ATTENDEE_RELATIONSHIP}</li>
* <li>{@link #ATTENDEE_TYPE}</li>
* <li>{@link #ATTENDEE_STATUS}</li>
+ * <li>{@link #ATTENDEE_IDENTITY}</li>
+ * <li>{@link #ATTENDEE_ID_NAMESPACE}</li>
* </ul>
*/
public static final class Attendees implements BaseColumns, AttendeesColumns, EventsColumns {
@@ -1158,6 +1203,22 @@
* <P>Type: INTEGER (boolean, readonly)</P>
*/
public static final String CAN_INVITE_OTHERS = "canInviteOthers";
+
+ /**
+ * The package name of the custom app that can provide a richer
+ * experience for the event. See the ACTION TYPE
+ * {@link CalendarContract#ACTION_HANDLE_CUSTOM_EVENT} for details.
+ * Column name.
+ * <P> Type: TEXT </P>
+ */
+ public static final String CUSTOM_APP_PACKAGE = "customAppPackage";
+
+ /**
+ * The URI used by the custom app for the event. Column name.
+ * <P>Type: TEXT</P>
+ */
+ public static final String CUSTOM_APP_URI = "customAppUri";
+
}
/**
@@ -1221,12 +1282,17 @@
Attendees.ATTENDEE_RELATIONSHIP,
Attendees.ATTENDEE_TYPE,
Attendees.ATTENDEE_STATUS,
+ Attendees.ATTENDEE_IDENTITY,
+ Attendees.ATTENDEE_ID_NAMESPACE
};
private static final int COLUMN_ATTENDEE_NAME = 0;
private static final int COLUMN_ATTENDEE_EMAIL = 1;
private static final int COLUMN_ATTENDEE_RELATIONSHIP = 2;
private static final int COLUMN_ATTENDEE_TYPE = 3;
private static final int COLUMN_ATTENDEE_STATUS = 4;
+ private static final int COLUMN_ATTENDEE_IDENTITY = 5;
+ private static final int COLUMN_ATTENDEE_ID_NAMESPACE = 6;
+
private static final String[] EXTENDED_PROJECTION = new String[] {
ExtendedProperties._ID,
ExtendedProperties.NAME,
@@ -1362,6 +1428,10 @@
subCursor.getInt(COLUMN_ATTENDEE_TYPE));
attendeeValues.put(Attendees.ATTENDEE_STATUS,
subCursor.getInt(COLUMN_ATTENDEE_STATUS));
+ attendeeValues.put(Attendees.ATTENDEE_IDENTITY,
+ subCursor.getInt(COLUMN_ATTENDEE_IDENTITY));
+ attendeeValues.put(Attendees.ATTENDEE_ID_NAMESPACE,
+ subCursor.getInt(COLUMN_ATTENDEE_ID_NAMESPACE));
entity.addSubValue(Attendees.CONTENT_URI, attendeeValues);
}
} finally {
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index cd8d51f..31ad12b 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -329,6 +329,14 @@
public static final String COLUMN_IS_PUBLIC_API = "is_public_api";
/**
+ * The name of the column holding a bitmask of allowed network types. This is only used for
+ * public API downloads.
+ * <P>Type: INTEGER</P>
+ * <P>Owner can Init/Read</P>
+ */
+ public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types";
+
+ /**
* The name of the column indicating whether roaming connections can be used. This is only
* used for public API downloads.
* <P>Type: BOOLEAN</P>
@@ -337,12 +345,12 @@
public static final String COLUMN_ALLOW_ROAMING = "allow_roaming";
/**
- * The name of the column holding a bitmask of allowed network types. This is only used for
- * public API downloads.
- * <P>Type: INTEGER</P>
+ * The name of the column indicating whether metered connections can be used. This is only
+ * used for public API downloads.
+ * <P>Type: BOOLEAN</P>
* <P>Owner can Init/Read</P>
*/
- public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types";
+ public static final String COLUMN_ALLOW_METERED = "allow_metered";
/**
* Whether or not this download should be displayed in the system's Downloads UI. Defaults
@@ -701,7 +709,10 @@
* blocked by {@link NetworkPolicyManager}.
*
* @hide
+ * @deprecated since behavior now uses
+ * {@link #STATUS_WAITING_FOR_NETWORK}
*/
+ @Deprecated
public static final int STATUS_BLOCKED = 498;
/** {@hide} */
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 38945c2..79d0144 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -306,13 +306,11 @@
/**
* The width of the image/video in pixels.
- * @hide
*/
public static final String WIDTH = "width";
/**
* The height of the image/video in pixels.
- * @hide
*/
public static final String HEIGHT = "height";
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6dfbb2f..3a5fdd1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3277,6 +3277,12 @@
"wifi_mobile_data_transition_wakelock_timeout_ms";
/**
+ * Whether network service discovery is enabled.
+ * @hide
+ */
+ public static final String NSD_ON = "nsd_on";
+
+ /**
* Whether background data usage is allowed by the user. See
* ConnectivityManager for more info.
*/
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 9612151..19d8d5c 100755
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1816,6 +1816,181 @@
public static final String BEARER = "bearer";
}
+ /**
+ * Contains received SMS cell broadcast messages.
+ */
+ public static final class CellBroadcasts implements BaseColumns {
+
+ /** Not instantiable. */
+ private CellBroadcasts() {}
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://cellbroadcasts");
+
+ /**
+ * Message geographical scope.
+ * <P>Type: INTEGER</P>
+ */
+ public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
+
+ /**
+ * Message serial number.
+ * <P>Type: INTEGER</P>
+ */
+ public static final String SERIAL_NUMBER = "serial_number";
+
+ /**
+ * PLMN of broadcast sender. (SERIAL_NUMBER + PLMN + LAC + CID) uniquely identifies a
+ * broadcast for duplicate detection purposes.
+ * <P>Type: TEXT</P>
+ */
+ public static final String PLMN = "plmn";
+
+ /**
+ * Location Area (GSM) or Service Area (UMTS) of broadcast sender. Unused for CDMA.
+ * Only included if Geographical Scope of message is not PLMN wide (01).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String LAC = "lac";
+
+ /**
+ * Cell ID of message sender (GSM/UMTS). Unused for CDMA. Only included when the
+ * Geographical Scope of message is cell wide (00 or 11).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String CID = "cid";
+
+ /**
+ * Message code (OBSOLETE: merged into SERIAL_NUMBER).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String V1_MESSAGE_CODE = "message_code";
+
+ /**
+ * Message identifier (OBSOLETE: renamed to SERVICE_CATEGORY).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String V1_MESSAGE_IDENTIFIER = "message_id";
+
+ /**
+ * Service category (GSM/UMTS message identifier, CDMA service category).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String SERVICE_CATEGORY = "service_category";
+
+ /**
+ * Message language code.
+ * <P>Type: TEXT</P>
+ */
+ public static final String LANGUAGE_CODE = "language";
+
+ /**
+ * Message body.
+ * <P>Type: TEXT</P>
+ */
+ public static final String MESSAGE_BODY = "body";
+
+ /**
+ * Message delivery time.
+ * <P>Type: INTEGER (long)</P>
+ */
+ public static final String DELIVERY_TIME = "date";
+
+ /**
+ * Has the message been viewed?
+ * <P>Type: INTEGER (boolean)</P>
+ */
+ public static final String MESSAGE_READ = "read";
+
+ /**
+ * Message format (3GPP or 3GPP2).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String MESSAGE_FORMAT = "format";
+
+ /**
+ * Message priority (including emergency).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String MESSAGE_PRIORITY = "priority";
+
+ /**
+ * ETWS warning type (ETWS alerts only).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String ETWS_WARNING_TYPE = "etws_warning_type";
+
+ /**
+ * CMAS message class (CMAS alerts only).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
+
+ /**
+ * CMAS category (CMAS alerts only).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String CMAS_CATEGORY = "cmas_category";
+
+ /**
+ * CMAS response type (CMAS alerts only).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
+
+ /**
+ * CMAS severity (CMAS alerts only).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String CMAS_SEVERITY = "cmas_severity";
+
+ /**
+ * CMAS urgency (CMAS alerts only).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String CMAS_URGENCY = "cmas_urgency";
+
+ /**
+ * CMAS certainty (CMAS alerts only).
+ * <P>Type: INTEGER</P>
+ */
+ public static final String CMAS_CERTAINTY = "cmas_certainty";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
+
+ /**
+ * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
+ */
+ public static final String[] QUERY_COLUMNS = {
+ _ID,
+ GEOGRAPHICAL_SCOPE,
+ PLMN,
+ LAC,
+ CID,
+ SERIAL_NUMBER,
+ SERVICE_CATEGORY,
+ LANGUAGE_CODE,
+ MESSAGE_BODY,
+ DELIVERY_TIME,
+ MESSAGE_READ,
+ MESSAGE_FORMAT,
+ MESSAGE_PRIORITY,
+ ETWS_WARNING_TYPE,
+ CMAS_MESSAGE_CLASS,
+ CMAS_CATEGORY,
+ CMAS_RESPONSE_TYPE,
+ CMAS_SEVERITY,
+ CMAS_URGENCY,
+ CMAS_CERTAINTY
+ };
+ }
+
public static final class Intents {
private Intents() {
// Not instantiable
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index a2038c9..9c887a1 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -405,6 +405,10 @@
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
} else if (name.equals("Alias")) {
mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
+ Intent intent = new Intent(BluetoothDevice.ACTION_ALIAS_CHANGED);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
} else if (name.equals("Class")) {
mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
Intent intent = new Intent(BluetoothDevice.ACTION_CLASS_CHANGED);
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index d78bbbf..c783e6a 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -69,7 +69,7 @@
private synchronized Searchables getSearchables() {
if (mSearchables == null) {
Log.i(TAG, "Building list of searchable activities");
- new MyPackageMonitor().register(mContext, true);
+ new MyPackageMonitor().register(mContext, null, true);
mSearchables = new Searchables(mContext);
mSearchables.buildSearchableList();
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 7ce96c0..6917fb2 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -140,6 +140,7 @@
boolean mIsCreating;
boolean mDrawingAllowed;
boolean mOffsetsChanged;
+ boolean mFixedSizeAllowed;
int mWidth;
int mHeight;
int mFormat;
@@ -211,7 +212,7 @@
@Override
public void setFixedSize(int width, int height) {
- if (Process.myUid() != Process.SYSTEM_UID) {
+ if (!mFixedSizeAllowed) {
// Regular apps can't do this. It can only work for
// certain designs of window animations, so you can't
// rely on it.
@@ -385,7 +386,12 @@
updateSurface(false, false, false);
}
}
-
+
+ /** {@hide} */
+ public void setFixedSizeAllowed(boolean allowed) {
+ mFixedSizeAllowed = allowed;
+ }
+
/**
* Called once to initialize the engine. After returning, the
* engine's surface will be created by the framework.
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index ff5a467..dc58ef2 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -117,7 +117,7 @@
mObjects = new PackedObjectVector<Directions>(1);
- mBlockEnds = new int[] { 0 };
+ mBlockEndLines = new int[] { 0 };
mBlockIndices = new int[] { INVALID_BLOCK_INDEX };
mNumberOfBlocks = 1;
@@ -391,23 +391,23 @@
int firstBlock = -1;
int lastBlock = -1;
for (int i = 0; i < mNumberOfBlocks; i++) {
- if (mBlockEnds[i] >= startLine) {
+ if (mBlockEndLines[i] >= startLine) {
firstBlock = i;
break;
}
}
for (int i = firstBlock; i < mNumberOfBlocks; i++) {
- if (mBlockEnds[i] >= endLine) {
+ if (mBlockEndLines[i] >= endLine) {
lastBlock = i;
break;
}
}
- final int lastBlockEndLine = mBlockEnds[lastBlock];
+ final int lastBlockEndLine = mBlockEndLines[lastBlock];
boolean createBlockBefore = startLine > (firstBlock == 0 ? 0 :
- mBlockEnds[firstBlock - 1] + 1);
+ mBlockEndLines[firstBlock - 1] + 1);
boolean createBlock = newLineCount > 0;
- boolean createBlockAfter = endLine < mBlockEnds[lastBlock];
+ boolean createBlockAfter = endLine < mBlockEndLines[lastBlock];
int numAddedBlocks = 0;
if (createBlockBefore) numAddedBlocks++;
@@ -419,27 +419,27 @@
if (newNumberOfBlocks == 0) {
// Even when text is empty, there is actually one line and hence one block
- mBlockEnds[0] = 0;
+ mBlockEndLines[0] = 0;
mBlockIndices[0] = INVALID_BLOCK_INDEX;
mNumberOfBlocks = 1;
return;
}
- if (newNumberOfBlocks > mBlockEnds.length) {
+ if (newNumberOfBlocks > mBlockEndLines.length) {
final int newSize = ArrayUtils.idealIntArraySize(newNumberOfBlocks);
- int[] blockEnds = new int[newSize];
+ int[] blockEndLines = new int[newSize];
int[] blockIndices = new int[newSize];
- System.arraycopy(mBlockEnds, 0, blockEnds, 0, firstBlock);
+ System.arraycopy(mBlockEndLines, 0, blockEndLines, 0, firstBlock);
System.arraycopy(mBlockIndices, 0, blockIndices, 0, firstBlock);
- System.arraycopy(mBlockEnds, lastBlock + 1,
- blockEnds, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
+ System.arraycopy(mBlockEndLines, lastBlock + 1,
+ blockEndLines, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
System.arraycopy(mBlockIndices, lastBlock + 1,
blockIndices, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
- mBlockEnds = blockEnds;
+ mBlockEndLines = blockEndLines;
mBlockIndices = blockIndices;
} else {
- System.arraycopy(mBlockEnds, lastBlock + 1,
- mBlockEnds, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
+ System.arraycopy(mBlockEndLines, lastBlock + 1,
+ mBlockEndLines, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
System.arraycopy(mBlockIndices, lastBlock + 1,
mBlockIndices, firstBlock + numAddedBlocks, mNumberOfBlocks - lastBlock - 1);
}
@@ -447,24 +447,24 @@
mNumberOfBlocks = newNumberOfBlocks;
final int deltaLines = newLineCount - (endLine - startLine + 1);
for (int i = firstBlock + numAddedBlocks; i < mNumberOfBlocks; i++) {
- mBlockEnds[i] += deltaLines;
+ mBlockEndLines[i] += deltaLines;
}
int blockIndex = firstBlock;
if (createBlockBefore) {
- mBlockEnds[blockIndex] = startLine - 1;
+ mBlockEndLines[blockIndex] = startLine - 1;
mBlockIndices[blockIndex] = INVALID_BLOCK_INDEX;
blockIndex++;
}
if (createBlock) {
- mBlockEnds[blockIndex] = startLine + newLineCount - 1;
+ mBlockEndLines[blockIndex] = startLine + newLineCount - 1;
mBlockIndices[blockIndex] = INVALID_BLOCK_INDEX;
blockIndex++;
}
if (createBlockAfter) {
- mBlockEnds[blockIndex] = lastBlockEndLine + deltaLines;
+ mBlockEndLines[blockIndex] = lastBlockEndLine + deltaLines;
mBlockIndices[blockIndex] = INVALID_BLOCK_INDEX;
}
}
@@ -473,10 +473,10 @@
* This package private method is used for test purposes only
* @hide
*/
- void setBlocksDataForTest(int[] blockEnds, int[] blockIndices, int numberOfBlocks) {
- mBlockEnds = new int[blockEnds.length];
+ void setBlocksDataForTest(int[] blockEndLines, int[] blockIndices, int numberOfBlocks) {
+ mBlockEndLines = new int[blockEndLines.length];
mBlockIndices = new int[blockIndices.length];
- System.arraycopy(blockEnds, 0, mBlockEnds, 0, blockEnds.length);
+ System.arraycopy(blockEndLines, 0, mBlockEndLines, 0, blockEndLines.length);
System.arraycopy(blockIndices, 0, mBlockIndices, 0, blockIndices.length);
mNumberOfBlocks = numberOfBlocks;
}
@@ -484,8 +484,8 @@
/**
* @hide
*/
- public int[] getBlockEnds() {
- return mBlockEnds;
+ public int[] getBlockEndLines() {
+ return mBlockEndLines;
}
/**
@@ -633,8 +633,8 @@
* @hide
*/
public static final int INVALID_BLOCK_INDEX = -1;
- // Stores the line numbers of the last line of each block
- private int[] mBlockEnds;
+ // Stores the line numbers of the last line of each block (inclusive)
+ private int[] mBlockEndLines;
// The indices of this block's display list in TextView's internal display list array or
// INVALID_BLOCK_INDEX if this block has been invalidated during an edition
private int[] mBlockIndices;
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index ab21b32..7d569ad 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -18,6 +18,7 @@
import static android.view.accessibility.AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -52,13 +53,21 @@
private ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
new ArrayList<AccessibilityNodeInfo>();
- private final Handler mHandler = new PrivateHandler();
+ private final Handler mHandler;
private final ViewRootImpl mViewRootImpl;
private final AccessibilityNodePrefetcher mPrefetcher;
+ private final long mMyLooperThreadId;
+
+ private final int mMyProcessId;
+
public AccessibilityInteractionController(ViewRootImpl viewRootImpl) {
+ Looper looper = viewRootImpl.mHandler.getLooper();
+ mMyLooperThreadId = looper.getThread().getId();
+ mMyProcessId = Process.myPid();
+ mHandler = new PrivateHandler(looper);
mViewRootImpl = viewRootImpl;
mPrefetcher = new AccessibilityNodePrefetcher();
}
@@ -134,8 +143,7 @@
// thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating
// client can handle the message to generate the result.
- if (interrogatingPid == Process.myPid()
- && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
@@ -166,7 +174,7 @@
} else {
root = findViewByAccessibilityId(accessibilityViewId);
}
- if (root != null && isDisplayedOnScreen(root)) {
+ if (root != null && root.isDisplayedOnScreen()) {
mPrefetcher.prefetchAccessibilityNodeInfos(root, virtualDescendantId, flags, infos);
}
} finally {
@@ -196,8 +204,7 @@
// thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating
// client can handle the message to generate the result.
- if (interrogatingPid == Process.myPid()
- && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
@@ -229,7 +236,7 @@
}
if (root != null) {
View target = root.findViewById(viewId);
- if (target != null && isDisplayedOnScreen(target)) {
+ if (target != null && target.isDisplayedOnScreen()) {
info = target.createAccessibilityNodeInfo();
}
}
@@ -260,8 +267,7 @@
// thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating
// client can handle the message to generate the result.
- if (interrogatingPid == Process.myPid()
- && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
@@ -292,7 +298,7 @@
} else {
root = mViewRootImpl.mView;
}
- if (root != null && isDisplayedOnScreen(root)) {
+ if (root != null && root.isDisplayedOnScreen()) {
AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
if (provider != null) {
infos = provider.findAccessibilityNodeInfosByText(text,
@@ -309,7 +315,7 @@
final int viewCount = foundViews.size();
for (int i = 0; i < viewCount; i++) {
View foundView = foundViews.get(i);
- if (isDisplayedOnScreen(foundView)) {
+ if (foundView.isDisplayedOnScreen()) {
provider = foundView.getAccessibilityNodeProvider();
if (provider != null) {
List<AccessibilityNodeInfo> infosFromProvider =
@@ -353,8 +359,7 @@
// thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating
// client can handle the message to generate the result.
- if (interogatingPid == Process.myPid()
- && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ if (interogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
@@ -385,7 +390,7 @@
} else {
root = mViewRootImpl.mView;
}
- if (root != null && isDisplayedOnScreen(root)) {
+ if (root != null && root.isDisplayedOnScreen()) {
switch (focusType) {
case AccessibilityNodeInfo.FOCUS_ACCESSIBILITY: {
View host = mViewRootImpl.mAccessibilityFocusedHost;
@@ -406,7 +411,7 @@
case AccessibilityNodeInfo.FOCUS_INPUT: {
// Input focus cannot go to virtual views.
View target = root.findFocus();
- if (target != null && isDisplayedOnScreen(target)) {
+ if (target != null && target.isDisplayedOnScreen()) {
focused = target.createAccessibilityNodeInfo();
}
} break;
@@ -441,8 +446,7 @@
// thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating
// client can handle the message to generate the result.
- if (interogatingPid == Process.myPid()
- && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ if (interogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
@@ -473,7 +477,7 @@
} else {
root = mViewRootImpl.mView;
}
- if (root != null && isDisplayedOnScreen(root)) {
+ if (root != null && root.isDisplayedOnScreen()) {
if ((direction & View.FOCUS_ACCESSIBILITY) == View.FOCUS_ACCESSIBILITY) {
AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
if (provider != null) {
@@ -511,8 +515,9 @@
}
public void performAccessibilityActionClientThread(long accessibilityNodeId, int action,
- int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
- int interogatingPid, long interrogatingTid) {
+ Bundle arguments, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, int flags, int interogatingPid,
+ long interrogatingTid) {
Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_PERFORM_ACCESSIBILITY_ACTION;
message.arg1 = flags;
@@ -522,13 +527,13 @@
args.argi2 = action;
args.argi3 = interactionId;
args.arg1 = callback;
+ args.arg2 = arguments;
message.obj = args;
// If the interrogation is performed by the same thread as the main UI
// thread in this process, set the message as a static reference so
// after this call completes the same thread but in the interrogating
// client can handle the message to generate the result.
- if (interogatingPid == Process.myPid()
- && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ if (interogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
@@ -545,6 +550,7 @@
final int interactionId = args.argi3;
final IAccessibilityInteractionConnectionCallback callback =
(IAccessibilityInteractionConnectionCallback) args.arg1;
+ Bundle arguments = (Bundle) args.arg2;
mPool.release(args);
boolean succeeded = false;
try {
@@ -559,12 +565,13 @@
} else {
target = mViewRootImpl.mView;
}
- if (target != null && isDisplayedOnScreen(target)) {
+ if (target != null && target.isDisplayedOnScreen()) {
AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
if (provider != null) {
- succeeded = provider.performAccessibilityAction(action, virtualDescendantId);
+ succeeded = provider.performAction(virtualDescendantId, action,
+ arguments);
} else if (virtualDescendantId == View.NO_ID) {
- succeeded = target.performAccessibilityAction(action);
+ succeeded = target.performAccessibilityAction(action, arguments);
}
}
} finally {
@@ -583,30 +590,13 @@
return null;
}
View foundView = root.findViewByAccessibilityId(accessibilityId);
- if (foundView != null && !isDisplayedOnScreen(foundView)) {
+ if (foundView != null && !foundView.isDisplayedOnScreen()) {
return null;
}
return foundView;
}
/**
- * Computes whether a view is visible on the screen.
- *
- * @param view The view to check.
- * @return Whether the view is visible on the screen.
- */
- private boolean isDisplayedOnScreen(View view) {
- // The first two checks are made also made by isShown() which
- // however traverses the tree up to the parent to catch that.
- // Therefore, we do some fail fast check to minimize the up
- // tree traversal.
- return (view.mAttachInfo != null
- && view.mAttachInfo.mWindowVisibility == View.VISIBLE
- && view.isShown()
- && view.getGlobalVisibleRect(mViewRootImpl.mTempRect));
- }
-
- /**
* This class encapsulates a prefetching strategy for the accessibility APIs for
* querying window content. It is responsible to prefetch a batch of
* AccessibilityNodeInfos in addition to the one for a requested node.
@@ -680,7 +670,7 @@
}
View child = children.getChildAt(i);
if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
- && isDisplayedOnScreen(child)) {
+ && child.isDisplayedOnScreen()) {
AccessibilityNodeInfo info = null;
AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
if (provider == null) {
@@ -714,7 +704,7 @@
return;
}
View child = children.getChildAt(i);
- if ( isDisplayedOnScreen(child)) {
+ if (child.isDisplayedOnScreen()) {
AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
if (provider == null) {
AccessibilityNodeInfo info = child.createAccessibilityNodeInfo();
@@ -845,8 +835,8 @@
private final static int MSG_FIND_FOCUS = 5;
private final static int MSG_FOCUS_SEARCH = 6;
- public PrivateHandler() {
- super(Looper.getMainLooper());
+ public PrivateHandler(Looper looper) {
+ super(looper);
}
@Override
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index ad2283e..bda8016 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -143,6 +143,49 @@
}
/**
+ * Return the range of display sizes an application can expect to encounter
+ * under normal operation, as long as there is no physical change in screen
+ * size. This is basically the sizes you will see as the orientation
+ * changes, taking into account whatever screen decoration there is in
+ * each rotation. For example, the status bar is always at the top of the
+ * screen, so it will reduce the height both in landscape and portrait, and
+ * the smallest height returned here will be the smaller of the two.
+ *
+ * This is intended for applications to get an idea of the range of sizes
+ * they will encounter while going through device rotations, to provide a
+ * stable UI through rotation. The sizes here take into account all standard
+ * system decorations that reduce the size actually available to the
+ * application: the status bar, navigation bar, system bar, etc. It does
+ * <em>not</em> take into account more transient elements like an IME
+ * soft keyboard.
+ *
+ * @param outSmallestSize Filled in with the smallest width and height
+ * that the application will encounter, in pixels (not dp units). The x
+ * (width) dimension here directly corresponds to
+ * {@link android.content.res.Configuration#smallestScreenWidthDp
+ * Configuration.smallestScreenWidthDp}, except the value here is in raw
+ * screen pixels rather than dp units. Your application may of course
+ * still get smaller space yet if, for example, a soft keyboard is
+ * being displayed.
+ * @param outLargestSize Filled in with the largest width and height
+ * that the application will encounter, in pixels (not dp units). Your
+ * application may of course still get larger space than this if,
+ * for example, screen decorations like the status bar are being hidden.
+ */
+ public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
+ try {
+ IWindowManager wm = getWindowManager();
+ wm.getCurrentSizeRange(outSmallestSize, outLargestSize);
+ } catch (RemoteException e) {
+ Slog.w("Display", "Unable to get display size range", e);
+ outSmallestSize.x = 0;
+ outSmallestSize.y = 0;
+ outLargestSize.x = 0;
+ outLargestSize.y = 0;
+ }
+ }
+
+ /**
* Return the maximum screen size dimension that will happen. This is
* mostly for wallpapers.
* @hide
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index bedafc7..7736f57 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -358,14 +358,13 @@
private static native void nSetDisplayListName(int displayList, String name);
@Override
- public int drawDisplayList(DisplayList displayList, int width, int height,
- Rect dirty, int flags) {
+ public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) {
return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).getNativeDisplayList(),
- width, height, dirty, flags);
+ dirty, flags);
}
private static native int nDrawDisplayList(int renderer, int displayList,
- int width, int height, Rect dirty, int flags);
+ Rect dirty, int flags);
@Override
void outputDisplayList(DisplayList displayList) {
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index de8c62d..2f4cd36 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -48,13 +48,11 @@
* Invoked after all drawing operation have been performed.
*/
public abstract void onPostDraw();
-
+
/**
* Draws the specified display list onto this canvas.
- *
+ *
* @param displayList The display list to replay.
- * @param width The width of the display list.
- * @param height The height of the display list.
* @param dirty The dirty region to redraw in the next pass, matters only
* if this method returns true, can be null.
* @param flags Optional flags about drawing, see {@link DisplayList} for
@@ -63,8 +61,7 @@
* @return One of {@link DisplayList#STATUS_DONE}, {@link DisplayList#STATUS_DRAW} or
* {@link DisplayList#STATUS_INVOKE}
*/
- public abstract int drawDisplayList(DisplayList displayList, int width, int height,
- Rect dirty, int flags);
+ public abstract int drawDisplayList(DisplayList displayList, Rect dirty, int flags);
/**
* Outputs the specified display list to the log. This method exists for use by
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 8bc36b7..1ec754a 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -484,7 +484,28 @@
* see {@link android.content.ComponentCallbacks}
*/
static void trimMemory(int level) {
- Gl20Renderer.trimMemory(level);
+ startTrimMemory(level);
+ endTrimMemory();
+ }
+
+ /**
+ * Starts the process of trimming memory. Usually this call will setup
+ * hardware rendering context and reclaim memory.Extra cleanup might
+ * be required by calling {@link #endTrimMemory()}.
+ *
+ * @param level Hint about the amount of memory that should be trimmed,
+ * see {@link android.content.ComponentCallbacks}
+ */
+ static void startTrimMemory(int level) {
+ Gl20Renderer.startTrimMemory(level);
+ }
+
+ /**
+ * Finishes the process of trimming memory. This method will usually
+ * cleanup special resources used by the memory trimming process.
+ */
+ static void endTrimMemory() {
+ Gl20Renderer.endTrimMemory();
}
/**
@@ -1099,8 +1120,7 @@
drawDisplayListStartTime = System.nanoTime();
}
- int status = canvas.drawDisplayList(displayList,
- view.getWidth(), view.getHeight(), mRedrawClip,
+ int status = canvas.drawDisplayList(displayList, mRedrawClip,
DisplayList.FLAG_CLIP_CHILDREN);
if (mProfileEnabled) {
@@ -1123,12 +1143,15 @@
callbacks.onHardwarePostDraw(canvas);
canvas.restoreToCount(saveCount);
view.mRecreateDisplayList = false;
+
mFrameCount++;
+
if (mDebugDirtyRegions) {
if (mDebugPaint == null) {
mDebugPaint = new Paint();
mDebugPaint.setColor(0x7fff0000);
}
+
if (dirty != null && (mFrameCount & 1) == 0) {
canvas.drawRect(dirty, mDebugPaint);
}
@@ -1447,7 +1470,7 @@
return null;
}
- static void trimMemory(int level) {
+ static void startTrimMemory(int level) {
if (sEgl == null || sEglConfig == null) return;
Gl20RendererEglContext managedContext =
@@ -1464,9 +1487,12 @@
} else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
}
+ }
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
+ static void endTrimMemory() {
+ if (sEgl != null && sEglDisplay != null) {
+ sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ }
}
private static void usePbufferSurface(EGLContext eglContext) {
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index b70d7b5..e1f01db 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -58,6 +58,7 @@
void getDisplaySize(out Point size);
void getRealDisplaySize(out Point size);
int getMaximumSizeDimension();
+ void getCurrentSizeRange(out Point smallestSize, out Point largestSize);
void setForcedDisplaySize(int longDimen, int shortDimen);
void clearForcedDisplaySize();
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 4848a7a..85f435c 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -167,6 +167,19 @@
/**
* The input source is a stylus pointing device.
+ * <p>
+ * Note that this bit merely indicates that an input device is capable of obtaining
+ * input from a stylus. To determine whether a given touch event was produced
+ * by a stylus, examine the tool type returned by {@link MotionEvent#getToolType(int)}
+ * for each individual pointer.
+ * </p><p>
+ * A single touch event may multiple pointers with different tool types,
+ * such as an event that has one pointer with tool type
+ * {@link MotionEvent#TOOL_TYPE_FINGER} and another pointer with tool type
+ * {@link MotionEvent#TOOL_TYPE_STYLUS}. So it is important to examine
+ * the tool type of each pointer, regardless of the source reported
+ * by {@link MotionEvent#getSource()}.
+ * </p>
*
* @see #SOURCE_CLASS_POINTER
*/
diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java
index 5602436..ef810a3 100755
--- a/core/java/android/view/InputEvent.java
+++ b/core/java/android/view/InputEvent.java
@@ -159,8 +159,26 @@
public abstract void setTainted(boolean tainted);
/**
- * Returns the time (in ns) when this specific event was generated.
+ * Retrieve the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base.
+ *
+ * @return Returns the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base.
+ */
+ public abstract long getEventTime();
+
+ /**
+ * Retrieve the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base but with
+ * nanosecond (instead of millisecond) precision.
+ * <p>
* The value is in nanosecond precision but it may not have nanosecond accuracy.
+ * </p>
+ *
+ * @return Returns the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base but with
+ * nanosecond (instead of millisecond) precision.
+ *
* @hide
*/
public abstract long getEventTimeNano();
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 12d7b12..1c61c6c 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -24,6 +24,7 @@
import android.hardware.input.InputManager;
import java.lang.Character;
+import java.text.Normalizer;
/**
* Describes the keys provided by a keyboard device and their associated labels.
@@ -135,6 +136,106 @@
*/
public static final int MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED = 1;
+ /*
+ * This bit will be set in the return value of {@link #get(int, int)} if the
+ * key is a "dead key."
+ */
+ public static final int COMBINING_ACCENT = 0x80000000;
+
+ /**
+ * Mask the return value from {@link #get(int, int)} with this value to get
+ * a printable representation of the accent character of a "dead key."
+ */
+ public static final int COMBINING_ACCENT_MASK = 0x7FFFFFFF;
+
+ /* Characters used to display placeholders for dead keys. */
+ private static final int ACCENT_ACUTE = '\u00B4';
+ private static final int ACCENT_BREVE = '\u02D8';
+ private static final int ACCENT_CARON = '\u02C7';
+ private static final int ACCENT_CEDILLA = '\u00B8';
+ private static final int ACCENT_COMMA_ABOVE = '\u1FBD';
+ private static final int ACCENT_COMMA_ABOVE_RIGHT = '\u02BC';
+ private static final int ACCENT_DOT_ABOVE = '\u02D9';
+ private static final int ACCENT_DOUBLE_ACUTE = '\u02DD';
+ private static final int ACCENT_GRAVE = '\u02CB';
+ private static final int ACCENT_CIRCUMFLEX = '\u02C6';
+ private static final int ACCENT_MACRON = '\u00AF';
+ private static final int ACCENT_MACRON_BELOW = '\u02CD';
+ private static final int ACCENT_OGONEK = '\u02DB';
+ private static final int ACCENT_REVERSED_COMMA_ABOVE = '\u02BD';
+ private static final int ACCENT_RING_ABOVE = '\u02DA';
+ private static final int ACCENT_TILDE = '\u02DC';
+ private static final int ACCENT_TURNED_COMMA_ABOVE = '\u02BB';
+ private static final int ACCENT_UMLAUT = '\u00A8';
+
+ /* Legacy dead key display characters used in previous versions of the API.
+ * We still support these characters by mapping them to their non-legacy version. */
+ private static final int ACCENT_GRAVE_LEGACY = '`';
+ private static final int ACCENT_CIRCUMFLEX_LEGACY = '^';
+ private static final int ACCENT_TILDE_LEGACY = '~';
+
+ /**
+ * Maps Unicode combining diacritical to display-form dead key.
+ */
+ private static final SparseIntArray sCombiningToAccent = new SparseIntArray();
+ private static final SparseIntArray sAccentToCombining = new SparseIntArray();
+ static {
+ addCombining('\u0300', ACCENT_GRAVE);
+ addCombining('\u0301', ACCENT_ACUTE);
+ addCombining('\u0302', ACCENT_CIRCUMFLEX);
+ addCombining('\u0303', ACCENT_TILDE);
+ addCombining('\u0304', ACCENT_MACRON);
+ addCombining('\u0306', ACCENT_BREVE);
+ addCombining('\u0307', ACCENT_DOT_ABOVE);
+ addCombining('\u0308', ACCENT_UMLAUT);
+ //addCombining('\u0309', ACCENT_HOOK_ABOVE);
+ addCombining('\u030A', ACCENT_RING_ABOVE);
+ addCombining('\u030B', ACCENT_DOUBLE_ACUTE);
+ addCombining('\u030C', ACCENT_CARON);
+ //addCombining('\u030D', ACCENT_VERTICAL_LINE_ABOVE);
+ //addCombining('\u030E', ACCENT_DOUBLE_VERTICAL_LINE_ABOVE);
+ //addCombining('\u030F', ACCENT_DOUBLE_GRAVE);
+ //addCombining('\u0310', ACCENT_CANDRABINDU);
+ //addCombining('\u0311', ACCENT_INVERTED_BREVE);
+ addCombining('\u0312', ACCENT_TURNED_COMMA_ABOVE);
+ addCombining('\u0313', ACCENT_COMMA_ABOVE);
+ addCombining('\u0314', ACCENT_REVERSED_COMMA_ABOVE);
+ addCombining('\u0315', ACCENT_COMMA_ABOVE_RIGHT);
+ //addCombining('\u031B', ACCENT_HORN);
+ //addCombining('\u0323', ACCENT_DOT_BELOW);
+ //addCombining('\u0326', ACCENT_COMMA_BELOW);
+ addCombining('\u0327', ACCENT_CEDILLA);
+ addCombining('\u0328', ACCENT_OGONEK);
+ //addCombining('\u0329', ACCENT_VERTICAL_LINE_BELOW);
+ addCombining('\u0331', ACCENT_MACRON_BELOW);
+ //addCombining('\u0342', ACCENT_PERISPOMENI);
+ //addCombining('\u0344', ACCENT_DIALYTIKA_TONOS);
+ //addCombining('\u0345', ACCENT_YPOGEGRAMMENI);
+
+ // One-way mappings to equivalent preferred accents.
+ sCombiningToAccent.append('\u0340', ACCENT_GRAVE);
+ sCombiningToAccent.append('\u0341', ACCENT_ACUTE);
+ sCombiningToAccent.append('\u0343', ACCENT_COMMA_ABOVE);
+
+ // One-way legacy mappings to preserve compatibility with older applications.
+ sAccentToCombining.append(ACCENT_GRAVE_LEGACY, '\u0300');
+ sAccentToCombining.append(ACCENT_CIRCUMFLEX_LEGACY, '\u0302');
+ sAccentToCombining.append(ACCENT_TILDE_LEGACY, '\u0303');
+ }
+
+ private static void addCombining(int combining, int accent) {
+ sCombiningToAccent.append(combining, accent);
+ sAccentToCombining.append(accent, combining);
+ }
+
+ /**
+ * Maps combinations of (display-form) combining key and second character
+ * to combined output character.
+ * These mappings are derived from the Unicode NFC tables as needed.
+ */
+ private static final SparseIntArray sDeadKeyCache = new SparseIntArray();
+ private static final StringBuilder sDeadKeyBuilder = new StringBuilder();
+
public static final Parcelable.Creator<KeyCharacterMap> CREATOR =
new Parcelable.Creator<KeyCharacterMap>() {
public KeyCharacterMap createFromParcel(Parcel in) {
@@ -230,9 +331,9 @@
metaState = KeyEvent.normalizeMetaState(metaState);
char ch = nativeGetCharacter(mPtr, keyCode, metaState);
- int map = COMBINING.get(ch);
+ int map = sCombiningToAccent.get(ch);
if (map != 0) {
- return map;
+ return map | COMBINING_ACCENT;
} else {
return ch;
}
@@ -346,7 +447,25 @@
* @return The combined character, or 0 if the characters cannot be combined.
*/
public static int getDeadChar(int accent, int c) {
- return DEAD.get((accent << 16) | c);
+ int combining = sAccentToCombining.get(accent);
+ if (combining == 0) {
+ return 0;
+ }
+
+ final int combination = (combining << 16) | c;
+ int combined;
+ synchronized (sDeadKeyCache) {
+ combined = sDeadKeyCache.get(combination, -1);
+ if (combined == -1) {
+ sDeadKeyBuilder.setLength(0);
+ sDeadKeyBuilder.append((char)c);
+ sDeadKeyBuilder.append((char)combining);
+ String result = Normalizer.normalize(sDeadKeyBuilder, Normalizer.Form.NFC);
+ combined = result.length() == 1 ? result.charAt(0) : 0;
+ sDeadKeyCache.put(combination, combined);
+ }
+ }
+ return combined;
}
/**
@@ -560,159 +679,6 @@
}
/**
- * Maps Unicode combining diacritical to display-form dead key
- * (display character shifted left 16 bits).
- */
- private static SparseIntArray COMBINING = new SparseIntArray();
-
- /**
- * Maps combinations of (display-form) dead key and second character
- * to combined output character.
- */
- private static SparseIntArray DEAD = new SparseIntArray();
-
- /*
- * TODO: Change the table format to support full 21-bit-wide
- * accent characters and combined characters if ever necessary.
- */
- private static final int ACUTE = '\u00B4' << 16;
- private static final int GRAVE = '`' << 16;
- private static final int CIRCUMFLEX = '^' << 16;
- private static final int TILDE = '~' << 16;
- private static final int UMLAUT = '\u00A8' << 16;
-
- /*
- * This bit will be set in the return value of {@link #get(int, int)} if the
- * key is a "dead key."
- */
- public static final int COMBINING_ACCENT = 0x80000000;
- /**
- * Mask the return value from {@link #get(int, int)} with this value to get
- * a printable representation of the accent character of a "dead key."
- */
- public static final int COMBINING_ACCENT_MASK = 0x7FFFFFFF;
-
- static {
- COMBINING.put('\u0300', (GRAVE >> 16) | COMBINING_ACCENT);
- COMBINING.put('\u0301', (ACUTE >> 16) | COMBINING_ACCENT);
- COMBINING.put('\u0302', (CIRCUMFLEX >> 16) | COMBINING_ACCENT);
- COMBINING.put('\u0303', (TILDE >> 16) | COMBINING_ACCENT);
- COMBINING.put('\u0308', (UMLAUT >> 16) | COMBINING_ACCENT);
-
- DEAD.put(ACUTE | 'A', '\u00C1');
- DEAD.put(ACUTE | 'C', '\u0106');
- DEAD.put(ACUTE | 'E', '\u00C9');
- DEAD.put(ACUTE | 'G', '\u01F4');
- DEAD.put(ACUTE | 'I', '\u00CD');
- DEAD.put(ACUTE | 'K', '\u1E30');
- DEAD.put(ACUTE | 'L', '\u0139');
- DEAD.put(ACUTE | 'M', '\u1E3E');
- DEAD.put(ACUTE | 'N', '\u0143');
- DEAD.put(ACUTE | 'O', '\u00D3');
- DEAD.put(ACUTE | 'P', '\u1E54');
- DEAD.put(ACUTE | 'R', '\u0154');
- DEAD.put(ACUTE | 'S', '\u015A');
- DEAD.put(ACUTE | 'U', '\u00DA');
- DEAD.put(ACUTE | 'W', '\u1E82');
- DEAD.put(ACUTE | 'Y', '\u00DD');
- DEAD.put(ACUTE | 'Z', '\u0179');
- DEAD.put(ACUTE | 'a', '\u00E1');
- DEAD.put(ACUTE | 'c', '\u0107');
- DEAD.put(ACUTE | 'e', '\u00E9');
- DEAD.put(ACUTE | 'g', '\u01F5');
- DEAD.put(ACUTE | 'i', '\u00ED');
- DEAD.put(ACUTE | 'k', '\u1E31');
- DEAD.put(ACUTE | 'l', '\u013A');
- DEAD.put(ACUTE | 'm', '\u1E3F');
- DEAD.put(ACUTE | 'n', '\u0144');
- DEAD.put(ACUTE | 'o', '\u00F3');
- DEAD.put(ACUTE | 'p', '\u1E55');
- DEAD.put(ACUTE | 'r', '\u0155');
- DEAD.put(ACUTE | 's', '\u015B');
- DEAD.put(ACUTE | 'u', '\u00FA');
- DEAD.put(ACUTE | 'w', '\u1E83');
- DEAD.put(ACUTE | 'y', '\u00FD');
- DEAD.put(ACUTE | 'z', '\u017A');
- DEAD.put(CIRCUMFLEX | 'A', '\u00C2');
- DEAD.put(CIRCUMFLEX | 'C', '\u0108');
- DEAD.put(CIRCUMFLEX | 'E', '\u00CA');
- DEAD.put(CIRCUMFLEX | 'G', '\u011C');
- DEAD.put(CIRCUMFLEX | 'H', '\u0124');
- DEAD.put(CIRCUMFLEX | 'I', '\u00CE');
- DEAD.put(CIRCUMFLEX | 'J', '\u0134');
- DEAD.put(CIRCUMFLEX | 'O', '\u00D4');
- DEAD.put(CIRCUMFLEX | 'S', '\u015C');
- DEAD.put(CIRCUMFLEX | 'U', '\u00DB');
- DEAD.put(CIRCUMFLEX | 'W', '\u0174');
- DEAD.put(CIRCUMFLEX | 'Y', '\u0176');
- DEAD.put(CIRCUMFLEX | 'Z', '\u1E90');
- DEAD.put(CIRCUMFLEX | 'a', '\u00E2');
- DEAD.put(CIRCUMFLEX | 'c', '\u0109');
- DEAD.put(CIRCUMFLEX | 'e', '\u00EA');
- DEAD.put(CIRCUMFLEX | 'g', '\u011D');
- DEAD.put(CIRCUMFLEX | 'h', '\u0125');
- DEAD.put(CIRCUMFLEX | 'i', '\u00EE');
- DEAD.put(CIRCUMFLEX | 'j', '\u0135');
- DEAD.put(CIRCUMFLEX | 'o', '\u00F4');
- DEAD.put(CIRCUMFLEX | 's', '\u015D');
- DEAD.put(CIRCUMFLEX | 'u', '\u00FB');
- DEAD.put(CIRCUMFLEX | 'w', '\u0175');
- DEAD.put(CIRCUMFLEX | 'y', '\u0177');
- DEAD.put(CIRCUMFLEX | 'z', '\u1E91');
- DEAD.put(GRAVE | 'A', '\u00C0');
- DEAD.put(GRAVE | 'E', '\u00C8');
- DEAD.put(GRAVE | 'I', '\u00CC');
- DEAD.put(GRAVE | 'N', '\u01F8');
- DEAD.put(GRAVE | 'O', '\u00D2');
- DEAD.put(GRAVE | 'U', '\u00D9');
- DEAD.put(GRAVE | 'W', '\u1E80');
- DEAD.put(GRAVE | 'Y', '\u1EF2');
- DEAD.put(GRAVE | 'a', '\u00E0');
- DEAD.put(GRAVE | 'e', '\u00E8');
- DEAD.put(GRAVE | 'i', '\u00EC');
- DEAD.put(GRAVE | 'n', '\u01F9');
- DEAD.put(GRAVE | 'o', '\u00F2');
- DEAD.put(GRAVE | 'u', '\u00F9');
- DEAD.put(GRAVE | 'w', '\u1E81');
- DEAD.put(GRAVE | 'y', '\u1EF3');
- DEAD.put(TILDE | 'A', '\u00C3');
- DEAD.put(TILDE | 'E', '\u1EBC');
- DEAD.put(TILDE | 'I', '\u0128');
- DEAD.put(TILDE | 'N', '\u00D1');
- DEAD.put(TILDE | 'O', '\u00D5');
- DEAD.put(TILDE | 'U', '\u0168');
- DEAD.put(TILDE | 'V', '\u1E7C');
- DEAD.put(TILDE | 'Y', '\u1EF8');
- DEAD.put(TILDE | 'a', '\u00E3');
- DEAD.put(TILDE | 'e', '\u1EBD');
- DEAD.put(TILDE | 'i', '\u0129');
- DEAD.put(TILDE | 'n', '\u00F1');
- DEAD.put(TILDE | 'o', '\u00F5');
- DEAD.put(TILDE | 'u', '\u0169');
- DEAD.put(TILDE | 'v', '\u1E7D');
- DEAD.put(TILDE | 'y', '\u1EF9');
- DEAD.put(UMLAUT | 'A', '\u00C4');
- DEAD.put(UMLAUT | 'E', '\u00CB');
- DEAD.put(UMLAUT | 'H', '\u1E26');
- DEAD.put(UMLAUT | 'I', '\u00CF');
- DEAD.put(UMLAUT | 'O', '\u00D6');
- DEAD.put(UMLAUT | 'U', '\u00DC');
- DEAD.put(UMLAUT | 'W', '\u1E84');
- DEAD.put(UMLAUT | 'X', '\u1E8C');
- DEAD.put(UMLAUT | 'Y', '\u0178');
- DEAD.put(UMLAUT | 'a', '\u00E4');
- DEAD.put(UMLAUT | 'e', '\u00EB');
- DEAD.put(UMLAUT | 'h', '\u1E27');
- DEAD.put(UMLAUT | 'i', '\u00EF');
- DEAD.put(UMLAUT | 'o', '\u00F6');
- DEAD.put(UMLAUT | 't', '\u1E97');
- DEAD.put(UMLAUT | 'u', '\u00FC');
- DEAD.put(UMLAUT | 'w', '\u1E85');
- DEAD.put(UMLAUT | 'x', '\u1E8D');
- DEAD.put(UMLAUT | 'y', '\u00FF');
- }
-
- /**
* Thrown by {@link KeyCharacterMap#load} when a key character map could not be loaded.
*/
public static class UnavailableException extends AndroidRuntimeException {
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index e4a4a75..ace7aa8 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -2375,17 +2375,31 @@
}
/**
- * Retrieve the time this event occurred,
+ * Retrieve the time this event occurred,
* in the {@link android.os.SystemClock#uptimeMillis} time base.
- *
+ *
* @return Returns the time this event occurred,
* in the {@link android.os.SystemClock#uptimeMillis} time base.
*/
+ @Override
public final long getEventTime() {
return mEventTime;
}
- /** @hide */
+ /**
+ * Retrieve the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base but with
+ * nanosecond (instead of millisecond) precision.
+ * <p>
+ * The value is in nanosecond precision but it may not have nanosecond accuracy.
+ * </p>
+ *
+ * @return Returns the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base but with
+ * nanosecond (instead of millisecond) precision.
+ *
+ * @hide
+ */
@Override
public final long getEventTimeNano() {
return mEventTime * 1000000L;
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index e51ba3d..78fa2d7 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1781,18 +1781,32 @@
}
/**
- * Returns the time (in ms) when this specific event was generated.
+ * Retrieve the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base.
+ *
+ * @return Returns the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base.
*/
+ @Override
public final long getEventTime() {
return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT) / NS_PER_MS;
}
/**
- * Returns the time (in ns) when this specific event was generated.
+ * Retrieve the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base but with
+ * nanosecond precision.
+ * <p>
* The value is in nanosecond precision but it may not have nanosecond accuracy.
+ * </p>
+ *
+ * @return Returns the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base but with
+ * nanosecond precision.
*
* @hide
*/
+ @Override
public final long getEventTimeNano() {
return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT);
}
@@ -2234,10 +2248,16 @@
/**
* Returns the time that a historical movement occurred between this event
- * and the previous event. Only applies to ACTION_MOVE events.
+ * and the previous event, in the {@link android.os.SystemClock#uptimeMillis} time base.
+ * <p>
+ * This only applies to ACTION_MOVE events.
+ * </p>
*
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
+ * @return Returns the time that a historical movement occurred between this
+ * event and the previous event,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base.
*
* @see #getHistorySize
* @see #getEventTime
@@ -2247,6 +2267,32 @@
}
/**
+ * Returns the time that a historical movement occurred between this event
+ * and the previous event, in the {@link android.os.SystemClock#uptimeMillis} time base
+ * but with nanosecond (instead of millisecond) precision.
+ * <p>
+ * This only applies to ACTION_MOVE events.
+ * </p><p>
+ * The value is in nanosecond precision but it may not have nanosecond accuracy.
+ * </p>
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ * @return Returns the time that a historical movement occurred between this
+ * event and the previous event,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base but with
+ * nanosecond (instead of millisecond) precision.
+ *
+ * @see #getHistorySize
+ * @see #getEventTime
+ *
+ * @hide
+ */
+ public final long getHistoricalEventTimeNano(int pos) {
+ return nativeGetEventTimeNanos(mNativePtr, pos);
+ }
+
+ /**
* {@link #getHistoricalX(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0ded5f9..a833cbe 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -39,6 +39,7 @@
import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
@@ -1044,12 +1045,12 @@
public static final int ACCESSIBILITY_FOCUS_DOWN = FOCUS_DOWN | FOCUS_ACCESSIBILITY;
/**
- * Use with {@link #focusSearch(int)}. Move acessibility focus to the next view.
+ * Use with {@link #focusSearch(int)}. Move acessibility focus forward.
*/
public static final int ACCESSIBILITY_FOCUS_FORWARD = FOCUS_FORWARD | FOCUS_ACCESSIBILITY;
/**
- * Use with {@link #focusSearch(int)}. Move acessibility focus to the previous view.
+ * Use with {@link #focusSearch(int)}. Move acessibility focus backward.
*/
public static final int ACCESSIBILITY_FOCUS_BACKWARD = FOCUS_BACKWARD | FOCUS_ACCESSIBILITY;
@@ -1064,6 +1065,16 @@
public static final int ACCESSIBILITY_FOCUS_OUT = 0x00000008 | FOCUS_ACCESSIBILITY;
/**
+ * Use with {@link #focusSearch(int)}. Move acessibility focus to the next view.
+ */
+ public static final int ACCESSIBILITY_FOCUS_NEXT = 0x00000010 | FOCUS_ACCESSIBILITY;
+
+ /**
+ * Use with {@link #focusSearch(int)}. Move acessibility focus to the previous view.
+ */
+ public static final int ACCESSIBILITY_FOCUS_PREVIOUS = 0x00000020 | FOCUS_ACCESSIBILITY;
+
+ /**
* Bits of {@link #getMeasuredWidthAndState()} and
* {@link #getMeasuredWidthAndState()} that provide the actual measured size.
*/
@@ -1520,14 +1531,6 @@
static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>();
/**
- * Temporary flag, used to enable processing of View properties in the native DisplayList
- * object instead of during draw(). Soon to be enabled by default for hardware-accelerated
- * apps.
- * @hide
- */
- public static final boolean USE_DISPLAY_LIST_PROPERTIES = true;
-
- /**
* Map used to store views' tags.
*/
private SparseArray<Object> mKeyedTags;
@@ -2472,6 +2475,12 @@
int mSystemUiVisibility;
/**
+ * Reference count for transient state.
+ * @see #setHasTransientState(boolean)
+ */
+ int mTransientStateCount = 0;
+
+ /**
* Count of how many windows this view has been attached to.
*/
int mWindowAttachCount;
@@ -4674,6 +4683,23 @@
}
/**
+ * Computes whether this view is visible on the screen.
+ *
+ * @return Whether the view is visible on the screen.
+ */
+ boolean isDisplayedOnScreen() {
+ // The first two checks are made also made by isShown() which
+ // however traverses the tree up to the parent to catch that.
+ // Therefore, we do some fail fast check to minimize the up
+ // tree traversal.
+ return (mAttachInfo != null
+ && mAttachInfo.mWindowVisibility == View.VISIBLE
+ && getAlpha() > 0
+ && isShown()
+ && getGlobalVisibleRect(mAttachInfo.mTmpInvalRect));
+ }
+
+ /**
* Sets a delegate for implementing accessibility support via compositon as
* opposed to inheritance. The delegate's primary use is for implementing
* backwards compatible widgets. For more details see {@link AccessibilityDelegate}.
@@ -5400,21 +5426,32 @@
/**
* Set whether this view is currently tracking transient state that the
- * framework should attempt to preserve when possible.
+ * framework should attempt to preserve when possible. This flag is reference counted,
+ * so every call to setHasTransientState(true) should be paired with a later call
+ * to setHasTransientState(false).
*
* @param hasTransientState true if this view has transient state
*/
public void setHasTransientState(boolean hasTransientState) {
- if (hasTransientState() == hasTransientState) return;
-
- mPrivateFlags2 = (mPrivateFlags2 & ~HAS_TRANSIENT_STATE) |
- (hasTransientState ? HAS_TRANSIENT_STATE : 0);
- if (mParent != null) {
- try {
- mParent.childHasTransientStateChanged(this, hasTransientState);
- } catch (AbstractMethodError e) {
- Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
- " does not fully implement ViewParent", e);
+ mTransientStateCount = hasTransientState ? mTransientStateCount + 1 :
+ mTransientStateCount - 1;
+ if (mTransientStateCount < 0) {
+ mTransientStateCount = 0;
+ Log.e(VIEW_LOG_TAG, "hasTransientState decremented below 0: " +
+ "unmatched pair of setHasTransientState calls");
+ }
+ if ((hasTransientState && mTransientStateCount == 1) ||
+ (hasTransientState && mTransientStateCount == 0)) {
+ // update flag if we've just incremented up from 0 or decremented down to 0
+ mPrivateFlags2 = (mPrivateFlags2 & ~HAS_TRANSIENT_STATE) |
+ (hasTransientState ? HAS_TRANSIENT_STATE : 0);
+ if (mParent != null) {
+ try {
+ mParent.childHasTransientStateChanged(this, hasTransientState);
+ } catch (AbstractMethodError e) {
+ Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+ " does not fully implement ViewParent", e);
+ }
}
}
}
@@ -6284,9 +6321,9 @@
boolean includeForAccessibility() {
if (mAttachInfo != null) {
if (!mAttachInfo.mIncludeNotImportantViews) {
- return isImportantForAccessibility();
+ return isImportantForAccessibility() && isDisplayedOnScreen();
} else {
- return true;
+ return isDisplayedOnScreen();
}
}
return false;
@@ -6356,19 +6393,17 @@
* @param action The action to perform.
* @return Whether the action was performed.
*/
- public boolean performAccessibilityAction(int action) {
+ public boolean performAccessibilityAction(int action, Bundle args) {
switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK: {
- final long now = SystemClock.uptimeMillis();
- // Send down.
- MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
- getWidth() / 2, getHeight() / 2, 0);
- onTouchEvent(event);
- // Send up.
- event.setAction(MotionEvent.ACTION_UP);
- onTouchEvent(event);
- // Clean up.
- event.recycle();
+ if (isClickable()) {
+ performClick();
+ }
+ } break;
+ case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
+ if (isLongClickable()) {
+ performLongClick();
+ }
} break;
case AccessibilityNodeInfo.ACTION_FOCUS: {
if (!hasFocus()) {
@@ -7323,7 +7358,7 @@
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
// If the window does not have input focus we take away accessibility
// focus as soon as the user stop hovering over the view.
- if (!mAttachInfo.mHasWindowFocus) {
+ if (mAttachInfo != null && !mAttachInfo.mHasWindowFocus) {
getViewRootImpl().setAccessibilityFocusedHost(null);
}
}
@@ -8226,7 +8261,7 @@
info.mMatrixDirty = true;
invalidateViewProperty(false, false);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setCameraDistance(-Math.abs(distance) / dpi);
}
}
@@ -8268,7 +8303,7 @@
info.mRotation = rotation;
info.mMatrixDirty = true;
invalidateViewProperty(false, true);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setRotation(rotation);
}
}
@@ -8315,7 +8350,7 @@
info.mRotationY = rotationY;
info.mMatrixDirty = true;
invalidateViewProperty(false, true);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setRotationY(rotationY);
}
}
@@ -8362,7 +8397,7 @@
info.mRotationX = rotationX;
info.mMatrixDirty = true;
invalidateViewProperty(false, true);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setRotationX(rotationX);
}
}
@@ -8401,7 +8436,7 @@
info.mScaleX = scaleX;
info.mMatrixDirty = true;
invalidateViewProperty(false, true);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setScaleX(scaleX);
}
}
@@ -8440,7 +8475,7 @@
info.mScaleY = scaleY;
info.mMatrixDirty = true;
invalidateViewProperty(false, true);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setScaleY(scaleY);
}
}
@@ -8487,7 +8522,7 @@
info.mPivotX = pivotX;
info.mMatrixDirty = true;
invalidateViewProperty(false, true);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setPivotX(pivotX);
}
}
@@ -8533,7 +8568,7 @@
info.mPivotY = pivotY;
info.mMatrixDirty = true;
invalidateViewProperty(false, true);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setPivotY(pivotY);
}
}
@@ -8599,7 +8634,7 @@
} else {
mPrivateFlags &= ~ALPHA_SET;
invalidateViewProperty(true, false);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setAlpha(alpha);
}
}
@@ -8626,7 +8661,7 @@
return true;
} else {
mPrivateFlags &= ~ALPHA_SET;
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setAlpha(alpha);
}
}
@@ -8678,7 +8713,7 @@
int oldHeight = mBottom - mTop;
mTop = top;
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setTop(mTop);
}
@@ -8747,7 +8782,7 @@
int oldHeight = mBottom - mTop;
mBottom = bottom;
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setBottom(mBottom);
}
@@ -8810,7 +8845,7 @@
int height = mBottom - mTop;
mLeft = left;
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setLeft(left);
}
@@ -8826,9 +8861,6 @@
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
- if (USE_DISPLAY_LIST_PROPERTIES) {
-
- }
}
}
@@ -8873,7 +8905,7 @@
int height = mBottom - mTop;
mRight = right;
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setRight(mRight);
}
@@ -8970,7 +9002,7 @@
info.mTranslationX = translationX;
info.mMatrixDirty = true;
invalidateViewProperty(false, true);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setTranslationX(translationX);
}
}
@@ -9007,7 +9039,7 @@
info.mTranslationY = translationY;
info.mMatrixDirty = true;
invalidateViewProperty(false, true);
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setTranslationY(translationY);
}
}
@@ -9118,7 +9150,7 @@
final boolean matrixIsIdentity = mTransformationInfo == null
|| mTransformationInfo.mMatrixIsIdentity;
if (matrixIsIdentity) {
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
invalidateViewProperty(false, false);
} else {
final ViewParent p = mParent;
@@ -9146,7 +9178,7 @@
mTop += offset;
mBottom += offset;
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.offsetTopBottom(offset);
invalidateViewProperty(false, false);
} else {
@@ -9169,7 +9201,7 @@
final boolean matrixIsIdentity = mTransformationInfo == null
|| mTransformationInfo.mMatrixIsIdentity;
if (matrixIsIdentity) {
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
invalidateViewProperty(false, false);
} else {
final ViewParent p = mParent;
@@ -9194,7 +9226,7 @@
mLeft += offset;
mRight += offset;
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.offsetLeftRight(offset);
invalidateViewProperty(false, false);
} else {
@@ -9623,8 +9655,7 @@
* list properties are not being used in this view
*/
void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
- if (!USE_DISPLAY_LIST_PROPERTIES || mDisplayList == null ||
- (mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) {
+ if (mDisplayList == null || (mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) {
if (invalidateParent) {
invalidateParentCaches();
}
@@ -11716,7 +11747,7 @@
int layerType = (
!(mParent instanceof ViewGroup) || ((ViewGroup)mParent).mDrawLayers) ?
getLayerType() : LAYER_TYPE_NONE;
- if (!isLayer && layerType != LAYER_TYPE_NONE && USE_DISPLAY_LIST_PROPERTIES) {
+ if (!isLayer && layerType != LAYER_TYPE_NONE) {
if (layerType == LAYER_TYPE_HARDWARE) {
final HardwareLayer layer = getHardwareLayer();
if (layer != null && layer.isValid()) {
@@ -11739,9 +11770,6 @@
computeScroll();
- if (!USE_DISPLAY_LIST_PROPERTIES) {
- restoreCount = canvas.save();
- }
canvas.translate(-mScrollX, -mScrollY);
if (!isLayer) {
mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
@@ -11756,16 +11784,11 @@
}
}
} finally {
- if (USE_DISPLAY_LIST_PROPERTIES) {
- canvas.restoreToCount(restoreCount);
- }
canvas.onPostDraw();
displayList.end();
- if (USE_DISPLAY_LIST_PROPERTIES) {
- displayList.setCaching(caching);
- }
- if (isLayer && USE_DISPLAY_LIST_PROPERTIES) {
+ displayList.setCaching(caching);
+ if (isLayer) {
displayList.setLeftTopRightBottom(0, 0, width, height);
} else {
setDisplayListProperties(displayList);
@@ -12299,7 +12322,7 @@
final int flags = parent.mGroupFlags;
final boolean initialized = a.isInitialized();
if (!initialized) {
- a.initialize(mRight - mLeft, mBottom - mTop, getWidth(), getHeight());
+ a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
onAnimationStart();
}
@@ -12357,7 +12380,7 @@
* previously-set transform values
*/
void setDisplayListProperties(DisplayList displayList) {
- if (USE_DISPLAY_LIST_PROPERTIES && displayList != null) {
+ if (displayList != null) {
displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
displayList.setHasOverlappingRendering(hasOverlappingRendering());
if (mParent instanceof ViewGroup) {
@@ -12417,8 +12440,7 @@
* to be called from anywhere else other than ViewGroup.drawChild().
*/
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
- boolean useDisplayListProperties = USE_DISPLAY_LIST_PROPERTIES && mAttachInfo != null &&
- mAttachInfo.mHardwareAccelerated;
+ boolean useDisplayListProperties = mAttachInfo != null && mAttachInfo.mHardwareAccelerated;
boolean more = false;
final boolean childHasIdentityMatrix = hasIdentityMatrix();
final int flags = parent.mGroupFlags;
@@ -12679,8 +12701,7 @@
}
} else {
mPrivateFlags &= ~DIRTY_MASK;
- ((HardwareCanvas) canvas).drawDisplayList(displayList,
- mRight - mLeft, mBottom - mTop, null, flags);
+ ((HardwareCanvas) canvas).drawDisplayList(displayList, null, flags);
}
}
} else if (cache != null) {
@@ -13168,7 +13189,7 @@
mTop = top;
mRight = right;
mBottom = bottom;
- if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ if (mDisplayList != null) {
mDisplayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
}
@@ -13846,13 +13867,7 @@
*/
public Insets getLayoutInsets() {
if (mLayoutInsets == null) {
- if (mBackground == null) {
- mLayoutInsets = Insets.NONE;
- } else {
- Rect insetRect = new Rect();
- boolean hasInsets = mBackground.getLayoutInsets(insetRect);
- mLayoutInsets = hasInsets ? Insets.of(insetRect) : Insets.NONE;
- }
+ mLayoutInsets = (mBackground == null) ? Insets.NONE : mBackground.getLayoutInsets();
}
return mLayoutInsets;
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 6371963..8c8711c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1569,6 +1569,43 @@
return handled;
}
+ private void exitHoverTargets() {
+ if (mHoveredSelf || mFirstHoverTarget != null) {
+ final long now = SystemClock.uptimeMillis();
+ MotionEvent event = MotionEvent.obtain(now, now,
+ MotionEvent.ACTION_HOVER_EXIT, 0.0f, 0.0f, 0);
+ event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ dispatchHoverEvent(event);
+ event.recycle();
+ }
+ }
+
+ private void cancelHoverTarget(View view) {
+ HoverTarget predecessor = null;
+ HoverTarget target = mFirstHoverTarget;
+ while (target != null) {
+ final HoverTarget next = target.next;
+ if (target.child == view) {
+ if (predecessor == null) {
+ mFirstHoverTarget = next;
+ } else {
+ predecessor.next = next;
+ }
+ target.recycle();
+
+ final long now = SystemClock.uptimeMillis();
+ MotionEvent event = MotionEvent.obtain(now, now,
+ MotionEvent.ACTION_HOVER_EXIT, 0.0f, 0.0f, 0);
+ event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ view.dispatchHoverEvent(event);
+ event.recycle();
+ return;
+ }
+ predecessor = target;
+ target = next;
+ }
+ }
+
/** @hide */
@Override
protected boolean hasHoveredChild() {
@@ -1997,6 +2034,32 @@
}
}
+ private void cancelTouchTarget(View view) {
+ TouchTarget predecessor = null;
+ TouchTarget target = mFirstTouchTarget;
+ while (target != null) {
+ final TouchTarget next = target.next;
+ if (target.child == view) {
+ if (predecessor == null) {
+ mFirstTouchTarget = next;
+ } else {
+ predecessor.next = next;
+ }
+ target.recycle();
+
+ final long now = SystemClock.uptimeMillis();
+ MotionEvent event = MotionEvent.obtain(now, now,
+ MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
+ event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ view.dispatchTouchEvent(event);
+ event.recycle();
+ return;
+ }
+ predecessor = target;
+ target = next;
+ }
+ }
+
/**
* Returns true if a child view can receive pointer events.
* @hide
@@ -2416,6 +2479,9 @@
// first send it an ACTION_CANCEL motion event.
cancelAndClearTouchTargets(null);
+ // Similarly, set ACTION_EXIT to all hover targets and clear them.
+ exitHoverTargets();
+
// In case view is detached while transition is running
mLayoutSuppressed = false;
@@ -2832,12 +2898,10 @@
boolean previousValue = (mGroupFlags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN;
if (clipChildren != previousValue) {
setBooleanFlag(FLAG_CLIP_CHILDREN, clipChildren);
- if (USE_DISPLAY_LIST_PROPERTIES) {
- for (int i = 0; i < mChildrenCount; ++i) {
- View child = getChildAt(i);
- if (child.mDisplayList != null) {
- child.mDisplayList.setClipChildren(clipChildren);
- }
+ for (int i = 0; i < mChildrenCount; ++i) {
+ View child = getChildAt(i);
+ if (child.mDisplayList != null) {
+ child.mDisplayList.setClipChildren(clipChildren);
}
}
}
@@ -3453,6 +3517,9 @@
clearChildFocus = true;
}
+ cancelTouchTarget(view);
+ cancelHoverTarget(view);
+
if (view.getAnimation() != null ||
(mTransitioningViews != null && mTransitioningViews.contains(view))) {
addDisappearingView(view);
@@ -3533,6 +3600,9 @@
clearChildFocus = view;
}
+ cancelTouchTarget(view);
+ cancelHoverTarget(view);
+
if (view.getAnimation() != null ||
(mTransitioningViews != null && mTransitioningViews.contains(view))) {
addDisappearingView(view);
@@ -3603,6 +3673,9 @@
clearChildFocus = view;
}
+ cancelTouchTarget(view);
+ cancelHoverTarget(view);
+
if (view.getAnimation() != null ||
(mTransitioningViews != null && mTransitioningViews.contains(view))) {
addDisappearingView(view);
@@ -3648,6 +3721,9 @@
child.clearFocus();
}
+ cancelTouchTarget(child);
+ cancelHoverTarget(child);
+
if ((animate && child.getAnimation() != null) ||
(mTransitioningViews != null && mTransitioningViews.contains(child))) {
addDisappearingView(child);
@@ -4151,7 +4227,7 @@
final View v = children[i];
v.mTop += offset;
v.mBottom += offset;
- if (USE_DISPLAY_LIST_PROPERTIES && v.mDisplayList != null) {
+ if (v.mDisplayList != null) {
v.mDisplayList.offsetTopBottom(offset);
invalidateViewProperty(false, false);
}
@@ -5792,11 +5868,13 @@
throw new IllegalStateException("Instance already recycled.");
}
clear();
- if (sPoolSize < MAX_POOL_SIZE) {
- mNext = sPool;
- mIsPooled = true;
- sPool = this;
- sPoolSize++;
+ synchronized (sPoolLock) {
+ if (sPoolSize < MAX_POOL_SIZE) {
+ mNext = sPool;
+ mIsPooled = true;
+ sPool = this;
+ sPoolSize++;
+ }
}
}
@@ -5889,11 +5967,13 @@
throw new IllegalStateException("Instance already recycled.");
}
clear();
- if (sPoolSize < MAX_POOL_SIZE) {
- mNext = sPool;
- mIsPooled = true;
- sPool = this;
- sPoolSize++;
+ synchronized (sPoolLock) {
+ if (sPoolSize < MAX_POOL_SIZE) {
+ mNext = sPool;
+ mIsPooled = true;
+ sPool = this;
+ sPoolSize++;
+ }
}
}
@@ -5943,9 +6023,9 @@
if (widthDiference != 0) {
return -widthDiference;
}
- // Return nondeterministically one of them since we do
- // not want to ignore any views.
- return 1;
+ // Just break the tie somehow. The accessibliity ids are unique
+ // and stable, hence this is deterministic tie breaking.
+ return mView.getAccessibilityViewId() - another.mView.getAccessibilityViewId();
}
private void init(ViewGroup root, View view) {
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 3626aba..ec37acf 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -714,6 +714,7 @@
* value accordingly.
*/
private void startAnimation() {
+ mView.setHasTransientState(true);
ValueAnimator animator = ValueAnimator.ofFloat(1.0f);
ArrayList<NameValuesHolder> nameValueList =
(ArrayList<NameValuesHolder>) mPendingAnimations.clone();
@@ -834,7 +835,7 @@
*/
private void setValue(int propertyConstant, float value) {
final View.TransformationInfo info = mView.mTransformationInfo;
- DisplayList displayList = View.USE_DISPLAY_LIST_PROPERTIES ? mView.mDisplayList : null;
+ final DisplayList displayList = mView.mDisplayList;
switch (propertyConstant) {
case TRANSLATION_X:
info.mTranslationX = value;
@@ -960,6 +961,7 @@
@Override
public void onAnimationEnd(Animator animation) {
+ mView.setHasTransientState(false);
if (mListener != null) {
mListener.onAnimationEnd(animation);
}
@@ -995,8 +997,7 @@
// Shouldn't happen, but just to play it safe
return;
}
- boolean useDisplayListProperties = View.USE_DISPLAY_LIST_PROPERTIES &&
- mView.mDisplayList != null;
+ boolean useDisplayListProperties = mView.mDisplayList != null;
// alpha requires slightly different treatment than the other (transform) properties.
// The logic in setAlpha() is not simply setting mAlpha, plus the invalidation
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1472993..e3681df 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -59,6 +59,7 @@
import android.util.Log;
import android.util.Slog;
import android.util.TypedValue;
+import android.view.KeyCharacterMap.FallbackAction;
import android.view.View.AttachInfo;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
@@ -323,6 +324,8 @@
private final int mDensity;
+ final KeyCharacterMap.FallbackAction mFallbackAction = new KeyCharacterMap.FallbackAction();
+
/**
* Consistency verifier for debugging purposes.
*/
@@ -1199,13 +1202,13 @@
}
}
+ // Execute enqueued actions on every traversal in case a detached view enqueued an action
+ getRunQueue().executeActions(attachInfo.mHandler);
+
boolean insetsChanged = false;
boolean layoutRequested = mLayoutRequested && !mStopped;
if (layoutRequested) {
- // Execute enqueued actions on every layout in case a view that was detached
- // enqueued an action after being detached
- getRunQueue().executeActions(attachInfo.mHandler);
final Resources res = mView.getContext().getResources();
@@ -2665,6 +2668,7 @@
private final static int MSG_PROCESS_INPUT_EVENTS = 19;
private final static int MSG_DISPATCH_SCREEN_STATE = 20;
private final static int MSG_INVALIDATE_DISPLAY_LIST = 21;
+ private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
final class ViewRootHandler extends Handler {
@Override
@@ -2712,6 +2716,8 @@
return "MSG_DISPATCH_SCREEN_STATE";
case MSG_INVALIDATE_DISPLAY_LIST:
return "MSG_INVALIDATE_DISPLAY_LIST";
+ case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST:
+ return "MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST";
}
return super.getMessageName(message);
}
@@ -2921,6 +2927,9 @@
case MSG_INVALIDATE_DISPLAY_LIST: {
invalidateDisplayLists();
} break;
+ case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
+ setAccessibilityFocusedHost(null);
+ } break;
}
}
}
@@ -4377,6 +4386,31 @@
mHandler.sendMessage(msg);
}
+ public void dispatchUnhandledKey(KeyEvent event) {
+ if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+ final KeyCharacterMap kcm = event.getKeyCharacterMap();
+ final int keyCode = event.getKeyCode();
+ final int metaState = event.getMetaState();
+
+ KeyEvent fallbackEvent = null;
+ synchronized (mFallbackAction) {
+ // Check for fallback actions specified by the key character map.
+ if (kcm.getFallbackAction(keyCode, metaState, mFallbackAction)) {
+ int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
+ fallbackEvent = KeyEvent.obtain(
+ event.getDownTime(), event.getEventTime(),
+ event.getAction(), mFallbackAction.keyCode,
+ event.getRepeatCount(), mFallbackAction.metaState,
+ event.getDeviceId(), event.getScanCode(),
+ flags, event.getSource(), null);
+ }
+ }
+ if (fallbackEvent != null) {
+ dispatchKey(fallbackEvent);
+ }
+ }
+ }
+
public void dispatchAppVisibility(boolean visible) {
Message msg = mHandler.obtainMessage(MSG_DISPATCH_APP_VISIBILITY);
msg.arg1 = visible ? 1 : 0;
@@ -5066,7 +5100,7 @@
}
} else {
ensureNoConnection();
- setAccessibilityFocusedHost(null);
+ mHandler.obtainMessage(MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST).sendToTarget();
}
}
@@ -5126,12 +5160,13 @@
@Override
public void performAccessibilityAction(long accessibilityNodeId, int action,
- int interactionId, IAccessibilityInteractionConnectionCallback callback,
- int flags, int interogatingPid, long interrogatingTid) {
+ Bundle arguments, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, int flags,
+ int interogatingPid, long interrogatingTid) {
ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController()
- .performAccessibilityActionClientThread(accessibilityNodeId, action,
+ .performAccessibilityActionClientThread(accessibilityNodeId, action, arguments,
interactionId, callback, flags, interogatingPid, interrogatingTid);
} else {
// We cannot make the call and notify the caller so it does not wait.
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 52bd860..a0f10410 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -429,8 +429,10 @@
/**
* @param level See {@link android.content.ComponentCallbacks}
+ *
+ * @hide
*/
- public void trimMemory(int level) {
+ public void startTrimMemory(int level) {
if (HardwareRenderer.isAvailable()) {
// On low-end gfx devices we trim when memory is moderate;
// on high-end devices we do this when low.
@@ -447,18 +449,21 @@
}
}
// Force a full memory flush
- HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
mNeedsEglTerminate = true;
+ HardwareRenderer.startTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
return;
}
- HardwareRenderer.trimMemory(level);
+
+ HardwareRenderer.startTrimMemory(level);
}
}
/**
* @hide
*/
- public void terminateEgl() {
+ public void endTrimMemory() {
+ HardwareRenderer.endTrimMemory();
+
if (mNeedsEglTerminate) {
ManagedEGLContext.doTerminate();
mNeedsEglTerminate = false;
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 35f0d9d..24e90fd 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -19,6 +19,7 @@
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.graphics.Rect;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
@@ -84,7 +85,7 @@
private final Object mInstanceLock = new Object();
- private int mInteractionId = -1;
+ private volatile int mInteractionId = -1;
private AccessibilityNodeInfo mFindAccessibilityNodeInfoResult;
@@ -150,6 +151,18 @@
}
/**
+ * Gets the root {@link AccessibilityNodeInfo} in the currently active window.
+ *
+ * @param connectionId The id of a connection for interacting with the system.
+ * @return The root {@link AccessibilityNodeInfo} if found, null otherwise.
+ */
+ public AccessibilityNodeInfo getRootInActiveWindow(int connectionId) {
+ return findAccessibilityNodeInfoByAccessibilityId(connectionId,
+ AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
+ AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
+ }
+
+ /**
* Finds an {@link AccessibilityNodeInfo} by accessibility id.
*
* @param connectionId The id of a connection for interacting with the system.
@@ -396,17 +409,18 @@
* {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
* to start from the root.
* @param action The action to perform.
+ * @param arguments Optional action arguments.
* @return Whether the action was performed.
*/
public boolean performAccessibilityAction(int connectionId, int accessibilityWindowId,
- long accessibilityNodeId, int action) {
+ long accessibilityNodeId, int action, Bundle arguments) {
try {
IAccessibilityServiceConnection connection = getConnection(connectionId);
if (connection != null) {
final int interactionId = mInteractionIdCounter.getAndIncrement();
final boolean success = connection.performAccessibilityAction(
- accessibilityWindowId, accessibilityNodeId, action, interactionId, this,
- Thread.currentThread().getId());
+ accessibilityWindowId, accessibilityNodeId, action, arguments,
+ interactionId, this, Thread.currentThread().getId());
if (success) {
return getPerformAccessibilityActionResultAndClear(interactionId);
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 1071c65..cdb9e77 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -17,9 +17,9 @@
package android.view.accessibility;
import android.graphics.Rect;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.text.TextUtils;
import android.util.SparseLongArray;
import android.view.View;
@@ -84,7 +84,7 @@
/**
* Action that gives input focus to the node.
*/
- public static final int ACTION_FOCUS = 0x00000001;
+ public static final int ACTION_FOCUS = 0x00000001;
/**
* Action that clears input focus of the node.
@@ -102,19 +102,98 @@
public static final int ACTION_CLEAR_SELECTION = 0x00000008;
/**
+ * Action that clicks on the node info.
+ */
+ public static final int ACTION_CLICK = 0x00000010;
+
+ /**
+ * Action that clicks on the node.
+ */
+ public static final int ACTION_LONG_CLICK = 0x00000020;
+
+ /**
* Action that gives accessibility focus to the node.
*/
- public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000010;
+ public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000040;
/**
* Action that clears accessibility focus of the node.
*/
- public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000020;
+ public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000080;
/**
- * Action that clicks on the node info./AccessibilityNodeInfoCache.java
+ * Action that requests from the node to go to the next entity in its content
+ * at a given granularity. For example, move to the next word, link, etc.
+ * <p>
+ * <strong>Arguments:</strong>
+ * <ul>
+ * <li>
+ * {@link #ACTION_ARGUMENT_GRANULARITY}
+ * </li>
+ * <li>
+ * </p>
+ * <p>
+ * <strong>Example:</strong>
+ * <code><pre><p>
+ * // Assume the first granularity was presented to the user and she is
+ * // making an explicit action to traverse the node at that granularity.
+ * CharSequence granularity = info.getGranularity(0);
+ * Bundle arguments = new Bundle();
+ * arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_GRANULARITY, granularity);
+ * info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_GRANULARITY, arguments);
+ * </code></pre></p>
+ * </li>
+ * </ul>
+ * </p>
+ * @see #setGranularities(CharSequence[])
+ * @see #getGranularities()
*/
- public static final int ACTION_CLICK = 0x00000040;
+ public static final int ACTION_NEXT_AT_GRANULARITY = 0x00000100;
+
+ /**
+ * Action that requests from the node to go to the previous entity in its content
+ * at a given granularity. For example, move to the next word, link, etc.
+ * <p>
+ * <strong>Arguments:</strong>
+ * <ul>
+ * <li>
+ * {@link #ACTION_ARGUMENT_GRANULARITY}
+ * </li>
+ * <li>
+ * </p>
+ * <p>
+ * <strong>Example:</strong>
+ * <code><pre><p>
+ * // Assume the first granularity was presented to the user and she is
+ * // making an explicit action to traverse the node at that granularity.
+ * CharSequence granularity = info.getGranularity(0);
+ * Bundle arguments = new Bundle();
+ * arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_GRANULARITY, granularity);
+ * info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_GRANULARITY, arguments);
+ * </code></pre></p>
+ * </li>
+ * </ul>
+ * </p>
+ * @see #setGranularities(CharSequence[])
+ * @see #getGranularities()
+ */
+ public static final int ACTION_PREVIOUS_AT_GRANULARITY = 0x00000200;
+
+ /**
+ * Argument for which content granularity to be used when traversing the node content.
+ * <p>
+ * <strong>Actions:</strong>
+ * <ul>
+ * <li>
+ * {@link #ACTION_PREVIOUS_AT_GRANULARITY}
+ * </li>
+ * <li>
+ * {@link #ACTION_PREVIOUS_AT_GRANULARITY}
+ * </li>
+ * </ul>
+ * </p>
+ */
+ public static final String ACTION_ARGUMENT_GRANULARITY = "ACTION_ARGUMENT_GRANULARITY";
/**
* The input focus.
@@ -226,9 +305,11 @@
private CharSequence mText;
private CharSequence mContentDescription;
- private SparseLongArray mChildNodeIds = new SparseLongArray();
+ private final SparseLongArray mChildNodeIds = new SparseLongArray();
private int mActions;
+ private CharSequence[] mGranularities;
+
private int mConnectionId = UNDEFINED;
/**
@@ -278,9 +359,9 @@
(root != null) ? root.getAccessibilityViewId() : UNDEFINED;
mSourceNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
}
-
+
/**
- * Find the view that has the input focus. The search starts from
+ * Find the view that has the specified focus type. The search starts from
* the view represented by this node info.
*
* @param focus The focus to find. One of {@link #FOCUS_INPUT} or
@@ -453,6 +534,32 @@
}
/**
+ * Sets the granularities for traversing the content of this node.
+ * <p>
+ * <strong>Note:</strong> Cannot be called from an
+ * {@link android.accessibilityservice.AccessibilityService}.
+ * This class is made immutable before being delivered to an AccessibilityService.
+ * </p>
+ *
+ * @param granularities The granularity names.
+ *
+ * @throws IllegalStateException If called from an AccessibilityService.
+ */
+ public void setGranularities(CharSequence[] granularities) {
+ enforceNotSealed();
+ mGranularities = granularities;
+ }
+
+ /**
+ * Gets the granularities for traversing the content of this node.
+ *
+ * @return The count.
+ */
+ public CharSequence[] getGranularities() {
+ return mGranularities;
+ }
+
+ /**
* Performs an action on the node.
* <p>
* <strong>Note:</strong> An action can be performed only if the request is made
@@ -470,7 +577,31 @@
return false;
}
AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
- return client.performAccessibilityAction(mConnectionId, mWindowId, mSourceNodeId, action);
+ return client.performAccessibilityAction(mConnectionId, mWindowId, mSourceNodeId,
+ action, null);
+ }
+
+ /**
+ * Performs an action on the node.
+ * <p>
+ * <strong>Note:</strong> An action can be performed only if the request is made
+ * from an {@link android.accessibilityservice.AccessibilityService}.
+ * </p>
+ *
+ * @param action The action to perform.
+ * @param arguments A bundle with additional arguments.
+ * @return True if the action was performed.
+ *
+ * @throws IllegalStateException If called outside of an AccessibilityService.
+ */
+ public boolean performAction(int action, Bundle arguments) {
+ enforceSealed();
+ if (!canPerformRequestOverConnection(mSourceNodeId)) {
+ return false;
+ }
+ AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+ return client.performAccessibilityAction(mConnectionId, mWindowId, mSourceNodeId,
+ action, arguments);
}
/**
@@ -1210,6 +1341,8 @@
parcel.writeLong(mParentNodeId);
parcel.writeInt(mConnectionId);
+ parcel.writeCharSequenceArray(mGranularities);
+
SparseLongArray childIds = mChildNodeIds;
final int childIdsSize = childIds.size();
parcel.writeInt(childIdsSize);
@@ -1231,10 +1364,10 @@
parcel.writeInt(mBooleanProperties);
- TextUtils.writeToParcel(mPackageName, parcel, flags);
- TextUtils.writeToParcel(mClassName, parcel, flags);
- TextUtils.writeToParcel(mText, parcel, flags);
- TextUtils.writeToParcel(mContentDescription, parcel, flags);
+ parcel.writeCharSequence(mPackageName);
+ parcel.writeCharSequence(mClassName);
+ parcel.writeCharSequence(mText);
+ parcel.writeCharSequence(mContentDescription);
// Since instances of this class are fetched via synchronous i.e. blocking
// calls in IPCs we always recycle as soon as the instance is marshaled.
@@ -1246,6 +1379,7 @@
*
* @param other The other instance.
*/
+ @SuppressWarnings("unchecked")
private void init(AccessibilityNodeInfo other) {
mSealed = other.mSealed;
mSourceNodeId = other.mSourceNodeId;
@@ -1260,7 +1394,11 @@
mContentDescription = other.mContentDescription;
mActions= other.mActions;
mBooleanProperties = other.mBooleanProperties;
- mChildNodeIds = other.mChildNodeIds.clone();
+ mGranularities = (other.mGranularities) != null ? other.mGranularities.clone() : null;
+ final int otherChildIdCount = other.mChildNodeIds.size();
+ for (int i = 0; i < otherChildIdCount; i++) {
+ mChildNodeIds.put(i, other.mChildNodeIds.valueAt(i));
+ }
}
/**
@@ -1275,6 +1413,8 @@
mParentNodeId = parcel.readLong();
mConnectionId = parcel.readInt();
+ mGranularities = parcel.readCharSequenceArray();
+
SparseLongArray childIds = mChildNodeIds;
final int childrenSize = parcel.readInt();
for (int i = 0; i < childrenSize; i++) {
@@ -1296,10 +1436,10 @@
mBooleanProperties = parcel.readInt();
- mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
- mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
- mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
- mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ mPackageName = parcel.readCharSequence();
+ mClassName = parcel.readCharSequence();
+ mText = parcel.readCharSequence();
+ mContentDescription = parcel.readCharSequence();
}
/**
@@ -1311,6 +1451,7 @@
mParentNodeId = ROOT_NODE_ID;
mWindowId = UNDEFINED;
mConnectionId = UNDEFINED;
+ mGranularities = null;
mChildNodeIds.clear();
mBoundsInParent.set(0, 0, 0, 0);
mBoundsInScreen.set(0, 0, 0, 0);
@@ -1389,6 +1530,17 @@
builder.append("; accessibilityViewId: " + getAccessibilityViewId(mSourceNodeId));
builder.append("; virtualDescendantId: " + getVirtualDescendantId(mSourceNodeId));
builder.append("; mParentNodeId: " + mParentNodeId);
+
+ CharSequence[] granularities = mGranularities;
+ builder.append("; granularities: [");
+ for (int i = 0, count = granularities.length; i < count; i++) {
+ builder.append(granularities[i]);
+ if (i < count - 1) {
+ builder.append(", ");
+ }
+ }
+ builder.append("]");
+
SparseLongArray childIds = mChildNodeIds;
builder.append("; childAccessibilityIds: [");
for (int i = 0, count = childIds.size(); i < count; i++) {
@@ -1396,8 +1548,8 @@
if (i < count - 1) {
builder.append(", ");
}
- }
- builder.append("]");
+ }
+ builder.append("]");
}
builder.append("; boundsInParent: " + mBoundsInParent);
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index 19e35dd..ba6433f 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -17,6 +17,7 @@
package android.view.accessibility;
import android.accessibilityservice.AccessibilityService;
+import android.os.Bundle;
import android.view.View;
import java.util.List;
@@ -47,12 +48,13 @@
* getAccessibilityNodeProvider(
* if (mAccessibilityNodeProvider == null) {
* mAccessibilityNodeProvider = new AccessibilityNodeProvider() {
- * public boolean performAccessibilityAction(int action, int virtualDescendantId) {
+ * public boolean performAction(int action, int virtualDescendantId) {
* // Implementation.
* return false;
* }
*
- * public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String text, int virtualDescendantId) {
+ * public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String text,
+ * int virtualDescendantId) {
* // Implementation.
* return null;
* }
@@ -99,15 +101,16 @@
* host View, with the given <code>virtualViewId</code> or the host View itself
* if <code>virtualViewId</code> equals to {@link View#NO_ID}.
*
- * @param action The action to perform.
* @param virtualViewId A client defined virtual view id.
+ * @param action The action to perform.
+ * @param arguments Optional action arguments.
* @return True if the action was performed.
*
- * @see View#performAccessibilityAction(int)
+ * @see View#performAccessibilityAction(int, Bundle)
* @see #createAccessibilityNodeInfo(int)
* @see AccessibilityNodeInfo
*/
- public boolean performAccessibilityAction(int action, int virtualViewId) {
+ public boolean performAction(int virtualViewId, int action, Bundle arguments) {
return false;
}
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
index 8182d29..9d7a928 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
@@ -16,6 +16,7 @@
package android.view.accessibility;
+import android.os.Bundle;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
@@ -47,7 +48,7 @@
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
long interrogatingTid);
- void performAccessibilityAction(long accessibilityNodeId, int action, int interactionId,
- IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
- long interrogatingTid);
+ void performAccessibilityAction(long accessibilityNodeId, int action, in Bundle arguments,
+ int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+ int interrogatingPid, long interrogatingTid);
}
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index ab798e8..2d9f60d 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -1047,15 +1047,7 @@
Message msg = obtainMessage(OVERRIDE_URL);
msg.getData().putString("url", url);
msg.obj = res;
- synchronized (this) {
- sendMessage(msg);
- try {
- wait();
- } catch (InterruptedException e) {
- Log.e(LOGTAG, "Caught exception while waiting for overrideUrl");
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- }
+ sendMessageToUiThreadSync(msg);
return res.getResult().booleanValue();
}
@@ -1223,16 +1215,7 @@
bundle.putString("host", schemePlusHost);
bundle.putString("username", username);
bundle.putString("password", password);
- synchronized (this) {
- sendMessage(msg);
- try {
- wait();
- } catch (InterruptedException e) {
- Log.e(LOGTAG,
- "Caught exception while waiting for onSavePassword");
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- }
+ sendMessageToUiThreadSync(msg);
// Doesn't matter here
return false;
}
@@ -1281,18 +1264,8 @@
mWebView.getWebView().new WebViewTransport();
final Message msg = obtainMessage(NOTIFY);
msg.obj = transport;
- synchronized (this) {
- sendMessage(obtainMessage(CREATE_WINDOW, dialog ? 1 : 0,
- userGesture ? 1 : 0, msg));
- try {
- wait();
- } catch (InterruptedException e) {
- Log.e(LOGTAG,
- "Caught exception while waiting for createWindow");
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- }
-
+ sendMessageToUiThreadSync(obtainMessage(CREATE_WINDOW, dialog ? 1 : 0,
+ userGesture ? 1 : 0, msg));
WebViewClassic w = WebViewClassic.fromWebView(transport.getWebView());
if (w != null) {
WebViewCore core = w.getWebViewCore();
@@ -1375,15 +1348,7 @@
Message alert = obtainMessage(JS_ALERT, result);
alert.getData().putString("message", message);
alert.getData().putString("url", url);
- synchronized (this) {
- sendMessage(alert);
- try {
- wait();
- } catch (InterruptedException e) {
- Log.e(LOGTAG, "Caught exception while waiting for jsAlert");
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- }
+ sendMessageToUiThreadSync(alert);
}
public boolean onJsConfirm(String url, String message) {
@@ -1396,15 +1361,7 @@
Message confirm = obtainMessage(JS_CONFIRM, result);
confirm.getData().putString("message", message);
confirm.getData().putString("url", url);
- synchronized (this) {
- sendMessage(confirm);
- try {
- wait();
- } catch (InterruptedException e) {
- Log.e(LOGTAG, "Caught exception while waiting for jsConfirm");
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- }
+ sendMessageToUiThreadSync(confirm);
return result.mJsResult.getResult();
}
@@ -1419,15 +1376,7 @@
prompt.getData().putString("message", message);
prompt.getData().putString("default", defaultValue);
prompt.getData().putString("url", url);
- synchronized (this) {
- sendMessage(prompt);
- try {
- wait();
- } catch (InterruptedException e) {
- Log.e(LOGTAG, "Caught exception while waiting for jsPrompt");
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- }
+ sendMessageToUiThreadSync(prompt);
return result.mJsResult.getStringResult();
}
@@ -1441,15 +1390,7 @@
Message confirm = obtainMessage(JS_UNLOAD, result);
confirm.getData().putString("message", message);
confirm.getData().putString("url", url);
- synchronized (this) {
- sendMessage(confirm);
- try {
- wait();
- } catch (InterruptedException e) {
- Log.e(LOGTAG, "Caught exception while waiting for jsUnload");
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- }
+ sendMessageToUiThreadSync(confirm);
return result.mJsResult.getResult();
}
@@ -1586,15 +1527,7 @@
}
JsResultReceiver result = new JsResultReceiver();
Message timeout = obtainMessage(JS_TIMEOUT, result);
- synchronized (this) {
- sendMessage(timeout);
- try {
- wait();
- } catch (InterruptedException e) {
- Log.e(LOGTAG, "Caught exception while waiting for jsUnload");
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- }
+ sendMessageToUiThreadSync(timeout);
return result.mJsResult.getResult();
}
@@ -1655,16 +1588,7 @@
UploadFile uploadFile = new UploadFile();
UploadFileMessageData data = new UploadFileMessageData(uploadFile, acceptType, capture);
myMessage.obj = data;
- synchronized (this) {
- sendMessage(myMessage);
- try {
- wait();
- } catch (InterruptedException e) {
- Log.e(LOGTAG,
- "Caught exception while waiting for openFileChooser");
- Log.e(LOGTAG, Log.getStackTraceString(e));
- }
- }
+ sendMessageToUiThreadSync(myMessage);
return uploadFile.getResult();
}
@@ -1723,4 +1647,16 @@
sendMessage(msg);
}
+
+ private synchronized void sendMessageToUiThreadSync(Message msg) {
+ sendMessage(msg);
+ WebCoreThreadWatchdog.pause();
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ Log.e(LOGTAG, "Caught exception waiting for synchronous UI message to be processed");
+ Log.e(LOGTAG, Log.getStackTraceString(e));
+ }
+ WebCoreThreadWatchdog.resume();
+ }
}
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 2997c1a..90dfc4e 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -16,27 +16,20 @@
package android.webkit;
-import android.net.ParseException;
import android.net.WebAddress;
-import android.os.AsyncTask;
-import android.util.Log;
-
/**
* Manages the cookies used by an application's {@link WebView} instances.
* Cookies are manipulated according to RFC2109.
*/
public class CookieManager {
-
- private static CookieManager sRef;
-
- private static final String LOGTAG = "webkit";
-
- private int mPendingCookieOperations = 0;
-
- private CookieManager() {
+ /**
+ * @hide Only for use by WebViewProvider implementations
+ */
+ protected CookieManager() {
}
+ @Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("doesn't implement Cloneable");
}
@@ -46,14 +39,11 @@
* before the application instantiates a {@link WebView} instance,
* {@link CookieSyncManager#createInstance(Context)} must be called
* first.
- *
+ *
* @return The singleton CookieManager instance
*/
public static synchronized CookieManager getInstance() {
- if (sRef == null) {
- sRef = new CookieManager();
- }
- return sRef;
+ return WebViewFactory.getProvider().getCookieManager();
}
/**
@@ -63,7 +53,7 @@
* cookies
*/
public synchronized void setAcceptCookie(boolean accept) {
- nativeSetAcceptCookie(accept);
+ throw new MustOverrideException();
}
/**
@@ -72,39 +62,20 @@
* @return True if {@link WebView} instances send and accept cookies
*/
public synchronized boolean acceptCookie() {
- return nativeAcceptCookie();
+ throw new MustOverrideException();
}
- /**
+ /**
* Sets a cookie for the given URL. Any existing cookie with the same host,
* path and name will be replaced with the new cookie. The cookie being set
* must not have expired and must not be a session cookie, otherwise it
* will be ignored.
* @param url The URL for which the cookie is set
- * @param value The cookie as a string, using the format of the
- * 'Set-Cookie' HTTP response header
+ * @param value The cookie as a string, using the format of the 'Set-Cookie'
+ * HTTP response header
*/
public void setCookie(String url, String value) {
- setCookie(url, value, false);
- }
-
- /**
- * See {@link setCookie(String, String)}
- * @param url The URL for which the cookie is set
- * @param value The value of the cookie, as a string, using the format of
- * the 'Set-Cookie' HTTP response header
- * @param privateBrowsing Whether to use the private browsing cookie jar
- */
- void setCookie(String url, String value, boolean privateBrowsing) {
- WebAddress uri;
- try {
- uri = new WebAddress(url);
- } catch (ParseException ex) {
- Log.e(LOGTAG, "Bad address: " + url);
- return;
- }
-
- nativeSetCookie(uri.toString(), value, privateBrowsing);
+ throw new MustOverrideException();
}
/**
@@ -114,11 +85,11 @@
* HTTP request header
*/
public String getCookie(String url) {
- return getCookie(url, false);
+ throw new MustOverrideException();
}
/**
- * See {@link getCookie(String)}
+ * See {@link #getCookie(String)}
* @param url The URL for which the cookies are requested
* @param privateBrowsing Whether to use the private browsing cookie jar
* @return value The cookies as a string, using the format of the 'Cookie'
@@ -126,15 +97,7 @@
* @hide Used by Browser, no intention to publish.
*/
public String getCookie(String url, boolean privateBrowsing) {
- WebAddress uri;
- try {
- uri = new WebAddress(url);
- } catch (ParseException ex) {
- Log.e(LOGTAG, "Bad address: " + url);
- return null;
- }
-
- return nativeGetCookie(uri.toString(), privateBrowsing);
+ throw new MustOverrideException();
}
/**
@@ -146,32 +109,7 @@
* @hide Used by RequestHandle, no intention to publish.
*/
public synchronized String getCookie(WebAddress uri) {
- return nativeGetCookie(uri.toString(), false);
- }
-
- /**
- * Waits for pending operations to completed.
- */
- void waitForCookieOperationsToComplete() {
- // Note that this function is applicable for both the java
- // and native http stacks, and works correctly with either.
- synchronized (this) {
- while (mPendingCookieOperations > 0) {
- try {
- wait();
- } catch (InterruptedException e) { }
- }
- }
- }
-
- private synchronized void signalCookieOperationsComplete() {
- mPendingCookieOperations--;
- assert mPendingCookieOperations > -1;
- notify();
- }
-
- private synchronized void signalCookieOperationsStart() {
- mPendingCookieOperations++;
+ throw new MustOverrideException();
}
/**
@@ -179,21 +117,14 @@
* date.
*/
public void removeSessionCookie() {
- signalCookieOperationsStart();
- new AsyncTask<Void, Void, Void>() {
- protected Void doInBackground(Void... none) {
- nativeRemoveSessionCookie();
- signalCookieOperationsComplete();
- return null;
- }
- }.execute();
+ throw new MustOverrideException();
}
/**
* Removes all cookies.
*/
public void removeAllCookie() {
- nativeRemoveAllCookie();
+ throw new MustOverrideException();
}
/**
@@ -201,32 +132,32 @@
* @return True if there are stored cookies.
*/
public synchronized boolean hasCookies() {
- return hasCookies(false);
+ throw new MustOverrideException();
}
/**
- * See {@link hasCookies()}.
+ * See {@link #hasCookies()}.
* @param privateBrowsing Whether to use the private browsing cookie jar
* @hide Used by Browser, no intention to publish.
*/
public synchronized boolean hasCookies(boolean privateBrowsing) {
- return nativeHasCookies(privateBrowsing);
+ throw new MustOverrideException();
}
/**
* Removes all expired cookies.
*/
public void removeExpiredCookie() {
- nativeRemoveExpiredCookie();
+ throw new MustOverrideException();
}
/**
- * Package level api, called from CookieSyncManager
- *
* Flush all cookies managed by the Chrome HTTP stack to flash.
+ *
+ * @hide Package level api, called from CookieSyncManager
*/
- void flushCookieStore() {
- nativeFlushCookieStore();
+ protected void flushCookieStore() {
+ throw new MustOverrideException();
}
/**
@@ -236,7 +167,8 @@
* file scheme URLs
*/
public static boolean allowFileSchemeCookies() {
- return nativeAcceptFileSchemeCookies();
+ // TODO: indirect this via the WebViewFactoryProvider.Statics interface. http://b/6379925
+ return CookieManagerClassic.allowFileSchemeCookies();
}
/**
@@ -250,19 +182,7 @@
* {@link WebView} or CookieManager instance has been created.
*/
public static void setAcceptFileSchemeCookies(boolean accept) {
- nativeSetAcceptFileSchemeCookies(accept);
+ // TODO: indirect this via the WebViewFactoryProvider.Statics interface. http://b/6379925
+ CookieManagerClassic.setAcceptFileSchemeCookies(accept);
}
-
- // Native functions
- private static native boolean nativeAcceptCookie();
- private static native String nativeGetCookie(String url, boolean privateBrowsing);
- private static native boolean nativeHasCookies(boolean privateBrowsing);
- private static native void nativeRemoveAllCookie();
- private static native void nativeRemoveExpiredCookie();
- private static native void nativeRemoveSessionCookie();
- private static native void nativeSetAcceptCookie(boolean accept);
- private static native void nativeSetCookie(String url, String value, boolean privateBrowsing);
- private static native void nativeFlushCookieStore();
- private static native boolean nativeAcceptFileSchemeCookies();
- private static native void nativeSetAcceptFileSchemeCookies(boolean accept);
}
diff --git a/core/java/android/webkit/CookieManagerClassic.java b/core/java/android/webkit/CookieManagerClassic.java
new file mode 100644
index 0000000..f1aebcf
--- /dev/null
+++ b/core/java/android/webkit/CookieManagerClassic.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.net.ParseException;
+import android.net.WebAddress;
+import android.os.AsyncTask;
+import android.util.Log;
+
+class CookieManagerClassic extends CookieManager {
+
+ private static CookieManagerClassic sRef;
+
+ private static final String LOGTAG = "webkit";
+
+ private int mPendingCookieOperations = 0;
+
+ private CookieManagerClassic() {
+ }
+
+ public static synchronized CookieManagerClassic getInstance() {
+ if (sRef == null) {
+ sRef = new CookieManagerClassic();
+ }
+ return sRef;
+ }
+
+ @Override
+ public synchronized void setAcceptCookie(boolean accept) {
+ nativeSetAcceptCookie(accept);
+ }
+
+ @Override
+ public synchronized boolean acceptCookie() {
+ return nativeAcceptCookie();
+ }
+
+ @Override
+ public void setCookie(String url, String value) {
+ setCookie(url, value, false);
+ }
+
+ /**
+ * See {@link #setCookie(String, String)}
+ * @param url The URL for which the cookie is set
+ * @param value The value of the cookie, as a string, using the format of
+ * the 'Set-Cookie' HTTP response header
+ * @param privateBrowsing Whether to use the private browsing cookie jar
+ */
+ void setCookie(String url, String value, boolean privateBrowsing) {
+ WebAddress uri;
+ try {
+ uri = new WebAddress(url);
+ } catch (ParseException ex) {
+ Log.e(LOGTAG, "Bad address: " + url);
+ return;
+ }
+
+ nativeSetCookie(uri.toString(), value, privateBrowsing);
+ }
+
+ @Override
+ public String getCookie(String url) {
+ return getCookie(url, false);
+ }
+
+ @Override
+ public String getCookie(String url, boolean privateBrowsing) {
+ WebAddress uri;
+ try {
+ uri = new WebAddress(url);
+ } catch (ParseException ex) {
+ Log.e(LOGTAG, "Bad address: " + url);
+ return null;
+ }
+
+ return nativeGetCookie(uri.toString(), privateBrowsing);
+ }
+
+ @Override
+ public synchronized String getCookie(WebAddress uri) {
+ return nativeGetCookie(uri.toString(), false);
+ }
+
+ /**
+ * Waits for pending operations to completed.
+ */
+ void waitForCookieOperationsToComplete() {
+ // Note that this function is applicable for both the java
+ // and native http stacks, and works correctly with either.
+ synchronized (this) {
+ while (mPendingCookieOperations > 0) {
+ try {
+ wait();
+ } catch (InterruptedException e) { }
+ }
+ }
+ }
+
+ private synchronized void signalCookieOperationsComplete() {
+ mPendingCookieOperations--;
+ assert mPendingCookieOperations > -1;
+ notify();
+ }
+
+ private synchronized void signalCookieOperationsStart() {
+ mPendingCookieOperations++;
+ }
+
+ @Override
+ public void removeSessionCookie() {
+ signalCookieOperationsStart();
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... none) {
+ nativeRemoveSessionCookie();
+ signalCookieOperationsComplete();
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public void removeAllCookie() {
+ nativeRemoveAllCookie();
+ }
+
+ @Override
+ public synchronized boolean hasCookies() {
+ return hasCookies(false);
+ }
+
+ @Override
+ public synchronized boolean hasCookies(boolean privateBrowsing) {
+ return nativeHasCookies(privateBrowsing);
+ }
+
+ @Override
+ public void removeExpiredCookie() {
+ nativeRemoveExpiredCookie();
+ }
+
+ @Override
+ protected void flushCookieStore() {
+ nativeFlushCookieStore();
+ }
+
+ /**
+ * Gets whether the application's {@link WebView} instances send and accept
+ * cookies for file scheme URLs.
+ * @return True if {@link WebView} instances send and accept cookies for
+ * file scheme URLs
+ */
+ public static boolean allowFileSchemeCookies() {
+ return nativeAcceptFileSchemeCookies();
+ }
+
+ /**
+ * Sets whether the application's {@link WebView} instances should send and
+ * accept cookies for file scheme URLs.
+ * Use of cookies with file scheme URLs is potentially insecure. Do not use
+ * this feature unless you can be sure that no unintentional sharing of
+ * cookie data can take place.
+ * <p>
+ * Note that calls to this method will have no effect if made after a
+ * {@link WebView} or CookieManager instance has been created.
+ */
+ public static void setAcceptFileSchemeCookies(boolean accept) {
+ nativeSetAcceptFileSchemeCookies(accept);
+ }
+
+ // Native functions
+ private static native boolean nativeAcceptCookie();
+ private static native String nativeGetCookie(String url, boolean privateBrowsing);
+ private static native boolean nativeHasCookies(boolean privateBrowsing);
+ private static native void nativeRemoveAllCookie();
+ private static native void nativeRemoveExpiredCookie();
+ private static native void nativeRemoveSessionCookie();
+ private static native void nativeSetAcceptCookie(boolean accept);
+ private static native void nativeSetCookie(String url, String value, boolean privateBrowsing);
+ private static native void nativeFlushCookieStore();
+ private static native boolean nativeAcceptFileSchemeCookies();
+ private static native void nativeSetAcceptFileSchemeCookies(boolean accept);
+}
diff --git a/core/java/android/webkit/GeolocationPermissions.java b/core/java/android/webkit/GeolocationPermissions.java
index a916884..cd5c9d1 100755
--- a/core/java/android/webkit/GeolocationPermissions.java
+++ b/core/java/android/webkit/GeolocationPermissions.java
@@ -16,13 +16,7 @@
package android.webkit;
-import android.os.Handler;
-import android.os.Message;
-
-import java.util.HashMap;
-import java.util.Map;
import java.util.Set;
-import java.util.Vector;
/**
* This class is used to manage permissions for the WebView's Geolocation
@@ -44,9 +38,6 @@
* The methods of this class can be used to modify and interrogate the stored
* Geolocation permissions at any time.
*/
-// This class is the Java counterpart of the WebKit C++ GeolocationPermissions
-// class. It simply marshals calls from the UI thread to the WebKit thread.
-//
// Within WebKit, Geolocation permissions may be applied either temporarily
// (for the duration of the page) or permanently. This class deals only with
// permanent permissions.
@@ -68,144 +59,12 @@
public void invoke(String origin, boolean allow, boolean retain);
};
- // Global instance
- private static GeolocationPermissions sInstance;
-
- private Handler mHandler;
- private Handler mUIHandler;
-
- // A queue to store messages until the handler is ready.
- private Vector<Message> mQueuedMessages;
-
- // Message ids
- static final int GET_ORIGINS = 0;
- static final int GET_ALLOWED = 1;
- static final int CLEAR = 2;
- static final int ALLOW = 3;
- static final int CLEAR_ALL = 4;
-
- // Message ids on the UI thread
- static final int RETURN_ORIGINS = 0;
- static final int RETURN_ALLOWED = 1;
-
- private static final String ORIGINS = "origins";
- private static final String ORIGIN = "origin";
- private static final String CALLBACK = "callback";
- private static final String ALLOWED = "allowed";
-
/**
* Get the singleton instance of this class.
* @return The singleton {@link GeolocationPermissions} instance.
*/
public static GeolocationPermissions getInstance() {
- if (sInstance == null) {
- sInstance = new GeolocationPermissions();
- }
- return sInstance;
- }
-
- /**
- * Creates the UI message handler. Must be called on the UI thread.
- * @hide
- */
- public void createUIHandler() {
- if (mUIHandler == null) {
- mUIHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // Runs on the UI thread.
- switch (msg.what) {
- case RETURN_ORIGINS: {
- Map values = (Map) msg.obj;
- Set<String> origins = (Set<String>) values.get(ORIGINS);
- ValueCallback<Set<String> > callback = (ValueCallback<Set<String> >) values.get(CALLBACK);
- callback.onReceiveValue(origins);
- } break;
- case RETURN_ALLOWED: {
- Map values = (Map) msg.obj;
- Boolean allowed = (Boolean) values.get(ALLOWED);
- ValueCallback<Boolean> callback = (ValueCallback<Boolean>) values.get(CALLBACK);
- callback.onReceiveValue(allowed);
- } break;
- }
- }
- };
- }
- }
-
- /**
- * Creates the message handler. Must be called on the WebKit thread.
- * @hide
- */
- public synchronized void createHandler() {
- if (mHandler == null) {
- mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // Runs on the WebKit thread.
- switch (msg.what) {
- case GET_ORIGINS: {
- Set origins = nativeGetOrigins();
- ValueCallback callback = (ValueCallback) msg.obj;
- Map values = new HashMap<String, Object>();
- values.put(CALLBACK, callback);
- values.put(ORIGINS, origins);
- postUIMessage(Message.obtain(null, RETURN_ORIGINS, values));
- } break;
- case GET_ALLOWED: {
- Map values = (Map) msg.obj;
- String origin = (String) values.get(ORIGIN);
- ValueCallback callback = (ValueCallback) values.get(CALLBACK);
- boolean allowed = nativeGetAllowed(origin);
- Map retValues = new HashMap<String, Object>();
- retValues.put(CALLBACK, callback);
- retValues.put(ALLOWED, Boolean.valueOf(allowed));
- postUIMessage(Message.obtain(null, RETURN_ALLOWED, retValues));
- } break;
- case CLEAR:
- nativeClear((String) msg.obj);
- break;
- case ALLOW:
- nativeAllow((String) msg.obj);
- break;
- case CLEAR_ALL:
- nativeClearAll();
- break;
- }
- }
- };
-
- // Handle the queued messages
- if (mQueuedMessages != null) {
- while (!mQueuedMessages.isEmpty()) {
- mHandler.sendMessage(mQueuedMessages.remove(0));
- }
- mQueuedMessages = null;
- }
- }
- }
-
- /**
- * Utility function to send a message to our handler.
- */
- private synchronized void postMessage(Message msg) {
- if (mHandler == null) {
- if (mQueuedMessages == null) {
- mQueuedMessages = new Vector<Message>();
- }
- mQueuedMessages.add(msg);
- } else {
- mHandler.sendMessage(msg);
- }
- }
-
- /**
- * Utility function to send a message to the handler on the UI thread
- */
- private void postUIMessage(Message msg) {
- if (mUIHandler != null) {
- mUIHandler.sendMessage(msg);
- }
+ return WebViewFactory.getProvider().getGeolocationPermissions();
}
/**
@@ -222,14 +81,7 @@
// (Database, Geolocation etc) do so, it's safe to match up origins based
// on this string.
public void getOrigins(ValueCallback<Set<String> > callback) {
- if (callback != null) {
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- Set origins = nativeGetOrigins();
- callback.onReceiveValue(origins);
- } else {
- postMessage(Message.obtain(null, GET_ORIGINS, callback));
- }
- }
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
@@ -243,54 +95,30 @@
* Geolocation API.
*/
public void getAllowed(String origin, ValueCallback<Boolean> callback) {
- if (callback == null) {
- return;
- }
- if (origin == null) {
- callback.onReceiveValue(null);
- return;
- }
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- boolean allowed = nativeGetAllowed(origin);
- callback.onReceiveValue(Boolean.valueOf(allowed));
- } else {
- Map values = new HashMap<String, Object>();
- values.put(ORIGIN, origin);
- values.put(CALLBACK, callback);
- postMessage(Message.obtain(null, GET_ALLOWED, values));
- }
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
* Clear the Geolocation permission state for the specified origin.
* @param origin The origin for which Geolocation permissions are cleared.
*/
- // This method may be called before the WebKit
- // thread has intialized the message handler. Messages will be queued until
- // this time.
public void clear(String origin) {
- // Called on the UI thread.
- postMessage(Message.obtain(null, CLEAR, origin));
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
* Allow the specified origin to use the Geolocation API.
* @param origin The origin for which Geolocation API use is allowed.
*/
- // This method may be called before the WebKit
- // thread has intialized the message handler. Messages will be queued until
- // this time.
public void allow(String origin) {
- // Called on the UI thread.
- postMessage(Message.obtain(null, ALLOW, origin));
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
* Clear the Geolocation permission state for all origins.
*/
public void clearAll() {
- // Called on the UI thread.
- postMessage(Message.obtain(null, CLEAR_ALL));
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
@@ -299,14 +127,7 @@
* Note this constructor was erroneously public and published in SDK levels prior to 16, but
* applications using it would receive a non-functional instance of this class (there was no
* way to call createHandler() and createUIHandler(), so it would not work).
- * @hide
+ * @hide Only for use by WebViewProvider implementations
*/
public GeolocationPermissions() {}
-
- // Native functions, run on the WebKit thread.
- private static native Set nativeGetOrigins();
- private static native boolean nativeGetAllowed(String origin);
- private static native void nativeClear(String origin);
- private static native void nativeAllow(String origin);
- private static native void nativeClearAll();
}
diff --git a/core/java/android/webkit/GeolocationPermissionsClassic.java b/core/java/android/webkit/GeolocationPermissionsClassic.java
new file mode 100755
index 0000000..8a9df39
--- /dev/null
+++ b/core/java/android/webkit/GeolocationPermissionsClassic.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.os.Handler;
+import android.os.Message;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+// This class is the Java counterpart of the WebKit C++ GeolocationPermissions
+// class. It simply marshals calls from the UI thread to the WebKit thread.
+final class GeolocationPermissionsClassic extends GeolocationPermissions {
+ private Handler mHandler;
+ private Handler mUIHandler;
+
+ // A queue to store messages until the handler is ready.
+ private Vector<Message> mQueuedMessages;
+
+ // Message ids
+ static final int GET_ORIGINS = 0;
+ static final int GET_ALLOWED = 1;
+ static final int CLEAR = 2;
+ static final int ALLOW = 3;
+ static final int CLEAR_ALL = 4;
+
+ // Message ids on the UI thread
+ static final int RETURN_ORIGINS = 0;
+ static final int RETURN_ALLOWED = 1;
+
+ private static final String ORIGINS = "origins";
+ private static final String ORIGIN = "origin";
+ private static final String CALLBACK = "callback";
+ private static final String ALLOWED = "allowed";
+
+ // Global instance
+ private static GeolocationPermissionsClassic sInstance;
+
+ public static GeolocationPermissionsClassic getInstance() {
+ if (sInstance == null) {
+ sInstance = new GeolocationPermissionsClassic();
+ }
+ return sInstance;
+ }
+
+ /**
+ * Creates the UI message handler. Must be called on the UI thread.
+ * @hide
+ */
+ public void createUIHandler() {
+ if (mUIHandler == null) {
+ mUIHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ // Runs on the UI thread.
+ switch (msg.what) {
+ case RETURN_ORIGINS: {
+ Map values = (Map) msg.obj;
+ Set<String> origins = (Set<String>) values.get(ORIGINS);
+ ValueCallback<Set<String> > callback = (ValueCallback<Set<String> >) values.get(CALLBACK);
+ callback.onReceiveValue(origins);
+ } break;
+ case RETURN_ALLOWED: {
+ Map values = (Map) msg.obj;
+ Boolean allowed = (Boolean) values.get(ALLOWED);
+ ValueCallback<Boolean> callback = (ValueCallback<Boolean>) values.get(CALLBACK);
+ callback.onReceiveValue(allowed);
+ } break;
+ }
+ }
+ };
+ }
+ }
+
+ /**
+ * Creates the message handler. Must be called on the WebKit thread.
+ * @hide
+ */
+ public synchronized void createHandler() {
+ if (mHandler == null) {
+ mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ // Runs on the WebKit thread.
+ switch (msg.what) {
+ case GET_ORIGINS: {
+ Set origins = nativeGetOrigins();
+ ValueCallback callback = (ValueCallback) msg.obj;
+ Map values = new HashMap<String, Object>();
+ values.put(CALLBACK, callback);
+ values.put(ORIGINS, origins);
+ postUIMessage(Message.obtain(null, RETURN_ORIGINS, values));
+ } break;
+ case GET_ALLOWED: {
+ Map values = (Map) msg.obj;
+ String origin = (String) values.get(ORIGIN);
+ ValueCallback callback = (ValueCallback) values.get(CALLBACK);
+ boolean allowed = nativeGetAllowed(origin);
+ Map retValues = new HashMap<String, Object>();
+ retValues.put(CALLBACK, callback);
+ retValues.put(ALLOWED, Boolean.valueOf(allowed));
+ postUIMessage(Message.obtain(null, RETURN_ALLOWED, retValues));
+ } break;
+ case CLEAR:
+ nativeClear((String) msg.obj);
+ break;
+ case ALLOW:
+ nativeAllow((String) msg.obj);
+ break;
+ case CLEAR_ALL:
+ nativeClearAll();
+ break;
+ }
+ }
+ };
+
+ // Handle the queued messages
+ if (mQueuedMessages != null) {
+ while (!mQueuedMessages.isEmpty()) {
+ mHandler.sendMessage(mQueuedMessages.remove(0));
+ }
+ mQueuedMessages = null;
+ }
+ }
+ }
+
+ /**
+ * Utility function to send a message to our handler.
+ */
+ private synchronized void postMessage(Message msg) {
+ if (mHandler == null) {
+ if (mQueuedMessages == null) {
+ mQueuedMessages = new Vector<Message>();
+ }
+ mQueuedMessages.add(msg);
+ } else {
+ mHandler.sendMessage(msg);
+ }
+ }
+
+ /**
+ * Utility function to send a message to the handler on the UI thread
+ */
+ private void postUIMessage(Message msg) {
+ if (mUIHandler != null) {
+ mUIHandler.sendMessage(msg);
+ }
+ }
+
+ // Note that we represent the origins as strings. These are created using
+ // WebCore::SecurityOrigin::toString(). As long as all 'HTML 5 modules'
+ // (Database, Geolocation etc) do so, it's safe to match up origins based
+ // on this string.
+ @Override
+ public void getOrigins(ValueCallback<Set<String> > callback) {
+ if (callback != null) {
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ Set origins = nativeGetOrigins();
+ callback.onReceiveValue(origins);
+ } else {
+ postMessage(Message.obtain(null, GET_ORIGINS, callback));
+ }
+ }
+ }
+
+ @Override
+ public void getAllowed(String origin, ValueCallback<Boolean> callback) {
+ if (callback == null) {
+ return;
+ }
+ if (origin == null) {
+ callback.onReceiveValue(null);
+ return;
+ }
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ boolean allowed = nativeGetAllowed(origin);
+ callback.onReceiveValue(Boolean.valueOf(allowed));
+ } else {
+ Map values = new HashMap<String, Object>();
+ values.put(ORIGIN, origin);
+ values.put(CALLBACK, callback);
+ postMessage(Message.obtain(null, GET_ALLOWED, values));
+ }
+ }
+
+ // This method may be called before the WebKit
+ // thread has intialized the message handler. Messages will be queued until
+ // this time.
+ @Override
+ public void clear(String origin) {
+ // Called on the UI thread.
+ postMessage(Message.obtain(null, CLEAR, origin));
+ }
+
+ // This method may be called before the WebKit
+ // thread has intialized the message handler. Messages will be queued until
+ // this time.
+ @Override
+ public void allow(String origin) {
+ // Called on the UI thread.
+ postMessage(Message.obtain(null, ALLOW, origin));
+ }
+
+ @Override
+ public void clearAll() {
+ // Called on the UI thread.
+ postMessage(Message.obtain(null, CLEAR_ALL));
+ }
+
+ GeolocationPermissionsClassic() {}
+
+ // Native functions, run on the WebKit thread.
+ private static native Set nativeGetOrigins();
+ private static native boolean nativeGetAllowed(String origin);
+ private static native void nativeClear(String origin);
+ private static native void nativeAllow(String origin);
+ private static native void nativeClearAll();
+}
diff --git a/core/java/android/webkit/MustOverrideException.java b/core/java/android/webkit/MustOverrideException.java
new file mode 100644
index 0000000..0643bf0
--- /dev/null
+++ b/core/java/android/webkit/MustOverrideException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+// TODO: Remove MustOverrideException and make all methods throwing it abstract instead;
+// needs API file update.
+class MustOverrideException extends RuntimeException {
+ MustOverrideException() {
+ super("abstract function called: must be overriden!");
+ }
+}
\ No newline at end of file
diff --git a/core/java/android/webkit/ViewStateSerializer.java b/core/java/android/webkit/ViewStateSerializer.java
index e672b62..35168cf 100644
--- a/core/java/android/webkit/ViewStateSerializer.java
+++ b/core/java/android/webkit/ViewStateSerializer.java
@@ -34,21 +34,21 @@
static final int VERSION = 1;
- static boolean serializeViewState(OutputStream stream, WebViewClassic web)
+ static boolean serializeViewState(OutputStream stream, DrawData draw)
throws IOException {
- int baseLayer = web.getBaseLayer();
+ int baseLayer = draw.mBaseLayer;
if (baseLayer == 0) {
return false;
}
DataOutputStream dos = new DataOutputStream(stream);
dos.writeInt(VERSION);
- dos.writeInt(web.getContentWidth());
- dos.writeInt(web.getContentHeight());
+ dos.writeInt(draw.mContentSize.x);
+ dos.writeInt(draw.mContentSize.y);
return nativeSerializeViewState(baseLayer, dos,
new byte[WORKING_STREAM_STORAGE]);
}
- static DrawData deserializeViewState(InputStream stream, WebViewClassic web)
+ static DrawData deserializeViewState(InputStream stream)
throws IOException {
DataInputStream dis = new DataInputStream(stream);
int version = dis.readInt();
@@ -62,13 +62,10 @@
final WebViewCore.DrawData draw = new WebViewCore.DrawData();
draw.mViewState = new WebViewCore.ViewState();
- int viewWidth = web.getViewWidth();
- int viewHeight = web.getViewHeightWithTitle() - web.getTitleHeight();
- draw.mViewSize = new Point(viewWidth, viewHeight);
draw.mContentSize = new Point(contentWidth, contentHeight);
- draw.mViewState.mDefaultScale = web.getDefaultZoomScale();
draw.mBaseLayer = baseLayer;
draw.mInvalRegion = new Region(0, 0, contentWidth, contentHeight);
+ stream.close();
return draw;
}
diff --git a/core/java/android/webkit/WebCoreThreadWatchdog.java b/core/java/android/webkit/WebCoreThreadWatchdog.java
index 0541d5d..655db31 100644
--- a/core/java/android/webkit/WebCoreThreadWatchdog.java
+++ b/core/java/android/webkit/WebCoreThreadWatchdog.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -146,6 +147,7 @@
break;
case TIMED_OUT:
+ if ((mContext == null) || !(mContext instanceof Activity)) return;
new AlertDialog.Builder(mContext)
.setMessage(com.android.internal.R.string.webpage_unresponsive)
.setPositiveButton(com.android.internal.R.string.force_close,
diff --git a/core/java/android/webkit/WebIconDatabase.java b/core/java/android/webkit/WebIconDatabase.java
index 9299b71..99f20ff 100644
--- a/core/java/android/webkit/WebIconDatabase.java
+++ b/core/java/android/webkit/WebIconDatabase.java
@@ -17,16 +17,7 @@
package android.webkit;
import android.content.ContentResolver;
-import android.database.Cursor;
import android.graphics.Bitmap;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Browser;
-import android.util.Log;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Vector;
/**
* Functions for manipulating the icon database used by WebView.
@@ -36,149 +27,6 @@
* single object.
*/
public class WebIconDatabase {
- private static final String LOGTAG = "WebIconDatabase";
- // Global instance of a WebIconDatabase
- private static WebIconDatabase sIconDatabase;
- // EventHandler for handling messages before and after the WebCore thread is
- // ready.
- private final EventHandler mEventHandler = new EventHandler();
-
- // Class to handle messages before WebCore is ready
- private static class EventHandler extends Handler {
- // Message ids
- static final int OPEN = 0;
- static final int CLOSE = 1;
- static final int REMOVE_ALL = 2;
- static final int REQUEST_ICON = 3;
- static final int RETAIN_ICON = 4;
- static final int RELEASE_ICON = 5;
- static final int BULK_REQUEST_ICON = 6;
- // Message for dispatching icon request results
- private static final int ICON_RESULT = 10;
- // Actual handler that runs in WebCore thread
- private Handler mHandler;
- // Vector of messages before the WebCore thread is ready
- private Vector<Message> mMessages = new Vector<Message>();
- // Class to handle a result dispatch
- private class IconResult {
- private final String mUrl;
- private final Bitmap mIcon;
- private final IconListener mListener;
- IconResult(String url, Bitmap icon, IconListener l) {
- mUrl = url;
- mIcon = icon;
- mListener = l;
- }
- void dispatch() {
- mListener.onReceivedIcon(mUrl, mIcon);
- }
- }
-
- @Override
- public void handleMessage(Message msg) {
- // Note: This is the message handler for the UI thread.
- switch (msg.what) {
- case ICON_RESULT:
- ((IconResult) msg.obj).dispatch();
- break;
- }
- }
-
- // Called by WebCore thread to create the actual handler
- private synchronized void createHandler() {
- if (mHandler == null) {
- mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // Note: This is the message handler for the WebCore
- // thread.
- switch (msg.what) {
- case OPEN:
- nativeOpen((String) msg.obj);
- break;
-
- case CLOSE:
- nativeClose();
- break;
-
- case REMOVE_ALL:
- nativeRemoveAllIcons();
- break;
-
- case REQUEST_ICON:
- IconListener l = (IconListener) msg.obj;
- String url = msg.getData().getString("url");
- requestIconAndSendResult(url, l);
- break;
-
- case BULK_REQUEST_ICON:
- bulkRequestIcons(msg);
- break;
-
- case RETAIN_ICON:
- nativeRetainIconForPageUrl((String) msg.obj);
- break;
-
- case RELEASE_ICON:
- nativeReleaseIconForPageUrl((String) msg.obj);
- break;
- }
- }
- };
- // Transfer all pending messages
- for (int size = mMessages.size(); size > 0; size--) {
- mHandler.sendMessage(mMessages.remove(0));
- }
- mMessages = null;
- }
- }
-
- private synchronized boolean hasHandler() {
- return mHandler != null;
- }
-
- private synchronized void postMessage(Message msg) {
- if (mMessages != null) {
- mMessages.add(msg);
- } else {
- mHandler.sendMessage(msg);
- }
- }
-
- private void bulkRequestIcons(Message msg) {
- HashMap map = (HashMap) msg.obj;
- IconListener listener = (IconListener) map.get("listener");
- ContentResolver cr = (ContentResolver) map.get("contentResolver");
- String where = (String) map.get("where");
-
- Cursor c = null;
- try {
- c = cr.query(
- Browser.BOOKMARKS_URI,
- new String[] { Browser.BookmarkColumns.URL },
- where, null, null);
- if (c.moveToFirst()) {
- do {
- String url = c.getString(0);
- requestIconAndSendResult(url, listener);
- } while (c.moveToNext());
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "BulkRequestIcons", e);
- } finally {
- if (c != null) c.close();
- }
- }
-
- private void requestIconAndSendResult(String url, IconListener listener) {
- Bitmap icon = nativeIconForPageUrl(url);
- if (icon != null) {
- sendMessage(obtainMessage(ICON_RESULT,
- new IconResult(url, icon, listener)));
- }
- }
- }
-
/**
* Interface for receiving icons from the database.
*/
@@ -197,31 +45,21 @@
* @param path The directory path where the icon database will be stored.
*/
public void open(String path) {
- if (path != null) {
- // Make the directories and parents if they don't exist
- File db = new File(path);
- if (!db.exists()) {
- db.mkdirs();
- }
- mEventHandler.postMessage(
- Message.obtain(null, EventHandler.OPEN, db.getAbsolutePath()));
- }
+ throw new MustOverrideException();
}
/**
* Close the shared instance of the icon database.
*/
public void close() {
- mEventHandler.postMessage(
- Message.obtain(null, EventHandler.CLOSE));
+ throw new MustOverrideException();
}
/**
* Removes all the icons in the database.
*/
public void removeAllIcons() {
- mEventHandler.postMessage(
- Message.obtain(null, EventHandler.REMOVE_ALL));
+ throw new MustOverrideException();
}
/**
@@ -231,36 +69,14 @@
* @param listener An implementation on IconListener to receive the result.
*/
public void requestIconForPageUrl(String url, IconListener listener) {
- if (listener == null || url == null) {
- return;
- }
- Message msg = Message.obtain(null, EventHandler.REQUEST_ICON, listener);
- msg.getData().putString("url", url);
- mEventHandler.postMessage(msg);
+ throw new MustOverrideException();
}
/** {@hide}
*/
public void bulkRequestIconForPageUrl(ContentResolver cr, String where,
IconListener listener) {
- if (listener == null) {
- return;
- }
-
- // Special case situation: we don't want to add this message to the
- // queue if there is no handler because we may never have a real
- // handler to service the messages and the cursor will never get
- // closed.
- if (mEventHandler.hasHandler()) {
- // Don't use Bundle as it is parcelable.
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put("contentResolver", cr);
- map.put("where", where);
- map.put("listener", listener);
- Message msg =
- Message.obtain(null, EventHandler.BULK_REQUEST_ICON, map);
- mEventHandler.postMessage(msg);
- }
+ throw new MustOverrideException();
}
/**
@@ -268,10 +84,7 @@
* @param url The page's url.
*/
public void retainIconForPageUrl(String url) {
- if (url != null) {
- mEventHandler.postMessage(
- Message.obtain(null, EventHandler.RETAIN_ICON, url));
- }
+ throw new MustOverrideException();
}
/**
@@ -279,10 +92,7 @@
* @param url The page's url.
*/
public void releaseIconForPageUrl(String url) {
- if (url != null) {
- mEventHandler.postMessage(
- Message.obtain(null, EventHandler.RELEASE_ICON, url));
- }
+ throw new MustOverrideException();
}
/**
@@ -293,30 +103,11 @@
*/
public static WebIconDatabase getInstance() {
// XXX: Must be created in the UI thread.
- if (sIconDatabase == null) {
- sIconDatabase = new WebIconDatabase();
- }
- return sIconDatabase;
+ return WebViewFactory.getProvider().getWebIconDatabase();
}
/**
- * Create the internal handler and transfer all pending messages.
- * XXX: Called by WebCore thread only!
+ * @hide Only for use by WebViewProvider implementations
*/
- /*package*/ void createHandler() {
- mEventHandler.createHandler();
- }
-
- /**
- * Private constructor to avoid anyone else creating an instance.
- */
- private WebIconDatabase() {}
-
- // Native functions
- private static native void nativeOpen(String path);
- private static native void nativeClose();
- private static native void nativeRemoveAllIcons();
- private static native Bitmap nativeIconForPageUrl(String url);
- private static native void nativeRetainIconForPageUrl(String url);
- private static native void nativeReleaseIconForPageUrl(String url);
+ protected WebIconDatabase() {}
}
diff --git a/core/java/android/webkit/WebIconDatabaseClassic.java b/core/java/android/webkit/WebIconDatabaseClassic.java
new file mode 100644
index 0000000..d6c4c33
--- /dev/null
+++ b/core/java/android/webkit/WebIconDatabaseClassic.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Browser;
+import android.util.Log;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Vector;
+
+class WebIconDatabaseClassic extends WebIconDatabase {
+ private static final String LOGTAG = "WebIconDatabase";
+ // Global instance of a WebIconDatabase
+ private static WebIconDatabaseClassic sIconDatabase;
+ // EventHandler for handling messages before and after the WebCore thread is
+ // ready.
+ private final EventHandler mEventHandler = new EventHandler();
+
+ // Class to handle messages before WebCore is ready
+ private static class EventHandler extends Handler {
+ // Message ids
+ static final int OPEN = 0;
+ static final int CLOSE = 1;
+ static final int REMOVE_ALL = 2;
+ static final int REQUEST_ICON = 3;
+ static final int RETAIN_ICON = 4;
+ static final int RELEASE_ICON = 5;
+ static final int BULK_REQUEST_ICON = 6;
+ // Message for dispatching icon request results
+ private static final int ICON_RESULT = 10;
+ // Actual handler that runs in WebCore thread
+ private Handler mHandler;
+ // Vector of messages before the WebCore thread is ready
+ private Vector<Message> mMessages = new Vector<Message>();
+ // Class to handle a result dispatch
+ private class IconResult {
+ private final String mUrl;
+ private final Bitmap mIcon;
+ private final IconListener mListener;
+ IconResult(String url, Bitmap icon, IconListener l) {
+ mUrl = url;
+ mIcon = icon;
+ mListener = l;
+ }
+ void dispatch() {
+ mListener.onReceivedIcon(mUrl, mIcon);
+ }
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ // Note: This is the message handler for the UI thread.
+ switch (msg.what) {
+ case ICON_RESULT:
+ ((IconResult) msg.obj).dispatch();
+ break;
+ }
+ }
+
+ // Called by WebCore thread to create the actual handler
+ private synchronized void createHandler() {
+ if (mHandler == null) {
+ mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ // Note: This is the message handler for the WebCore
+ // thread.
+ switch (msg.what) {
+ case OPEN:
+ nativeOpen((String) msg.obj);
+ break;
+
+ case CLOSE:
+ nativeClose();
+ break;
+
+ case REMOVE_ALL:
+ nativeRemoveAllIcons();
+ break;
+
+ case REQUEST_ICON:
+ IconListener l = (IconListener) msg.obj;
+ String url = msg.getData().getString("url");
+ requestIconAndSendResult(url, l);
+ break;
+
+ case BULK_REQUEST_ICON:
+ bulkRequestIcons(msg);
+ break;
+
+ case RETAIN_ICON:
+ nativeRetainIconForPageUrl((String) msg.obj);
+ break;
+
+ case RELEASE_ICON:
+ nativeReleaseIconForPageUrl((String) msg.obj);
+ break;
+ }
+ }
+ };
+ // Transfer all pending messages
+ for (int size = mMessages.size(); size > 0; size--) {
+ mHandler.sendMessage(mMessages.remove(0));
+ }
+ mMessages = null;
+ }
+ }
+
+ private synchronized boolean hasHandler() {
+ return mHandler != null;
+ }
+
+ private synchronized void postMessage(Message msg) {
+ if (mMessages != null) {
+ mMessages.add(msg);
+ } else {
+ mHandler.sendMessage(msg);
+ }
+ }
+
+ private void bulkRequestIcons(Message msg) {
+ HashMap map = (HashMap) msg.obj;
+ IconListener listener = (IconListener) map.get("listener");
+ ContentResolver cr = (ContentResolver) map.get("contentResolver");
+ String where = (String) map.get("where");
+
+ Cursor c = null;
+ try {
+ c = cr.query(
+ Browser.BOOKMARKS_URI,
+ new String[] { Browser.BookmarkColumns.URL },
+ where, null, null);
+ if (c.moveToFirst()) {
+ do {
+ String url = c.getString(0);
+ requestIconAndSendResult(url, listener);
+ } while (c.moveToNext());
+ }
+ } catch (IllegalStateException e) {
+ Log.e(LOGTAG, "BulkRequestIcons", e);
+ } finally {
+ if (c != null) c.close();
+ }
+ }
+
+ private void requestIconAndSendResult(String url, IconListener listener) {
+ Bitmap icon = nativeIconForPageUrl(url);
+ if (icon != null) {
+ sendMessage(obtainMessage(ICON_RESULT,
+ new IconResult(url, icon, listener)));
+ }
+ }
+ }
+
+ @Override
+ public void open(String path) {
+ if (path != null) {
+ // Make the directories and parents if they don't exist
+ File db = new File(path);
+ if (!db.exists()) {
+ db.mkdirs();
+ }
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.OPEN, db.getAbsolutePath()));
+ }
+ }
+
+ @Override
+ public void close() {
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.CLOSE));
+ }
+
+ @Override
+ public void removeAllIcons() {
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.REMOVE_ALL));
+ }
+
+ /**
+ * Request the Bitmap representing the icon for the given page
+ * url. If the icon exists, the listener will be called with the result.
+ * @param url The page's url.
+ * @param listener An implementation on IconListener to receive the result.
+ */
+ public void requestIconForPageUrl(String url, IconListener listener) {
+ if (listener == null || url == null) {
+ return;
+ }
+ Message msg = Message.obtain(null, EventHandler.REQUEST_ICON, listener);
+ msg.getData().putString("url", url);
+ mEventHandler.postMessage(msg);
+ }
+
+ /** {@hide}
+ */
+ public void bulkRequestIconForPageUrl(ContentResolver cr, String where,
+ IconListener listener) {
+ if (listener == null) {
+ return;
+ }
+
+ // Special case situation: we don't want to add this message to the
+ // queue if there is no handler because we may never have a real
+ // handler to service the messages and the cursor will never get
+ // closed.
+ if (mEventHandler.hasHandler()) {
+ // Don't use Bundle as it is parcelable.
+ HashMap<String, Object> map = new HashMap<String, Object>();
+ map.put("contentResolver", cr);
+ map.put("where", where);
+ map.put("listener", listener);
+ Message msg =
+ Message.obtain(null, EventHandler.BULK_REQUEST_ICON, map);
+ mEventHandler.postMessage(msg);
+ }
+ }
+
+ @Override
+ public void retainIconForPageUrl(String url) {
+ if (url != null) {
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.RETAIN_ICON, url));
+ }
+ }
+
+ @Override
+ public void releaseIconForPageUrl(String url) {
+ if (url != null) {
+ mEventHandler.postMessage(
+ Message.obtain(null, EventHandler.RELEASE_ICON, url));
+ }
+ }
+
+ /**
+ * Get the global instance of WebIconDatabase.
+ * @return A single instance of WebIconDatabase. It will be the same
+ * instance for the current process each time this method is
+ * called.
+ */
+ public static WebIconDatabaseClassic getInstance() {
+ // XXX: Must be created in the UI thread.
+ if (sIconDatabase == null) {
+ sIconDatabase = new WebIconDatabaseClassic();
+ }
+ return sIconDatabase;
+ }
+
+ /**
+ * Create the internal handler and transfer all pending messages.
+ * XXX: Called by WebCore thread only!
+ */
+ /*package*/ void createHandler() {
+ mEventHandler.createHandler();
+ }
+
+ /**
+ * Private constructor to avoid anyone else creating an instance.
+ */
+ private WebIconDatabaseClassic() {}
+
+ // Native functions
+ private static native void nativeOpen(String path);
+ private static native void nativeClose();
+ private static native void nativeRemoveAllIcons();
+ private static native Bitmap nativeIconForPageUrl(String url);
+ private static native void nativeRetainIconForPageUrl(String url);
+ private static native void nativeReleaseIconForPageUrl(String url);
+}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index ba48da1..1bbf00f 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -17,6 +17,7 @@
package android.webkit;
import android.os.Message;
+import android.os.Build;
/**
* Manages settings state for a WebView. When a WebView is first created, it
@@ -26,18 +27,10 @@
* been destroyed, any method call on WebSettings will throw an
* IllegalStateException.
*/
-// This is (effectively) an abstract base class; concrete WebViewProviders must
+// This is an abstract base class: concrete WebViewProviders must
// create a class derived from this, and return an instance of it in the
// WebViewProvider.getWebSettingsProvider() method implementation.
-public class WebSettings {
- // TODO: Remove MustOverrideException and make all methods throwing it abstract instead;
- // needs API file update.
- private static class MustOverrideException extends RuntimeException {
- MustOverrideException() {
- super("abstract function called: must be overriden!");
- }
- }
-
+public abstract class WebSettings {
/**
* Enum for controlling the layout of html.
* NORMAL means no rendering changes.
@@ -771,6 +764,29 @@
}
/**
+ * Configure scripting (such as XmlHttpRequest) access from file scheme URLs
+ * to any origin. Note, calling this method with a true argument value also
+ * implies calling setAllowFileAccessFromFileURLs with a true. The default
+ * value is false for API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN}
+ * and higher and true otherwise.
+ *
+ . * @param flag True if the WebView should allow scripting access from file
+ * scheme URLs to any origin
+ */
+ public abstract void setAllowUniversalAccessFromFileURLs(boolean flag);
+
+ /**
+ * Configure scripting (such as XmlHttpRequest) access from file scheme URLs
+ * to file origin. The default value is false for API level
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} and higher and true
+ * otherwise.
+ *
+ * @param flag True if the WebView should allow scripting access from file
+ * scheme URLs to file origin
+ */
+ public abstract void setAllowFileAccessFromFileURLs(boolean flag);
+
+ /**
* Tell the WebView to enable plugins.
* @param flag True if the WebView should load plugins.
* @deprecated This method has been deprecated in favor of
@@ -912,6 +928,26 @@
}
/**
+ * Return true if scripting access {see @setAllowUniversalAccessFromFileURLs} from
+ * file URLs to any origin is enabled. The default value is false for API level
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} and higher and true otherwise.
+ *
+ * @return True if the WebView allows scripting access from file scheme requests
+ * to any origin
+ */
+ public abstract boolean getAllowUniversalAccessFromFileURLs();
+
+ /**
+ * Return true if scripting access {see @setAllowFileAccessFromFileURLs} from file
+ * URLs to file origin is enabled. The default value is false for API level
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} and higher, and true otherwise.
+ *
+ * @return True if the WebView allows scripting access from file scheme requests
+ * to file origin
+ */
+ public abstract boolean getAllowFileAccessFromFileURLs();
+
+ /**
* Return true if plugins are enabled.
* @return True if plugins are enabled.
* @deprecated This method has been replaced by {@link #getPluginState}
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index aa3d8d3..354bb5a 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -72,6 +72,8 @@
private boolean mBlockNetworkImage = false;
private boolean mBlockNetworkLoads;
private boolean mJavaScriptEnabled = false;
+ private boolean mAllowUniversalAccessFromFileURLs = false;
+ private boolean mAllowFileAccessFromFileURLs = false;
private boolean mHardwareAccelSkia = false;
private boolean mShowVisualIndicator = false;
private PluginState mPluginState = PluginState.OFF;
@@ -286,6 +288,13 @@
mBlockNetworkLoads = mContext.checkPermission(
"android.permission.INTERNET", android.os.Process.myPid(),
android.os.Process.myUid()) != PackageManager.PERMISSION_GRANTED;
+
+ // SDK specific settings. See issue 6212665
+ if (mContext.getApplicationInfo().targetSdkVersion <
+ Build.VERSION_CODES.JELLY_BEAN) {
+ mAllowUniversalAccessFromFileURLs = true;
+ mAllowFileAccessFromFileURLs = true;
+ }
}
private static final String ACCEPT_LANG_FOR_US_LOCALE = "en-US";
@@ -1101,6 +1110,28 @@
}
/**
+ * @see android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs
+ */
+ @Override
+ public synchronized void setAllowUniversalAccessFromFileURLs(boolean flag) {
+ if (mAllowUniversalAccessFromFileURLs != flag) {
+ mAllowUniversalAccessFromFileURLs = flag;
+ postSync();
+ }
+ }
+
+ /**
+ * @see android.webkit.WebSettings#setAllowFileAccessFromFileURLs
+ */
+ @Override
+ public synchronized void setAllowFileAccessFromFileURLs(boolean flag) {
+ if (mAllowFileAccessFromFileURLs != flag) {
+ mAllowFileAccessFromFileURLs = flag;
+ postSync();
+ }
+ }
+
+ /**
* Tell the WebView to use Skia's hardware accelerated rendering path
* @param flag True if the WebView should use Skia's hw-accel path
*/
@@ -1324,6 +1355,22 @@
}
/**
+ * @see android.webkit.WebSettings#getAllowUniversalFileAccessFromFileURLs
+ */
+ @Override
+ public synchronized boolean getAllowUniversalAccessFromFileURLs() {
+ return mAllowUniversalAccessFromFileURLs;
+ }
+
+ /**
+ * @see android.webkit.WebSettings#getAllowFileAccessFromFileURLs
+ */
+ @Override
+ public synchronized boolean getAllowFileAccessFromFileURLs() {
+ return mAllowFileAccessFromFileURLs;
+ }
+
+ /**
* @see android.webkit.WebSettings#getPluginsEnabled()
*/
@Override
diff --git a/core/java/android/webkit/WebStorage.java b/core/java/android/webkit/WebStorage.java
index 041791b..c46d161 100644
--- a/core/java/android/webkit/WebStorage.java
+++ b/core/java/android/webkit/WebStorage.java
@@ -16,13 +16,7 @@
package android.webkit;
-import android.os.Handler;
-import android.os.Message;
-
-import java.util.Collection;
-import java.util.HashMap;
import java.util.Map;
-import java.util.Set;
/**
* This class is used to manage the JavaScript storage APIs provided by the
@@ -56,34 +50,6 @@
public void updateQuota(long newQuota);
};
- // Global instance of a WebStorage
- private static WebStorage sWebStorage;
-
- // Message ids
- static final int UPDATE = 0;
- static final int SET_QUOTA_ORIGIN = 1;
- static final int DELETE_ORIGIN = 2;
- static final int DELETE_ALL = 3;
- static final int GET_ORIGINS = 4;
- static final int GET_USAGE_ORIGIN = 5;
- static final int GET_QUOTA_ORIGIN = 6;
-
- // Message ids on the UI thread
- static final int RETURN_ORIGINS = 0;
- static final int RETURN_USAGE_ORIGIN = 1;
- static final int RETURN_QUOTA_ORIGIN = 2;
-
- private static final String ORIGINS = "origins";
- private static final String ORIGIN = "origin";
- private static final String CALLBACK = "callback";
- private static final String USAGE = "usage";
- private static final String QUOTA = "quota";
-
- private Map <String, Origin> mOrigins;
-
- private Handler mHandler = null;
- private Handler mUIHandler = null;
-
/**
* This class encapsulates information about the amount of storage
* currently used by an origin for the JavaScript storage APIs.
@@ -94,18 +60,21 @@
private long mQuota = 0;
private long mUsage = 0;
- private Origin(String origin, long quota, long usage) {
+ /** @hide */
+ protected Origin(String origin, long quota, long usage) {
mOrigin = origin;
mQuota = quota;
mUsage = usage;
}
- private Origin(String origin, long quota) {
+ /** @hide */
+ protected Origin(String origin, long quota) {
mOrigin = origin;
mQuota = quota;
}
- private Origin(String origin) {
+ /** @hide */
+ protected Origin(String origin) {
mOrigin = origin;
}
@@ -142,114 +111,6 @@
}
}
- /**
- * Message handler, UI side
- * @hide
- */
- public void createUIHandler() {
- if (mUIHandler == null) {
- mUIHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case RETURN_ORIGINS: {
- Map values = (Map) msg.obj;
- Map origins = (Map) values.get(ORIGINS);
- ValueCallback<Map> callback = (ValueCallback<Map>) values.get(CALLBACK);
- callback.onReceiveValue(origins);
- } break;
-
- case RETURN_USAGE_ORIGIN: {
- Map values = (Map) msg.obj;
- ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK);
- callback.onReceiveValue((Long)values.get(USAGE));
- } break;
-
- case RETURN_QUOTA_ORIGIN: {
- Map values = (Map) msg.obj;
- ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK);
- callback.onReceiveValue((Long)values.get(QUOTA));
- } break;
- }
- }
- };
- }
- }
-
- /**
- * Message handler, WebCore side
- * @hide
- */
- public synchronized void createHandler() {
- if (mHandler == null) {
- mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case SET_QUOTA_ORIGIN: {
- Origin website = (Origin) msg.obj;
- nativeSetQuotaForOrigin(website.getOrigin(),
- website.getQuota());
- } break;
-
- case DELETE_ORIGIN: {
- Origin website = (Origin) msg.obj;
- nativeDeleteOrigin(website.getOrigin());
- } break;
-
- case DELETE_ALL:
- nativeDeleteAllData();
- break;
-
- case GET_ORIGINS: {
- syncValues();
- ValueCallback callback = (ValueCallback) msg.obj;
- Map origins = new HashMap(mOrigins);
- Map values = new HashMap<String, Object>();
- values.put(CALLBACK, callback);
- values.put(ORIGINS, origins);
- postUIMessage(Message.obtain(null, RETURN_ORIGINS, values));
- } break;
-
- case GET_USAGE_ORIGIN: {
- syncValues();
- Map values = (Map) msg.obj;
- String origin = (String) values.get(ORIGIN);
- ValueCallback callback = (ValueCallback) values.get(CALLBACK);
- Origin website = mOrigins.get(origin);
- Map retValues = new HashMap<String, Object>();
- retValues.put(CALLBACK, callback);
- if (website != null) {
- long usage = website.getUsage();
- retValues.put(USAGE, new Long(usage));
- }
- postUIMessage(Message.obtain(null, RETURN_USAGE_ORIGIN, retValues));
- } break;
-
- case GET_QUOTA_ORIGIN: {
- syncValues();
- Map values = (Map) msg.obj;
- String origin = (String) values.get(ORIGIN);
- ValueCallback callback = (ValueCallback) values.get(CALLBACK);
- Origin website = mOrigins.get(origin);
- Map retValues = new HashMap<String, Object>();
- retValues.put(CALLBACK, callback);
- if (website != null) {
- long quota = website.getQuota();
- retValues.put(QUOTA, new Long(quota));
- }
- postUIMessage(Message.obtain(null, RETURN_QUOTA_ORIGIN, retValues));
- } break;
-
- case UPDATE:
- syncValues();
- break;
- }
- }
- };
- }
- }
-
/*
* When calling getOrigins(), getUsageForOrigin() and getQuotaForOrigin(),
* we need to get the values from WebCore, but we cannot block while doing so
@@ -270,26 +131,7 @@
* representation of the origin to a {@link WebStorage.Origin} object.
*/
public void getOrigins(ValueCallback<Map> callback) {
- if (callback != null) {
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- syncValues();
- callback.onReceiveValue(mOrigins);
- } else {
- postMessage(Message.obtain(null, GET_ORIGINS, callback));
- }
- }
- }
-
- /**
- * Returns a list of origins having a database
- * should only be called from WebViewCore.
- */
- Collection<Origin> getOriginsSync() {
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- update();
- return mOrigins.values();
- }
- return null;
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
@@ -300,23 +142,7 @@
* a {@link ValueCallback}.
*/
public void getUsageForOrigin(String origin, ValueCallback<Long> callback) {
- if (callback == null) {
- return;
- }
- if (origin == null) {
- callback.onReceiveValue(null);
- return;
- }
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- syncValues();
- Origin website = mOrigins.get(origin);
- callback.onReceiveValue(new Long(website.getUsage()));
- } else {
- HashMap values = new HashMap<String, Object>();
- values.put(ORIGIN, origin);
- values.put(CALLBACK, callback);
- postMessage(Message.obtain(null, GET_USAGE_ORIGIN, values));
- }
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
@@ -327,23 +153,7 @@
* enforced on a per-origin basis for the Application Cache API.
*/
public void getQuotaForOrigin(String origin, ValueCallback<Long> callback) {
- if (callback == null) {
- return;
- }
- if (origin == null) {
- callback.onReceiveValue(null);
- return;
- }
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- syncValues();
- Origin website = mOrigins.get(origin);
- callback.onReceiveValue(new Long(website.getUsage()));
- } else {
- HashMap values = new HashMap<String, Object>();
- values.put(ORIGIN, origin);
- values.put(CALLBACK, callback);
- postMessage(Message.obtain(null, GET_QUOTA_ORIGIN, values));
- }
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
@@ -353,14 +163,7 @@
* for the Application Cache API.
*/
public void setQuotaForOrigin(String origin, long quota) {
- if (origin != null) {
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- nativeSetQuotaForOrigin(origin, quota);
- } else {
- postMessage(Message.obtain(null, SET_QUOTA_ORIGIN,
- new Origin(origin, quota)));
- }
- }
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
@@ -369,14 +172,7 @@
* its string representation.
*/
public void deleteOrigin(String origin) {
- if (origin != null) {
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- nativeDeleteOrigin(origin);
- } else {
- postMessage(Message.obtain(null, DELETE_ORIGIN,
- new Origin(origin)));
- }
- }
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
@@ -385,38 +181,7 @@
* Storage APIs.
*/
public void deleteAllData() {
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- nativeDeleteAllData();
- } else {
- postMessage(Message.obtain(null, DELETE_ALL));
- }
- }
-
- /**
- * Sets the maximum size of the ApplicationCache.
- * This should only ever be called on the WebKit thread.
- * @hide
- */
- public void setAppCacheMaximumSize(long size) {
- nativeSetAppCacheMaximumSize(size);
- }
-
- /**
- * Utility function to send a message to our handler
- */
- private synchronized void postMessage(Message msg) {
- if (mHandler != null) {
- mHandler.sendMessage(msg);
- }
- }
-
- /**
- * Utility function to send a message to the handler on the UI thread
- */
- private void postUIMessage(Message msg) {
- if (mUIHandler != null) {
- mUIHandler.sendMessage(msg);
- }
+ // Must be a no-op for backward compatibility: see the hidden constructor for reason.
}
/**
@@ -424,37 +189,7 @@
* @return The singleton {@link WebStorage} instance.
*/
public static WebStorage getInstance() {
- if (sWebStorage == null) {
- sWebStorage = new WebStorage();
- }
- return sWebStorage;
- }
-
- /**
- * @hide
- * Post a Sync request
- */
- public void update() {
- if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
- syncValues();
- } else {
- postMessage(Message.obtain(null, UPDATE));
- }
- }
-
- /**
- * Run on the WebCore thread
- * set the local values with the current ones
- */
- private void syncValues() {
- Set<String> tmp = nativeGetOrigins();
- mOrigins = new HashMap<String, Origin>();
- for (String origin : tmp) {
- Origin website = new Origin(origin,
- nativeGetQuotaForOrigin(origin),
- nativeGetUsageForOrigin(origin));
- mOrigins.put(origin, website);
- }
+ return WebViewFactory.getProvider().getWebStorage();
}
/**
@@ -466,13 +201,4 @@
* @hide
*/
public WebStorage() {}
-
- // Native functions
- private static native Set nativeGetOrigins();
- private static native long nativeGetUsageForOrigin(String origin);
- private static native long nativeGetQuotaForOrigin(String origin);
- private static native void nativeSetQuotaForOrigin(String origin, long quota);
- private static native void nativeDeleteOrigin(String origin);
- private static native void nativeDeleteAllData();
- private static native void nativeSetAppCacheMaximumSize(long size);
}
diff --git a/core/java/android/webkit/WebStorageClassic.java b/core/java/android/webkit/WebStorageClassic.java
new file mode 100644
index 0000000..62de5e6
--- /dev/null
+++ b/core/java/android/webkit/WebStorageClassic.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.os.Handler;
+import android.os.Message;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/** @hide */
+public class WebStorageClassic extends WebStorage {
+ // Global instance of a WebStorage
+ private static WebStorageClassic sWebStorage;
+
+ // Message ids
+ static final int UPDATE = 0;
+ static final int SET_QUOTA_ORIGIN = 1;
+ static final int DELETE_ORIGIN = 2;
+ static final int DELETE_ALL = 3;
+ static final int GET_ORIGINS = 4;
+ static final int GET_USAGE_ORIGIN = 5;
+ static final int GET_QUOTA_ORIGIN = 6;
+
+ // Message ids on the UI thread
+ static final int RETURN_ORIGINS = 0;
+ static final int RETURN_USAGE_ORIGIN = 1;
+ static final int RETURN_QUOTA_ORIGIN = 2;
+
+ private static final String ORIGINS = "origins";
+ private static final String ORIGIN = "origin";
+ private static final String CALLBACK = "callback";
+ private static final String USAGE = "usage";
+ private static final String QUOTA = "quota";
+
+ private Map <String, Origin> mOrigins;
+
+ private Handler mHandler = null;
+ private Handler mUIHandler = null;
+
+ /**
+ * @hide
+ * Message handler, UI side
+ * @hide
+ */
+ public void createUIHandler() {
+ if (mUIHandler == null) {
+ mUIHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case RETURN_ORIGINS: {
+ Map values = (Map) msg.obj;
+ Map origins = (Map) values.get(ORIGINS);
+ ValueCallback<Map> callback = (ValueCallback<Map>) values.get(CALLBACK);
+ callback.onReceiveValue(origins);
+ } break;
+
+ case RETURN_USAGE_ORIGIN: {
+ Map values = (Map) msg.obj;
+ ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK);
+ callback.onReceiveValue((Long)values.get(USAGE));
+ } break;
+
+ case RETURN_QUOTA_ORIGIN: {
+ Map values = (Map) msg.obj;
+ ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK);
+ callback.onReceiveValue((Long)values.get(QUOTA));
+ } break;
+ }
+ }
+ };
+ }
+ }
+
+ /**
+ * Message handler, WebCore side
+ * @hide
+ */
+ public synchronized void createHandler() {
+ if (mHandler == null) {
+ mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SET_QUOTA_ORIGIN: {
+ Origin website = (Origin) msg.obj;
+ nativeSetQuotaForOrigin(website.getOrigin(),
+ website.getQuota());
+ } break;
+
+ case DELETE_ORIGIN: {
+ Origin website = (Origin) msg.obj;
+ nativeDeleteOrigin(website.getOrigin());
+ } break;
+
+ case DELETE_ALL:
+ nativeDeleteAllData();
+ break;
+
+ case GET_ORIGINS: {
+ syncValues();
+ ValueCallback callback = (ValueCallback) msg.obj;
+ Map origins = new HashMap(mOrigins);
+ Map values = new HashMap<String, Object>();
+ values.put(CALLBACK, callback);
+ values.put(ORIGINS, origins);
+ postUIMessage(Message.obtain(null, RETURN_ORIGINS, values));
+ } break;
+
+ case GET_USAGE_ORIGIN: {
+ syncValues();
+ Map values = (Map) msg.obj;
+ String origin = (String) values.get(ORIGIN);
+ ValueCallback callback = (ValueCallback) values.get(CALLBACK);
+ Origin website = mOrigins.get(origin);
+ Map retValues = new HashMap<String, Object>();
+ retValues.put(CALLBACK, callback);
+ if (website != null) {
+ long usage = website.getUsage();
+ retValues.put(USAGE, new Long(usage));
+ }
+ postUIMessage(Message.obtain(null, RETURN_USAGE_ORIGIN, retValues));
+ } break;
+
+ case GET_QUOTA_ORIGIN: {
+ syncValues();
+ Map values = (Map) msg.obj;
+ String origin = (String) values.get(ORIGIN);
+ ValueCallback callback = (ValueCallback) values.get(CALLBACK);
+ Origin website = mOrigins.get(origin);
+ Map retValues = new HashMap<String, Object>();
+ retValues.put(CALLBACK, callback);
+ if (website != null) {
+ long quota = website.getQuota();
+ retValues.put(QUOTA, new Long(quota));
+ }
+ postUIMessage(Message.obtain(null, RETURN_QUOTA_ORIGIN, retValues));
+ } break;
+
+ case UPDATE:
+ syncValues();
+ break;
+ }
+ }
+ };
+ }
+ }
+
+ /*
+ * When calling getOrigins(), getUsageForOrigin() and getQuotaForOrigin(),
+ * we need to get the values from WebCore, but we cannot block while doing so
+ * as we used to do, as this could result in a full deadlock (other WebCore
+ * messages received while we are still blocked here, see http://b/2127737).
+ *
+ * We have to do everything asynchronously, by providing a callback function.
+ * We post a message on the WebCore thread (mHandler) that will get the result
+ * from WebCore, and we post it back on the UI thread (using mUIHandler).
+ * We can then use the callback function to return the value.
+ */
+
+ @Override
+ public void getOrigins(ValueCallback<Map> callback) {
+ if (callback != null) {
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ syncValues();
+ callback.onReceiveValue(mOrigins);
+ } else {
+ postMessage(Message.obtain(null, GET_ORIGINS, callback));
+ }
+ }
+ }
+
+ /**
+ * Returns a list of origins having a database
+ * should only be called from WebViewCore.
+ */
+ Collection<Origin> getOriginsSync() {
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ update();
+ return mOrigins.values();
+ }
+ return null;
+ }
+
+ @Override
+ public void getUsageForOrigin(String origin, ValueCallback<Long> callback) {
+ if (callback == null) {
+ return;
+ }
+ if (origin == null) {
+ callback.onReceiveValue(null);
+ return;
+ }
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ syncValues();
+ Origin website = mOrigins.get(origin);
+ callback.onReceiveValue(new Long(website.getUsage()));
+ } else {
+ HashMap values = new HashMap<String, Object>();
+ values.put(ORIGIN, origin);
+ values.put(CALLBACK, callback);
+ postMessage(Message.obtain(null, GET_USAGE_ORIGIN, values));
+ }
+ }
+
+ @Override
+ public void getQuotaForOrigin(String origin, ValueCallback<Long> callback) {
+ if (callback == null) {
+ return;
+ }
+ if (origin == null) {
+ callback.onReceiveValue(null);
+ return;
+ }
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ syncValues();
+ Origin website = mOrigins.get(origin);
+ callback.onReceiveValue(new Long(website.getUsage()));
+ } else {
+ HashMap values = new HashMap<String, Object>();
+ values.put(ORIGIN, origin);
+ values.put(CALLBACK, callback);
+ postMessage(Message.obtain(null, GET_QUOTA_ORIGIN, values));
+ }
+ }
+
+ @Override
+ public void setQuotaForOrigin(String origin, long quota) {
+ if (origin != null) {
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ nativeSetQuotaForOrigin(origin, quota);
+ } else {
+ postMessage(Message.obtain(null, SET_QUOTA_ORIGIN,
+ new Origin(origin, quota)));
+ }
+ }
+ }
+
+ @Override
+ public void deleteOrigin(String origin) {
+ if (origin != null) {
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ nativeDeleteOrigin(origin);
+ } else {
+ postMessage(Message.obtain(null, DELETE_ORIGIN,
+ new Origin(origin)));
+ }
+ }
+ }
+
+ @Override
+ public void deleteAllData() {
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ nativeDeleteAllData();
+ } else {
+ postMessage(Message.obtain(null, DELETE_ALL));
+ }
+ }
+
+ /**
+ * Sets the maximum size of the ApplicationCache.
+ * This should only ever be called on the WebKit thread.
+ * Not part of the base-class API: this is only used by dump render tree.
+ */
+ public void setAppCacheMaximumSize(long size) {
+ nativeSetAppCacheMaximumSize(size);
+ }
+
+ /**
+ * Utility function to send a message to our handler
+ */
+ private synchronized void postMessage(Message msg) {
+ if (mHandler != null) {
+ mHandler.sendMessage(msg);
+ }
+ }
+
+ /**
+ * Utility function to send a message to the handler on the UI thread
+ */
+ private void postUIMessage(Message msg) {
+ if (mUIHandler != null) {
+ mUIHandler.sendMessage(msg);
+ }
+ }
+
+ /**
+ * Get the singleton instance of this class.
+ * @return The singleton {@link WebStorage} instance.
+ */
+ public static WebStorageClassic getInstance() {
+ if (sWebStorage == null) {
+ sWebStorage = new WebStorageClassic();
+ }
+ return sWebStorage;
+ }
+
+ /**
+ * @hide
+ * Post a Sync request
+ */
+ public void update() {
+ if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
+ syncValues();
+ } else {
+ postMessage(Message.obtain(null, UPDATE));
+ }
+ }
+
+ /**
+ * Run on the WebCore thread
+ * set the local values with the current ones
+ */
+ private void syncValues() {
+ Set<String> tmp = nativeGetOrigins();
+ mOrigins = new HashMap<String, Origin>();
+ for (String origin : tmp) {
+ Origin website = new Origin(origin,
+ nativeGetQuotaForOrigin(origin),
+ nativeGetUsageForOrigin(origin));
+ mOrigins.put(origin, website);
+ }
+ }
+
+ WebStorageClassic() {}
+
+ // Native functions
+ private static native Set nativeGetOrigins();
+ private static native long nativeGetUsageForOrigin(String origin);
+ private static native long nativeGetQuotaForOrigin(String origin);
+ private static native void nativeSetQuotaForOrigin(String origin, long quota);
+ private static native void nativeDeleteOrigin(String origin);
+ private static native void nativeDeleteAllData();
+ private static native void nativeSetAppCacheMaximumSize(long size);
+}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index bd10cca..d3d3d49 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -55,7 +55,7 @@
* through a history, zoom in and out, perform text searches and more.</p>
* <p>To enable the built-in zoom, set
* {@link #getSettings() WebSettings}.{@link WebSettings#setBuiltInZoomControls(boolean)}
- * (introduced in API version 3).
+ * (introduced in API level {@link android.os.Build.VERSION_CODES#CUPCAKE}).
* <p>Note that, in order for your Activity to access the Internet and load web pages
* in a WebView, you must add the {@code INTERNET} permissions to your
* Android Manifest file:</p>
@@ -199,8 +199,9 @@
* appearance on a medium density screen. So, it applies 1.5x scaling on a high density screen
* (because its pixels are smaller) and 0.75x scaling on a low density screen (because its pixels
* are bigger).
- * Starting with API Level 5 (Android 2.0), WebView supports DOM, CSS, and meta tag features to help
- * you (as a web developer) target screens with different screen densities.</p>
+ * Starting with API level {@link android.os.Build.VERSION_CODES#ECLAIR}, WebView supports DOM, CSS,
+ * and meta tag features to help you (as a web developer) target screens with different screen
+ * densities.</p>
* <p>Here's a summary of the features you can use to handle different screen densities:</p>
* <ul>
* <li>The {@code window.devicePixelRatio} DOM property. The value of this property specifies the
@@ -268,12 +269,7 @@
implements ViewTreeObserver.OnGlobalFocusChangeListener,
ViewGroup.OnHierarchyChangeListener {
- // Default Provider factory class name.
- private static final String DEFAULT_WEB_VIEW_FACTORY = "android.webkit.WebViewClassic$Factory";
-
private static final String LOGTAG = "webview_proxy";
- // TODO: flip DEBUG to always be disabled.
- private static final boolean DEBUG = true;
/**
* Transportation object for returning WebView across thread boundaries.
@@ -1533,13 +1529,13 @@
* Gets the zoom controls for the WebView, as a separate View. The caller is
* responsible for inserting this View into the layout hierarchy.
* <p/>
- * API Level 3 introduced built-in zoom mechanisms for the WebView, as
- * opposed to these separate zoom controls. The built-in mechanisms are
- * preferred and can be enabled using
- * {@link WebSettings#setBuiltInZoomControls}.
+ * API level {@link android.os.Build.VERSION_CODES#CUPCAKE} introduced
+ * built-in zoom mechanisms for the WebView, as opposed to these separate
+ * zoom controls. The built-in mechanisms are preferred and can be enabled
+ * using {@link WebSettings#setBuiltInZoomControls}.
*
* @deprecated The built-in zoom mechanisms are preferred.
- * @hide since API version 16.
+ * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN}
*/
@Deprecated
public View getZoomControls() {
@@ -1702,16 +1698,11 @@
// Private internal stuff
//-------------------------------------------------------------------------
- // Cache the factory both for efficiency, and ensure any one process gets all webviews from the
- // same provider.
- private static WebViewFactoryProvider sProviderFactory;
-
private WebViewProvider mProvider;
private void ensureProviderCreated() {
checkThread();
if (mProvider == null) {
- if (DEBUG) Log.v(LOGTAG, "instantiating webview provider instance");
// As this can get called during the base class constructor chain, pass the minimum
// number of dependencies here; the rest are deferred to init().
mProvider = getFactory().createWebView(this, new PrivateAccess());
@@ -1722,30 +1713,7 @@
// For now the main purpose of this function (and the factory abstration) is to keep
// us honest and minimize usage of WebViewClassic internals when binding the proxy.
checkThread();
- if (sProviderFactory != null) return sProviderFactory;
-
- sProviderFactory = getFactoryByName(DEFAULT_WEB_VIEW_FACTORY);
- if (sProviderFactory == null) {
- if (DEBUG) Log.v (LOGTAG, "Falling back to explicit linkage");
- sProviderFactory = new WebViewClassic.Factory();
- }
- return sProviderFactory;
- }
-
- private static WebViewFactoryProvider getFactoryByName(String providerName) {
- try {
- if (DEBUG) Log.v(LOGTAG, "attempt to load class " + providerName);
- Class<?> c = Class.forName(providerName);
- if (DEBUG) Log.v(LOGTAG, "instantiating factory");
- return (WebViewFactoryProvider) c.newInstance();
- } catch (ClassNotFoundException e) {
- Log.e(LOGTAG, "error loading " + providerName, e);
- } catch (IllegalAccessException e) {
- Log.e(LOGTAG, "error loading " + providerName, e);
- } catch (InstantiationException e) {
- Log.e(LOGTAG, "error loading " + providerName, e);
- }
- return null;
+ return WebViewFactory.getProvider();
}
private static void checkThread() {
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 893849b9..3bd9960 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -1074,7 +1074,6 @@
private static final int STD_SPEED = 480; // pixels per second
// time for the longest scroll animation
private static final int MAX_DURATION = 750; // milliseconds
- private static final int SLIDE_TITLE_DURATION = 500; // milliseconds
// Used by OverScrollGlow
OverScroller mScroller;
@@ -1460,14 +1459,6 @@
static class Factory implements WebViewFactoryProvider, WebViewFactoryProvider.Statics {
@Override
- public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) {
- return new WebViewClassic(webView, privateAccess);
- }
-
- @Override
- public Statics getStatics() { return this; }
-
- @Override
public String findAddress(String addr) {
return WebViewClassic.findAddress(addr);
}
@@ -1480,14 +1471,40 @@
}
}
+ @Override
+ public Statics getStatics() { return this; }
+
+ @Override
+ public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) {
+ return new WebViewClassic(webView, privateAccess);
+ }
+
+ @Override
+ public GeolocationPermissions getGeolocationPermissions() {
+ return GeolocationPermissionsClassic.getInstance();
+ }
+
+ @Override
+ public CookieManager getCookieManager() {
+ return CookieManagerClassic.getInstance();
+ }
+
+ @Override
+ public WebIconDatabase getWebIconDatabase() {
+ return WebIconDatabaseClassic.getInstance();
+ }
+
+ @Override
+ public WebStorage getWebStorage() {
+ return WebStorageClassic.getInstance();
+ }
}
private void onHandleUiEvent(MotionEvent event, int eventType, int flags) {
switch (eventType) {
case WebViewInputDispatcher.EVENT_TYPE_LONG_PRESS:
HitTestResult hitTest = getHitTestResult();
- if (hitTest != null
- && hitTest.getType() != HitTestResult.UNKNOWN_TYPE) {
+ if (hitTest != null) {
performLongClick();
}
break;
@@ -2439,34 +2456,51 @@
* version specific, and may not be able to be loaded by newer versions
* of WebView.
* @param stream The {@link OutputStream} to save to
- * @return True if saved successfully
+ * @param callback The {@link ValueCallback} to call with the result
*/
- public boolean saveViewState(OutputStream stream) {
- try {
- return ViewStateSerializer.serializeViewState(stream, this);
- } catch (IOException e) {
- Log.w(LOGTAG, "Failed to saveViewState", e);
+ public void saveViewState(OutputStream stream, ValueCallback<Boolean> callback) {
+ if (mWebViewCore == null) {
+ callback.onReceiveValue(false);
+ return;
}
- return false;
+ mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SAVE_VIEW_STATE,
+ new WebViewCore.SaveViewStateRequest(stream, callback));
}
/**
* Loads the view data from the input stream. See
* {@link #saveViewState(OutputStream)} for more information.
* @param stream The {@link InputStream} to load from
- * @return True if loaded successfully
*/
- public boolean loadViewState(InputStream stream) {
- try {
- mLoadedPicture = ViewStateSerializer.deserializeViewState(stream, this);
- mBlockWebkitViewMessages = true;
- setNewPicture(mLoadedPicture, true);
- mLoadedPicture.mViewState = null;
- return true;
- } catch (IOException e) {
- Log.w(LOGTAG, "Failed to loadViewState", e);
- }
- return false;
+ public void loadViewState(InputStream stream) {
+ mBlockWebkitViewMessages = true;
+ new AsyncTask<InputStream, Void, DrawData>() {
+
+ @Override
+ protected DrawData doInBackground(InputStream... params) {
+ try {
+ return ViewStateSerializer.deserializeViewState(params[0]);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected void onPostExecute(DrawData draw) {
+ if (draw == null) {
+ Log.e(LOGTAG, "Failed to load view state!");
+ return;
+ }
+ int viewWidth = getViewWidth();
+ int viewHeight = getViewHeightWithTitle() - getTitleHeight();
+ draw.mViewSize = new Point(viewWidth, viewHeight);
+ draw.mViewState.mDefaultScale = getDefaultZoomScale();
+ mLoadedPicture = draw;
+ setNewPicture(mLoadedPicture, true);
+ mLoadedPicture.mViewState = null;
+ }
+
+ }.execute(stream);
}
/**
@@ -3910,6 +3944,9 @@
mSelectCursorExtent.offset(dx, dy);
mSelectCursorExtentTextQuad.offset(dx, dy);
}
+ } else if (mHandleAlpha.getAlpha() > 0) {
+ // stop fading as we're not going to move with the layer.
+ mHandleAlphaAnimator.end();
}
if (mAutoCompletePopup != null &&
mCurrentScrollingLayerId == mEditTextLayerId) {
@@ -4013,17 +4050,6 @@
* @param url The URL of the page which has finished loading.
*/
/* package */ void onPageFinished(String url) {
- if (mPageThatNeedsToSlideTitleBarOffScreen != null) {
- // If the user is now on a different page, or has scrolled the page
- // past the point where the title bar is offscreen, ignore the
- // scroll request.
- if (mPageThatNeedsToSlideTitleBarOffScreen.equals(url)
- && getScrollX() == 0 && getScrollY() == 0) {
- pinScrollTo(0, mYDistanceToSlideTitleOffScreen, true,
- SLIDE_TITLE_DURATION);
- }
- mPageThatNeedsToSlideTitleBarOffScreen = null;
- }
mZoomManager.onPageFinished(url);
injectAccessibilityForUrl(url);
}
@@ -4135,93 +4161,16 @@
return -1;
}
- /**
- * The URL of a page that sent a message to scroll the title bar off screen.
- *
- * Many mobile sites tell the page to scroll to (0,1) in order to scroll the
- * title bar off the screen. Sometimes, the scroll position is set before
- * the page finishes loading. Rather than scrolling while the page is still
- * loading, keep track of the URL and new scroll position so we can perform
- * the scroll once the page finishes loading.
- */
- private String mPageThatNeedsToSlideTitleBarOffScreen;
-
- /**
- * The destination Y scroll position to be used when the page finishes
- * loading. See mPageThatNeedsToSlideTitleBarOffScreen.
- */
- private int mYDistanceToSlideTitleOffScreen;
-
// scale from content to view coordinates, and pin
- // return true if pin caused the final x/y different than the request cx/cy,
- // and a future scroll may reach the request cx/cy after our size has
- // changed
- // return false if the view scroll to the exact position as it is requested,
- // where negative numbers are taken to mean 0
- private boolean setContentScrollTo(int cx, int cy) {
- if (mDrawHistory) {
- // disallow WebView to change the scroll position as History Picture
- // is used in the view system.
- // One known case where this is called is that WebCore tries to
- // restore the scroll position. As history Picture already uses the
- // saved scroll position, it is ok to skip this.
- return false;
- }
- int vx;
- int vy;
- if ((cx | cy) == 0) {
- // If the page is being scrolled to (0,0), do not add in the title
- // bar's height, and simply scroll to (0,0). (The only other work
- // in contentToView_ is to multiply, so this would not change 0.)
- vx = 0;
- vy = 0;
- } else {
- vx = contentToViewX(cx);
- vy = contentToViewY(cy);
- }
-// Log.d(LOGTAG, "content scrollTo [" + cx + " " + cy + "] view=[" +
-// vx + " " + vy + "]");
- // Some mobile sites attempt to scroll the title bar off the page by
- // scrolling to (0,1). If we are at the top left corner of the
- // page, assume this is an attempt to scroll off the title bar, and
- // animate the title bar off screen slowly enough that the user can see
- // it.
- if (cx == 0 && cy == 1 && getScrollX() == 0 && getScrollY() == 0
- && getTitleHeight() > 0) {
- // FIXME: 100 should be defined somewhere as our max progress.
- if (getProgress() < 100) {
- // Wait to scroll the title bar off screen until the page has
- // finished loading. Keep track of the URL and the destination
- // Y position
- mPageThatNeedsToSlideTitleBarOffScreen = getUrl();
- mYDistanceToSlideTitleOffScreen = vy;
- } else {
- pinScrollTo(vx, vy, true, SLIDE_TITLE_DURATION);
- }
- // Since we are animating, we have not yet reached the desired
- // scroll position. Do not return true to request another attempt
- return false;
- }
- pinScrollTo(vx, vy, false, 0);
- // If the request was to scroll to a negative coordinate, treat it as if
- // it was a request to scroll to 0
- if ((getScrollX() != vx && cx >= 0) || (getScrollY() != vy && cy >= 0)) {
- return true;
- } else {
- return false;
- }
- }
-
- // scale from content to view coordinates, and pin
- private void spawnContentScrollTo(int cx, int cy) {
+ private void contentScrollTo(int cx, int cy, boolean animate) {
if (mDrawHistory) {
// disallow WebView to change the scroll position as History Picture
// is used in the view system.
return;
}
- int vx = contentToViewDimension(cx - mScrollOffset.x);
- int vy = contentToViewDimension(cy - mScrollOffset.y);
- pinScrollBy(vx, vy, true, 0);
+ int vx = contentToViewX(cx);
+ int vy = contentToViewY(cy);
+ pinScrollTo(vx, vy, animate, 0);
}
/**
@@ -4491,9 +4440,7 @@
}
canvas.restoreToCount(saveCount);
- if (mSelectingText) {
- drawTextSelectionHandles(canvas);
- }
+ drawTextSelectionHandles(canvas);
if (extras == DRAW_EXTRAS_CURSOR_RING) {
if (mTouchMode == TOUCH_SHORTPRESS_START_MODE) {
@@ -4731,6 +4678,9 @@
}
private void onZoomAnimationStart() {
+ if (!mSelectingText && mHandleAlpha.getAlpha() > 0) {
+ mHandleAlphaAnimator.end();
+ }
}
private void onZoomAnimationEnd() {
@@ -4761,6 +4711,36 @@
private final DrawFilter mScrollFilter =
new PaintFlagsDrawFilter(SCROLL_BITS, 0);
+ private class SelectionHandleAlpha {
+ private int mAlpha = 0;
+ public void setAlpha(int alpha) {
+ mAlpha = alpha;
+ if (mSelectHandleCenter != null) {
+ mSelectHandleCenter.setAlpha(alpha);
+ mSelectHandleLeft.setAlpha(alpha);
+ mSelectHandleRight.setAlpha(alpha);
+ // TODO: Use partial invalidate
+ invalidate();
+ }
+ }
+
+ public int getAlpha() {
+ return mAlpha;
+ }
+
+ }
+
+ private void startSelectingText() {
+ mSelectingText = true;
+ mHandleAlphaAnimator.setIntValues(255);
+ mHandleAlphaAnimator.start();
+ }
+ private void endSelectingText() {
+ mSelectingText = false;
+ mHandleAlphaAnimator.setIntValues(0);
+ mHandleAlphaAnimator.start();
+ }
+
private void ensureSelectionHandles() {
if (mSelectHandleCenter == null) {
mSelectHandleCenter = mContext.getResources().getDrawable(
@@ -4769,6 +4749,7 @@
com.android.internal.R.drawable.text_select_handle_left);
mSelectHandleRight = mContext.getResources().getDrawable(
com.android.internal.R.drawable.text_select_handle_right);
+ mHandleAlpha.setAlpha(mHandleAlpha.getAlpha());
mSelectHandleCenterOffset = new Point(0,
-mSelectHandleCenter.getIntrinsicHeight());
mSelectHandleLeftOffset = new Point(0,
@@ -4780,31 +4761,40 @@
}
private void drawTextSelectionHandles(Canvas canvas) {
+ if (mHandleAlpha.getAlpha() == 0) {
+ return;
+ }
ensureSelectionHandles();
- int[] handles = new int[4];
- getSelectionHandles(handles);
- int start_x = contentToViewDimension(handles[0]);
- int start_y = contentToViewDimension(handles[1]);
- int end_x = contentToViewDimension(handles[2]);
- int end_y = contentToViewDimension(handles[3]);
+ if (mSelectingText) {
+ int[] handles = new int[4];
+ getSelectionHandles(handles);
+ int start_x = contentToViewDimension(handles[0]);
+ int start_y = contentToViewDimension(handles[1]);
+ int end_x = contentToViewDimension(handles[2]);
+ int end_y = contentToViewDimension(handles[3]);
+
+ if (mIsCaretSelection) {
+ // Caret handle is centered
+ start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2);
+ mSelectHandleCenter.setBounds(start_x, start_y,
+ start_x + mSelectHandleCenter.getIntrinsicWidth(),
+ start_y + mSelectHandleCenter.getIntrinsicHeight());
+ } else {
+ // Magic formula copied from TextView
+ start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
+ mSelectHandleLeft.setBounds(start_x, start_y,
+ start_x + mSelectHandleLeft.getIntrinsicWidth(),
+ start_y + mSelectHandleLeft.getIntrinsicHeight());
+ end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
+ mSelectHandleRight.setBounds(end_x, end_y,
+ end_x + mSelectHandleRight.getIntrinsicWidth(),
+ end_y + mSelectHandleRight.getIntrinsicHeight());
+ }
+ }
if (mIsCaretSelection) {
- // Caret handle is centered
- start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2);
- mSelectHandleCenter.setBounds(start_x, start_y,
- start_x + mSelectHandleCenter.getIntrinsicWidth(),
- start_y + mSelectHandleCenter.getIntrinsicHeight());
mSelectHandleCenter.draw(canvas);
} else {
- // Magic formula copied from TextView
- start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
- mSelectHandleLeft.setBounds(start_x, start_y,
- start_x + mSelectHandleLeft.getIntrinsicWidth(),
- start_y + mSelectHandleLeft.getIntrinsicHeight());
- end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
- mSelectHandleRight.setBounds(end_x, end_y,
- end_x + mSelectHandleRight.getIntrinsicWidth(),
- end_y + mSelectHandleRight.getIntrinsicHeight());
mSelectHandleLeft.draw(canvas);
mSelectHandleRight.draw(canvas);
}
@@ -5458,7 +5448,7 @@
selectionDone();
return false;
}
- mSelectingText = true;
+ startSelectingText();
mTouchMode = TOUCH_DRAG_MODE;
return true;
}
@@ -5512,7 +5502,7 @@
void selectionDone() {
if (mSelectingText) {
hidePasteButton();
- mSelectingText = false;
+ endSelectingText();
// finish is idempotent, so this is fine even if selectionDone was
// called by mSelectCallback.onDestroyActionMode
if (mSelectCallback != null) {
@@ -6644,6 +6634,9 @@
private long mTrackballUpTime = 0;
private long mLastCursorTime = 0;
private Rect mLastCursorBounds;
+ private SelectionHandleAlpha mHandleAlpha = new SelectionHandleAlpha();
+ private ObjectAnimator mHandleAlphaAnimator =
+ ObjectAnimator.ofInt(mHandleAlpha, "alpha", 0);
// Set by default; BrowserActivity clears to interpret trackball data
// directly for movement. Currently, the framework only passes
@@ -7428,11 +7421,7 @@
}
}
final Point p = (Point) msg.obj;
- if (msg.arg1 == 1) {
- spawnContentScrollTo(p.x, p.y);
- } else {
- setContentScrollTo(p.x, p.y);
- }
+ contentScrollTo(p.x, p.y, msg.arg1 == 1);
break;
}
case UPDATE_ZOOM_RANGE: {
@@ -8073,7 +8062,7 @@
int scrollX = viewState.mShouldStartScrolledRight
? getContentWidth() : viewState.mScrollX;
int scrollY = viewState.mScrollY;
- setContentScrollTo(scrollX, scrollY);
+ contentScrollTo(scrollX, scrollY, false);
if (!mDrawHistory) {
// As we are on a new page, hide the keyboard
hideSoftKeyboard();
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 0c34037..6aff10a 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -20,6 +20,7 @@
import android.net.http.SslError;
import android.os.Message;
import android.view.KeyEvent;
+import android.view.ViewRootImpl;
public class WebViewClient {
@@ -273,6 +274,10 @@
* @param event The key event.
*/
public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
+ ViewRootImpl root = view.getViewRootImpl();
+ if (root != null) {
+ root.dispatchUnhandledKey(event);
+ }
}
/**
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index aea23c0..75141fd 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -44,8 +44,11 @@
import junit.framework.Assert;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
@@ -186,10 +189,10 @@
// The WebIconDatabase needs to be initialized within the UI thread so
// just request the instance here.
WebIconDatabase.getInstance();
- // Create the WebStorage singleton and the UI handler
- WebStorage.getInstance().createUIHandler();
+ // Create the WebStorageClassic singleton and the UI handler
+ WebStorageClassic.getInstance().createUIHandler();
// Create the UI handler for GeolocationPermissions
- GeolocationPermissions.getInstance().createUIHandler();
+ GeolocationPermissionsClassic.getInstance().createUIHandler();
// Get the memory class of the current device. V8 will use these values
// to GC more effectively.
@@ -224,11 +227,11 @@
// Sync the native settings and also create the WebCore thread handler.
mSettings.syncSettingsAndCreateHandler(mBrowserFrame);
// Create the handler and transfer messages for the IconDatabase
- WebIconDatabase.getInstance().createHandler();
- // Create the handler for WebStorage
- WebStorage.getInstance().createHandler();
+ WebIconDatabaseClassic.getInstance().createHandler();
+ // Create the handler for WebStorageClassic
+ WebStorageClassic.getInstance().createHandler();
// Create the handler for GeolocationPermissions.
- GeolocationPermissions.getInstance().createHandler();
+ GeolocationPermissionsClassic.getInstance().createHandler();
// The transferMessages call will transfer all pending messages to the
// WebCore thread handler.
mEventHub.transferMessages();
@@ -1046,6 +1049,15 @@
public int mMatchIndex;
}
+ static class SaveViewStateRequest {
+ SaveViewStateRequest(OutputStream s, ValueCallback<Boolean> cb) {
+ mStream = s;
+ mCallback = cb;
+ }
+ public OutputStream mStream;
+ public ValueCallback<Boolean> mCallback;
+ }
+
/**
* @hide
*/
@@ -1178,11 +1190,13 @@
static final int KEY_PRESS = 223;
static final int SET_INITIAL_FOCUS = 224;
+ static final int SAVE_VIEW_STATE = 225;
+
// Private handler for WebCore messages.
private Handler mHandler;
// Message queue for containing messages before the WebCore thread is
// ready.
- private ArrayList<Message> mMessages = new ArrayList<Message>();
+ private LinkedList<Message> mMessages = new LinkedList<Message>();
// Flag for blocking messages. This is used during DESTROY to avoid
// posting more messages to the EventHub or to WebView's event handler.
private boolean mBlockMessages;
@@ -1294,20 +1308,20 @@
break;
case LOAD_URL: {
- CookieManager.getInstance().waitForCookieOperationsToComplete();
+ CookieManagerClassic.getInstance().waitForCookieOperationsToComplete();
GetUrlData param = (GetUrlData) msg.obj;
loadUrl(param.mUrl, param.mExtraHeaders);
break;
}
case POST_URL: {
- CookieManager.getInstance().waitForCookieOperationsToComplete();
+ CookieManagerClassic.getInstance().waitForCookieOperationsToComplete();
PostUrlData param = (PostUrlData) msg.obj;
mBrowserFrame.postUrl(param.mUrl, param.mPostData);
break;
}
case LOAD_DATA:
- CookieManager.getInstance().waitForCookieOperationsToComplete();
+ CookieManagerClassic.getInstance().waitForCookieOperationsToComplete();
BaseUrlData loadParams = (BaseUrlData) msg.obj;
String baseUrl = loadParams.mBaseUrl;
if (baseUrl != null) {
@@ -1752,8 +1766,13 @@
case SET_INITIAL_FOCUS:
nativeSetInitialFocus(mNativeClass, msg.arg1);
break;
+ case SAVE_VIEW_STATE:
+ SaveViewStateRequest request = (SaveViewStateRequest) msg.obj;
+ saveViewState(request.mStream, request.mCallback);
+ break;
}
}
+
};
// Take all queued messages and resend them to the new handler.
synchronized (this) {
@@ -1822,10 +1841,13 @@
mDrawIsScheduled = false;
}
if (mMessages != null) {
- Throwable throwable = new Throwable(
- "EventHub.removeMessages(int what = " + what + ") is not supported " +
- "before the WebViewCore is set up.");
- Log.w(LOGTAG, Log.getStackTraceString(throwable));
+ Iterator<Message> iter = mMessages.iterator();
+ while (iter.hasNext()) {
+ Message m = iter.next();
+ if (m.what == what) {
+ iter.remove();
+ }
+ }
} else {
mHandler.removeMessages(what);
}
@@ -2107,7 +2129,7 @@
// Utility method for exceededDatabaseQuota and reachedMaxAppCacheSize
// callbacks. Computes the sum of database quota for all origins.
private long getUsedQuota() {
- WebStorage webStorage = WebStorage.getInstance();
+ WebStorageClassic webStorage = WebStorageClassic.getInstance();
Collection<WebStorage.Origin> origins = webStorage.getOriginsSync();
if (origins == null) {
@@ -2249,6 +2271,31 @@
}
}
+ private void saveViewState(OutputStream stream,
+ ValueCallback<Boolean> callback) {
+ // TODO: Create a native method to do this better without overloading
+ // the draw path (and fix saving <canvas>)
+ DrawData draw = new DrawData();
+ if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "saveViewState start");
+ draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mInvalRegion,
+ draw.mContentSize);
+ boolean result = false;
+ try {
+ result = ViewStateSerializer.serializeViewState(stream, draw);
+ } catch (Throwable t) {
+ Log.w(LOGTAG, "Failed to save view state", t);
+ }
+ callback.onReceiveValue(result);
+ if (draw.mBaseLayer != 0) {
+ if (mDrawIsScheduled) {
+ mDrawIsScheduled = false;
+ mEventHub.removeMessages(EventHub.WEBKIT_DRAW);
+ }
+ mLastDrawData = draw;
+ webkitDraw(draw);
+ }
+ }
+
static void reducePriority() {
// remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages
sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY);
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
new file mode 100644
index 0000000..73ae910
--- /dev/null
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.util.Log;
+
+/**
+ * Top level factory, used creating all the main WebView implementation classes.
+ */
+class WebViewFactory {
+ // Default Provider factory class name.
+ private static final String DEFAULT_WEB_VIEW_FACTORY = "android.webkit.WebViewClassic$Factory";
+
+ private static final String LOGTAG = "WebViewFactory";
+
+ private static final boolean DEBUG = false;
+
+ // Cache the factory both for efficiency, and ensure any one process gets all webviews from the
+ // same provider.
+ private static WebViewFactoryProvider sProviderInstance;
+
+ static synchronized WebViewFactoryProvider getProvider() {
+ // For now the main purpose of this function (and the factory abstraction) is to keep
+ // us honest and minimize usage of WebViewClassic internals when binding the proxy.
+ if (sProviderInstance != null) return sProviderInstance;
+
+ sProviderInstance = getFactoryByName(DEFAULT_WEB_VIEW_FACTORY);
+ if (sProviderInstance == null) {
+ if (DEBUG) Log.v(LOGTAG, "Falling back to explicit linkage");
+ sProviderInstance = new WebViewClassic.Factory();
+ }
+ return sProviderInstance;
+ }
+
+ private static WebViewFactoryProvider getFactoryByName(String providerName) {
+ try {
+ if (DEBUG) Log.v(LOGTAG, "attempt to load class " + providerName);
+ Class<?> c = Class.forName(providerName);
+ if (DEBUG) Log.v(LOGTAG, "instantiating factory");
+ return (WebViewFactoryProvider) c.newInstance();
+ } catch (ClassNotFoundException e) {
+ Log.e(LOGTAG, "error loading " + providerName, e);
+ } catch (IllegalAccessException e) {
+ Log.e(LOGTAG, "error loading " + providerName, e);
+ } catch (InstantiationException e) {
+ Log.e(LOGTAG, "error loading " + providerName, e);
+ }
+ return null;
+ }
+}
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 22bf0bf..a832b0a 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -23,18 +23,6 @@
* @hide
*/
public interface WebViewFactoryProvider {
-
- /**
- * Construct a new WebView provider.
- * @param webView the WebView instance bound to this implementation instance. Note it will not
- * necessarily be fully constructed at the point of this call: defer real initialization to
- * WebViewProvider.init().
- * @param privateAccess provides access into WebView internal methods.
- */
- WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess);
-
- Statics getStatics();
-
/**
* This Interface provides glue for implementing the backend of WebView static methods which
* cannot be implemented in-situ in the proxy class.
@@ -53,4 +41,43 @@
*/
void setPlatformNotificationsEnabled(boolean enable);
}
+
+ Statics getStatics();
+
+ /**
+ * Construct a new WebViewProvider.
+ * @param webView the WebView instance bound to this implementation instance. Note it will not
+ * necessarily be fully constructed at the point of this call: defer real initialization to
+ * WebViewProvider.init().
+ * @param privateAccess provides access into WebView internal methods.
+ */
+ WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess);
+
+ /**
+ * Gets the singleton GeolocationPermissions instance for this WebView implementation. The
+ * implementation must return the same instance on subsequent calls.
+ * @return the single GeolocationPermissions instance.
+ */
+ GeolocationPermissions getGeolocationPermissions();
+
+ /**
+ * Gets the singleton CookieManager instance for this WebView implementation. The
+ * implementation must return the same instance on subsequent calls.
+ * @return the singleton CookieManager instance.
+ */
+ CookieManager getCookieManager();
+
+ /**
+ * Gets the singleton WebIconDatabase instance for this WebView implementation. The
+ * implementation must return the same instance on subsequent calls.
+ * @return the singleton WebIconDatabase instance.
+ */
+ WebIconDatabase getWebIconDatabase();
+
+ /**
+ * Gets the singleton WebStorage instance for this WebView implementation. The
+ * implementation must return the same instance on subsequent calls.
+ * @return the singleton WebStorage instance.
+ */
+ WebStorage getWebStorage();
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index e68049c..53d5e0b 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -403,7 +403,7 @@
/**
* Handles scrolling between positions within the list.
*/
- private PositionScroller mPositionScroller;
+ PositionScroller mPositionScroller;
/**
* The offset in pixels form the top of the AdapterView to the top
@@ -3080,6 +3080,10 @@
return isClickable() || isLongClickable();
}
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+
if (mFastScroller != null) {
boolean intercepted = mFastScroller.onTouchEvent(ev);
if (intercepted) {
@@ -3564,6 +3568,10 @@
int action = ev.getAction();
View v;
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+
if (mFastScroller != null) {
boolean intercepted = mFastScroller.onInterceptTouchEvent(ev);
if (intercepted) {
@@ -3748,7 +3756,7 @@
mScroller.fling(0, initialY, 0, initialVelocity,
0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE);
mTouchMode = TOUCH_MODE_FLING;
- post(this);
+ postOnAnimation(this);
if (PROFILE_FLINGING) {
if (!mFlingProfilingStarted) {
@@ -3766,7 +3774,7 @@
if (mScroller.springBack(0, mScrollY, 0, 0, 0, 0)) {
mTouchMode = TOUCH_MODE_OVERFLING;
invalidate();
- post(this);
+ postOnAnimation(this);
} else {
mTouchMode = TOUCH_MODE_REST;
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
@@ -3778,7 +3786,7 @@
Integer.MIN_VALUE, Integer.MAX_VALUE, 0, getHeight());
mTouchMode = TOUCH_MODE_OVERFLING;
invalidate();
- post(this);
+ postOnAnimation(this);
}
void edgeReached(int delta) {
@@ -3800,7 +3808,7 @@
}
}
invalidate();
- post(this);
+ postOnAnimation(this);
}
void startScroll(int distance, int duration) {
@@ -3808,7 +3816,7 @@
mLastFlingY = initialY;
mScroller.startScroll(0, initialY, 0, distance, duration);
mTouchMode = TOUCH_MODE_FLING;
- post(this);
+ postOnAnimation(this);
}
void endFling() {
@@ -3907,7 +3915,7 @@
if (more && !atEnd) {
if (atEdge) invalidate();
mLastFlingY = y;
- post(this);
+ postOnAnimation(this);
} else {
endFling();
@@ -3948,7 +3956,7 @@
}
} else {
invalidate();
- post(this);
+ postOnAnimation(this);
}
} else {
endFling();
@@ -3959,7 +3967,6 @@
}
}
-
class PositionScroller implements Runnable {
private static final int SCROLL_DURATION = 400;
@@ -4009,7 +4016,7 @@
mBoundPos = INVALID_POSITION;
mLastSeenPos = INVALID_POSITION;
- post(this);
+ postOnAnimation(this);
}
void start(int position, int boundPosition) {
@@ -4070,7 +4077,7 @@
mBoundPos = boundPosition;
mLastSeenPos = INVALID_POSITION;
- post(this);
+ postOnAnimation(this);
}
void startWithOffset(int position, int offset) {
@@ -4080,6 +4087,8 @@
void startWithOffset(int position, int offset, int duration) {
stop();
+ offset += getPaddingTop();
+
mTargetPos = position;
mOffsetFromTop = offset;
mBoundPos = INVALID_POSITION;
@@ -4108,7 +4117,7 @@
(int) (duration / screenTravelCount);
mLastSeenPos = INVALID_POSITION;
- post(this);
+ postOnAnimation(this);
}
void stop() {
@@ -4116,10 +4125,6 @@
}
public void run() {
- if (mTouchMode != TOUCH_MODE_FLING && mLastSeenPos != INVALID_POSITION) {
- return;
- }
-
final int listHeight = getHeight();
final int firstPos = mFirstPosition;
@@ -4134,7 +4139,7 @@
if (lastPos == mLastSeenPos) {
// No new views, let things keep going.
- post(this);
+ postOnAnimation(this);
return;
}
@@ -4142,14 +4147,15 @@
final int lastViewHeight = lastView.getHeight();
final int lastViewTop = lastView.getTop();
final int lastViewPixelsShowing = listHeight - lastViewTop;
- final int extraScroll = lastPos < mItemCount - 1 ? mExtraScroll : mListPadding.bottom;
+ final int extraScroll = lastPos < mItemCount - 1 ?
+ Math.max(mListPadding.bottom, mExtraScroll) : mListPadding.bottom;
- smoothScrollBy(lastViewHeight - lastViewPixelsShowing + extraScroll,
- mScrollDuration);
+ final int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll;
+ smoothScrollBy(scrollBy, mScrollDuration);
mLastSeenPos = lastPos;
if (lastPos < mTargetPos) {
- post(this);
+ postOnAnimation(this);
}
break;
}
@@ -4166,21 +4172,21 @@
if (nextPos == mLastSeenPos) {
// No new views, let things keep going.
- post(this);
+ postOnAnimation(this);
return;
}
final View nextView = getChildAt(nextViewIndex);
final int nextViewHeight = nextView.getHeight();
final int nextViewTop = nextView.getTop();
- final int extraScroll = mExtraScroll;
+ final int extraScroll = Math.max(mListPadding.bottom, mExtraScroll);
if (nextPos < mBoundPos) {
smoothScrollBy(Math.max(0, nextViewHeight + nextViewTop - extraScroll),
mScrollDuration);
mLastSeenPos = nextPos;
- post(this);
+ postOnAnimation(this);
} else {
if (nextViewTop > extraScroll) {
smoothScrollBy(nextViewTop - extraScroll, mScrollDuration);
@@ -4192,7 +4198,7 @@
case MOVE_UP_POS: {
if (firstPos == mLastSeenPos) {
// No new views, let things keep going.
- post(this);
+ postOnAnimation(this);
return;
}
@@ -4201,14 +4207,15 @@
return;
}
final int firstViewTop = firstView.getTop();
- final int extraScroll = firstPos > 0 ? mExtraScroll : mListPadding.top;
+ final int extraScroll = firstPos > 0 ?
+ Math.max(mExtraScroll, mListPadding.top) : mListPadding.top;
smoothScrollBy(firstViewTop - extraScroll, mScrollDuration);
mLastSeenPos = firstPos;
if (firstPos > mTargetPos) {
- post(this);
+ postOnAnimation(this);
}
break;
}
@@ -4230,12 +4237,13 @@
final int lastViewHeight = lastView.getHeight();
final int lastViewTop = lastView.getTop();
final int lastViewPixelsShowing = listHeight - lastViewTop;
+ final int extraScroll = Math.max(mListPadding.top, mExtraScroll);
mLastSeenPos = lastPos;
if (lastPos > mBoundPos) {
- smoothScrollBy(-(lastViewPixelsShowing - mExtraScroll), mScrollDuration);
- post(this);
+ smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration);
+ postOnAnimation(this);
} else {
- final int bottom = listHeight - mExtraScroll;
+ final int bottom = listHeight - extraScroll;
final int lastViewBottom = lastViewTop + lastViewHeight;
if (bottom > lastViewBottom) {
smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration);
@@ -4270,10 +4278,10 @@
final float modifier = Math.min(Math.abs(screenTravelCount), 1.f);
if (position < firstPos) {
smoothScrollBy((int) (-getHeight() * modifier), mScrollDuration);
- post(this);
+ postOnAnimation(this);
} else if (position > lastPos) {
smoothScrollBy((int) (getHeight() * modifier), mScrollDuration);
- post(this);
+ postOnAnimation(this);
} else {
// On-screen, just scroll.
final int targetTop = getChildAt(position - firstPos).getTop();
@@ -4620,7 +4628,7 @@
// invalidate before moving the children to avoid unnecessary invalidate
// calls to bubble up from the children all the way to the top
if (!awakenScrollBars()) {
- invalidate();
+ invalidate();
}
offsetChildrenTopAndBottom(incrementalDeltaY);
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index ca5648a..ae68794 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -123,7 +123,7 @@
invalidate();
if (needUpdate) {
updateThumbPos(getWidth(), getHeight());
- if (thumb.isStateful()) {
+ if (thumb != null && thumb.isStateful()) {
// Note that if the states are different this won't work.
// For now, let's consider that an app bug.
int[] state = getDrawableState();
diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java
index bc44521..c53b5f6 100644
--- a/core/java/android/widget/ActivityChooserModel.java
+++ b/core/java/android/widget/ActivityChooserModel.java
@@ -365,7 +365,7 @@
} else {
mHistoryFileName = historyFileName;
}
- mPackageMonitor.register(mContext, true);
+ mPackageMonitor.register(mContext, null, true);
}
/**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 040a385..22e22be 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -151,6 +151,7 @@
boolean mShowErrorAfterAttach;
boolean mInBatchEditControllers;
+ boolean mShowSoftInputOnFocus = true;
SuggestionsPopupWindow mSuggestionsPopupWindow;
SuggestionRangeSpan mSuggestionRangeSpan;
@@ -1241,24 +1242,21 @@
}
DynamicLayout dynamicLayout = (DynamicLayout) layout;
- int[] blockEnds = dynamicLayout.getBlockEnds();
+ int[] blockEndLines = dynamicLayout.getBlockEndLines();
int[] blockIndices = dynamicLayout.getBlockIndices();
final int numberOfBlocks = dynamicLayout.getNumberOfBlocks();
- final int mScrollX = mTextView.getScrollX();
- final int mScrollY = mTextView.getScrollY();
- canvas.translate(mScrollX, mScrollY);
int endOfPreviousBlock = -1;
int searchStartIndex = 0;
for (int i = 0; i < numberOfBlocks; i++) {
- int blockEnd = blockEnds[i];
+ int blockEndLine = blockEndLines[i];
int blockIndex = blockIndices[i];
final boolean blockIsInvalid = blockIndex == DynamicLayout.INVALID_BLOCK_INDEX;
if (blockIsInvalid) {
blockIndex = getAvailableDisplayListIndex(blockIndices, numberOfBlocks,
searchStartIndex);
- // Dynamic layout internal block indices structure is updated from Editor
+ // Note how dynamic layout's internal block indices get updated from Editor
blockIndices[i] = blockIndex;
searchStartIndex = blockIndex + 1;
}
@@ -1272,28 +1270,36 @@
}
if (!blockDisplayList.isValid()) {
+ final int blockBeginLine = endOfPreviousBlock + 1;
+ final int top = layout.getLineTop(blockBeginLine);
+ final int bottom = layout.getLineBottom(blockEndLine);
+
final HardwareCanvas hardwareCanvas = blockDisplayList.start();
try {
- hardwareCanvas.setViewport(width, height);
+ hardwareCanvas.setViewport(width, bottom - top);
// The dirty rect should always be null for a display list
hardwareCanvas.onPreDraw(null);
- hardwareCanvas.translate(-mScrollX, -mScrollY);
- layout.drawText(hardwareCanvas, endOfPreviousBlock + 1, blockEnd);
- hardwareCanvas.translate(mScrollX, mScrollY);
+ // drawText is always relative to TextView's origin, this translation brings
+ // this range of text back to the top of the viewport
+ hardwareCanvas.translate(0, -top);
+ layout.drawText(hardwareCanvas, blockBeginLine, blockEndLine);
+ hardwareCanvas.translate(0, top);
} finally {
hardwareCanvas.onPostDraw();
blockDisplayList.end();
- if (View.USE_DISPLAY_LIST_PROPERTIES) {
- blockDisplayList.setLeftTopRightBottom(0, 0, width, height);
- }
+ blockDisplayList.setLeftTopRightBottom(0, top, width, bottom);
+ // Same as drawDisplayList below, handled by our TextView's parent
+ blockDisplayList.setClipChildren(false);
}
}
- ((HardwareCanvas) canvas).drawDisplayList(blockDisplayList, width, height, null,
- DisplayList.FLAG_CLIP_CHILDREN);
- endOfPreviousBlock = blockEnd;
+ // TODO When View.USE_DISPLAY_LIST_PROPERTIES is the only code path, the
+ // width and height parameters should be removed and the bounds set above in
+ // setLeftTopRightBottom should be used instead for quick rejection.
+ ((HardwareCanvas) canvas).drawDisplayList(blockDisplayList, null,
+ 0 /* no child clipping, our TextView parent enforces it */);
+ endOfPreviousBlock = blockEndLine;
}
- canvas.translate(-mScrollX, -mScrollY);
} else {
// Boring layout is used for empty and hint text
layout.drawText(canvas, firstLine, lastLine);
@@ -1332,6 +1338,38 @@
if (translate) canvas.translate(0, -cursorOffsetVertical);
}
+ /**
+ * Invalidates all the sub-display lists that overlap the specified character range
+ */
+ void invalidateTextDisplayList(Layout layout, int start, int end) {
+ if (mTextDisplayLists != null && layout instanceof DynamicLayout) {
+ final int firstLine = layout.getLineForOffset(start);
+ final int lastLine = layout.getLineForOffset(end);
+
+ DynamicLayout dynamicLayout = (DynamicLayout) layout;
+ int[] blockEndLines = dynamicLayout.getBlockEndLines();
+ int[] blockIndices = dynamicLayout.getBlockIndices();
+ final int numberOfBlocks = dynamicLayout.getNumberOfBlocks();
+
+ int i = 0;
+ // Skip the blocks before firstLine
+ while (i < numberOfBlocks) {
+ if (blockEndLines[i] >= firstLine) break;
+ i++;
+ }
+
+ // Invalidate all subsequent blocks until lastLine is passed
+ while (i < numberOfBlocks) {
+ final int blockIndex = blockIndices[i];
+ if (blockIndex != DynamicLayout.INVALID_BLOCK_INDEX) {
+ mTextDisplayLists[blockIndex].invalidate();
+ }
+ if (blockEndLines[i] >= lastLine) break;
+ i++;
+ }
+ }
+ }
+
void invalidateTextDisplayList() {
if (mTextDisplayLists != null) {
for (int i = 0; i < mTextDisplayLists.length; i++) {
@@ -1400,7 +1438,7 @@
}
final boolean selectionStarted = mSelectionActionMode != null || willExtract;
- if (selectionStarted && !mTextView.isTextSelectable()) {
+ if (selectionStarted && !mTextView.isTextSelectable() && mShowSoftInputOnFocus) {
// Show the IME to be able to replace text, except when selecting non editable text.
final InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null) {
@@ -1572,11 +1610,9 @@
}
void onScrollChanged() {
- if (mPositionListener != null) {
- mPositionListener.onScrollChanged();
- }
- // Internal scroll affects the clip boundaries
- invalidateTextDisplayList();
+ if (mPositionListener != null) {
+ mPositionListener.onScrollChanged();
+ }
}
/**
@@ -2545,6 +2581,7 @@
// There is no way to know if the word was indeed added. Re-check.
// TODO The ExtractEditText should remove the span in the original text instead
editable.removeSpan(suggestionInfo.suggestionSpan);
+ Selection.setSelection(editable, spanEnd);
updateSpellCheckSpans(spanStart, spanEnd, false);
} else {
// SuggestionSpans are removed by replace: save them before
diff --git a/core/java/android/widget/ExpandableListConnector.java b/core/java/android/widget/ExpandableListConnector.java
index 2ff6b70..bda64ba 100644
--- a/core/java/android/widget/ExpandableListConnector.java
+++ b/core/java/android/widget/ExpandableListConnector.java
@@ -372,7 +372,8 @@
@Override
public boolean isEnabled(int flatListPos) {
- final ExpandableListPosition pos = getUnflattenedPos(flatListPos).position;
+ final PositionMetadata metadata = getUnflattenedPos(flatListPos);
+ final ExpandableListPosition pos = metadata.position;
boolean retValue;
if (pos.type == ExpandableListPosition.CHILD) {
@@ -382,7 +383,7 @@
retValue = true;
}
- pos.recycle();
+ metadata.recycle();
return retValue;
}
@@ -461,7 +462,8 @@
@Override
public int getItemViewType(int flatListPos) {
- final ExpandableListPosition pos = getUnflattenedPos(flatListPos).position;
+ final PositionMetadata metadata = getUnflattenedPos(flatListPos);
+ final ExpandableListPosition pos = metadata.position;
int retValue;
if (mExpandableListAdapter instanceof HeterogeneousExpandableList) {
@@ -481,7 +483,7 @@
}
}
- pos.recycle();
+ metadata.recycle();
return retValue;
}
@@ -590,8 +592,10 @@
* @param groupPos position of the group to collapse
*/
boolean collapseGroup(int groupPos) {
- PositionMetadata pm = getFlattenedPos(ExpandableListPosition.obtain(
- ExpandableListPosition.GROUP, groupPos, -1, -1));
+ ExpandableListPosition elGroupPos = ExpandableListPosition.obtain(
+ ExpandableListPosition.GROUP, groupPos, -1, -1);
+ PositionMetadata pm = getFlattenedPos(elGroupPos);
+ elGroupPos.recycle();
if (pm == null) return false;
boolean retValue = collapseGroup(pm);
@@ -631,8 +635,10 @@
* @param groupPos the group to be expanded
*/
boolean expandGroup(int groupPos) {
- PositionMetadata pm = getFlattenedPos(ExpandableListPosition.obtain(
- ExpandableListPosition.GROUP, groupPos, -1, -1));
+ ExpandableListPosition elGroupPos = ExpandableListPosition.obtain(
+ ExpandableListPosition.GROUP, groupPos, -1, -1);
+ PositionMetadata pm = getFlattenedPos(elGroupPos);
+ elGroupPos.recycle();
boolean retValue = expandGroup(pm);
pm.recycle();
return retValue;
@@ -971,7 +977,10 @@
public int groupInsertIndex;
private void resetState() {
- position = null;
+ if (position != null) {
+ position.recycle();
+ position = null;
+ }
groupMetadata = null;
groupInsertIndex = 0;
}
@@ -1005,6 +1014,7 @@
}
public void recycle() {
+ resetState();
synchronized (sPool) {
if (sPool.size() < MAX_POOL_SIZE) {
sPool.add(this);
diff --git a/core/java/android/widget/ExpandableListPosition.java b/core/java/android/widget/ExpandableListPosition.java
index e8d6113..bb68da6 100644
--- a/core/java/android/widget/ExpandableListPosition.java
+++ b/core/java/android/widget/ExpandableListPosition.java
@@ -125,6 +125,10 @@
return elp;
}
+ /**
+ * Do not call this unless you obtained this via ExpandableListPosition.obtain().
+ * PositionMetadata will handle recycling its own children.
+ */
public void recycle() {
synchronized (sPool) {
if (sPool.size() < MAX_POOL_SIZE) {
diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java
index c2d8bda..a746370 100644
--- a/core/java/android/widget/ExpandableListView.java
+++ b/core/java/android/widget/ExpandableListView.java
@@ -326,7 +326,6 @@
indicator.draw(canvas);
}
}
-
pos.recycle();
}
@@ -613,8 +612,10 @@
* was already expanded, this will return false)
*/
public boolean expandGroup(int groupPos, boolean animate) {
- PositionMetadata pm = mConnector.getFlattenedPos(ExpandableListPosition.obtain(
- ExpandableListPosition.GROUP, groupPos, -1, -1));
+ ExpandableListPosition elGroupPos = ExpandableListPosition.obtain(
+ ExpandableListPosition.GROUP, groupPos, -1, -1);
+ PositionMetadata pm = mConnector.getFlattenedPos(elGroupPos);
+ elGroupPos.recycle();
boolean retValue = mConnector.expandGroup(pm);
if (mOnGroupExpandListener != null) {
@@ -776,8 +777,10 @@
* @return The flat list position for the given child or group.
*/
public int getFlatListPosition(long packedPosition) {
- PositionMetadata pm = mConnector.getFlattenedPos(ExpandableListPosition
- .obtainPosition(packedPosition));
+ ExpandableListPosition elPackedPos = ExpandableListPosition
+ .obtainPosition(packedPosition);
+ PositionMetadata pm = mConnector.getFlattenedPos(elPackedPos);
+ elPackedPos.recycle();
final int flatListPosition = pm.position.flatListPos;
pm.recycle();
return getAbsoluteFlatPosition(flatListPosition);
@@ -988,11 +991,11 @@
final int adjustedPosition = getFlatPositionForConnector(flatListPosition);
PositionMetadata pm = mConnector.getUnflattenedPos(adjustedPosition);
ExpandableListPosition pos = pm.position;
- pm.recycle();
id = getChildOrGroupId(pos);
long packedPosition = pos.getPackedPosition();
- pos.recycle();
+
+ pm.recycle();
return new ExpandableListContextMenuInfo(view, packedPosition, id);
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 0f1dab5..0a40d5e 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1463,6 +1463,9 @@
mResurrectToPosition = position;
}
mLayoutMode = LAYOUT_SET_SELECTION;
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
requestLayout();
}
@@ -1475,6 +1478,10 @@
void setSelectionInt(int position) {
int previousSelectedPosition = mNextSelectedPosition;
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+
setNextSelectedPositionInt(position);
layoutChildren();
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 6c7ea67..7593bff 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -200,26 +200,8 @@
}
@Override
- protected boolean onSetAlpha(int alpha) {
- if (!USE_DISPLAY_LIST_PROPERTIES && getBackground() == null) {
- int scale = alpha + (alpha >> 7);
- if (mViewAlphaScale != scale) {
- mViewAlphaScale = scale;
- mColorMod = true;
- applyColorMod();
- }
- return true;
- }
- return false;
- }
-
- @Override
public boolean hasOverlappingRendering() {
- if (!USE_DISPLAY_LIST_PROPERTIES) {
- return super.hasOverlappingRendering();
- } else {
- return (getBackground() != null);
- }
+ return (getBackground() != null);
}
@Override
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 71700b3..5098523 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1926,6 +1926,9 @@
mSyncRowId = mAdapter.getItemId(position);
}
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
requestLayout();
}
}
@@ -1950,6 +1953,10 @@
}
}
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+
layoutChildren();
if (awakeScrollbars) {
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 992849d..11d1ed0 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -26,6 +26,7 @@
import android.graphics.Paint.Align;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
@@ -2068,7 +2069,7 @@
}
@Override
- public boolean performAccessibilityAction(int action, int virtualViewId) {
+ public boolean performAction(int virtualViewId, int action, Bundle arguments) {
switch (virtualViewId) {
case VIRTUAL_VIEW_ID_INPUT: {
switch (action) {
@@ -2086,7 +2087,7 @@
}
} break;
}
- return super.performAccessibilityAction(action, virtualViewId);
+ return super.performAction(virtualViewId, action, arguments);
}
public void sendAccessibilityEventForVirtualView(int virtualViewId, int eventType) {
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index e188207..02cb46b 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -24,6 +24,7 @@
import android.text.method.WordIterator;
import android.text.style.SpellCheckSpan;
import android.text.style.SuggestionSpan;
+import android.util.Log;
import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SpellCheckerSession;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
@@ -43,6 +44,8 @@
* @hide
*/
public class SpellChecker implements SpellCheckerSessionListener {
+ private static final String TAG = SpellChecker.class.getSimpleName();
+ private static final boolean DBG = false;
// No more than this number of words will be parsed on each iteration to ensure a minimum
// lock of the UI thread
@@ -57,6 +60,8 @@
// Pause between each spell check to keep the UI smooth
private final static int SPELL_PAUSE_DURATION = 400; // milliseconds
+ private static final int MIN_SENTENCE_LENGTH = 50;
+
private static final int USE_SPAN_RANGE = -1;
private final TextView mTextView;
@@ -266,6 +271,12 @@
editable.subSequence(start, end).toString();
spellCheckSpan.setSpellCheckInProgress(true);
textInfos[textInfosCount++] = new TextInfo(word, mCookie, mIds[i]);
+ if (DBG) {
+ Log.d(TAG, "create TextInfo: (" + i + "/" + mLength + ")" + word
+ + ", cookie = " + mCookie + ", seq = "
+ + mIds[i] + ", sel start = " + selectionStart + ", sel end = "
+ + selectionEnd + ", start = " + start + ", end = " + end);
+ }
}
}
@@ -499,15 +510,28 @@
if (wordEnd < start) {
return;
}
- wordStart = regionEnd;
// TODO: Find the start position of the sentence.
// Set span with the context
final int spellCheckStart = Math.max(
- 0, Math.min(wordStart, regionEnd - WORD_ITERATOR_INTERVAL));
+ 0, Math.min(wordStart, regionEnd - MIN_SENTENCE_LENGTH));
if (regionEnd <= spellCheckStart) {
return;
}
- addSpellCheckSpan(editable, spellCheckStart, regionEnd);
+ final int selectionStart = Selection.getSelectionStart(editable);
+ final int selectionEnd = Selection.getSelectionEnd(editable);
+ if (DBG) {
+ Log.d(TAG, "addSpellCheckSpan: "
+ + editable.subSequence(spellCheckStart, regionEnd)
+ + ", regionEnd = " + regionEnd + ", spellCheckStart = "
+ + spellCheckStart + ", sel start = " + selectionStart + ", sel end ="
+ + selectionEnd);
+ }
+ // Do not check this word if the user is currently editing it
+ if (spellCheckStart >= 0 && regionEnd > spellCheckStart
+ && (selectionEnd < spellCheckStart || selectionStart > regionEnd)) {
+ addSpellCheckSpan(editable, spellCheckStart, regionEnd);
+ }
+ wordStart = regionEnd;
} else {
while (wordStart <= end) {
if (wordEnd >= start && wordEnd > wordStart) {
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 0786909..471f259 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -29,6 +29,8 @@
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
+import android.text.method.AllCapsTransformationMethod;
+import android.text.method.TransformationMethod2;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
@@ -91,6 +93,7 @@
private ColorStateList mTextColors;
private Layout mOnLayout;
private Layout mOffLayout;
+ private TransformationMethod2 mSwitchTransformationMethod;
@SuppressWarnings("hiding")
private final Rect mTempRect = new Rect();
@@ -207,6 +210,15 @@
setSwitchTypefaceByIndex(typefaceIndex, styleIndex);
+ boolean allCaps = appearance.getBoolean(com.android.internal.R.styleable.
+ TextAppearance_textAllCaps, false);
+ if (allCaps) {
+ mSwitchTransformationMethod = new AllCapsTransformationMethod(getContext());
+ mSwitchTransformationMethod.setLengthChangesAllowed(true);
+ } else {
+ mSwitchTransformationMethod = null;
+ }
+
appearance.recycle();
}
@@ -526,8 +538,12 @@
}
private Layout makeLayout(CharSequence text) {
- return new StaticLayout(text, mTextPaint,
- (int) Math.ceil(Layout.getDesiredWidth(text, mTextPaint)),
+ final CharSequence transformed = (mSwitchTransformationMethod != null)
+ ? mSwitchTransformationMethod.getTransformation(text, this)
+ : text;
+
+ return new StaticLayout(transformed, mTextPaint,
+ (int) Math.ceil(Layout.getDesiredWidth(transformed, mTextPaint)),
Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 37d9db7..f452973 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -261,8 +261,6 @@
// System wide time for last cut or copy action.
static long LAST_CUT_OR_COPY_TIME;
- private int mCurrentAlpha = 255;
-
private ColorStateList mTextColor;
private ColorStateList mHintTextColor;
private ColorStateList mLinkTextColor;
@@ -2314,6 +2312,27 @@
}
/**
+ * Sets whether the soft input method will be made visible when this
+ * TextView gets focused. The default is true.
+ * @hide
+ */
+ @android.view.RemotableViewMethod
+ public final void setShowSoftInputOnFocus(boolean show) {
+ createEditorIfNeeded("setShowSoftInputOnFocus");
+ mEditor.mShowSoftInputOnFocus = show;
+ }
+
+ /**
+ * Returns whether the soft input method will be made visible when this
+ * TextView gets focused. The default is true.
+ * @hide
+ */
+ public final boolean getShowSoftInputOnFocus() {
+ // When there is no Editor, return default true value
+ return mEditor == null || mEditor.mShowSoftInputOnFocus;
+ }
+
+ /**
* Gives the text a shadow of the specified radius and color, the specified
* distance from its normal position.
*
@@ -4270,41 +4289,8 @@
}
@Override
- protected boolean onSetAlpha(int alpha) {
- // Alpha is supported if and only if the drawing can be done in one pass.
- // TODO text with spans with a background color currently do not respect this alpha.
- if (!USE_DISPLAY_LIST_PROPERTIES &&
- (getBackground() != null || mText instanceof Spannable || hasSelection())) {
- if (mCurrentAlpha != alpha) {
- mCurrentAlpha = alpha;
- final Drawables dr = mDrawables;
- if (dr != null) {
- if (dr.mDrawableLeft != null) dr.mDrawableLeft.mutate().setAlpha(alpha);
- if (dr.mDrawableTop != null) dr.mDrawableTop.mutate().setAlpha(alpha);
- if (dr.mDrawableRight != null) dr.mDrawableRight.mutate().setAlpha(alpha);
- if (dr.mDrawableBottom != null) dr.mDrawableBottom.mutate().setAlpha(alpha);
- if (dr.mDrawableStart != null) dr.mDrawableStart.mutate().setAlpha(alpha);
- if (dr.mDrawableEnd != null) dr.mDrawableEnd.mutate().setAlpha(alpha);
- }
- if (mEditor != null) getEditor().invalidateTextDisplayList();
- }
- return true;
- }
-
- if (mCurrentAlpha != 255) {
- if (mEditor != null) getEditor().invalidateTextDisplayList();
- }
- mCurrentAlpha = 255;
- return false;
- }
-
- @Override
public boolean hasOverlappingRendering() {
- if (!USE_DISPLAY_LIST_PROPERTIES) {
- return super.hasOverlappingRendering();
- } else {
- return (getBackground() != null || mText instanceof Spannable || hasSelection());
- }
+ return (getBackground() != null || mText instanceof Spannable || hasSelection());
}
/**
@@ -4412,10 +4398,6 @@
// XXX should pass to skin instead of drawing directly
highlightPaint.setColor(mCurTextColor);
- if (mCurrentAlpha != 255) {
- highlightPaint.setAlpha(
- (mCurrentAlpha * Color.alpha(mCurTextColor)) / 255);
- }
highlightPaint.setStyle(Paint.Style.STROKE);
highlight = mHighlightPath;
}
@@ -4429,10 +4411,6 @@
// XXX should pass to skin instead of drawing directly
highlightPaint.setColor(mHighlightColor);
- if (mCurrentAlpha != 255) {
- highlightPaint.setAlpha(
- (mCurrentAlpha * Color.alpha(mHighlightColor)) / 255);
- }
highlightPaint.setStyle(Paint.Style.FILL);
highlight = mHighlightPath;
@@ -4443,8 +4421,6 @@
@Override
protected void onDraw(Canvas canvas) {
- if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return;
-
restartMarqueeIfNeeded();
// Draw the background for this view
@@ -4531,10 +4507,6 @@
}
mTextPaint.setColor(color);
- if (mCurrentAlpha != 255) {
- // If set, the alpha will override the color's alpha. Multiply the alphas.
- mTextPaint.setAlpha((mCurrentAlpha * Color.alpha(color)) / 255);
- }
mTextPaint.drawableState = getDrawableState();
canvas.save();
@@ -5030,7 +5002,7 @@
&& mLayout != null && onCheckIsTextEditor()) {
InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
- if (imm != null) {
+ if (imm != null && getShowSoftInputOnFocus()) {
imm.showSoftInput(this, 0);
}
}
@@ -6860,7 +6832,10 @@
} else {
ims.mContentChanged = true;
}
- if (mEditor != null) getEditor().invalidateTextDisplayList();
+ if (mEditor != null) {
+ if (oldStart >= 0) getEditor().invalidateTextDisplayList(mLayout, oldStart, oldEnd);
+ if (newStart >= 0) getEditor().invalidateTextDisplayList(mLayout, newStart, newEnd);
+ }
}
if (MetaKeyKeyListener.isMetaTracker(buf, what)) {
@@ -7060,7 +7035,7 @@
// Show the IME, except when selecting in read-only text.
final InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
- if (!textIsSelectable) {
+ if (!textIsSelectable && mEditor.mShowSoftInputOnFocus) {
handled |= imm != null && imm.showSoftInput(this, 0);
}
@@ -7135,7 +7110,6 @@
@Override
protected float getLeftFadingEdgeStrength() {
- if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return 0.0f;
if (mEllipsize == TextUtils.TruncateAt.MARQUEE &&
mMarqueeFadeMode != MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) {
if (mMarquee != null && !mMarquee.isStopped()) {
@@ -7165,7 +7139,6 @@
@Override
protected float getRightFadingEdgeStrength() {
- if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return 0.0f;
if (mEllipsize == TextUtils.TruncateAt.MARQUEE &&
mMarqueeFadeMode != MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) {
if (mMarquee != null && !mMarquee.isStopped()) {
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 1ba6d43..d0071e3 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -16,6 +16,7 @@
package com.android.internal.app;
+import com.android.internal.view.ActionBarPolicy;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuPopupHelper;
import com.android.internal.view.menu.SubMenuBuilder;
@@ -183,18 +184,13 @@
mContextDisplayMode = mActionView.isSplitActionBar() ?
CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL;
- // Older apps get the home button interaction enabled by default.
- // Newer apps need to enable it explicitly.
- setHomeButtonEnabled(mContext.getApplicationInfo().targetSdkVersion <
- Build.VERSION_CODES.ICE_CREAM_SANDWICH);
-
- setHasEmbeddedTabs(mContext.getResources().getBoolean(
- com.android.internal.R.bool.action_bar_embed_tabs));
+ ActionBarPolicy abp = ActionBarPolicy.get(mContext);
+ setHomeButtonEnabled(abp.enableHomeButtonByDefault());
+ setHasEmbeddedTabs(abp.hasEmbeddedTabs());
}
public void onConfigurationChanged(Configuration newConfig) {
- setHasEmbeddedTabs(mContext.getResources().getBoolean(
- com.android.internal.R.bool.action_bar_embed_tabs));
+ setHasEmbeddedTabs(ActionBarPolicy.get(mContext).hasEmbeddedTabs());
}
private void setHasEmbeddedTabs(boolean hasEmbeddedTabs) {
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index d407080..4322a20 100755
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -32,4 +32,6 @@
boolean checkExternalFreeStorage(in Uri fileUri);
ObbInfo getObbInfo(in String filename);
long calculateDirectorySize(in String directory);
+ /** Return file system stats: [0] is total bytes, [1] is available bytes */
+ long[] getFileSystemStats(in String path);
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index af722a8..5862d3e 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -99,7 +99,7 @@
ap.mTitle = title;
ap.mOnClickListener = this;
- mPackageMonitor.register(this, false);
+ mPackageMonitor.register(this, getMainLooper(), false);
if (alwaysUseOption) {
LayoutInflater inflater = (LayoutInflater) getSystemService(
@@ -135,7 +135,7 @@
@Override
protected void onRestart() {
super.onRestart();
- mPackageMonitor.register(this, false);
+ mPackageMonitor.register(this, getMainLooper(), false);
mAdapter.handlePackagesChanged();
}
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index 6a46929..d867ff9 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -24,6 +24,8 @@
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetooth;
+import android.nfc.NfcAdapter;
+import android.nfc.INfcAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@@ -48,7 +50,7 @@
public final class ShutdownThread extends Thread {
// constants
private static final String TAG = "ShutdownThread";
- private static final int MAX_NUM_PHONE_STATE_READS = 16;
+ private static final int MAX_NUM_PHONE_STATE_READS = 24;
private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500;
// maximum time we wait for the shutdown broadcast before going on.
private static final int MAX_BROADCAST_TIME = 10*1000;
@@ -62,11 +64,15 @@
private static boolean sIsStarted = false;
private static boolean mReboot;
+ private static boolean mRebootSafeMode;
private static String mRebootReason;
// Provides shutdown assurance in case the system_server is killed
public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested";
+ // Indicates whether we are rebooting into safe mode
+ public static final String REBOOT_SAFEMODE_PROPERTY = "persist.sys.safemode";
+
// static instance of this thread
private static final ShutdownThread sInstance = new ShutdownThread();
@@ -90,6 +96,12 @@
* @param confirm true if user confirmation is needed before shutting down.
*/
public static void shutdown(final Context context, boolean confirm) {
+ mReboot = false;
+ mRebootSafeMode = false;
+ shutdownInner(context, confirm);
+ }
+
+ static void shutdownInner(final Context context, boolean confirm) {
// ensure that only one thread is trying to power down.
// any additional calls are just returned
synchronized (sIsStartedGuard) {
@@ -101,16 +113,20 @@
final int longPressBehavior = context.getResources().getInteger(
com.android.internal.R.integer.config_longPressOnPowerBehavior);
- final int resourceId = longPressBehavior == 2
- ? com.android.internal.R.string.shutdown_confirm_question
- : com.android.internal.R.string.shutdown_confirm;
+ final int resourceId = mRebootSafeMode
+ ? com.android.internal.R.string.reboot_safemode_confirm
+ : (longPressBehavior == 2
+ ? com.android.internal.R.string.shutdown_confirm_question
+ : com.android.internal.R.string.shutdown_confirm);
Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
if (confirm) {
final CloseDialogReceiver closer = new CloseDialogReceiver(context);
final AlertDialog dialog = new AlertDialog.Builder(context)
- .setTitle(com.android.internal.R.string.power_off)
+ .setTitle(mRebootSafeMode
+ ? com.android.internal.R.string.reboot_safemode_title
+ : com.android.internal.R.string.power_off)
.setMessage(resourceId)
.setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
@@ -160,8 +176,23 @@
*/
public static void reboot(final Context context, String reason, boolean confirm) {
mReboot = true;
+ mRebootSafeMode = false;
mRebootReason = reason;
- shutdown(context, confirm);
+ shutdownInner(context, confirm);
+ }
+
+ /**
+ * Request a reboot into safe mode. Must be called from a Looper thread in which its UI
+ * is shown.
+ *
+ * @param context Context used to display the shutdown progress dialog.
+ * @param confirm true if user confirmation is needed before shutting down.
+ */
+ public static void rebootSafeMode(final Context context, boolean confirm) {
+ mReboot = true;
+ mRebootSafeMode = true;
+ mRebootReason = null;
+ shutdownInner(context, confirm);
}
private static void beginShutdownSequence(Context context) {
@@ -231,6 +262,7 @@
* Shuts off power regardless of radio and bluetooth state if the alloted time has passed.
*/
public void run() {
+ boolean nfcOff;
boolean bluetoothOff;
boolean radioOff;
@@ -251,6 +283,14 @@
SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
}
+ /*
+ * If we are rebooting into safe mode, write a system property
+ * indicating so.
+ */
+ if (mRebootSafeMode) {
+ SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1");
+ }
+
Log.i(TAG, "Sending shutdown broadcast...");
// First send the high-level shut down broadcast.
@@ -284,16 +324,29 @@
}
}
+ final INfcAdapter nfc =
+ INfcAdapter.Stub.asInterface(ServiceManager.checkService("nfc"));
final ITelephony phone =
ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
final IBluetooth bluetooth =
IBluetooth.Stub.asInterface(ServiceManager.checkService(
BluetoothAdapter.BLUETOOTH_SERVICE));
-
final IMountService mount =
IMountService.Stub.asInterface(
ServiceManager.checkService("mount"));
-
+
+ try {
+ nfcOff = nfc == null ||
+ nfc.getState() == NfcAdapter.STATE_OFF;
+ if (!nfcOff) {
+ Log.w(TAG, "Turning off NFC...");
+ nfc.disable(false); // Don't persist new state
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during NFC shutdown", ex);
+ nfcOff = true;
+ }
+
try {
bluetoothOff = bluetooth == null ||
bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
@@ -317,7 +370,7 @@
radioOff = true;
}
- Log.i(TAG, "Waiting for Bluetooth and Radio...");
+ Log.i(TAG, "Waiting for NFC, Bluetooth and Radio...");
// Wait a max of 32 seconds for clean shutdown
for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) {
@@ -338,8 +391,17 @@
radioOff = true;
}
}
- if (radioOff && bluetoothOff) {
- Log.i(TAG, "Radio and Bluetooth shutdown complete.");
+ if (!nfcOff) {
+ try {
+ nfcOff = nfc.getState() == NfcAdapter.STATE_OFF;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during NFC shutdown", ex);
+ nfcOff = true;
+ }
+ }
+
+ if (radioOff && bluetoothOff && nfcOff) {
+ Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete.");
break;
}
SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index fa0873d..b1b57e7 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -20,6 +20,7 @@
import android.content.Intent;
import android.appwidget.AppWidgetProviderInfo;
import com.android.internal.appwidget.IAppWidgetHost;
+import android.os.Bundle;
import android.os.IBinder;
import android.widget.RemoteViews;
@@ -42,6 +43,8 @@
// for AppWidgetManager
//
void updateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views);
+ void updateAppWidgetExtras(int appWidgetId, in Bundle extras);
+ Bundle getAppWidgetExtras(int appWidgetId);
void partiallyUpdateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views);
void updateAppWidgetProvider(in ComponentName provider, in RemoteViews views);
void notifyAppWidgetViewDataChanged(in int[] appWidgetIds, int viewId);
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index 266728b..61866e5 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -16,15 +16,24 @@
package com.android.internal.content;
-import android.os.storage.IMountService;
-
+import android.os.FileUtils;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.storage.IMountService;
import android.os.storage.StorageResultCode;
import android.util.Log;
import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import libcore.io.IoUtils;
/**
* Constants used internally between the PackageManager
@@ -196,4 +205,64 @@
}
return false;
}
+
+ public static void extractPublicFiles(String packagePath, File publicZipFile)
+ throws IOException {
+ final FileOutputStream fstr = new FileOutputStream(publicZipFile);
+ final ZipOutputStream publicZipOutStream = new ZipOutputStream(fstr);
+ try {
+ final ZipFile privateZip = new ZipFile(packagePath);
+ try {
+ // Copy manifest, resources.arsc and res directory to public zip
+ for (final ZipEntry zipEntry : Collections.list(privateZip.entries())) {
+ final String zipEntryName = zipEntry.getName();
+ if ("AndroidManifest.xml".equals(zipEntryName)
+ || "resources.arsc".equals(zipEntryName)
+ || zipEntryName.startsWith("res/")) {
+ copyZipEntry(zipEntry, privateZip, publicZipOutStream);
+ }
+ }
+ } finally {
+ try {
+ privateZip.close();
+ } catch (IOException e) {
+ }
+ }
+
+ publicZipOutStream.finish();
+ publicZipOutStream.flush();
+ FileUtils.sync(fstr);
+ publicZipOutStream.close();
+ FileUtils.setPermissions(publicZipFile.getAbsolutePath(), FileUtils.S_IRUSR
+ | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1);
+ } finally {
+ IoUtils.closeQuietly(publicZipOutStream);
+ }
+ }
+
+ private static void copyZipEntry(ZipEntry zipEntry, ZipFile inZipFile,
+ ZipOutputStream outZipStream) throws IOException {
+ byte[] buffer = new byte[4096];
+ int num;
+
+ ZipEntry newEntry;
+ if (zipEntry.getMethod() == ZipEntry.STORED) {
+ // Preserve the STORED method of the input entry.
+ newEntry = new ZipEntry(zipEntry);
+ } else {
+ // Create a new entry so that the compressed len is recomputed.
+ newEntry = new ZipEntry(zipEntry.getName());
+ }
+ outZipStream.putNextEntry(newEntry);
+
+ final InputStream data = inZipFile.getInputStream(zipEntry);
+ try {
+ while ((num = data.read(buffer)) > 0) {
+ outZipStream.write(buffer, 0, num);
+ }
+ outZipStream.flush();
+ } finally {
+ IoUtils.closeQuietly(data);
+ }
+ }
}
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 32d86413..f41fcc6 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -21,6 +21,9 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
import java.util.HashSet;
@@ -32,7 +35,11 @@
static final IntentFilter sPackageFilt = new IntentFilter();
static final IntentFilter sNonDataFilt = new IntentFilter();
static final IntentFilter sExternalFilt = new IntentFilter();
-
+
+ static final Object sLock = new Object();
+ static HandlerThread sBackgroundThread;
+ static Handler sBackgroundHandler;
+
static {
sPackageFilt.addAction(Intent.ACTION_PACKAGE_ADDED);
sPackageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED);
@@ -49,6 +56,7 @@
final HashSet<String> mUpdatingPackages = new HashSet<String>();
Context mRegisteredContext;
+ Handler mRegisteredHandler;
String[] mDisappearingPackages;
String[] mAppearingPackages;
String[] mModifiedPackages;
@@ -57,18 +65,35 @@
String[] mTempArray = new String[1];
- public void register(Context context, boolean externalStorage) {
+ public void register(Context context, Looper thread, boolean externalStorage) {
if (mRegisteredContext != null) {
throw new IllegalStateException("Already registered");
}
mRegisteredContext = context;
- context.registerReceiver(this, sPackageFilt);
- context.registerReceiver(this, sNonDataFilt);
+ if (thread == null) {
+ synchronized (sLock) {
+ if (sBackgroundThread == null) {
+ sBackgroundThread = new HandlerThread("PackageMonitor",
+ android.os.Process.THREAD_PRIORITY_BACKGROUND);
+ sBackgroundThread.start();
+ sBackgroundHandler = new Handler(sBackgroundThread.getLooper());
+ }
+ mRegisteredHandler = sBackgroundHandler;
+ }
+ } else {
+ mRegisteredHandler = new Handler(thread);
+ }
+ context.registerReceiver(this, sPackageFilt, null, mRegisteredHandler);
+ context.registerReceiver(this, sNonDataFilt, null, mRegisteredHandler);
if (externalStorage) {
- context.registerReceiver(this, sExternalFilt);
+ context.registerReceiver(this, sExternalFilt, null, mRegisteredHandler);
}
}
-
+
+ public Handler getRegisteredHandler() {
+ return mRegisteredHandler;
+ }
+
public void unregister() {
if (mRegisteredContext == null) {
throw new IllegalStateException("Not registered");
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index 0c5d5ef..d1c2d2e 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -150,7 +150,7 @@
*/
public static final int CMD_CHANNEL_DISCONNECTED = BASE + 4;
- private static final int CMD_TO_STRING_COUNT = CMD_CHANNEL_DISCONNECTED + 1;
+ private static final int CMD_TO_STRING_COUNT = CMD_CHANNEL_DISCONNECTED - BASE + 1;
private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
static {
sCmdToString[CMD_CHANNEL_HALF_CONNECTED - BASE] = "CMD_CHANNEL_HALF_CONNECTED";
diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java
new file mode 100644
index 0000000..0c6b780
--- /dev/null
+++ b/core/java/com/android/internal/view/ActionBarPolicy.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.view;
+
+import com.android.internal.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.os.Build;
+import android.view.ViewConfiguration;
+
+/**
+ * Allows components to query for various configuration policy decisions
+ * about how the action bar should lay out and behave on the current device.
+ */
+public class ActionBarPolicy {
+ private Context mContext;
+
+ public static ActionBarPolicy get(Context context) {
+ return new ActionBarPolicy(context);
+ }
+
+ private ActionBarPolicy(Context context) {
+ mContext = context;
+ }
+
+ public int getMaxActionButtons() {
+ return mContext.getResources().getInteger(R.integer.max_action_buttons);
+ }
+
+ public boolean showsOverflowMenuButton() {
+ return !ViewConfiguration.get(mContext).hasPermanentMenuKey();
+ }
+
+ public int getEmbeddedMenuWidthLimit() {
+ return mContext.getResources().getDisplayMetrics().widthPixels / 2;
+ }
+
+ public boolean hasEmbeddedTabs() {
+ final int targetSdk = mContext.getApplicationInfo().targetSdkVersion;
+ if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN) {
+ return mContext.getResources().getBoolean(R.bool.action_bar_embed_tabs);
+ }
+
+ // The embedded tabs policy changed in Jellybean; give older apps the old policy
+ // so they get what they expect.
+ return mContext.getResources().getBoolean(R.bool.action_bar_embed_tabs_pre_jb);
+ }
+
+ public int getTabContainerHeight() {
+ TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar,
+ com.android.internal.R.attr.actionBarStyle, 0);
+ int height = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
+ Resources r = mContext.getResources();
+ if (!hasEmbeddedTabs()) {
+ // Stacked tabs; limit the height
+ height = Math.min(height,
+ r.getDimensionPixelSize(R.dimen.action_bar_stacked_max_height));
+ }
+ a.recycle();
+ return height;
+ }
+
+ public boolean enableHomeButtonByDefault() {
+ // Older apps get the home button interaction enabled by default.
+ // Newer apps need to enable it explicitly.
+ return mContext.getApplicationInfo().targetSdkVersion <
+ Build.VERSION_CODES.ICE_CREAM_SANDWICH;
+ }
+
+ public int getStackedTabMaxWidth() {
+ return mContext.getResources().getDimensionPixelSize(
+ R.dimen.action_bar_stacked_tab_max_width);
+ }
+}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index dca45a9..73324c0 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -16,6 +16,7 @@
package com.android.internal.view.menu;
+import com.android.internal.view.ActionBarPolicy;
import com.android.internal.view.menu.ActionMenuView.ActionMenuChildView;
import android.content.Context;
@@ -29,7 +30,6 @@
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.View.MeasureSpec;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.ImageButton;
@@ -79,17 +79,18 @@
final Resources res = context.getResources();
+ final ActionBarPolicy abp = ActionBarPolicy.get(context);
if (!mReserveOverflowSet) {
- mReserveOverflow = !ViewConfiguration.get(context).hasPermanentMenuKey();
+ mReserveOverflow = abp.showsOverflowMenuButton();
}
if (!mWidthLimitSet) {
- mWidthLimit = res.getDisplayMetrics().widthPixels / 2;
+ mWidthLimit = abp.getEmbeddedMenuWidthLimit();
}
// Measure for initial configuration
if (!mMaxItemsSet) {
- mMaxItems = res.getInteger(com.android.internal.R.integer.max_action_buttons);
+ mMaxItems = abp.getMaxActionButtons();
}
int width = mWidthLimit;
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index 06f5158..25a9c54 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -161,10 +161,12 @@
@Override
public void setVisibility(int visibility) {
- if (mVisibilityAnim != null) {
- mVisibilityAnim.end();
+ if (visibility != getVisibility()) {
+ if (mVisibilityAnim != null) {
+ mVisibilityAnim.end();
+ }
+ super.setVisibility(visibility);
}
- super.setVisibility(visibility);
}
public boolean showOverflowMenu() {
diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
index 1767d68..83ac8968 100644
--- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java
+++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
@@ -15,7 +15,7 @@
*/
package com.android.internal.widget;
-import com.android.internal.R;
+import com.android.internal.view.ActionBarPolicy;
import android.animation.Animator;
import android.animation.ObjectAnimator;
@@ -23,7 +23,6 @@
import android.app.ActionBar;
import android.content.Context;
import android.content.res.Configuration;
-import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.TextUtils.TruncateAt;
import android.view.Gravity;
@@ -55,6 +54,7 @@
private boolean mAllowCollapse;
int mMaxTabWidth;
+ int mStackedTabMaxWidth;
private int mContentHeight;
private int mSelectedTabIndex;
@@ -69,10 +69,9 @@
super(context);
setHorizontalScrollBarEnabled(false);
- TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionBar,
- com.android.internal.R.attr.actionBarStyle, 0);
- setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0));
- a.recycle();
+ ActionBarPolicy abp = ActionBarPolicy.get(context);
+ setContentHeight(abp.getTabContainerHeight());
+ mStackedTabMaxWidth = abp.getStackedTabMaxWidth();
mTabLayout = createTabLayout();
addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -93,6 +92,7 @@
} else {
mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2;
}
+ mMaxTabWidth = Math.min(mMaxTabWidth, mStackedTabMaxWidth);
} else {
mMaxTabWidth = -1;
}
@@ -187,6 +187,7 @@
final LinearLayout tabLayout = new LinearLayout(getContext(), null,
com.android.internal.R.attr.actionBarTabBarStyle);
tabLayout.setMeasureWithLargestChildEnabled(true);
+ tabLayout.setGravity(Gravity.CENTER);
tabLayout.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
return tabLayout;
@@ -205,12 +206,11 @@
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
+ ActionBarPolicy abp = ActionBarPolicy.get(getContext());
// Action bar can change size on configuration changes.
// Reread the desired height from the theme-specified style.
- TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionBar,
- com.android.internal.R.attr.actionBarStyle, 0);
- setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0));
- a.recycle();
+ setContentHeight(abp.getTabContainerHeight());
+ mStackedTabMaxWidth = abp.getStackedTabMaxWidth();
}
public void animateToVisibility(int visibility) {
diff --git a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
index adfd3dc..0a99f17 100644
--- a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
+++ b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
@@ -26,8 +26,11 @@
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.StateSet;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
@@ -90,8 +93,14 @@
private void initialize() {
mModestyPanel = new View(getContext());
// If the SizeAdaptiveLayout has a solid background, use it as a transition hint.
- if (getBackground() instanceof ColorDrawable) {
- mModestyPanel.setBackgroundDrawable(getBackground());
+ Drawable background = getBackground();
+ if (background instanceof StateListDrawable) {
+ StateListDrawable sld = (StateListDrawable) background;
+ sld.setState(StateSet.WILD_CARD);
+ background = sld.getCurrent();
+ }
+ if (background instanceof ColorDrawable) {
+ mModestyPanel.setBackgroundDrawable(background);
} else {
mModestyPanel.setBackgroundColor(Color.BLACK);
}
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index fca5f20..0777ea2 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -120,6 +120,13 @@
return 0;
}
+ // Check that the database is really read/write when that is what we asked for.
+ if ((sqliteFlags & SQLITE_OPEN_READWRITE) && sqlite3_db_readonly(db, NULL)) {
+ throw_sqlite3_exception(env, db, "Could not open the database in read/write mode.");
+ sqlite3_close(db);
+ return 0;
+ }
+
// Set the default busy handler to retry for 1000ms and then return SQLITE_BUSY
err = sqlite3_busy_timeout(db, 1000 /* ms */);
if (err != SQLITE_OK) {
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 36b4b45..6cd8955 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -457,9 +457,9 @@
// connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
- jobject weak_this, jint cameraId, jboolean force, jboolean keep)
+ jobject weak_this, jint cameraId)
{
- sp<Camera> camera = Camera::connect(cameraId, force, keep);
+ sp<Camera> camera = Camera::connect(cameraId);
if (camera == NULL) {
jniThrowRuntimeException(env, "Fail to connect to camera service");
@@ -821,15 +821,6 @@
}
}
-static bool android_hardware_Camera_isReleased(JNIEnv *env, jobject thiz)
-{
- ALOGV("isReleased");
- sp<Camera> camera = get_native_camera(env, thiz, NULL);
- if (camera == 0) return true;
-
- return (camera->sendCommand(CAMERA_CMD_PING, 0, 0) != NO_ERROR);
-}
-
//-------------------------------------------------
static JNINativeMethod camMethods[] = {
@@ -840,7 +831,7 @@
"(ILandroid/hardware/Camera$CameraInfo;)V",
(void*)android_hardware_Camera_getCameraInfo },
{ "native_setup",
- "(Ljava/lang/Object;IZZ)V",
+ "(Ljava/lang/Object;I)V",
(void*)android_hardware_Camera_native_setup },
{ "native_release",
"()V",
@@ -908,9 +899,6 @@
{ "enableFocusMoveCallback",
"(I)V",
(void *)android_hardware_Camera_enableFocusMoveCallback},
- { "isReleased",
- "()Z",
- (void *)android_hardware_Camera_isReleased},
};
struct field {
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 2fe0b9e..0f04e6f 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -28,6 +28,8 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
+#include <utils/SortedVector.h>
+#include <utils/threads.h>
#include <media/AudioRecord.h>
#include <media/mediarecorder.h>
@@ -55,9 +57,12 @@
struct audiorecord_callback_cookie {
jclass audioRecord_class;
jobject audioRecord_ref;
- };
+ bool busy;
+ Condition cond;
+};
-Mutex sLock;
+static Mutex sLock;
+static SortedVector <audiorecord_callback_cookie *> sAudioRecordCallBackCookies;
// ----------------------------------------------------------------------------
@@ -87,13 +92,21 @@
// ----------------------------------------------------------------------------
static void recorderCallback(int event, void* user, void *info) {
+
+ audiorecord_callback_cookie *callbackInfo = (audiorecord_callback_cookie *)user;
+ {
+ Mutex::Autolock l(sLock);
+ if (sAudioRecordCallBackCookies.indexOf(callbackInfo) < 0) {
+ return;
+ }
+ callbackInfo->busy = true;
+ }
if (event == AudioRecord::EVENT_MORE_DATA) {
// set size to 0 to signal we're not using the callback to read more data
AudioRecord::Buffer* pBuff = (AudioRecord::Buffer*)info;
pBuff->size = 0;
} else if (event == AudioRecord::EVENT_MARKER) {
- audiorecord_callback_cookie *callbackInfo = (audiorecord_callback_cookie *)user;
JNIEnv *env = AndroidRuntime::getJNIEnv();
if (user && env) {
env->CallStaticVoidMethod(
@@ -107,7 +120,6 @@
}
} else if (event == AudioRecord::EVENT_NEW_POS) {
- audiorecord_callback_cookie *callbackInfo = (audiorecord_callback_cookie *)user;
JNIEnv *env = AndroidRuntime::getJNIEnv();
if (user && env) {
env->CallStaticVoidMethod(
@@ -120,8 +132,36 @@
}
}
}
+ {
+ Mutex::Autolock l(sLock);
+ callbackInfo->busy = false;
+ callbackInfo->cond.broadcast();
+ }
}
+// ----------------------------------------------------------------------------
+static sp<AudioRecord> getAudioRecord(JNIEnv* env, jobject thiz)
+{
+ Mutex::Autolock l(sLock);
+ AudioRecord* const ar =
+ (AudioRecord*)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ return sp<AudioRecord>(ar);
+}
+
+static sp<AudioRecord> setAudioRecord(JNIEnv* env, jobject thiz, const sp<AudioRecord>& ar)
+{
+ Mutex::Autolock l(sLock);
+ sp<AudioRecord> old =
+ (AudioRecord*)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ if (ar.get()) {
+ ar->incStrong(thiz);
+ }
+ if (old != 0) {
+ old->decStrong(thiz);
+ }
+ env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, (int)ar.get());
+ return old;
+}
// ----------------------------------------------------------------------------
static int
@@ -162,6 +202,12 @@
return AUDIORECORD_ERROR_SETUP_INVALIDSOURCE;
}
+ jclass clazz = env->GetObjectClass(thiz);
+ if (clazz == NULL) {
+ ALOGE("Can't find %s when setting up callback.", kClassPathName);
+ return AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
+ }
+
if (jSession == NULL) {
ALOGE("Error creating AudioRecord: invalid session ID pointer");
return AUDIORECORD_ERROR;
@@ -176,27 +222,20 @@
env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
nSession = NULL;
- audiorecord_callback_cookie *lpCallbackData = NULL;
- AudioRecord* lpRecorder = NULL;
-
// create an uninitialized AudioRecord object
- lpRecorder = new AudioRecord();
- if (lpRecorder == NULL) {
+ sp<AudioRecord> lpRecorder = new AudioRecord();
+ if (lpRecorder == NULL) {
ALOGE("Error creating AudioRecord instance.");
return AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
}
// create the callback information:
// this data will be passed with every AudioRecord callback
- jclass clazz = env->GetObjectClass(thiz);
- if (clazz == NULL) {
- ALOGE("Can't find %s when setting up callback.", kClassPathName);
- goto native_track_failure;
- }
- lpCallbackData = new audiorecord_callback_cookie;
+ audiorecord_callback_cookie *lpCallbackData = new audiorecord_callback_cookie;
lpCallbackData->audioRecord_class = (jclass)env->NewGlobalRef(clazz);
// we use a weak reference so the AudioRecord object can be garbage collected.
lpCallbackData->audioRecord_ref = env->NewGlobalRef(weak_this);
+ lpCallbackData->busy = false;
lpRecorder->set((audio_source_t) source,
sampleRateInHertz,
@@ -225,9 +264,13 @@
env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
nSession = NULL;
+ { // scope for the lock
+ Mutex::Autolock l(sLock);
+ sAudioRecordCallBackCookies.add(lpCallbackData);
+ }
// save our newly created C++ AudioRecord in the "nativeRecorderInJavaObj" field
// of the Java object
- env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, (int)lpRecorder);
+ setAudioRecord(env, thiz, lpRecorder);
// save our newly created callback information in the "nativeCallbackCookie" field
// of the Java object (in mNativeCallbackCookie) so we can free the memory in finalize()
@@ -240,11 +283,6 @@
env->DeleteGlobalRef(lpCallbackData->audioRecord_class);
env->DeleteGlobalRef(lpCallbackData->audioRecord_ref);
delete lpCallbackData;
-
-native_track_failure:
- delete lpRecorder;
-
- env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, 0);
env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
return AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
@@ -256,8 +294,7 @@
static int
android_media_AudioRecord_start(JNIEnv *env, jobject thiz, jint event, jint triggerSession)
{
- AudioRecord *lpRecorder =
- (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
if (lpRecorder == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return AUDIORECORD_ERROR;
@@ -272,8 +309,7 @@
static void
android_media_AudioRecord_stop(JNIEnv *env, jobject thiz)
{
- AudioRecord *lpRecorder =
- (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
if (lpRecorder == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
@@ -285,30 +321,35 @@
// ----------------------------------------------------------------------------
-static void android_media_AudioRecord_release(JNIEnv *env, jobject thiz) {
- // serialize access. Ugly, but functional.
- Mutex::Autolock lock(&sLock);
- AudioRecord *lpRecorder =
- (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+#define CALLBACK_COND_WAIT_TIMEOUT_MS 1000
+static void android_media_AudioRecord_release(JNIEnv *env, jobject thiz) {
+ sp<AudioRecord> lpRecorder = setAudioRecord(env, thiz, 0);
+ if (lpRecorder == NULL) {
+ return;
+ }
+ ALOGV("About to delete lpRecorder: %x\n", (int)lpRecorder.get());
+ lpRecorder->stop();
+
audiorecord_callback_cookie *lpCookie = (audiorecord_callback_cookie *)env->GetIntField(
thiz, javaAudioRecordFields.nativeCallbackCookie);
// reset the native resources in the Java object so any attempt to access
// them after a call to release fails.
- env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, 0);
env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
- // delete the AudioRecord object
- if (lpRecorder) {
- ALOGV("About to delete lpRecorder: %x\n", (int)lpRecorder);
- lpRecorder->stop();
- delete lpRecorder;
- }
-
// delete the callback information
if (lpCookie) {
+ Mutex::Autolock l(sLock);
ALOGV("deleting lpCookie: %x\n", (int)lpCookie);
+ while (lpCookie->busy) {
+ if (lpCookie->cond.waitRelative(sLock,
+ milliseconds(CALLBACK_COND_WAIT_TIMEOUT_MS)) !=
+ NO_ERROR) {
+ break;
+ }
+ }
+ sAudioRecordCallBackCookies.remove(lpCookie);
env->DeleteGlobalRef(lpCookie->audioRecord_class);
env->DeleteGlobalRef(lpCookie->audioRecord_ref);
delete lpCookie;
@@ -327,11 +368,8 @@
jbyteArray javaAudioData,
jint offsetInBytes, jint sizeInBytes) {
jbyte* recordBuff = NULL;
- AudioRecord *lpRecorder = NULL;
-
// get the audio recorder from which we'll read new audio samples
- lpRecorder =
- (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
if (lpRecorder == NULL) {
ALOGE("Unable to retrieve AudioRecord object, can't record");
return 0;
@@ -378,12 +416,8 @@
// ----------------------------------------------------------------------------
static jint android_media_AudioRecord_readInDirectBuffer(JNIEnv *env, jobject thiz,
jobject jBuffer, jint sizeInBytes) {
- AudioRecord *lpRecorder = NULL;
- //ALOGV("Entering android_media_AudioRecord_readInBuffer");
-
// get the audio recorder from which we'll read new audio samples
- lpRecorder =
- (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
if (lpRecorder==NULL)
return 0;
@@ -411,35 +445,29 @@
static jint android_media_AudioRecord_set_marker_pos(JNIEnv *env, jobject thiz,
jint markerPos) {
- AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
- thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
-
- if (lpRecorder) {
- return
- android_media_translateRecorderErrorCode( lpRecorder->setMarkerPosition(markerPos) );
- } else {
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
+ if (lpRecorder == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioRecord pointer for setMarkerPosition()");
return AUDIORECORD_ERROR;
}
+ return android_media_translateRecorderErrorCode( lpRecorder->setMarkerPosition(markerPos) );
}
// ----------------------------------------------------------------------------
static jint android_media_AudioRecord_get_marker_pos(JNIEnv *env, jobject thiz) {
- AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
- thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
uint32_t markerPos = 0;
- if (lpRecorder) {
- lpRecorder->getMarkerPosition(&markerPos);
- return (jint)markerPos;
- } else {
+ if (lpRecorder == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioRecord pointer for getMarkerPosition()");
return AUDIORECORD_ERROR;
}
+ lpRecorder->getMarkerPosition(&markerPos);
+ return (jint)markerPos;
}
@@ -447,35 +475,30 @@
static jint android_media_AudioRecord_set_pos_update_period(JNIEnv *env, jobject thiz,
jint period) {
- AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
- thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
- if (lpRecorder) {
- return
- android_media_translateRecorderErrorCode( lpRecorder->setPositionUpdatePeriod(period) );
- } else {
+ if (lpRecorder == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioRecord pointer for setPositionUpdatePeriod()");
return AUDIORECORD_ERROR;
}
+ return android_media_translateRecorderErrorCode( lpRecorder->setPositionUpdatePeriod(period) );
}
// ----------------------------------------------------------------------------
static jint android_media_AudioRecord_get_pos_update_period(JNIEnv *env, jobject thiz) {
- AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
- thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
uint32_t period = 0;
- if (lpRecorder) {
- lpRecorder->getPositionUpdatePeriod(&period);
- return (jint)period;
- } else {
+ if (lpRecorder == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioRecord pointer for getPositionUpdatePeriod()");
return AUDIORECORD_ERROR;
}
+ lpRecorder->getPositionUpdatePeriod(&period);
+ return (jint)period;
}
@@ -486,7 +509,8 @@
static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject thiz,
jint sampleRateInHertz, jint nbChannels, jint audioFormat) {
- ALOGV(">> android_media_AudioRecord_get_min_buff_size(%d, %d, %d)", sampleRateInHertz, nbChannels, audioFormat);
+ ALOGV(">> android_media_AudioRecord_get_min_buff_size(%d, %d, %d)",
+ sampleRateInHertz, nbChannels, audioFormat);
int frameCount = 0;
status_t result = AudioRecord::getMinFrameCount(&frameCount,
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 9fbc477..7e5263d 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -59,7 +59,9 @@
struct audiotrack_callback_cookie {
jclass audioTrack_class;
jobject audioTrack_ref;
- };
+ bool busy;
+ Condition cond;
+};
// ----------------------------------------------------------------------------
class AudioTrackJniStorage {
@@ -90,6 +92,9 @@
}
};
+static Mutex sLock;
+static SortedVector <audiotrack_callback_cookie *> sAudioTrackCallBackCookies;
+
// ----------------------------------------------------------------------------
#define DEFAULT_OUTPUT_SAMPLE_RATE 44100
@@ -120,13 +125,22 @@
// ----------------------------------------------------------------------------
static void audioCallback(int event, void* user, void *info) {
+
+ audiotrack_callback_cookie *callbackInfo = (audiotrack_callback_cookie *)user;
+ {
+ Mutex::Autolock l(sLock);
+ if (sAudioTrackCallBackCookies.indexOf(callbackInfo) < 0) {
+ return;
+ }
+ callbackInfo->busy = true;
+ }
+
if (event == AudioTrack::EVENT_MORE_DATA) {
// set size to 0 to signal we're not using the callback to write more data
AudioTrack::Buffer* pBuff = (AudioTrack::Buffer*)info;
pBuff->size = 0;
} else if (event == AudioTrack::EVENT_MARKER) {
- audiotrack_callback_cookie *callbackInfo = (audiotrack_callback_cookie *)user;
JNIEnv *env = AndroidRuntime::getJNIEnv();
if (user && env) {
env->CallStaticVoidMethod(
@@ -140,7 +154,6 @@
}
} else if (event == AudioTrack::EVENT_NEW_POS) {
- audiotrack_callback_cookie *callbackInfo = (audiotrack_callback_cookie *)user;
JNIEnv *env = AndroidRuntime::getJNIEnv();
if (user && env) {
env->CallStaticVoidMethod(
@@ -153,10 +166,39 @@
}
}
}
+ {
+ Mutex::Autolock l(sLock);
+ callbackInfo->busy = false;
+ callbackInfo->cond.broadcast();
+ }
}
// ----------------------------------------------------------------------------
+static sp<AudioTrack> getAudioTrack(JNIEnv* env, jobject thiz)
+{
+ Mutex::Autolock l(sLock);
+ AudioTrack* const at =
+ (AudioTrack*)env->GetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+ return sp<AudioTrack>(at);
+}
+
+static sp<AudioTrack> setAudioTrack(JNIEnv* env, jobject thiz, const sp<AudioTrack>& at)
+{
+ Mutex::Autolock l(sLock);
+ sp<AudioTrack> old =
+ (AudioTrack*)env->GetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+ if (at.get()) {
+ at->incStrong(thiz);
+ }
+ if (old != 0) {
+ old->decStrong(thiz);
+ }
+ env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, (int)at.get());
+ return old;
+}
+
+// ----------------------------------------------------------------------------
static int
android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jint streamType, jint sampleRateInHertz, jint javaChannelMask,
@@ -231,32 +273,20 @@
AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT;
int frameCount = buffSizeInBytes / (nbChannels * bytesPerSample);
- AudioTrackJniStorage* lpJniStorage = new AudioTrackJniStorage();
-
- // initialize the callback information:
- // this data will be passed with every AudioTrack callback
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
ALOGE("Can't find %s when setting up callback.", kClassPathName);
- delete lpJniStorage;
return AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED;
}
- lpJniStorage->mCallbackData.audioTrack_class = (jclass)env->NewGlobalRef(clazz);
- // we use a weak reference so the AudioTrack object can be garbage collected.
- lpJniStorage->mCallbackData.audioTrack_ref = env->NewGlobalRef(weak_this);
-
- lpJniStorage->mStreamType = atStreamType;
if (jSession == NULL) {
ALOGE("Error creating AudioTrack: invalid session ID pointer");
- delete lpJniStorage;
return AUDIOTRACK_ERROR;
}
jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
if (nSession == NULL) {
ALOGE("Error creating AudioTrack: Error retrieving session id pointer");
- delete lpJniStorage;
return AUDIOTRACK_ERROR;
}
int sessionId = nSession[0];
@@ -264,12 +294,21 @@
nSession = NULL;
// create the native AudioTrack object
- AudioTrack* lpTrack = new AudioTrack();
+ sp<AudioTrack> lpTrack = new AudioTrack();
if (lpTrack == NULL) {
ALOGE("Error creating uninitialized AudioTrack");
- goto native_track_failure;
+ return AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED;
}
+ // initialize the callback information:
+ // this data will be passed with every AudioTrack callback
+ AudioTrackJniStorage* lpJniStorage = new AudioTrackJniStorage();
+ lpJniStorage->mStreamType = atStreamType;
+ lpJniStorage->mCallbackData.audioTrack_class = (jclass)env->NewGlobalRef(clazz);
+ // we use a weak reference so the AudioTrack object can be garbage collected.
+ lpJniStorage->mCallbackData.audioTrack_ref = env->NewGlobalRef(weak_this);
+ lpJniStorage->mCallbackData.busy = false;
+
// initialize the native AudioTrack object
if (memoryMode == javaAudioTrackFields.MODE_STREAM) {
@@ -279,7 +318,7 @@
format,// word length, PCM
nativeChannelMask,
frameCount,
- AUDIO_POLICY_OUTPUT_FLAG_NONE,
+ AUDIO_OUTPUT_FLAG_NONE,
audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)
0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
0,// shared mem
@@ -300,7 +339,7 @@
format,// word length, PCM
nativeChannelMask,
frameCount,
- AUDIO_POLICY_OUTPUT_FLAG_NONE,
+ AUDIO_OUTPUT_FLAG_NONE,
audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user));
0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
lpJniStorage->mMemBase,// shared mem
@@ -323,9 +362,13 @@
env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
nSession = NULL;
+ { // scope for the lock
+ Mutex::Autolock l(sLock);
+ sAudioTrackCallBackCookies.add(&lpJniStorage->mCallbackData);
+ }
// save our newly created C++ AudioTrack in the "nativeTrackInJavaObj" field
// of the Java object (in mNativeTrackInJavaObj)
- env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, (int)lpTrack);
+ setAudioTrack(env, thiz, lpTrack);
// save the JNI resources so we can free them later
//ALOGV("storing lpJniStorage: %x\n", (int)lpJniStorage);
@@ -335,10 +378,6 @@
// failures:
native_init_failure:
- delete lpTrack;
- env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, 0);
-
-native_track_failure:
if (nSession != NULL) {
env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
}
@@ -346,8 +385,8 @@
env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_ref);
delete lpJniStorage;
env->SetIntField(thiz, javaAudioTrackFields.jniData, 0);
- return AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED;
+ return AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED;
}
@@ -355,9 +394,8 @@
static void
android_media_AudioTrack_start(JNIEnv *env, jobject thiz)
{
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
- if (lpTrack == NULL ) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for start()");
return;
@@ -371,9 +409,8 @@
static void
android_media_AudioTrack_stop(JNIEnv *env, jobject thiz)
{
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
- if (lpTrack == NULL ) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for stop()");
return;
@@ -387,9 +424,8 @@
static void
android_media_AudioTrack_pause(JNIEnv *env, jobject thiz)
{
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
- if (lpTrack == NULL ) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for pause()");
return;
@@ -403,9 +439,8 @@
static void
android_media_AudioTrack_flush(JNIEnv *env, jobject thiz)
{
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
- if (lpTrack == NULL ) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for flush()");
return;
@@ -418,9 +453,8 @@
static void
android_media_AudioTrack_set_volume(JNIEnv *env, jobject thiz, jfloat leftVol, jfloat rightVol )
{
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
- if (lpTrack == NULL ) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setVolume()");
return;
@@ -430,68 +464,75 @@
}
// ----------------------------------------------------------------------------
-static void android_media_AudioTrack_native_finalize(JNIEnv *env, jobject thiz) {
- //ALOGV("android_media_AudioTrack_native_finalize jobject: %x\n", (int)thiz);
- // delete the AudioTrack object
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
- if (lpTrack) {
- //ALOGV("deleting lpTrack: %x\n", (int)lpTrack);
- lpTrack->stop();
- delete lpTrack;
+#define CALLBACK_COND_WAIT_TIMEOUT_MS 1000
+static void android_media_AudioTrack_native_release(JNIEnv *env, jobject thiz) {
+ sp<AudioTrack> lpTrack = setAudioTrack(env, thiz, 0);
+ if (lpTrack == NULL) {
+ return;
}
+ //ALOGV("deleting lpTrack: %x\n", (int)lpTrack);
+ lpTrack->stop();
// delete the JNI data
AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetIntField(
thiz, javaAudioTrackFields.jniData);
+ // reset the native resources in the Java object so any attempt to access
+ // them after a call to release fails.
+ env->SetIntField(thiz, javaAudioTrackFields.jniData, 0);
+
if (pJniStorage) {
- // delete global refs created in native_setup
- env->DeleteGlobalRef(pJniStorage->mCallbackData.audioTrack_class);
- env->DeleteGlobalRef(pJniStorage->mCallbackData.audioTrack_ref);
+ Mutex::Autolock l(sLock);
+ audiotrack_callback_cookie *lpCookie = &pJniStorage->mCallbackData;
//ALOGV("deleting pJniStorage: %x\n", (int)pJniStorage);
+ while (lpCookie->busy) {
+ if (lpCookie->cond.waitRelative(sLock,
+ milliseconds(CALLBACK_COND_WAIT_TIMEOUT_MS)) !=
+ NO_ERROR) {
+ break;
+ }
+ }
+ sAudioTrackCallBackCookies.remove(lpCookie);
+ // delete global refs created in native_setup
+ env->DeleteGlobalRef(lpCookie->audioTrack_class);
+ env->DeleteGlobalRef(lpCookie->audioTrack_ref);
delete pJniStorage;
}
}
-// ----------------------------------------------------------------------------
-static void android_media_AudioTrack_native_release(JNIEnv *env, jobject thiz) {
- // do everything a call to finalize would
- android_media_AudioTrack_native_finalize(env, thiz);
- // + reset the native resources in the Java object so any attempt to access
- // them after a call to release fails.
- env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, 0);
- env->SetIntField(thiz, javaAudioTrackFields.jniData, 0);
+// ----------------------------------------------------------------------------
+static void android_media_AudioTrack_native_finalize(JNIEnv *env, jobject thiz) {
+ //ALOGV("android_media_AudioTrack_native_finalize jobject: %x\n", (int)thiz);
+ android_media_AudioTrack_native_release(env, thiz);
}
-
// ----------------------------------------------------------------------------
-jint writeToTrack(AudioTrack* pTrack, jint audioFormat, jbyte* data,
+jint writeToTrack(const sp<AudioTrack>& track, jint audioFormat, jbyte* data,
jint offsetInBytes, jint sizeInBytes) {
// give the data to the native AudioTrack object (the data starts at the offset)
ssize_t written = 0;
// regular write() or copy the data to the AudioTrack's shared memory?
- if (pTrack->sharedBuffer() == 0) {
- written = pTrack->write(data + offsetInBytes, sizeInBytes);
+ if (track->sharedBuffer() == 0) {
+ written = track->write(data + offsetInBytes, sizeInBytes);
} else {
if (audioFormat == javaAudioTrackFields.PCM16) {
// writing to shared memory, check for capacity
- if ((size_t)sizeInBytes > pTrack->sharedBuffer()->size()) {
- sizeInBytes = pTrack->sharedBuffer()->size();
+ if ((size_t)sizeInBytes > track->sharedBuffer()->size()) {
+ sizeInBytes = track->sharedBuffer()->size();
}
- memcpy(pTrack->sharedBuffer()->pointer(), data + offsetInBytes, sizeInBytes);
+ memcpy(track->sharedBuffer()->pointer(), data + offsetInBytes, sizeInBytes);
written = sizeInBytes;
} else if (audioFormat == javaAudioTrackFields.PCM8) {
// data contains 8bit data we need to expand to 16bit before copying
// to the shared memory
// writing to shared memory, check for capacity,
// note that input data will occupy 2X the input space due to 8 to 16bit conversion
- if (((size_t)sizeInBytes)*2 > pTrack->sharedBuffer()->size()) {
- sizeInBytes = pTrack->sharedBuffer()->size() / 2;
+ if (((size_t)sizeInBytes)*2 > track->sharedBuffer()->size()) {
+ sizeInBytes = track->sharedBuffer()->size() / 2;
}
int count = sizeInBytes;
- int16_t *dst = (int16_t *)pTrack->sharedBuffer()->pointer();
+ int16_t *dst = (int16_t *)track->sharedBuffer()->pointer();
const int8_t *src = (const int8_t *)(data + offsetInBytes);
while (count--) {
*dst++ = (int16_t)(*src++^0x80) << 8;
@@ -510,13 +551,9 @@
jbyteArray javaAudioData,
jint offsetInBytes, jint sizeInBytes,
jint javaAudioFormat) {
- jbyte* cAudioData = NULL;
- AudioTrack *lpTrack = NULL;
//ALOGV("android_media_AudioTrack_native_write_byte(offset=%d, sizeInBytes=%d) called",
// offsetInBytes, sizeInBytes);
-
- // get the audio track to load with samples
- lpTrack = (AudioTrack *)env->GetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for write()");
@@ -528,6 +565,7 @@
// a way that it becomes much more efficient. When doing so, we will have to prevent the
// AudioSystem callback to be called while in critical section (in case of media server
// process crash for instance)
+ jbyte* cAudioData = NULL;
if (javaAudioData) {
cAudioData = (jbyte *)env->GetByteArrayElements(javaAudioData, NULL);
if (cAudioData == NULL) {
@@ -564,183 +602,148 @@
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_get_native_frame_count(JNIEnv *env, jobject thiz) {
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
-
- if (lpTrack) {
- return lpTrack->frameCount();
- } else {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for frameCount()");
return AUDIOTRACK_ERROR;
}
+
+ return lpTrack->frameCount();
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_set_playback_rate(JNIEnv *env, jobject thiz,
jint sampleRateInHz) {
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
-
- if (lpTrack) {
- return android_media_translateErrorCode(lpTrack->setSampleRate(sampleRateInHz));
- } else {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setSampleRate()");
return AUDIOTRACK_ERROR;
}
+ return android_media_translateErrorCode(lpTrack->setSampleRate(sampleRateInHz));
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_get_playback_rate(JNIEnv *env, jobject thiz) {
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
-
- if (lpTrack) {
- return (jint) lpTrack->getSampleRate();
- } else {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for getSampleRate()");
return AUDIOTRACK_ERROR;
}
+ return (jint) lpTrack->getSampleRate();
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_set_marker_pos(JNIEnv *env, jobject thiz,
jint markerPos) {
-
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
-
- if (lpTrack) {
- return android_media_translateErrorCode( lpTrack->setMarkerPosition(markerPos) );
- } else {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setMarkerPosition()");
return AUDIOTRACK_ERROR;
}
+ return android_media_translateErrorCode( lpTrack->setMarkerPosition(markerPos) );
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_get_marker_pos(JNIEnv *env, jobject thiz) {
-
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
uint32_t markerPos = 0;
- if (lpTrack) {
- lpTrack->getMarkerPosition(&markerPos);
- return (jint)markerPos;
- } else {
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for getMarkerPosition()");
return AUDIOTRACK_ERROR;
}
+ lpTrack->getMarkerPosition(&markerPos);
+ return (jint)markerPos;
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_set_pos_update_period(JNIEnv *env, jobject thiz,
jint period) {
-
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
-
- if (lpTrack) {
- return android_media_translateErrorCode( lpTrack->setPositionUpdatePeriod(period) );
- } else {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setPositionUpdatePeriod()");
return AUDIOTRACK_ERROR;
}
+ return android_media_translateErrorCode( lpTrack->setPositionUpdatePeriod(period) );
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_get_pos_update_period(JNIEnv *env, jobject thiz) {
-
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
uint32_t period = 0;
- if (lpTrack) {
- lpTrack->getPositionUpdatePeriod(&period);
- return (jint)period;
- } else {
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for getPositionUpdatePeriod()");
return AUDIOTRACK_ERROR;
}
+ lpTrack->getPositionUpdatePeriod(&period);
+ return (jint)period;
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_set_position(JNIEnv *env, jobject thiz,
jint position) {
-
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
-
- if (lpTrack) {
- return android_media_translateErrorCode( lpTrack->setPosition(position) );
- } else {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setPosition()");
return AUDIOTRACK_ERROR;
}
+ return android_media_translateErrorCode( lpTrack->setPosition(position) );
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_get_position(JNIEnv *env, jobject thiz) {
-
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
uint32_t position = 0;
- if (lpTrack) {
- lpTrack->getPosition(&position);
- return (jint)position;
- } else {
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for getPosition()");
return AUDIOTRACK_ERROR;
}
+ lpTrack->getPosition(&position);
+ return (jint)position;
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_set_loop(JNIEnv *env, jobject thiz,
jint loopStart, jint loopEnd, jint loopCount) {
-
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
- if (lpTrack) {
- return android_media_translateErrorCode( lpTrack->setLoop(loopStart, loopEnd, loopCount) );
- } else {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setLoop()");
return AUDIOTRACK_ERROR;
}
+ return android_media_translateErrorCode( lpTrack->setLoop(loopStart, loopEnd, loopCount) );
}
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_reload(JNIEnv *env, jobject thiz) {
-
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
- if (lpTrack) {
- return android_media_translateErrorCode( lpTrack->reload() );
- } else {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for reload()");
return AUDIOTRACK_ERROR;
}
+ return android_media_translateErrorCode( lpTrack->reload() );
}
@@ -795,8 +798,7 @@
static void
android_media_AudioTrack_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level )
{
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
if (lpTrack == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setAuxEffectSendLevel()");
@@ -809,17 +811,13 @@
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_attachAuxEffect(JNIEnv *env, jobject thiz,
jint effectId) {
-
- AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
- thiz, javaAudioTrackFields.nativeTrackInJavaObj);
-
- if (lpTrack) {
- return android_media_translateErrorCode( lpTrack->attachAuxEffect(effectId) );
- } else {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for attachAuxEffect()");
return AUDIOTRACK_ERROR;
}
+ return android_media_translateErrorCode( lpTrack->attachAuxEffect(effectId) );
}
// ----------------------------------------------------------------------------
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 724d9fb..1f2b1ae 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -31,20 +31,22 @@
int dhcp_do_request(const char *ifname,
const char *ipaddr,
const char *gateway,
- uint32_t *prefixLength,
+ uint32_t *prefixLength,
const char *dns1,
const char *dns2,
const char *server,
- uint32_t *lease);
+ uint32_t *lease,
+ const char *vendorInfo);
int dhcp_do_request_renew(const char *ifname,
const char *ipaddr,
const char *gateway,
- uint32_t *prefixLength,
+ uint32_t *prefixLength,
const char *dns1,
const char *dns2,
const char *server,
- uint32_t *lease);
+ uint32_t *lease,
+ const char *vendorInfo);
int dhcp_stop(const char *ifname);
int dhcp_release_lease(const char *ifname);
@@ -68,6 +70,7 @@
jfieldID dns2;
jfieldID serverAddress;
jfieldID leaseDuration;
+ jfieldID vendorInfo;
} dhcpInfoInternalFieldIds;
static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
@@ -116,16 +119,17 @@
char dns2[PROPERTY_VALUE_MAX];
char server[PROPERTY_VALUE_MAX];
uint32_t lease;
+ char vendorInfo[PROPERTY_VALUE_MAX];
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
if (nameStr == NULL) return (jboolean)false;
if (renew) {
result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
- dns1, dns2, server, &lease);
+ dns1, dns2, server, &lease, vendorInfo);
} else {
result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
- dns1, dns2, server, &lease);
+ dns1, dns2, server, &lease, vendorInfo);
}
env->ReleaseStringUTFChars(ifname, nameStr);
@@ -161,6 +165,7 @@
env->SetObjectField(info, dhcpInfoInternalFieldIds.serverAddress,
env->NewStringUTF(server));
env->SetIntField(info, dhcpInfoInternalFieldIds.leaseDuration, lease);
+ env->SetObjectField(info, dhcpInfoInternalFieldIds.vendorInfo, env->NewStringUTF(vendorInfo));
}
return (jboolean)(result == 0);
}
@@ -230,6 +235,7 @@
dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalClass, "dns2", "Ljava/lang/String;");
dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;");
dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalClass, "leaseDuration", "I");
+ dhcpInfoInternalFieldIds.vendorInfo = env->GetFieldID(dhcpInfoInternalClass, "vendorInfo", "Ljava/lang/String;");
return AndroidRuntime::registerNativeMethods(env,
NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 41cc203..93be342a 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -21,6 +21,7 @@
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
+#include <cutils/sched_policy.h>
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -49,6 +50,8 @@
static pthread_key_t gBgKey = -1;
#endif
+// For both of these, err should be in the errno range (positive), not a status_t (negative)
+
static void signalExceptionForPriorityError(JNIEnv* env, int err)
{
switch (err) {
@@ -168,27 +171,36 @@
return -1;
}
-void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
+void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int tid, jint grp)
{
- int res = androidSetThreadSchedulingGroup(pid, grp);
+ ALOGV("%s tid=%d grp=%d", __func__, tid, grp);
+ SchedPolicy sp = (SchedPolicy) grp;
+ int res = set_sched_policy(tid, sp);
if (res != NO_ERROR) {
- signalExceptionForGroupError(env, res == BAD_VALUE ? EINVAL : errno);
- return;
+ signalExceptionForGroupError(env, -res);
}
}
void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
{
+ ALOGV("%s pid=%d grp=%d", __func__, pid, grp);
DIR *d;
FILE *fp;
char proc_path[255];
struct dirent *de;
- if (grp > ANDROID_TGROUP_MAX || grp < 0) {
+ if ((grp == SP_FOREGROUND) || (grp > SP_MAX)) {
signalExceptionForGroupError(env, EINVAL);
return;
}
+ bool isDefault = false;
+ if (grp < 0) {
+ grp = SP_FOREGROUND;
+ isDefault = true;
+ }
+ SchedPolicy sp = (SchedPolicy) grp;
+
#if POLICY_DEBUG
char cmdline[32];
int fd;
@@ -203,7 +215,7 @@
close(fd);
}
- if (grp == ANDROID_TGROUP_BG_NONINTERACT) {
+ if (sp == SP_BACKGROUND) {
ALOGD("setProcessGroup: vvv pid %d (%s)", pid, cmdline);
} else {
ALOGD("setProcessGroup: ^^^ pid %d (%s)", pid, cmdline);
@@ -230,16 +242,18 @@
continue;
}
- t_pri = getpriority(PRIO_PROCESS, t_pid);
+ if (isDefault) {
+ t_pri = getpriority(PRIO_PROCESS, t_pid);
- if (grp == ANDROID_TGROUP_DEFAULT &&
- t_pri >= ANDROID_PRIORITY_BACKGROUND) {
- // This task wants to stay at background
- continue;
+ if (t_pri >= ANDROID_PRIORITY_BACKGROUND) {
+ // This task wants to stay at background
+ continue;
+ }
}
- if (androidSetThreadSchedulingGroup(t_pid, grp) != NO_ERROR) {
- signalExceptionForGroupError(env, errno);
+ int err = set_sched_policy(t_pid, sp);
+ if (err != NO_ERROR) {
+ signalExceptionForGroupError(env, -err);
break;
}
}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 6028814..d4d60d3 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -660,9 +660,9 @@
static jint android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList,
- jint width, jint height, jobject dirty, jint flags) {
+ jobject dirty, jint flags) {
android::uirenderer::Rect bounds;
- status_t status = renderer->drawDisplayList(displayList, width, height, bounds, flags);
+ status_t status = renderer->drawDisplayList(displayList, bounds, flags);
if (status != DrawGlInfo::kStatusDone && dirty != NULL) {
env->CallVoidMethod(dirty, gRectClassInfo.set,
int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
@@ -917,7 +917,7 @@
{ "nGetDisplayListSize", "(I)I", (void*) android_view_GLES20Canvas_getDisplayListSize },
{ "nSetDisplayListName", "(ILjava/lang/String;)V",
(void*) android_view_GLES20Canvas_setDisplayListName },
- { "nDrawDisplayList", "(IIIILandroid/graphics/Rect;I)I",
+ { "nDrawDisplayList", "(IILandroid/graphics/Rect;I)I",
(void*) android_view_GLES20Canvas_drawDisplayList },
{ "nCreateDisplayListRenderer", "()I", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index 5cb172b..d1f0a6a 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -35,13 +35,13 @@
} gInputDeviceClassInfo;
jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& deviceInfo) {
- ScopedLocalRef<jstring> nameObj(env, env->NewStringUTF(deviceInfo.getName().string()));
+ ScopedLocalRef<jstring> nameObj(env, env->NewStringUTF(deviceInfo.getDisplayName().string()));
if (!nameObj.get()) {
return NULL;
}
ScopedLocalRef<jstring> descriptorObj(env,
- env->NewStringUTF(deviceInfo.getDescriptor().string()));
+ env->NewStringUTF(deviceInfo.getIdentifier().descriptor.string()));
if (!descriptorObj.get()) {
return NULL;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f5c0f8f..4443bc8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -202,6 +202,23 @@
android:label="@string/permlab_receiveEmergencyBroadcast"
android:description="@string/permdesc_receiveEmergencyBroadcast" />
+ <!-- Allows an application to read previously received cell broadcast
+ messages and to register a content observer to get notifications when
+ a cell broadcast has been received and added to the database. For
+ emergency alerts, the database is updated immediately after the
+ alert dialog and notification sound/vibration/speech are presented.
+ The "read" column is then updated after the user dismisses the alert.
+ This enables supplementary emergency assistance apps to start loading
+ additional emergency information (if Internet access is available)
+ when the alert is first received, and to delay presenting the info
+ to the user until after the initial alert dialog is dismissed.
+ @hide Pending API council approval -->
+ <permission android:name="android.permission.READ_CELL_BROADCASTS"
+ android:permissionGroup="android.permission-group.MESSAGES"
+ android:protectionLevel="dangerous"
+ android:label="@string/permlab_readCellBroadcasts"
+ android:description="@string/permdesc_readCellBroadcasts" />
+
<!-- Allows an application to read SMS messages. -->
<permission android:name="android.permission.READ_SMS"
android:permissionGroup="android.permission-group.MESSAGES"
@@ -737,6 +754,14 @@
android:label="@string/permlab_removeTasks"
android:description="@string/permdesc_removeTasks" />
+ <!-- Allows an application to start any activity, regardless of permission
+ protection or exported state. @hide -->
+ <permission android:name="android.permission.START_ANY_ACTIVITY"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signature"
+ android:label="@string/permlab_startAnyActivity"
+ android:description="@string/permdesc_startAnyActivity" />
+
<!-- @hide Change the screen compatibility mode of applications -->
<permission android:name="android.permission.SET_SCREEN_COMPATIBILITY"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
diff --git a/packages/SystemUI/res/drawable/notification_row_bg.xml b/core/res/res/drawable/notification_bg.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/notification_row_bg.xml
rename to core/res/res/drawable/notification_bg.xml
diff --git a/core/res/res/layout-sw600dp/status_bar_latest_event_ticker.xml b/core/res/res/layout-sw720dp/status_bar_latest_event_ticker.xml
similarity index 100%
rename from core/res/res/layout-sw600dp/status_bar_latest_event_ticker.xml
rename to core/res/res/layout-sw720dp/status_bar_latest_event_ticker.xml
diff --git a/core/res/res/layout-sw600dp/status_bar_latest_event_ticker_large_icon.xml b/core/res/res/layout-sw720dp/status_bar_latest_event_ticker_large_icon.xml
similarity index 100%
rename from core/res/res/layout-sw600dp/status_bar_latest_event_ticker_large_icon.xml
rename to core/res/res/layout-sw720dp/status_bar_latest_event_ticker_large_icon.xml
diff --git a/core/res/res/layout/adaptive_notification_wrapper.xml b/core/res/res/layout/adaptive_notification_wrapper.xml
new file mode 100644
index 0000000..df9d720
--- /dev/null
+++ b/core/res/res/layout/adaptive_notification_wrapper.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:textAppearance="?android:attr/dropDownHintAppearance"
+ android:singleLine="true"
+ android:layout_marginLeft="3dip"
+ android:layout_marginTop="3dip"
+ android:layout_marginRight="3dip"
+ android:layout_marginBottom="3dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
diff --git a/core/res/res/layout/notification_template_base.xml b/core/res/res/layout/notification_template_base.xml
index b9710d6..af05aed 100644
--- a/core/res/res/layout/notification_template_base.xml
+++ b/core/res/res/layout/notification_template_base.xml
@@ -15,9 +15,13 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+ android:background="@android:drawable/notification_bg"
android:id="@+id/status_bar_latest_event_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="64dp"
+ internal:layout_minHeight="64dp"
+ internal:layout_maxHeight="64dp"
>
<ImageView android:id="@+id/icon"
android:layout_width="@dimen/notification_large_icon_width"
diff --git a/core/res/res/layout/notification_template_big_base.xml b/core/res/res/layout/notification_template_big_base.xml
new file mode 100644
index 0000000..5de584d
--- /dev/null
+++ b/core/res/res/layout/notification_template_big_base.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+ android:background="@android:drawable/notification_bg"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ internal:layout_minHeight="65dp"
+ internal:layout_maxHeight="unbounded"
+ >
+ <ImageView android:id="@+id/icon"
+ android:layout_width="@dimen/notification_large_icon_width"
+ android:layout_height="@dimen/notification_large_icon_height"
+ android:background="@android:drawable/notify_panel_notification_icon_bg_tile"
+ android:scaleType="center"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="fill_vertical"
+ android:layout_marginLeft="@dimen/notification_large_icon_width"
+ android:minHeight="@dimen/notification_large_icon_height"
+ android:orientation="vertical"
+ android:paddingLeft="12dp"
+ android:paddingRight="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
+ android:gravity="center_vertical"
+ >
+ <LinearLayout
+ android:id="@+id/line1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView android:id="@+id/title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:layout_weight="1"
+ />
+ <ViewStub android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_time"
+ />
+ <ViewStub android:id="@+id/chronometer"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_chronometer"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/text2"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="-2dp"
+ android:layout_marginBottom="-2dp"
+ android:singleLine="true"
+ android:fadingEdge="horizontal"
+ android:ellipsize="marquee"
+ android:visibility="gone"
+ />
+ <TextView android:id="@+id/big_text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="false"
+ android:visibility="gone"
+ />
+ <LinearLayout
+ android:id="@+id/line3"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView android:id="@+id/text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="center"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ <TextView android:id="@+id/info"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:singleLine="true"
+ android:gravity="center"
+ android:paddingLeft="8dp"
+ />
+ <ImageView android:id="@+id/right_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:scaleType="center"
+ android:paddingLeft="8dp"
+ android:visibility="gone"
+ android:drawableAlpha="180"
+ />
+ </LinearLayout>
+ <ProgressBar
+ android:id="@android:id/progress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ style="?android:attr/progressBarStyleHorizontal"
+ />
+ <LinearLayout
+ android:id="@+id/actions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ >
+ <!-- actions will be added here -->
+ </LinearLayout>
+ </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_template_big_picture.xml b/core/res/res/layout/notification_template_big_picture.xml
index 8be84bd..51e46b2 100644
--- a/core/res/res/layout/notification_template_big_picture.xml
+++ b/core/res/res/layout/notification_template_big_picture.xml
@@ -15,9 +15,13 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+ android:background="@android:drawable/notification_bg"
android:id="@+id/status_bar_latest_event_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ internal:layout_minHeight="65dp"
+ internal:layout_maxHeight="unbounded"
>
<ImageView
android:id="@+id/big_picture"
@@ -30,4 +34,4 @@
android:layout_height="wrap_content"
android:layout_marginTop="192dp"
/>
-</FrameLayout>
\ No newline at end of file
+</FrameLayout>
diff --git a/core/res/res/layout/notification_template_big_text.xml b/core/res/res/layout/notification_template_big_text.xml
new file mode 100644
index 0000000..b6d71e1
--- /dev/null
+++ b/core/res/res/layout/notification_template_big_text.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+ android:background="@android:drawable/notification_bg"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ internal:layout_minHeight="65dp"
+ internal:layout_maxHeight="unbounded"
+ >
+ <ImageView android:id="@+id/icon"
+ android:layout_width="@dimen/notification_large_icon_width"
+ android:layout_height="@dimen/notification_large_icon_height"
+ android:background="@android:drawable/notify_panel_notification_icon_bg_tile"
+ android:scaleType="center"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="fill_vertical"
+ android:layout_marginLeft="@dimen/notification_large_icon_width"
+ android:minHeight="@dimen/notification_large_icon_height"
+ android:orientation="vertical"
+ android:paddingLeft="12dp"
+ android:paddingRight="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
+ android:gravity="center_vertical"
+ >
+ <LinearLayout
+ android:id="@+id/line1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView android:id="@+id/title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:layout_weight="1"
+ />
+ <ViewStub android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_time"
+ />
+ <ViewStub android:id="@+id/chronometer"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_chronometer"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/text2"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="-2dp"
+ android:layout_marginBottom="-2dp"
+ android:singleLine="true"
+ android:fadingEdge="horizontal"
+ android:ellipsize="marquee"
+ android:visibility="gone"
+ />
+ <TextView android:id="@+id/big_text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="false"
+ android:visibility="gone"
+ />
+ <LinearLayout
+ android:id="@+id/line3"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView android:id="@+id/text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="center"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ <TextView android:id="@+id/info"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:singleLine="true"
+ android:gravity="center"
+ android:paddingLeft="8dp"
+ />
+ <ImageView android:id="@+id/right_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:scaleType="center"
+ android:paddingLeft="8dp"
+ android:visibility="gone"
+ android:drawableAlpha="180"
+ />
+ </LinearLayout>
+ <ProgressBar
+ android:id="@android:id/progress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ style="?android:attr/progressBarStyleHorizontal"
+ />
+ <LinearLayout
+ android:id="@+id/actions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ >
+ <!-- actions will be added here -->
+ </LinearLayout>
+ </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_template_inbox.xml b/core/res/res/layout/notification_template_inbox.xml
new file mode 100644
index 0000000..82342d4
--- /dev/null
+++ b/core/res/res/layout/notification_template_inbox.xml
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ >
+ <ImageView android:id="@+id/icon"
+ android:layout_width="@dimen/notification_large_icon_width"
+ android:layout_height="@dimen/notification_large_icon_height"
+ android:background="@android:drawable/notify_panel_notification_icon_bg_tile"
+ android:scaleType="center"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="fill_vertical"
+ android:layout_marginLeft="@dimen/notification_large_icon_width"
+ android:minHeight="@dimen/notification_large_icon_height"
+ android:orientation="vertical"
+ android:paddingLeft="12dp"
+ android:paddingRight="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
+ android:gravity="center_vertical"
+ >
+ <LinearLayout
+ android:id="@+id/line1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView android:id="@+id/title"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:layout_weight="1"
+ />
+ <ViewStub android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_time"
+ />
+ <ViewStub android:id="@+id/chronometer"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:visibility="gone"
+ android:layout="@layout/notification_template_part_chronometer"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/text2"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="-2dp"
+ android:layout_marginBottom="-2dp"
+ android:singleLine="true"
+ android:fadingEdge="horizontal"
+ android:ellipsize="marquee"
+ android:visibility="gone"
+ />
+ <TextView android:id="@+id/inbox_text0"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ />
+ <TextView android:id="@+id/inbox_text1"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ />
+ <TextView android:id="@+id/inbox_text2"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ />
+ <TextView android:id="@+id/inbox_text3"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ />
+ <TextView android:id="@+id/inbox_text4"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:visibility="gone"
+ />
+ <LinearLayout
+ android:id="@+id/line3"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView android:id="@+id/text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="center"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+ <TextView android:id="@+id/info"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:singleLine="true"
+ android:gravity="center"
+ android:paddingLeft="8dp"
+ />
+ <ImageView android:id="@+id/right_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:scaleType="center"
+ android:paddingLeft="8dp"
+ android:visibility="gone"
+ android:drawableAlpha="180"
+ />
+ </LinearLayout>
+ <ProgressBar
+ android:id="@android:id/progress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ style="?android:attr/progressBarStyleHorizontal"
+ />
+ <LinearLayout
+ android:id="@+id/actions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ >
+ <!-- actions will be added here -->
+ </LinearLayout>
+ </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/raw/accessibility_gestures.bin b/core/res/res/raw/accessibility_gestures.bin
index 1f95e56..f7e6615 100644
--- a/core/res/res/raw/accessibility_gestures.bin
+++ b/core/res/res/raw/accessibility_gestures.bin
Binary files differ
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index d299436..f225f52 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Jou tablet gaan nou afskakel."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Jou foon gaan nou afsit."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Wil jy afskakel?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Onlangs"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Geen onlangse programme nie."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet-opsies"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Laat die program toe om MMS-boodskappe te ontvang en te verwerk. Kwaadwillige programme kan jou boodskappe monitor of uitvee sonder om dit aan jou te wys."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"ontvang nooduitsendings"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Laat die program toe om nooduitsending-boodskappe te ontvang en te verwerk. Hierdie toestemming is net beskikbaar vir stelselprogramme."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lees seluitsending-boodskappe"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Laat die program toe om seluitsending-boodskappe te lees wat deur jou toestel ontvang word. Seluitsending-waarskuwings word in sommige plekke afgelewer om jou van noodsituasies te waarsku. Kwaadwillige programme mag inmeng met die prestasie of die werking van jou toestel wanneer \'n noodgeval se seluitsending ontvang word."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"stuur SMS-boodskappe"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Laat die program toe om SMS-boodskappe te stuur. Kwaadwillige programme kan jou geld kos deur boodskappe te stuur sonder jou bevestiging."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"stuur sms-boodskappe met geen bestiging"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Laat die program toe om take na die voorgrond en agtergrond te skuif. Kwaadwillige programme kan hulself sonder jou beheer na vore dwing."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"stop lopende programme"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Laat die program toe om take te verwyder en hul programme te dood. Kwaadwillige programme kan die gedrag van ander programme ontwrig."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"begin enige aktiwiteit"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Laat die program toe om \'n aktiwiteit te begin, ongeag van toestemming-beskerming of uitgevoerde status."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"stel skermversoenbaarheid"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Laat die program toe om om die skermversoenbaarheid-modus van ander programme te beheer. Kwaadwillige programme kan die gedrag van ander programme breek."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"aktiveer programontfouting"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Fabriektoets het gefaal"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index b2714dd..6ab257c 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -70,7 +70,7 @@
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"የደዋይ ID ወደ አልተከለከለም ነባሪዎች።ቀጥሎ ጥሪ፡ ተከልክሏል"</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"የደዋይ ID ነባሪዎች ወደአልተከለከለም። ቀጥሎ ጥሪ፡አልተከለከለም"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"አገልግሎት አልቀረበም።"</string>
- <string name="CLIRPermanent" msgid="3377371145926835671">"የደዋይ መታወቂያ ቅንጅቶች መለወጥ አትችልም፡፡"</string>
+ <string name="CLIRPermanent" msgid="3377371145926835671">"የደዋይ መታወቂያ ቅንብሮች መለወጥ አትችልም፡፡"</string>
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"ክልክል ድረስተለውጧል"</string>
<string name="RestrictedOnData" msgid="8653794784690065540">"የውሂብ አገልግሎት የታገደ ነው።"</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"የአደጋ ጊዜአገልግሎት የታገደ ነው።"</string>
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"ጡባዊዎ ይዘጋል።"</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"ስልክዎ ይዘጋል።"</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"ዘግተህ መውጣት ትፈልጋለህ?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"የቅርብ ጊዜ"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"ምንም የቅርብ ጊዜ ትግበራዎች የሉም"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"የጡባዊ አማራጮች"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"ኤም ኤም ኤስ መልዕክቶችን ለመቀበል እና ለማስኬድ ለመተግበሪያው ይፈቅዳሉ፡፡ ተንኮል አዘል መተግበሪያዎች አንተን ሳያሳዩ ሊሰርዙዎቸው ወይም መልዕክቶችህን ሊቆጣጠሩ ይችላሉ፡፡"</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"የአደጋ ጊዜ ስርጭቶችን ተቀበል"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"ድንገተኛ የስርጭት መልዕክቶችን ለመቀበል እና ለማስኬድ ለመተግበሪያው ይፈቅዳሉ፡፡ ይሄ ፍቃድ ለስርዓት መተግበሪዎች ብቻ ነው የሚገኘው፡፡"</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"የህዋስ ስርጭት መልዕክቶችን አንብብ"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"መሣሪያህ የህዋስ ስርጭት መልዕክቶች ሲቀበል መተግበሪያው እንዲያነበው ይፈቅድለታል። የህዋስ ስርጭት ማንቂያዎች አስቸኳይ ሁኔታዎች ሲያጋጥሙ አንዳንድ አካባቢዎች ላይ የሚላኩ ናቸው። የህዋስ ስርጭት ሲደርስ ተንኮል አዘል መተግበሪያዎች በመሣሪያህ አፈጻጸም ወይም አሰራር ላይ ጣልቃ ሊገቡ ይችላሉ።"</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"የSMS መልዕክቶች ላክ"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"ኤስ ኤም ኤስ መልዕክቶችን መላክ ለመተግበሪያው ይፈቅዳሉ፡፡ ያላንተ ማረጋገጫ ተንኮል አዘል መተግበሪያዎች መልዕክቶችን በመላክ ገንዘብ ሊያስወጡህ ይችላሉ፡፡"</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"ያለ ምንም ማረጋገጫ የSMS መልዕክቶች ላክ"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"ወደ ግንባር ዎይ እና ዳራ ስራዎችን ለማንቀሳቀስ ለመተግበሪያው ይፈቅዳሉ፡፡ ያለአንተ ቁጥጥር ተንኮል አዘል መተግበሪያዎች ራሳቸውን ወደፊት መምጣት ሊያስገድዱ ይችላሉ፡፡"</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"የአሂድ ትግበራዎች አቁም"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"ተግባሮችን ለማስወገድ እና መተግበሪያዎቻቸውን ለመግደል ለመተግበሪያ ይፈቅዳል። ጎጂ የሆኑ መተግበሪያዎች የሌሎችን መተግበሪያዎችን ባህሪ ሊያውኩ ይችላሉ።"</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ማንኛውም እንቅስቃሴ ጀምር"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"መተግበሪያው ማንኛውም እንቅስቃሴ፣ የፍቃድ ጥበቃም ሆነ ወደ ውጭ የተላከበት ሁኔታ ሳይታይ፣ እንዲጀምር ይፈቅድለታል።"</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"የማያ ገጽ ተኳኋኝነት መድብ"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"መተግበሪያው የሌሎች መተግበሪያዎች የማያ ገጽ ተኳኋኝነት ሁናቴ እንዲቆጣጠር ይፈቅዳል። ተንኮለኛ መተግበሪያዎች የሌሎች መተግበሪያዎች ባህሪ ሊሰብሩ ይችላሉ።"</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"የትግበራ ማረሚያ አንቃ"</string>
@@ -375,7 +383,7 @@
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"የንዑስ ክፈፍ ቋት አንብብ"</string>
<string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"የክፈፍ ቋት ይዘት ለማንበብ ለመተግበሪያው ይፈቅዳሉ።"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"የድምፅ ቅንብሮችን ለውጥ"</string>
- <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"የዓለም አቀፍ ኦዲዮ ቅንጅቶች እንደ ድምፅ እና ፈለግ ለመቀየር ለመተግበሪያው ይፈቅዳሉ ።"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"የዓለም አቀፍ ኦዲዮ ቅንብሮች እንደ ድምፅ እና ፈለግ ለመቀየር ለመተግበሪያው ይፈቅዳሉ ።"</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"ኦዲዮ ቅዳ"</string>
<string name="permdesc_recordAudio" msgid="2387462233976248635">"መተግበሪያ የድምፅ መዝገብ ዱካን ለመድረስ ይፈቅዳል።"</string>
<string name="permlab_camera" msgid="3616391919559751192">"ፎቶዎች እና ቪዲዮዎች አንሳ"</string>
@@ -445,7 +453,7 @@
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"የልጣፍአዘጋጅ መጠን ፍንጮች"</string>
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"የስርዓቱን ልጥፍ መጠንለማዘጋጀት ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"ስርዓትን ወደ ፋብሪካ ነባሪዎች ዳግም አስጀምር"</string>
- <string name="permdesc_masterClear" msgid="3665380492633910226">"ወደ ፋብሪካው ቅንጅቶች ሙሉ በሙሉ ስርዓቱን ዳግም ለማስጀመር ለመተግበሪያው ይፈቅዳሉ ፤ ሁሉንም ውሂብ፣ አወቃቀር፣ እና የተጫኑ መተግበሪያዎችን በማጥፈት፡፡"</string>
+ <string name="permdesc_masterClear" msgid="3665380492633910226">"ወደ ፋብሪካው ቅንብሮች ሙሉ በሙሉ ስርዓቱን ዳግም ለማስጀመር ለመተግበሪያው ይፈቅዳሉ ፤ ሁሉንም ውሂብ፣ አወቃቀር፣ እና የተጫኑ መተግበሪያዎችን በማጥፈት፡፡"</string>
<string name="permlab_setTime" msgid="2021614829591775646">"ሰዓት ሙላ"</string>
<string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"መተግበሪያውን የጡባዊ ተኮን ሰዓት ለመለወጥ ይፈቅዳሉ።"</string>
<string name="permdesc_setTime" product="default" msgid="1855702730738020">"መተግበሪያውን የስልኩን ሰዓት ለመለወጥ ይፈቅዳሉ።"</string>
@@ -474,7 +482,7 @@
<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="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"የዳራ ውሂብ አጠቃቀም ቅንብሮች ለመለወጥ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
<string name="permlab_accessWifiState" msgid="8100926650211034400">"የWi-Fi ሁኔታ እይ"</string>
<string name="permdesc_accessWifiState" msgid="7770452658226256831">"ስለWi-Fi ሁኔታ መረጃን ለማየት ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
<string name="permlab_changeWifiState" msgid="7280632711057112137">"የWi-Fi ሁኔታን ለውጥ"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"የፋብሪካሙከራ ተስኗል"</string>
@@ -924,7 +940,7 @@
<string name="capital_off" msgid="6815870386972805832">"ውጪ"</string>
<string name="whichApplication" msgid="4533185947064773386">"... በመጠቀም ድርጊቱን አጠናቅ"</string>
<string name="alwaysUse" msgid="4583018368000610438">"ለዕርምጃ ነባሪ ተጠቀም።"</string>
- <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ነባሪ አጽዳ በስርዓት ቅንጅቶች ውስጥ > Apps &gt፤ወርዷል፡፡"</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ነባሪ አጽዳ በስርዓት ቅንብሮች ውስጥ > Apps &gt፤ወርዷል፡፡"</string>
<string name="chooseActivity" msgid="7486876147751803333">"ድርጊት ምረጥ"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"ለUSB መሳሪያ መተግበሪያ ምረጥ"</string>
<string name="noApplications" msgid="2991814273936504689">"ምንም ትግበራዎች ይህን ድርጊት ማከናወን አይችሉም።"</string>
@@ -945,7 +961,7 @@
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> በዋናነት የተነሳው።"</string>
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"የልኬት ለውጥ"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"ሁልጊዜ አሳይ"</string>
- <string name="screen_compat_mode_hint" msgid="1064524084543304459">"በስርዓት ቅንጅቶች ውስጥ ይሄንን ዳግም አንቃ> Apps &gt፤ወርዷል፡፡"</string>
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"በስርዓት ቅንብሮች ውስጥ ይሄንን ዳግም አንቃ> Apps &gt፤ወርዷል፡፡"</string>
<string name="smv_application" msgid="3307209192155442829">"መተግበሪያው <xliff:g id="APPLICATION">%1$s</xliff:g>( ሂደት<xliff:g id="PROCESS">%2$s</xliff:g>) በራስ ተነሳሺ StrictMode ደንብን ይተላለፋል።"</string>
<string name="smv_process" msgid="5120397012047462446">"ሂደቱ <xliff:g id="PROCESS">%1$s</xliff:g> በራስ ተነሳሺ StrictMode ፖሊሲን ይተላለፋል።"</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android እያሻሻለ ነው..."</string>
@@ -1008,7 +1024,7 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"ፒን፦"</string>
<string name="select_character" msgid="3365550120617701745">"ቁምፊ አስገባ"</string>
<string name="sms_control_title" msgid="7296612781128917719">"የSMS መልዕክቶች መበላክ ላይ"</string>
- <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ቁጥሩ ብዙ የሆኑ የኤስ.ኤም.ኤስ. መልዕቶችን እየላከ ነው። ይሄ መተግበሪያ መልዕክቶችን መላኩን እንዲቀጥል መፍቀድ ትፈልጋለህ?"</string>
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ቁጥራቸው ብዙ የሆኑ የኤስ.ኤም.ኤስ. መልዕክቶችን እየላከ ነው። ይሄ መተግበሪያ መልዕክቶችን መላኩን እንዲቀጥል መፍቀድ ትፈልጋለህ?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"ፍቀድ"</string>
<string name="sms_control_no" msgid="625438561395534982">"ከልክል"</string>
<string name="sms_short_code_confirm_title" msgid="1666863092640877318">"ኤስ.ኤም.ኤስ. ለአጭር ኮድ ይላክ?"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index daef582..7c4f7f3 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"سيتم إيقاف تشغيل الجهاز اللوحي."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"سيتم إيقاف تشغيل هاتفك."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"هل تريد إيقاف التشغيل؟"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"حديثة"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"ليست هناك تطبيقات حديثة."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"خيارات الجهاز اللوحي"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"للسماح للتطبيق بتلقي رسائل الوسائط المتعددة ومعالجتها. قد تراقب بعض التطبيقات الضارة رسائلك أو تحذفها بدون عرضها لك."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"تلقي بث الطوارئ"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"للسماح للتطبيق بتلقي رسائل بث الطوارئ ومعالجتها. لا يتوفر هذا الإذن سوى لتطبيقات النظام."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"قراءة رسائل بث الخلية"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"السماح للتطبيق بقراءة رسائل بث الخلية التي يتلقاها هذا الجهاز. يتم تسليم تنبيهات بث الخلية في بعض المواقع لتحذيرك من حالات طارئة. يمكن أن تتداخل التطبيقات الضارة مع أداء أو تشغيل الجهاز عندما يتم تلقي بث خلية طارئ."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"إرسال رسائل قصيرة SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"للسماح للتطبيق بإرسال رسائل قصيرة SMS. قد تكلفك التطبيقات الضارة المال من خلال إرسال رسائل بدون تأكيدك."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"إرسال رسائل قصيرة SMS بدون تأكيد"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"للسماح لتطبيق ما بنقل المهام إلى المقدمة والخلفية. قد تفرض التطبيقات الضارة نفسها إلى المقدمة بدون تحكم منك."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"إيقاف التطبيقات التي قيد التشغيل"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"للسماح للتطبيق بإزالة المهام وإنهاء تطبيقاتها. قد تعطل التطبيقات الضارة عمل التطبيقات الأخرى."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"بدء أي نشاط"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"للسماح للتطبيق ببدء أي نشاط، بغض النظر عن حماية الإذن أو حالة التصدير."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"تعيين توافق الشاشة"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"السماح للتطبيق بالتحكم في وضع التوافق مع شاشة التطبيقات الأخرى. قد تتسبب التطبيقات الضارة في تعطيل سلوك التطبيقات الأخرى."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"تمكين تصحيح أخطاء التطبيق"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ب ت ث"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"أخفق اختبار المصنع"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"رقم التعريف الشخصي:"</string>
<string name="select_character" msgid="3365550120617701745">"إدراج حرف"</string>
<string name="sms_control_title" msgid="7296612781128917719">"إرسال رسائل قصيرة SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> يرسل عددًا كبيرًا من الرسائل القصيرة SMS. هل تريد السماح لهذا التطبيق بالاستمرار في إرسال الرسائل؟"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"السماح"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"رفض"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"إرسال رسالة SMS إلى رمز قصير؟"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"هل تريد إرسال رسالة قصيرة SMS مميزة؟"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> يريد إرسال رسالة نصية إلى <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>، والذي يُعد رمزًا قصيرًا لرسالة قصيرة SMS.<p>قد يؤدي إرسال رسائل نصية إلى بعض الرموز القصيرة إلى تحصيل رسوم من حساب جوالك للخدمات المميزة.<p>هل تريد السماح لهذا التطبيق بإرسال الرسالة؟"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> يريد إرسال رسالة نصية إلى <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>، والذي يُعد رمزًا قصيرًا لرسالة قصيرة SMS مميزة.<p><b>سيؤدي إرسال رسالة إلى هذه الوجهة إلى تحصيل رسوم من حساب جوالك للخدمات المميزة.</b><p>هل تريد السماح لهذا التطبيق بإرسال الرسالة؟"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"إرسال رسالة"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"عدم الإرسال"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"الإبلاغ عن تطبيق ضار"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"تمت إزالة بطاقة SIM"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"لن تكون شبكة الجوال متاحة حتى تتم إعادة التشغيل وإدخال بطاقة SIM صالحة."</string>
<string name="sim_done_button" msgid="827949989369963775">"تم"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index c155537..604d5e8 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшэт будзе адключаны."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Ваш тэлефон будзе выключаны."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Закрыць?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Апошнія"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Няма апошніх прыкладанняў."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Параметры планшэта"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Дазваляе прыкладанням атрымліваць і апрацоўваць MMS-паведамленні. Шкоднасныя прыкладанні могуць адсочваць вашы паведамленні або выдаляць іх, не паказваючы вам."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"атрымліваць экстраныя трансляцыі"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Дазваляе прыкладанням атрымліваць і апрацоўваць экстраныя паведамленні. Гэты дазвол даступны толькі для сістэмных прыкладанняў."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"адпраўляць SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Дазваляе прыкладанням дасылаць SMS-паведамленні. Шкоднасныя прыкладанні могуць каштаваць вам грошай з-за адпраўкі паведамленняў без вашага пацвярджэння."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"адпраўляць SMS-паведамленні без пацверджання"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Дазваляе прыкладанням перамяшчаць заданні на пярэдні план і фон. Шкоднасныя прыкладанні могуць прымусова рабіць сябе асноўнымі без вашага ведама."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"спыніць запушчаныя прыкладанні"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Дазваляе прыкладанням выдаляць заданні і спыняць прыкладанні, якія іх выкарыстоўваюць. Шкоднасныя прыкладаннi могуць перашкодзiць працы іншых прыкладанняў."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"усталяваць сумяшчальнасць экранаў"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Дазваляе прыкладанню кіраваць рэжымам сумяшчальнасці экранаў іншых прыкладанняў. Шкоднаснае ПЗ можа перашкодзiць працы іншых прыкладанняў."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"уключыць адладку прыкладання"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Не атрымалася выканаць заводскую праверку"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-код"</string>
<string name="select_character" msgid="3365550120617701745">"Уставіць сімвал"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Адпраўка SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"Прыкладанне <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> дасылае вялікую колькасць SMS-паведамленняў. Дазволіць гэтаму прыкладанню працягваць адпраўляць паведамленні?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Дазволіць"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Забараніць"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Адправiць SMS на кароткі нумар?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Адправiць платнае SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Прыкладанне <b><xliff:g id="APP_NAME">%1$s</xliff:g></b&gt спрабуе адправiць тэкставае паведамленне на нумар <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, які, здаецца, з\'яўляецца кароткім нумарам для SMS.<p>Дасыланне тэкставых паведамленняў на кароткія нумары можа прывесці да спісання сродкаў з вашага мабільнага рахунку за платныя паслугі.</b><p>Жадаеце дазволіць гэтаму прыкладанню даслаць паведамленне?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Прыкладанне <b><xliff:g id="APP_NAME">%1$s</xliff:g></b&g спрабуе адправiць тэкставае паведамленне на нумар <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, які з\'яўляецца платным кароткім нумарам для SMS.<p><b>Адпраўка паведамлення гэтаму атрымальніку прывядзе да спісання сродкаў з вашага мабільнага рахунку за платныя паслугі.</b><p>Жадаеце дазволіць гэтаму прыкладанню даслаць паведамленне?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Адправiць паведамленне"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Не адпраўляць"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Павед. аб шкодн. прыкладаннях"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-карта выдаленая"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Мабільная сетка будзе недаступная да перазагрузкі з дзеючай SIM-картай."</string>
<string name="sim_done_button" msgid="827949989369963775">"Гатова"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 7860382..5103bb9 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Таблетът ви ще се изключи."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Телефонът ви ще се изключи."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Искате ли да изключите?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Скорошни"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Няма скорошни приложения."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Опции за таблета"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Разрешава на приложението да получава и обработва MMS съобщения. Злонамерените приложения могат да наблюдават съобщенията ви или да ги изтрият, без да ви ги покажат."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"получаване на спешни излъчвания"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Разрешава на приложението да получава и обработва спешни съобщения за излъчване. Това разрешение е налице само за системни приложения."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"изпращане на SMS съобщения"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Разрешава на приложението да изпраща SMS съобщения. Злонамерените приложения могат да ви въвлекат в разходи, като изпращат съобщения без потвърждение от ваша страна."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"изпращане на SMS съобщения без потвърждаване"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Разрешава на приложението да прехвърля задачи на преден и на заден план. Злонамерените приложения могат сами да се изведат на преден план без ваша намеса."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"спиране на изпълняваните приложения"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Разрешава на приложението да премахва задачи и да прекратява приложенията им. Злонамерените приложения могат да нарушат поведението на други приложения."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"задаване на съвместимост на екрана"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Разрешава на приложението да контролира режима на съвместимост на екрана на други приложения. Злонамерените програми могат да нарушат поведението на други приложения."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"активиране на отстраняването на грешки в приложения"</string>
@@ -286,10 +298,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Разрешава на приложението да променя ориентацията на екрана по всяко време. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"промяна на скоростта на курсор"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Разрешава на приложението да променя скоростта на курсора на мишката или на тракпада по всяко време. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"промяна на клавиат. подредба"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Разрешава на приложението да променя клавиатурната подредба. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"изпращане на сигнали от Linux до приложенията"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Разрешава на приложението да подаде заявка предоставеният сигнал да се изпрати до всички постоянни процеси."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"задаване на постоянно изпълнение на приложението"</string>
@@ -736,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Фабричният тест не бе успешен"</string>
@@ -1010,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"ПИН:"</string>
<string name="select_character" msgid="3365550120617701745">"Вмъкване на знак"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Изпращане на SMS съобщения"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> изпраща голям брой SMS съобщения. Искате ли да разрешите на това приложение да продължи да го прави?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Разрешаване"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Отказване"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Да се изпрати ли SMS до кратък код?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Да се изпрати ли импулсен SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> иска да изпрати текстово съобщение до <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, което изглежда е кратък код на SMS.<p>Изпращането на съобщения до някои такива кодове може да доведе до таксуване на мобилната ви сметка за услуги, които се плащат допълнително.<p>Искате ли да разрешите на това приложение да изпрати съобщението?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> иска да изпрати текстово съобщение до <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, което е кратък код за импулсен SMS.<p><b>Изпращането до тази точка ще доведе до таксуване на мобилната ви сметка за услуги, които се плащат допълнително.</b><p>Искате ли да разрешите на това приложение да изпрати съобщението?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Изпращане на съобщението"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Да не се изпраща"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Сигнал за злонам. приложение"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM картата е премахната"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Няма да имате достъп до мобилната мрежа, докато не рестартирате с поставена валидна SIM карта."</string>
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
@@ -1079,10 +1087,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"Докоснете, за да деактивирате отстраняването на грешки през USB."</string>
<string name="select_input_method" msgid="4653387336791222978">"Избор на метод на въвеждане"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Методи на въвеждане: Настройка"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"Физическа клавиатура"</string>
+ <string name="hardware" msgid="7517821086888990278">"Хардуер"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index e266a85..7505109 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"La tauleta s\'apagarà."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"El telèfon s\'apagarà."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Vols apagar-lo?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recents"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"No hi ha aplicacions recents"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opcions de la tauleta"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Permet que l\'aplicació rebi i processi missatges MMS. Les aplicacions malicioses poden supervisar els missatges o suprimir-los sense mostrar-te\'ls."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"recepció d\'emissions d\'emergència"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Permet que l\'aplicació rebi i processi missatges de difusió d\'emergència. Aquest permís només està disponible per a les aplicacions del sistema."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"llegir missatges de difusió mòbil"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permet que l\'aplicació llegeixi missatges de difusió mòbil rebuts pel dispositiu. Les alertes de difusió mòbil s\'entreguen en algunes ubicacions per alertar de situacions d\'emergència. És possible que les aplicacions malicioses interfereixin en el rendiment o en el funcionament del dispositiu quan es rep una difusió mòbil d\'emergència."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"enviar missatges SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Permet que l\'aplicació enviï missatges SMS. Les aplicacions malicioses poden enviar missatges sense la teva confirmació, cosa que et pot fer gastar diners."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"enviament de missatges SMS sense confirmació"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Permet que l\'aplicació desplaci tasques en primer o segon pla. Les aplicacions malicioses poden aparèixer en primer pla sense el teu consentiment."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"atura les aplicacions que s\'estan executant"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Permet que l\'aplicació elimini tasques i finalitzi les seves aplicacions. Les aplicacions malicioses poden alterar el comportament d\'altres aplicacions."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"iniciar qualsevol activitat"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permet que l\'aplicació iniciï qualsevol activitat, amb independència de la protecció del permís o de l\'estat exportat."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"definició de la compatibilitat de pantalla"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Permet que l\'aplicació controli el mode de compatibilitat de pantalla d\'altres aplicacions. És possible que les aplicacions malicioses interrompin el comportament d\'altres aplicacions."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"activa la depuració d\'aplicacions"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Error a la prova de fàbrica"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 33f91e8..7b7ee4d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet se vypne."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Váš telefon bude vypnut."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Chcete vypnout telefon?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Nejnovější"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Žádné nové aplikace"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Možnosti tabletu"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Umožňuje aplikaci přijmout a zpracovat zprávy MMS. Škodlivé aplikace mohou sledovat vaše zprávy nebo je smazat, aniž by se vám zobrazily."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"příjem nouzového vysílání"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Umožňuje aplikaci přijmout a zpracovat zprávy tísňového vysílání. Toto oprávnění je dostupné pouze pro systémové aplikace."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"odesílaní zpráv SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Umožňuje aplikaci odesílat zprávy SMS. Škodlivé aplikace vás mohou připravit o peníze odesíláním zpráv bez vašeho svolení."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"posílat zprávy SMS bez potvrzení"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Umožňuje aplikaci přesunout úlohy na popředí nebo pozadí. Škodlivé aplikace mohou vynutit zobrazení na popředí bez vašeho svolení."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"zastavení činnosti aplikací"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Umožňuje aplikaci odstranit úlohy a ukončit jejich aplikace. Škodlivé aplikace mohou narušit chování ostatních aplikací."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"nastavit kompatibilitu obrazovky"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Umožňuje aplikaci ovládat režim kompatibility obrazovky v ostatních aplikacích. Škodlivé aplikace mohou narušit chování ostatních aplikací."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"povolení ladění aplikací"</string>
@@ -286,10 +298,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Umožňuje aplikaci kdykoli změnit otočení obrazovky. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"změna rychlosti kurzoru"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Umožňuje aplikaci kdykoli změnit rychlost ukazatele myši nebo touchpadu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"změnit rozložení klávesnice"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Umožňuje aplikaci změnit rozložení klávesnice. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"odeslání signálů systému Linux aplikacím"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Umožňuje aplikaci vyžádat zaslání poskytnutého signálu všem trvalým procesům."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"trvalé spuštění aplikace"</string>
@@ -736,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Test továrního nastavení se nezdařil"</string>
@@ -1010,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Vkládání znaků"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Odesílání zpráv SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"Aplikace <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>odesílá velký počet SMS zpráv. Chcete aplikaci povolit, aby zprávy odesílala i nadále?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Povolit"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Odmítnout"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Odeslat SMS?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Odeslat zprávu Premium SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Aplikace<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce odeslat zprávu na číslo <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, což je zřejmě číslo služby SMS.<p>Za odesílání zpráv na určitá čísla mohou být na mobilní účet naúčtovány poplatky za prémiové služby.<p>Chcete aplikaci povolit odeslání zprávy?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Aplikace <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce poslat zprávu na číslo <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, což je číslo služby Premium SMS.<p><b>Pokud zprávu odešlete na toto číslo, budou vám na mobilní účet naúčtovány poplatky za prémiové služby.</b><p>Chcete aplikaci povolit odeslání zprávy?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Odeslat zprávu"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Neodesílat"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Nahlásit škodlivou aplikaci"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Karta SIM odebrána"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilní síť bude dostupná až poté, co vložíte platnou kartu SIM a restartujete zařízení."</string>
<string name="sim_done_button" msgid="827949989369963775">"Hotovo"</string>
@@ -1079,10 +1087,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"Dotykem zakážete ladění USB."</string>
<string name="select_input_method" msgid="4653387336791222978">"Vybrat metodu vstupu"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Nastavit metody vstupu"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnice"</string>
+ <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c5b0e17..1575205 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Din tabletcomputer slukkes nu."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Din telefon slukkes nu."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Vil du slukke?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Seneste"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Der er ingen seneste apps."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Valgmuligheder for tabletcomputeren"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Tillader, at appen kan modtage og behandle mms-beskeder. Ondsindede apps kan overvåge dine beskeder eller slette dem uden at vise dem til dig."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"modtage nødudsendelser"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Tillader, at appen kan modtage og behandle nødtransmissioner. Denne tilladelse er kun tilgængelig for systemapps."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"læse mobiltransmissionsbeskeder"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tillader, at appen læser mobiltransmissionsbeskeder, der modtages af din enhed. I nogle områder sendes mobiltransmissionsbeskeder for at advare om nødsituationer. Ondsindede apps kan forstyrre ydelsen eller driften af din enhed, når en mobiltransmission om en nødsituation modtages."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"send sms-beskeder"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Tillader, at appen kan sende sms-beskeder. Ondsindede apps kan medføre store omkostninger ved at sende beskeder uden din bekræftelse."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"sende sms-meddelelser uden bekræftelse"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Tillader, at appen kan flytte opgaver til forgrunden og baggrunden. Ondsindede apps kan tvinge sig selv i forgrunden uden din kontrol."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"stoppe kørsel af apps"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Tillader, at en app kan fjerne opgaver og lukke deres apps. Ondsindede apps kan forstyrre adfærden for andre apps."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"starte en aktivitet"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Tillader, at appen starter en hvilken som helst aktivitet, uanset tilladelsesbeskyttelse eller eksportstatus."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"indstil skærmens kompatibilitet"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Tillader, at appen kontrollerer kompatibilitetstilstanden for skærme i andre applikationer. Ondsindede applikationer kan forstyrre andre applikationers adfærd."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"aktivere fejlretning af appen"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Fabrikstest mislykkedes"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"Pinkode:"</string>
<string name="select_character" msgid="3365550120617701745">"Indsæt tegn"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Sender sms-beskeder"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sender et stort antal sms-beskeder. Vil du tillade, at denne app fortsat sender beskeder?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Tillad"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Afvis"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Send sms til shortcode?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Vil du sende en premium-sms?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vil du sende en sms til <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, som ser ud til at være en premium-sms-shortcode.&.<p>Hvis du sender en sms til nogle shortcodes, kan det medføre, at din mobilkonto bliver debiteret for premium-tjenester.<p>Vil du tillade, at denne app sender beskeden?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vil du sende en sms til <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, som er en premium-sms-shortcode.<p><b>Hvis du sender en besked til denne destination, bliver din mobilkonto debiteret for premium-tjenester.</b><p>Vil du tillade, at denne app sender beskeden?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Send besked"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Send ikke"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Rapportér ondsindet app"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kort blev fjernet"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Det mobile netværk er utilgængeligt, indtil du genstarter med et gyldigt SIM-kort."</string>
<string name="sim_done_button" msgid="827949989369963775">"Udfør"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 5a24cb3..8671c66 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ihr Tablet wird heruntergefahren."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon wird heruntergefahren."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Möchten Sie das Gerät herunterfahren?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Kürzlich geöffnet"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Keine kürzlich geöffneten Apps"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet-Optionen"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Ermöglicht der App, MMS-Mitteilungen zu empfangen und zu verarbeiten. Schädliche Apps können so Ihre Nachrichten überwachen oder löschen, bevor sie angezeigt werden."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Notfall-Broadcasts empfangen"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Ermöglicht der App, Notfall-Broadcasts zu empfangen und zu verarbeiten. Diese Berechtigung steht nur System-Apps zur Verfügung."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Cell Broadcast-Nachrichten lesen"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ermöglicht es der App, von Ihrem Gerät empfangene Cell Broadcast-Nachrichten zu lesen. Cell Broadcast-Benachrichtigungen werden an einigen Standorten gesendet, um Sie über Notfallsituationen zu informieren. Schädliche Apps können die Leistung oder den Betrieb Ihres Geräts beeinträchtigen, wenn eine Cell Broadcast-Notfallbenachrichtigung eingeht."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"Kurznachrichten senden"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Ermöglicht der App das Senden von SMS. Bei schädlichen Apps können Kosten entstehen, wenn diese Nachrichten ohne Ihre Zustimmung versenden."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"SMS-Nachrichten ohne Bestätigung senden"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Ermöglicht der App, Aufgaben in den Vorder- und Hintergrund zu verschieben. Schädliche Apps können so ohne Ihr Zutun eine Anzeige im Vordergrund erzwingen."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"Aktive Apps beenden"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Ermöglicht der App, Aufgaben zu entfernen und die entsprechenden Apps zu beenden. Schädliche Apps können das Verhalten anderer Apps stören."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"Beliebige Aktivität starten"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Ermöglicht es der App, ungeachtet der Berechtigungen oder des Exportstatus beliebige Aktivitäten zu starten"</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Bildschirmkompatibilität festlegen"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Ermöglicht der App, den Bildschirmkompatibilitätsmodus anderer Apps zu steuern. Schädliche Apps können das Verhalten anderer Apps stören."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"Fehlerbeseitigung für App aktivieren"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Werkstest fehlgeschlagen"</string>
@@ -929,7 +945,7 @@
<string name="chooseUsbActivity" msgid="6894748416073583509">"App für USB-Gerät auswählen"</string>
<string name="noApplications" msgid="2991814273936504689">"Diese Aktion kann von keiner App ausgeführt werden."</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
- <string name="aerr_application" msgid="932628488013092776">"Leider wurde <xliff:g id="APPLICATION">%1$s</xliff:g> beendet."</string>
+ <string name="aerr_application" msgid="932628488013092776">"Leider wurde \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" beendet."</string>
<string name="aerr_process" msgid="4507058997035697579">"Leider wurde der Prozess <xliff:g id="PROCESS">%1$s</xliff:g> beendet."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reagiert nicht."\n\n"Möchten Sie die App schließen?"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Zeichen einfügen"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Kurznachrichten werden gesendet"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sendet eine große Anzahl SMS. Möchten Sie zulassen, dass die App weiterhin Nachrichten sendet?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Zulassen"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Nicht zulassen"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"SMS an Kurzwahl senden?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Premium-SMS senden?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> versucht, eine SMS an <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> zu senden. Dabei scheint es sich um eine SMS-Kurzwahl zu handeln.<p>Wenn Sie SMS an eine Kurzwahl senden, werden Ihnen für Ihr Mobilfunkkonto möglicherweise Premiumdienste in Rechnung gestellt.<p>Möchten Sie zulassen, dass die App die Nachricht sendet?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> versucht, eine SMS an die Premium-SMS-Kurzwahl <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> zu senden.<p><b>Wenn Sie eine Nachricht an diese Zieladresse senden, werden Ihnen für Ihr Mobilfunkkonto Premiumdienste in Rechnung gestellt.</b><p>Möchten Sie zulassen, dass die App die Nachricht sendet?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Nachricht senden"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nicht senden"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Schädliche App melden"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-Karte entfernt"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Das Mobilfunknetz ist erst wieder verfügbar, wenn Sie einen Neustart mit einer gültigen SIM-Karte durchführen."</string>
<string name="sim_done_button" msgid="827949989369963775">"Fertig"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 7c951cc..2b8c101 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Το tablet σας θα απενεργοποιηθεί."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Το τηλέφωνό σας θα απενεργοποιηθεί."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Θέλετε να γίνει τερματισμός λειτουργίας;"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Πρόσφατα"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Δεν υπάρχουν πρόσφατες εφαρμογές."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Επιλογές tablet"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Επιτρέπει στην εφαρμογή τη λήψη και την επεξεργασία μηνυμάτων MMS. Τυχόν κακόβουλες εφαρμογές ενδέχεται να παρακολουθούν τα μηνύματά σας ή να τα διαγράφουν χωρίς να εμφανίζονται πρώτα σε εσάς."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"λαμβάνει τις μεταδόσεις σε περιπτώσεις έκτακτης ανάγκης"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Επιτρέπει στην εφαρμογή τη λήψη και την επεξεργασία μηνυμάτων μετάδοσης. Αυτή η άδεια διατίθεται μόνο για εφαρμογές συστήματος."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ανάγνωση μηνυμάτων που έχουν μεταδοθεί μέσω κινητού τηλεφώνου"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Επιτρέπει στην εφαρμογή την ανάγνωση μηνυμάτων που έχουν μεταδοθεί μέσω κινητού τηλεφώνου και έχουν ληφθεί από τη συσκευή σας. Ειδοποιήσεις που μεταδίδονται μέσω κινητού παραδίδονται σε ορισμένες τοποθεσίες για να σας προειδοποιήσουν για καταστάσεις έκτακτης ανάγκης. Κακόβουλες εφαρμογές ενδέχεται να παρεμποδίσουν την απόδοση ή τη λειτουργία της συσκευής σας κατά τη λήψη μετάδοσης μέσω κινητού σχετικά με μια επείγουσα κατάσταση."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"αποστολή μηνυμάτων SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Επιτρέπει στην εφαρμογή την αποστολή μηνυμάτων SMS. Τυχόν κακόβουλες εφαρμογές ενδέχεται να κοστίσουν μέσω της αποστολής μηνυμάτων χωρίς δική σας επιβεβαίωση."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"αποστολή μηνυμάτων SMS χωρίς επιβεβαίωση"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Επιτρέπει στην εφαρμογή τη μετακίνηση εργασιών στο προσκήνιο και στο φόντο. Τυχόν κακόβουλες εφαρμογές μπορούν να προωθηθούν στο προσκήνιο χωρίς να μπορείτε να τις ελέγξετε."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"διακοπή εκτέλεσης εφαρμογών"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Επιτρέπει στην εφαρμογή την κατάργηση ενεργειών και την απομάκρυνση των εφαρμογών τους. Τυχόν κακόβουλες εφαρμογές ενδέχεται να διαταράξουν τη λειτουργία άλλων εφαρμογών."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"έναρξη οποιασδήποτε δραστηριότητας"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Επιτρέπει στην εφαρμογή την έναρξη οποιασδήποτε δραστηριότητας, ανεξάρτητα από την προστασία αδειών ή την κατάσταση εξαγωγής."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ρύθμιση συμβατότητας οθόνης"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Επιτρέπει στην εφαρμογή να ελέγξει τη λειτουργία συμβατότητας της οθόνης με άλλες εφαρμογές. Οι κακόβουλες εφαρμογές μπορεί να επηρεάσουν τη συμπεριφορά άλλων εφαρμογών."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"ενεργοποίηση εντοπισμού σφαλμάτων εφαρμογής"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ΑΒΓ"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Η εργοστασιακή δοκιμή απέτυχε"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Εισαγωγή χαρακτήρα"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Αποστολή μηνυμάτων SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"Η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> στέλνει έναν μεγάλο αριθμό μηνυμάτων SMS. Θέλετε να επιτρέψετε σε αυτήν την εφαρμογή να συνεχίσει να στέλνει μηνύματα;"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Αποδοχή"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Άρνηση"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Να αποσταλεί SMS στον κωδικό;"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Να σταλεί SMS ειδικής χρέωσης;"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ζητά την έγκρισή σας για την αποστολή μηνύματος κειμένου στον αριθμό <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ο οποίος φαίνεται ότι είναι κωδικός για την αποστολή SMS με ειδική χρέωση.<p>Η αποστολή μηνύματος σε αυτόν τον αριθμό θα χρεωθεί στον λογαριασμό του κινητού σας ως παροχή υπηρεσιών.<p>Θέλετε να επιτρέψετε σε αυτήν την εφαρμογή να στείλει το μήνυμα;"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> θέλει να στείλει ένα μήνυμα κειμένου στον αριθμό <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ο οποίος είναι ένας κωδικός αποστολής SMS με ειδική χρέωση.<p><b>Η αποστολή μηνύματος σε αυτόν τον αριθμό θα χρεωθεί στον λογαριασμό του κινητού σας ως παροχή υπηρεσιών.</b><p>Θέλετε να επιτρέψετε σε αυτήν την εφαρμογή να στείλει το μήνυμα;"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Αποστολή μηνύματος"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Να μην αποσταλεί"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Αναφορά κακόβουλης εφαρμογής"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Η κάρτα SIM αφαιρέθηκε"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Το δίκτυο κινητής τηλεφωνίας δεν θα είναι διαθέσιμο μέχρι να κάνετε επανεκκίνηση αφού τοποθετήσετε μια έγκυρη κάρτα SIM."</string>
<string name="sim_done_button" msgid="827949989369963775">"Τέλος"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 208e96a..b73e468 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Your tablet will shut down."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Your phone will shut down."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Do you want to shut down?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"No recent apps"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet options"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Allows the app to receive and process MMS messages. Malicious apps may monitor your messages or delete them without showing them to you."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"receive emergency broadcasts"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Allows the app to receive and process emergency broadcast messages. This permission is only available for system apps."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"send SMS messages"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Allows the app to send SMS messages. Malicious apps may cost you money by sending messages without your confirmation."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"send SMS messages with no confirmation"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Allows the app to move tasks to the foreground and background. Malicious apps may force themselves to the front without your control."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"stop running apps"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Allows the app to remove tasks and kill their apps. Malicious apps may disrupt the behaviour of other apps."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"start any activity"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Allows the app to start any activity, regardless of permission protection or exported state."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"set screen compatibility"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Allows the app to control the screen compatibility mode of other applications. Malicious applications may break the behaviour of other applications."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"enable app debugging"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Factory test failed"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6f1ee53..bfdede5 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tu tablet se apagará."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Tu dispositivo se apagará."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"¿Deseas apagarlo?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"No hay aplicaciones recientes."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opciones de tablet"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Permite que la aplicación reciba y procese mensajes MMS. Las aplicaciones maliciosas pueden controlar tus mensajes o eliminarlos sin mostrártelos."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"recibir mensajes de emergencia"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Permite que la aplicación reciba y procese mensajes de emergencia. Este permiso sólo está disponible para las aplicaciones del sistema."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Leer mensajes de difusión celular"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite a la aplicación leer los mensajes de difusión celular que recibe tu dispositivo. En algunas ubicaciones, las alertas de difusión celular se envían para advertir situaciones de emergencia. Las aplicaciones maliciosas pueden afectar el rendimiento o funcionamiento de tu dispositivo cuando se recibe un un mensaje de difusión celular de emergencia."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"enviar mensajes SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Permite que la aplicación envíe mensajes SMS. Las aplicaciones maliciosas pueden generar gastos a causa del envío de mensajes sin tu confirmación."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"Enviar mensajes SMS sin confirmación"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Permite que la aplicación mueva tareas al primero o segundo plano. Las aplicaciones maliciosas pueden forzar su paso al primer plano sin que tú las controles."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"detener las aplicaciones en ejecución"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite que la aplicación elimine tareas y cierre sus aplicaciones. Las aplicaciones malintencionadas pueden usar este permiso para interferir en el comportamiento de otras aplicaciones."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"Iniciar cualquier actividad"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permite a la aplicación iniciar una actividad, sin importar si fue exportada ni si se encuentra protegida por permisos."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Definir compatibilidad de pantalla"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Permite a la aplicación controlar el modo de compatibilidad de las pantallas de otras aplicaciones. Las aplicaciones malintencionadas pueden interrumpir el funcionamiento de otras aplicaciones."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"activar depuración de aplicación"</string>
@@ -286,7 +294,7 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite que la aplicación cambie la rotación de la pantalla en cualquier momento. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"cambiar velocidad del puntero"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permite que la aplicación cambie la velocidad del puntero del mouse o el trackpad en cualquier momento. Las aplicaciones normales no deben utilizar este permiso."</string>
- <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"Cambiar el diseño del teclado"</string>
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"cambiar el diseño del teclado"</string>
<string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Permite que la aplicación cambie el diseño del teclado. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"enviar señales de Linux a las aplicaciones"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permite que la aplicación solicite que la señal suministrada se envíe a todos los procesos persistentes."</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Error en la prueba de fábrica"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Insertar caracteres"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Enviando mensajes SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> está enviando una gran cantidad de mensajes SMS. ¿Quieres permitir que está aplicación siga enviando mensajes?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Rechazar"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"¿Enviar SMS premium?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"¿Enviar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> quiere enviar un mensaje de texto a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, y parece que se trata de un SMS premium.<p>Al enviar mensajes de texto a estos números, es posible que se facturen servicios premium en tu cuenta móvil.<p>¿Quieres permitir que esta aplicación envíe el mensaje?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> quiere enviar un mensaje de texto a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, y se trata de un SMS premium.<p><b>Al enviar un mensaje a este destino, se podrán facturar servicios premium en tu cuenta móvil.</b><p>¿Quieres permitir que esta aplicación envíe el mensaje?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Enviar mensaje"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"No enviar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Notificar aplicación malintencionada"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM eliminada"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"La red para celulares no estará disponible hasta que reinicies, luego de insertar una tarjeta SIM válida."</string>
<string name="sim_done_button" msgid="827949989369963775">"Finalizado"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 95e1152..d0e204b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"El tablet se apagará."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"El teléfono se apagará."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"¿Seguro que quieres apagar el teléfono?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"No hay aplicaciones recientes."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opciones del tablet"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Permite que la aplicación reciba y procese mensajes MMS. Las aplicaciones malintencionadas pueden usar este permiso para controlar o eliminar los mensajes sin mostrarlos al usuario."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"recibir mensajes de emergencia"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Permite que la aplicación reciba y procese mensajes de emergencia. Este permiso solo está disponible para las aplicaciones del sistema."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"leer mensajes de difusión móvil"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que la aplicación lea mensajes de difusión móvil que haya recibido el dispositivo. Las alertas de difusión móvil se envían en algunas ubicaciones para avisar de situaciones de emergencia. Es posible que las aplicaciones malintencionadas interfieran en el rendimiento o en el funcionamiento del dispositivo si se recibe una alerta de difusión móvil de emergencia."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"enviar mensajes SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Permite que la aplicación envíe mensajes SMS. Es posible que tengas que pagar por los mensajes que las aplicaciones malintencionadas envíen sin tu confirmación."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"enviar mensajes SMS sin confirmación"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Permite que la aplicación mueva tareas a segundo o a primer plano. Algunas aplicaciones malintencionadas pueden aparecer en primer plano sin el control del usuario."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"detener aplicaciones en ejecución"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite que la aplicación termine tareas y cierre sus aplicaciones. Las aplicaciones malintencionadas pueden usar este permiso para interferir en el comportamiento de otras aplicaciones."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"iniciar una actividad"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permite que la aplicación inicie una actividad, independientemente de la protección de permisos o de si está exportada."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"establecer compatibilidad de pantalla"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Permite que la aplicación controle el modo de compatibilidad de la pantalla de otras aplicaciones. Las aplicaciones malintencionadas pueden influir de forma negativa en el funcionamiento de otras aplicaciones."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"habilitar depuración de aplicación"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Fallo en la prueba de fábrica"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Insertar carácter"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Enviando mensajes SMS..."</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> está enviando un gran número de mensajes SMS. ¿Quieres permitir que está aplicación siga enviando mensajes?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Denegar"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"¿Enviar SMS premium?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"¿Enviar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> quiere enviar un mensaje de texto a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> y parece que se trata de un SMS premium.<p>Al enviar mensajes de texto a estos números, es posible que se facturen servicios premium en tu cuenta móvil.<p>¿Quieres permitir que esta aplicación envíe el mensaje?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> quiere enviar un mensaje de texto a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> y se trata de un SMS premium.<p><b>Al enviar un mensaje a este destino, se podrán facturar servicios premium en tu cuenta móvil.</b><p>¿Quieres permitir que esta aplicación envíe el mensaje?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Enviar mensaje"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"No enviar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Notificar aplicación malintencionada"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM eliminada"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"La red móvil no estará disponible hasta que reinicies el dispositivo con una tarjeta SIM válida."</string>
<string name="sim_done_button" msgid="827949989369963775">"Listo"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index a72691f..8f70b51 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Teie tahvelarvuti lülitub välja."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Teie telefon lülitub välja."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Kas soovite välja lülitada?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Hiljutised"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Hiljutisi rakendusi pole."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tahvelarvuti valikud"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Võimaldab rakendusel vastu võtta ja töödelda multimeediumsõnumeid. Pahatahtlikud rakendused võivad teie sõnumeid jälgida või neid kustutada teile näitamata."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"hädaabiteadete vastuvõtmine"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Võimaldab rakendusel vastu võtta ja töödelda hädaabisõnumeid. See õigus on saadaval ainult süsteemirakendustele."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"mobiilsidesõnumite lugemine"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Võimaldab rakendusel lugeda seadme vastu võetud mobiilsidesõnumeid. Mobiilsidemärguandeid edastatakse mõnes asukohas eriolukorrast teavitamiseks. Pahatahtlikud rakendused võivad segada seadme toimivust või tööd eriolukorra sõnumi vastuvõtmisel."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"saada SMS-sõnumeid"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Võimaldab rakendusel saata SMS-sõnumeid. Pahatahtlikud rakendused võivad teile kulukaks minna, kui saadavad sõnumeid teie nõusolekuta."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"lühisõnumite saatmine ilma kinnituseta"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Võimaldab rakendusel teisaldada ülesanded esiplaanile ja taustale. Pahatahtlikud rakendused võivad sundida end esiplaanile tulema teie loata."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"käitatud rakenduste peatamine"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Võimaldab rakendusel eemaldada ülesanded ja peatada nende rakendused. Pahatahtlikud rakendused võivad häirida teiste rakenduste käitumist."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"mis tahes toimingu alustamine"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Võimaldab rakendusel käivitada mis tahes toimingu loa kaitsest või eksporditud olekust sõltumata."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"kuva ühilduvuse seadmine"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Võimaldab rakendusel juhtida teiste rakenduste kuva ühilduvuse režiimi. Pahatahtlikud rakendused võivad teisi rakendusi häirida."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"Rakenduse silumise lubamine"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Tehasetest ebaõnnestus"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-kood:"</string>
<string name="select_character" msgid="3365550120617701745">"Sisesta tähemärk"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS-sõnumite saatmine"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> saadab suurel hulgal SMS-sõnumeid. Kas tahate lubada sellel rakendusel ka edaspidi sõnumeid saata?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Luba"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Keela"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Kas saata SMS lühinumbrile?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Kas saata tasuline SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tahab saata tekstsõnumi adressaadile <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, mis paistab olevat SMS-i lühinumber.<p>Mõnele lühinumbrile saadetud sõnumi eest võidakse teie mobiilikontole esitada arve tasuliste teenuste eest.<p>Kas lubate rakendusel selle sõnumi saata?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tahab saata tekstsõnumi adressaadile <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, mis on tasulise SMS-i lühinumber.<p><b>Kui saadate sõnumi sellele adressaadile, esitatakse teie mobiilikontole arve tasuliste teenuste eest.</b><p>Kas lubate rakendusel sõnumi saata?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Saada sõnum"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ära saada"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Teata pahatahtlikust rakend."</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kaart eemaldatud"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobiilsidevõrk ei ole saadaval, kuni sisestate kehtiva SIM-kaardi ja taaskäivitate seadme."</string>
<string name="sim_done_button" msgid="827949989369963775">"Valmis"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d33fe74..dd32ec5 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"رایانه لوحی شما خاموش می شود."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"گوشی شما خاموش می شود."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"آیا میخواهید تلفن خاموش شود؟"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"اخیر"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"برنامههای جدید موجود نیست."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"گزینه های رایانه لوحی"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"به برنامه اجازه میدهد تا پیامهای MMS را دریافت و پردازش کند. برنامههای مخرب پیامهای شما را کنترل میکنند یا بدون نشان دادن آنها به شما آنها را پاک میکنند."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"دریافت پخش های اضطراری"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"به برنامه اجازه میدهد تا پیامهای پخش اضطراری را دریافت و پردازش کند. این مجوز فقط برای برنامههای سیستم در دسترس است."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"ارسال پیامک ها"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"به برنامه اجازه میدهد پیامهای کوتاه ارسال کند. ممکن است برنامههای مخرب با ارسال پیام بدون تایید شما برای شما هزینه داشته باشند."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"ارسال پیامک بدون تأیید"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"به برنامه اجازه میدهد تا کارها را به پیش زمینه و پس زمینه منتقل کند. برنامههای مخرب میتوانند بدون کنترل به اجبار خود را به جلو منتقل کنند."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"متوقف کردن برنامههای در حال اجرا"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"به برنامه اجازه میدهد تا کارها را حذف کند و برنامههای آنها را متوقف کند. برنامههای مخرب میتوانند در اجرای برنامههای دیگر اختلال ایجاد کنند."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"تنظیم سازگاری با صفحه نمایش"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"به برنامه کاربردی اجازه کنترل حالت سازگاری صفحه نمایش برای برنامههای دیگر را میدهد. برنامههای خرابکار ممکن است باعث کارکرد نادرست دیگر برنامهها شوند."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"فعال کردن عیبیابی برنامه"</string>
@@ -287,7 +299,7 @@
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"تغییر سرعت اشاره گر"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"به برنامه اجازه میدهد تا سرعت ماوس و پد کنترل را هر وقت خواست تغییر دهد. برای برنامههای عادی نیاز نیست."</string>
<string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"تغییر چیدمان صفحه کلید"</string>
- <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"به برنامه اجازه میدهد تا چیدمان صفحه کلید را تغییر دهد. این کار هیچ گاه برای برنامههای عادی نیاز نیست."</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"به برنامه اجازه میدهد تا چیدمان صفحه کلید را تغییر دهد. این کار هیچگاه برای برنامههای عادی نیاز نیست."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ارسال سیگنالهای Linux به برنامهها"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"به برنامه اجازه میدهد تا درخواست کند سیگنال ارائه شده به همه مراحل دائم ارسال شود."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"همیشه برنامه اجرا شود"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"تست کارخانه انجام نشد"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"پین:"</string>
<string name="select_character" msgid="3365550120617701745">"درج نویسه"</string>
<string name="sms_control_title" msgid="7296612781128917719">"ارسال پیامک ها"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> در حال ارسال تعداد زیادی پیامک است. آیا اجازه میدهید این برنامه همچنان پیامک ارسال کند؟"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"اجازه دادن"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"ردکردن"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"پیامک به کد کوتاه ارسال شود؟"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"پیامک ممتاز ارسال شود؟"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> میخواهد یک پیام نوشتاری را به <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ارسال کند که به نظر میرسد یک کد کوتاه پیامک است.<p>ارسال پیامهای نوشتاری به برخی از کدهای کوتاه ممکن است باعث شود برای حساب تلفن همراه شما بابت استفاده از سرویسهای ممتاز صورتحساب ارسال شود.<p>آیا به این برنامه اجازه میدهید پیام ارسال کند؟"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> میخواهد یک پیام نوشتاری را به <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ارسال کند که یک کد کوتاه پیامک ممتاز است.<p><b>ارسال پیام به این مقصد ممکن است باعث شود برای حساب تلفن همراه شما بابت استفاده از سرویسهای ممتاز صورتحساب ارسال شود.</b><p>آیا به این برنامه اجازه میدهید پیامک ارسال کند؟"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"ارسال پیام"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"ارسال نشود"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"گزارش برنامه مخرب"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"سیم کارت برداشته شد"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"تا وقتی که با یک سیمکارت معتبر راهاندازی مجدد نکنید شبکه تلفن همراه غیر قابل دسترس خواهد بود."</string>
<string name="sim_done_button" msgid="827949989369963775">"انجام شد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f03e1af..93af802 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet-laitteesi sammutetaan."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Puhelin suljetaan."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Haluatko sammuttaa?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Viimeisimmät"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Ei viimeaikaisia sovelluksia"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet-laitteen asetukset"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Antaa sovelluksen vastaanottaa ja käsitellä MMS-viestejä. Haitalliset sovellukset voivat valvoa viestejä tai poistaa niitä näyttämättä niitä sinulle."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"vastaanota hätätilalähetyksiä"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Antaa sovelluksen vastaanottaa ja käsitellä hätälähetysviestejä. Tämä lupa on vain järjestelmäsovellusten käytettävissä."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"lähetä tekstiviestejä"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Antaa sovelluksen lähettää tekstiviestejä. Haitalliset sovellukset voivat tuhlata rahaa lähettämällä viestejä ilman vahvistusta."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"lähettää tekstiviestejä ilman vahvistusta"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Antaa sovelluksen siirtää tehtäviä etualalle ja taustalle. Haitalliset sovellukset voivat pakottaa itsensä etualalle ilman käyttäjän hallintaa."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"käynnissä olevien sovellusten pysäyttäminen"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Antaa sovelluksen poistaa tehtäviä ja lopettaa niiden sovelluksia. Haitalliset sovellukset voivat häiritä muiden sovellusten toimintaa."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"aseta näytön yhteensopivuus"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Sallii sovelluksen hallita toisten sovellusten näytön yhteensopivuustilaa. Haittasovellukset voivat häiritä toisten sovellusten toimintaa."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"sovellusten vianetsinnän käyttöönotto"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Tehdastesti epäonnistui"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-koodi:"</string>
<string name="select_character" msgid="3365550120617701745">"Lisää merkki"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Tekstiviestien lähettäminen"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> lähettää suuria määriä tekstiviestejä. Annetaanko tämän sovelluksen jatkaa tekstiviestien lähettämistä?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Salli"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Kiellä"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Lähetetäänkö viesti?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Lähetä maksullinen viesti?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> haluaa lähettää tekstiviestin kohteeseen <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, joka voi olla maksullinen numero.<p><b>Jos lähetät viestin tähän kohteeseen, sinua saatetaan veloittaa maksullisten palveluiden käytöstä.</b><p>Annetaanko sovelluksen lähettää viesti?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> haluaa lähettää tekstiviestin kohteeseen <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, joka on maksullinen numero.<p><b>Jos lähetät viestin tähän kohteeseen, sinua veloitetaan maksullisten palveluiden käytöstä.</b><p>Annetaanko sovelluksen lähettää viesti?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Lähetä viesti"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Älä lähetä"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Ilmoita haittasovelluksesta"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kortti poistettu"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobiiliverkko ei ole käytettävissä, ennen kuin käynnistät uudelleen kelvollisella laitteeseen kytketyllä SIM-kortilla."</string>
<string name="sim_done_button" msgid="827949989369963775">"Valmis"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 72ac5f4..9548251 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Votre tablette va s\'éteindre."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Votre téléphone va s\'éteindre."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Voulez-vous éteindre le téléphone ?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Récentes"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Aucune application récente"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Options de la tablette"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Permet à l\'application de recevoir et de traiter des MMS. Des applications malveillantes peuvent surveiller vos messages ou les supprimer avant même que vous puissiez les voir."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"recevoir les messages de diffusion d\'urgence"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Permet à l\'application de recevoir et de traiter les messages d\'urgence. Cette autorisation n\'est disponible que pour les applications système."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lire les messages reçus via un canal de diffusion cellulaire"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permet à l\'application de lire les messages que votre appareil reçoit via un canal de diffusion cellulaire. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Les applications malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lorsqu\'un message est reçu via un canal de diffusion cellulaire."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"Envoi de messages SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Permet à l\'application d\'envoyer des SMS. Des applications malveillantes peuvent engendrer des frais en envoyant des messages à votre insu."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"envoyer des SMS sans confirmation"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Permet à l\'application de faire passer les tâches de premier plan en arrière-plan. Des applications malveillantes peuvent exploiter cette fonctionnalité pour passer au premier plan sans votre consentement."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"arrêter les applications en cours d\'exécution"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Permet à l\'application de supprimer des tâches et de fermer les applications qui les exécutent. Des applications malveillantes peuvent exploiter cette fonctionnalité pour perturber le comportement des autres applications."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"démarrer n\'importe quelle activité"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permet à l\'application de démarrer n\'importe quelle activité, quels que soient l\'état exporté ou le degré de protection appliqué à l\'autorisation."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"définir la compatibilité de l\'écran"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Permettre de contrôler le mode de compatibilité de l\'écran des autres applications. Des applications malveillantes peuvent perturber le fonctionnement d\'autres applications."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"activer le débogage des applications"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Échec du test usine"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"Code PIN :"</string>
<string name="select_character" msgid="3365550120617701745">"Insérer un caractère"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Envoi de messages SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> envoie un grand nombre de SMS. Autorisez-vous cette application à poursuivre l\'envoi des messages ?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Autoriser"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Refuser"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Envoyer SMS au numéro abrégé ?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Envoyer un SMS premium ?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> essaie d\'envoyer un SMS à <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>. Il s\'agit apparemment d\'un numéro abrégé.<p>L\'envoi de SMS à de tels numéros peut entraîner la facturation de services premium sur votre compte mobile.<p>Autorisez-vous cette application à envoyer ce message ?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> essaie d\'envoyer un SMS à <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>. Il s\'agit apparemment d\'un numéro abrégé de type premium.<p><b>L\'envoi de SMS à ce destinataire entraînera la facturation de services premium sur votre compte mobile.</b><p>Autorisez-vous cette application à envoyer le message ?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Envoyer le message"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ne pas envoyer"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Signaler appli malveillante"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Carte SIM retirée"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Le réseau mobile ne sera pas disponible avant le redémarrage avec une carte SIM valide insérée."</string>
<string name="sim_done_button" msgid="827949989369963775">"OK"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index e94e286..61b323d 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"आपकी टेबलेट शट डाउन हो जाएगी."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"आपका फ़ोन शट डाउन हो जाएगा."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"क्या आप शट डाउन करना चाहते हैं?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"हाल के"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"कोई हाल ही के एप्लिकेशन नहीं."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"टेबलेट विकल्प"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"एप्लिकेशन को MMS संदेश प्राप्त करने और संसाधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन आपके संदेशों की निगरानी कर सकते हैं या आपको दिखाए बिना उन्हें हटा सकते हैं."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"आपातकालीन प्रसारण प्राप्त करें"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"एप्लिकेशन को आपातकालीन प्रसारण संदेशों को प्राप्त करने और संसाधित करने देता है. यह अनुमति केवल सिस्टम एप्लिकेशन में उपलब्ध है."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"SMS संदेश भेजें"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"एप्लिकेशन को SMS संदेशों को भेजने देता है. दुर्भावनापूर्ण एप्लिकेशन आपकी पुष्टि के बिना संदेश भेजकर आप पर शुल्क लगा सकते हैं."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"बिना किसी पुष्टि के SMS संदेश भेजें"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"एप्लिकेशन को अग्रभूमि और पृष्ठभूमि में कार्यों को ले जाने देता है. दुर्भावनापूर्ण एप्लिकेशन आपके नियंत्रण के बिना स्वयं को बलपूर्वक आगे कर सकते हैं."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"चलने वाले एप्लिकेशन रोकें"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"किसी एप्लिकेशन को कार्यों को निकालने और उनके एप्लिकेशन समाप्त करने देता है. दुर्भावनापूर्ण एप्लिकेशन अन्य एप्लिकेशन का व्यवहार बाधित कर सकते हैं."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"स्क्रीन संगतता सेट करें"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"एप्लिकेशन को अन्य एप्लिकेशन के स्क्रीन संगतता मोड को नियंत्रित करने देता है. दुर्भावनापूर्ण एप्लिकेशन अन्य एप्लिकेशन का व्यवहार बाधित कर सकते हैं."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"एप्लिकेशन डीबग करना सक्षम करें"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"फ़ैक्ट्री परीक्षण विफल"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"पिन:"</string>
<string name="select_character" msgid="3365550120617701745">"वर्ण सम्मिलित करें"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS संदेश भेज रहा है"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> बड़ी संख्या में SMS संदेश भेज रहा है. क्या आप इस एप्लिकेशन को संदेश भेजना जारी रखने देना चाहते हैं?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"अनुमति दें"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"अस्वीकार करें"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"शॉर्ट कोड पर SMS भेजें?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"प्रीमियम SMS भेजें?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>, <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> को एक पाठ संदेश भेजना चाहता है, जो एक SMS शॉर्ट कोड लगता है.<p>कुछ शॉर्ट कोड को पाठ संदेश भेजने से आपके मोबाइल खाते पर प्रीमियम सेवाओं का शुल्क लिया जा सकता है.<p>क्या आप इस एप्लिकेशन को यह संदेश भेजने देना चाहते हैं?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>, <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> को एक पाठ संदेश भेजना चाहता है, जो एक प्रीमियम SMS शॉर्ट कोड है.<p><b>इस गंतव्य पर कोई संदेश भेजने से आपके मोबाइल खाते पर प्रीमियम सेवाओं का शुल्क लिया जाएगा.</b><p>क्या आप इस एप्लिकेशन को संदेश भेजने देना चाहते हैं?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"संदेश भेजें"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"न भेजें"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"दुर्भावनापूर्ण एप्लि. की रिपोर्ट करें"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"सिमकार्ड निकाला गया"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"मान्य सिम कार्ड डालकर पुन: प्रारंभ करने तक मोबाइल नेटवर्क अनुपलब्ध रहेगा."</string>
<string name="sim_done_button" msgid="827949989369963775">"पूर्ण"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 412bc61..f23037d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Vaš tabletni uređaj će se isključiti."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Vaš će se telefon ipak isključiti"</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Želite li isključiti uređaj?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Nedavni"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Nema nedavnih aplikacija."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opcije tabletnog uređaja"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Omogućuje aplikaciji primanje i obradu MMS poruka. Zlonamjerne aplikacije mogu nadzirati vaše poruke ili ih brisati, a da vam ih ne pokažu."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"primanje hitnih odašiljanja"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Omogućuje aplikaciji primanje i obradu poruka hitnih odašiljanja. Ta je dozvola dostupna samo aplikacijama sustava."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"slanje SMS poruka"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Omogućuje aplikaciji slanje SMS poruka. Zlonamjerne aplikacije mogu vam prouzročiti troškove šaljući poruke bez vašeg znanja."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"slanje SMS poruka bez potvrde"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Omogućuje aplikaciji da premjesti zadatke u prednji plan ili pozadinu. Zlonamjerne aplikacije mogu na silu doći u prednji plan bez vašeg nadzora."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"zaustavljanje pokrenutih aplikacija"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Omogućuje aplikaciji uklanjanje zadataka i uklanjanje njihovih aplikacija. Zlonamjerne aplikacije mogu poremetiti rad drugih aplikacija."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"postavljanje kompatibilnosti sa zaslonom"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Aplikaciji omogućuje upravljanje načinom kompatibilnosti aplikacija sa zaslonom. Zlonamjerne aplikacije mogu prekinuti takvo ponašanje ostalih aplikacija."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"omogućavanje rješavanja programskih pogrešaka u aplikaciji"</string>
@@ -286,10 +298,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Omogućuje aplikaciji promjenu rotacije zaslona u bilo kojem trenutku. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"promjena brzine pokazivača"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Omogućuje aplikaciji promjenu brzine miša ili dodirne pločice. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"promjena rasporeda tipkovnice"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Omogućuje da aplikacija promijeni raspored tipkovnice. Nikada ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"slanje Linux signala aplikacijama"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Aplikaciji omogućuje zahtijevanje da isporučeni signal bude poslan na sve trajne procese."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"trajni rad aplikacije"</string>
@@ -736,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Tvorničko testiranje nije uspjelo"</string>
@@ -1010,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Umetni znak"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Slanje SMS poruka"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> šalje veliki broj SMS poruka. Želite li dopustiti ovoj aplikaciji da nastavi slati poruke?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Dopusti"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Odbij"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Poslati SMS na skraćeni broj?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Poslati premium SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> želi poslati tekstnu poruku na <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, a čini se da je to skraćeni SMS broj.<p>Slanje tekstnih poruka na neke skraćene interne brojeve može dovesti do naplate premium usluga na vašem računu mobilnog uređaja.<p>Želite li dopustiti aplikaciji da pošalje poruku?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> želi poslati tekstnu poruku na <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, a to je skraćeni premium SMS broj.<p><b>Slanje poruke na taj broj dovest će do naplate premium usluga na vašem računu mobilnog uređaja.</b><p>Želite li dopustiti toj aplikaciji da pošalje poruku?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Pošalji poruku"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ne šalji"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Prijavi zlonamjerne aplikacije"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM kartica uklonjena"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilna mreža bit će nedostupna do ponovnog pokretanja s umetnutom važećom SIM karticom."</string>
<string name="sim_done_button" msgid="827949989369963775">"Gotovo"</string>
@@ -1079,10 +1087,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
<string name="select_input_method" msgid="4653387336791222978">"Odabir načina unosa"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Postavljanje načina unosa"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"Fizička tipkovnica"</string>
+ <string name="hardware" msgid="7517821086888990278">"Hardver"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index c8f039f..4e90b80 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"A táblagép ki fog kapcsolni."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"A telefon le fog állni."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Kikapcsolja?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Legutóbbiak"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Nincs újabb alkalmazás."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Táblagép beállításait"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Lehetővé teszi az alkalmazás számára, hogy MMS-eket fogadjon és dolgozzon fel. A rosszindulatú alkalmazások megfigyelhetik vagy törölhetik az üzeneteket anélkül, hogy Ön látná azokat."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"vészhelyzeti közlemények fogadása"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Lehetővé teszi az alkalmazás számára vészhelyzeti üzenetek fogadását és feldolgozását. Ez az engedély csak rendszeralkalmazások számára érhető el."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"cellán belüli üzenetek olvasása"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Lehetővé teszi az alkalmazás számára az eszközre érkező cellán belüli üzenetek olvasását. Bizonyos helyeken figyelmeztető üzeneteket kaphat a cellán belül a vészhelyzetekről. A rosszindulatú alkalmazások befolyásolhatják az eszköz teljesítményét vagy működését vészhelyzeti cellaüzenet érkezésekor."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"SMS-ek küldése"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Lehetővé teszi az alkalmazás számára SMS üzeneteket küldését. A rosszindulatú alkalmazások pénzbe kerülő üzeneteket küldhetnek az Ön jóváhagyása nélkül."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"SMS üzenetek küldése megerősítés nélkül"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Lehetővé teszi az alkalmazás számára, hogy feladatokat helyezzen át az előtérből a háttérbe és fordítva. A rosszindulatú alkalmazások az előtérbe helyezhetik magukat az Ön engedélye nélkül."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"futó alkalmazások leállítása"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Lehetővé teszi, hogy az alkalmazás feladatokat távolítson el és leállítsa azok alkalmazásait. Rosszindulatú alkalmazások megzavarhatják más alkalmazások viselkedését."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"bármely tevékenység elindítása"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Lehetővé teszi az alkalmazás számára bármely tevékenység elindítását az engedélyektől és exportált állapottól függetlenül."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Képernyő-kompatibilitás beállítása"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Lehetővé teszi, hogy az alkalmazás szabályozza az egyéb alkalmazások képernyő-kompatibilitási módját. A kártékony alkalmazások megzavarhatják a többi alkalmazás viselkedését."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"alkalmazások hibakeresésének bekapcsolása"</string>
@@ -286,7 +294,7 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Lehetővé teszi az alkalmazás számára a képernyő elforgatásának bármikori módosítását. A normál alkalmazásoknak erre soha nincs szüksége."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"mutató sebességének módosítása"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Lehetővé teszi az alkalmazás számára, hogy bármikor módosítsa az egér vagy az érintőpad mutatójának sebességét. Normál alkalmazásoknak soha nem lehet rá szükségük."</string>
- <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"billentyűzetkiosztás módosítása"</string>
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"billentyűkiosztás módosítása"</string>
<string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a billentyűzetkiosztást. Normál alkalmazásoknak alapesetben nem lehet szükségük rá."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linux-jelek küldése az alkalmazásoknak"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Lehetővé teszi az alkalmazás számára, hogy a megadott jelet elküldje az összes állandó folyamatnak."</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"A gyári teszt sikertelen"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN kód:"</string>
<string name="select_character" msgid="3365550120617701745">"Karakter beszúrása"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS-ek küldése"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></ b> nagyszámú SMS üzenetet küld. Engedélyezi, hogy ez az alkalmazás továbbra is üzeneteket küldjön?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Engedélyezés"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Elutasítás"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"SMS küldése a rövid kódra?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Elküldi az emelt díjas SMS-t?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"A(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> szöveges üzenetet szeretne küldeni a(z) <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> címre, ami egy SMS rövid kódja.<p>Az egyes rövid kódokra küldött üzenetek miatt mobilszámláján emelt díjas szolgáltatások lesznek kiszámlázva.</b><p>Engedélyezi, hogy az alkalmazás elküldje az üzenetet?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"A(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> szöveges üzenetet szeretne küldeni a(z) <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> címre, ami egy emelt díjas SMS rövid kódja.<p>Az ide küldött üzenet miatt mobilszámláján emelt díjas szolgáltatások lesznek kiszámlázva.</b><p>Engedélyezi, hogy az alkalmazás elküldje az üzenetet?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Üzenet küldése"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nincs küldés"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Rosszindulatú alk. bejelentése"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kártya eltávolítva"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"A mobilhálózat nem lesz elérhető, amíg újra nem indítja egy érvényes SIM kártya behelyezése után."</string>
<string name="sim_done_button" msgid="827949989369963775">"Kész"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 03dac8a..4918c66 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet Anda akan dimatikan."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Ponsel Anda akan dimatikan."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Anda ingin mematikannya?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Terbaru"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Tidak ada apl terbaru."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opsi tablet"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Mengizinkan apl menerima dan memproses pesan MMS. Apl berbahaya dapat memantau atau menghapus pesan tanpa menunjukkannya kepada Anda."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"terima siaran darurat"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Mengizinkan apl menerima dan memproses pesan siaran darurat. Izin ini hanya tersedia untuk apl sistem."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"kirim pesan SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Mengizinkan apl mengirim pesan SMS. Apl berbahaya dapat menimbulkan pengeluaran dengan mengirimkan pesan tanpa konfirmasi."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"mengirim SMS tanpa konfirmasi"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Mengizinkan apl memindah tugas ke latar depan dan latar belakang. Apl berbahaya dapat memaksa berpindah ke depan tanpa kontrol Anda."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"menghentikan apl yang berjalan"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Memungkinkan apl menghapus tugas dan menutup aplikasinya. Apl berbahaya dapat mengganggu perilaku apl lain."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"menyetel kompatibilitas layar"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Memungkinkan apl mengontrol mode kompatibilitas layar aplikasi lain. Aplikasi berbahaya dapat merusak perilaku aplikasi lain."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"mengaktifkan debugging apl"</string>
@@ -286,10 +298,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Mengizinkan apl mengubah rotasi layar kapan saja. Tidak pernah dibutuhkan oleh apl normal."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ubah kecepatan penunjuk"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Mengizinkan apl mengubah kecepatan mouse atau pointer trackpad kapan saja. Tidak pernah diperlukan oleh apl normal."</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"Ubah tata letak keyboard"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Memungkinkan aplikasi untuk mengubah tata letak keyboard. Tidak pernah dibutuhkan oleh aplikasi normal."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"mengirim sinyal Linux ke apl"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Mengizinkan apl meminta agar sinyal yang disediakan dikirim ke semua proses yang ada."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"membuat apl selalu berjalan"</string>
@@ -736,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Uji pabrik gagal"</string>
@@ -1010,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Sisipkan huruf"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Mengirim pesan SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sedang mengirim pesan SMS dalam jumlah besar. Izinkan aplikasi ini untuk melanjutkan pengiriman pesan?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Izinkan"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Tolak"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Kirim SMS ke kode singkat?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Kirim SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> akan mengirim pesan teks ke <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, yang akan muncul sebagai kode singkat SMS.<p>Mengirim pesan teks ke beberapa kode singkat menyebabkan Anda dikenakan biaya layanan premium pada akun seluler Anda.<p>Izinkan aplikasi ini mengirim pesan?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> akan mengirim pesan teks ke <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, yang merupakan kode singkat SMS premium.<p><b>Mengirim pesan ke tujuan ini menyebabkan Anda dikenakan biaya layanan premium pada akun seluler Anda.</b><p>Izinkan aplikasi ini mengirim pesan?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Kirim pesan"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Jangan kirim"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Laporkan aplikasi berbahaya"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Kartu SIM dihapus"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Jaringan seluler tidak akan tersedia sampai Anda memulai lagi dengan memasukkan kartu SIM yang valid."</string>
<string name="sim_done_button" msgid="827949989369963775">"Selesai"</string>
@@ -1079,10 +1087,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk menonaktifkan debugging USB."</string>
<string name="select_input_method" msgid="4653387336791222978">"Pilih metode masukan"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Menyiapkan metode masukan"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"Keyboard fisik"</string>
+ <string name="hardware" msgid="7517821086888990278">"Perangkat Keras"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"calon"</u></string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index e9e5924..884ce078 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Il tablet verrà spento."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Il telefono verrà spento."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Spegnere?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recenti"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Nessuna applicazione recente."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opzioni tablet"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Consente all\'applicazione di ricevere ed elaborare messaggi MMS. Le applicazioni dannose potrebbero monitorare i tuoi messaggi o eliminarli senza mostrarteli."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"ricezione di trasmissioni di emergenza"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Consente all\'applicazione di ricevere ed elaborare messaggi broadcast di emergenza. Questa autorizzazione è disponibile solo per applicazioni di sistema."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lettura di messaggi cell broadcast"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Consente all\'applicazione di leggere i messaggi cell broadcast ricevuti dal dispositivo. Gli avvisi cell broadcast vengono trasmessi in alcune località per avvertire di eventuali situazioni di emergenza. Le applicazioni dannose potrebbero interferire con il rendimento o con il funzionamento del dispositivo quando si riceve un messaggio cell broadcast di emergenza."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"invio SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Consente all\'applicazione di inviare messaggi SMS. Le applicazioni dannose potrebbero comportare addebiti inviando messaggi senza la tua conferma."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"invio di messaggi SMS senza conferma"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Consente all\'applicazione di spostare attività in primo piano e in background. Le applicazioni dannose potrebbero forzare la loro impostazione in primo piano senza il tuo controllo."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"interruzione applicazioni in esecuzione"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Consente all\'applicazione di rimuovere le attività e terminare le loro applicazioni. Le applicazioni dannose potrebbero interferire con il comportamento di altre applicazioni."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"inizio di un\'attività"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Consente all\'applicazione di iniziare un\'attività, indipendentemente dalla protezione delle autorizzazioni o dallo stato esportato."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"impostazione compatibilità schermo"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Consente all\'applicazione di controllare la modalità di compatibilità dello schermo di altre applicazioni. Le applicazioni dannose potrebbero disturbare il comportamento di altre applicazioni."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"attivazione debug delle applicazioni"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Test di fabbrica non riuscito"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Inserisci carattere"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Invio SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sta inviando molti SMS. Vuoi consentire all\'applicazione di continuare a inviare messaggi?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Consenti"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Nega"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Inviare SMS a codice breve?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Inviare SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vorrebbe inviare un messaggio di testo a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, che sembra essere un codice breve SMS.<p>L\'invio di messaggi di testo ad alcuni codici brevi potrebbe comportare l\'addebito di servizi premium sul tuo account per cellulari.<p>Vuoi consentire a questa applicazione di inviare il messaggio?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vorrebbe inviare un messaggio di testo a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, che è un codice breve SMS premium.<p><b>L\'invio di un messaggio a questa destinazione comporterà l\'addebito di servizi premium sul tuo account per cellulari.</b><p>Vuoi consentire a questa applicazione di inviare il messaggio?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Invia messaggio"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Non inviare"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Segnala applicazione dannosa"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Scheda SIM rimossa"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"La rete mobile non sarà disponibile finché non eseguirai il riavvio con una scheda SIM valida inserita."</string>
<string name="sim_done_button" msgid="827949989369963775">"Fine"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 731546c..0c89121 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"הטבלט שלך יכבה."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"הטלפון שלך יכובה."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"האם ברצונך לבצע כיבוי?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"נוצרו לאחרונה"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"אין יישומים אחרונים"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"אפשרויות טאבלט"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"מאפשר ליישום לקבל ולעבד הודעות MMS. יישומים זדוניים עלולים לעקוב אחר ההודעות שלך או למחוק אותן מבלי להציגן בפניך."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"קבל שידורי חירום"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"מאפשר ליישום לקבל ולעבד לשדר הודעות חירום משודרות. הרשאה זו זמינה רק ליישומי מערכת."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"קריאת הודעות שידור סלולרי"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"מאפשר ליישום לקרוא הודעות שידור סלולרי שהתקבלו במכשיר שלך. התראות שידור סלולרי נשלחות במקומות מסוימים על מנת להזהיר אותך מפני מצבי חירום. יישומים זדוניים עשויים להפריע לביצועים או לפעולה של המכשיר שלך כאשר מתקבל שידור חירום סלולרי."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"שלוח הודעות SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"מאפשר ליישום לשלוח הודעות SMS. יישומים זדוניים עלולים לעלות לך כסף בגין שליחת הודעות ללא אישור שלך."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"שלח הודעות SMS ללא אישור"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"מאפשר ליישום להעביר משימות לחזית ולרקע. יישומים זדוניים עלולים לאלץ את עצמם לעבור לחזית ללא שליטה מצדך."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"עצירת יישומים פעילים"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"הרשאה זו מאפשרת ליישום להסיר משימות ולסגור את היישומים שבהם הן פועלות. יישומים זדוניים עלולים לשבש את פעולתם של יישומים אחרים."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"התחלת פעילות מכל סוג שהוא"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"מאפשר ליישום להתחיל בפעילות מכל סוג שהוא, ללא התחשבות בהגנת הרשאות או במצב מיוצא."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"הגדרת תאימות מסך"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"מאפשר ליישום לשלוט במצב תאימות המסך של יישומים אחרים. יישומים זדוניים עלולים לפגוע בהתנהגות של יישומים אחרים."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"הפעלה של ניקוי באגים ביישומים"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"אבג"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"בדיקת היצרן נכשלה"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"הוסף תו"</string>
<string name="sms_control_title" msgid="7296612781128917719">"שולח הודעות SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b> <xliff:g id="APP_NAME">%1$s</xliff:g> </ b> שולח מספר רב של הודעות SMS. האם ברצונך לאפשר ליישום זה להמשיך לשלוח הודעות?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"אפשר"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"דחה"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"לשלוח SMS לקוד קצר?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"לשלוח SMS פרימיום?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b> <xliff:g id="APP_NAME">%1$s</xliff:g> </ b> רוצה לשלוח הודעת טקסט אל <b> <xliff:g id="DEST_ADDRESS">%2$s</xliff:g> </ b>, שנראה כמו קוד SMS קצר. <p> שליחת הודעות טקסט לקודים קצרים מסוימים עשויה לגרום לחיוב חשבון הנייד שלך בשירותי פרימיום. <p> האם ברצונך לאפשר ליישום זה לשלוח את ההודעה?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b> <xliff:g id="APP_NAME">%1$s</xliff:g> </ b> רוצה לשלוח הודעת טקסט ל-<b> <xliff:g id="DEST_ADDRESS">%2$s</xliff:g> </ b>, שהוא קוד פרימיום קצר של SMS. <b> <p> שליחת הודעה ליעד זה תגרום לחיוב חשבון הנייד שלך בשירותי פרימיום. </ b> <p> האם ברצונך לאפשר ליישום זה לשלוח את ההודעה?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"שלח הודעה"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"אל תשלח"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"דווח על יישום זדוני"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"כרטיס ה-SIM הוסר"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"הרשת הסלולרית לא תהיה זמינה עד שתפעיל מחדש לאחר הכנסת כרטיס SIM חוקי."</string>
<string name="sim_done_button" msgid="827949989369963775">"סיום"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index e9d3558..6deeb09 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"タブレットの電源をOFFにします。"</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"携帯電話の電源を切ります。"</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"シャットダウンしますか?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"新着"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"最近使ったアプリはありません。"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"タブレットオプション"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"MMSメッセージの受信と処理をアプリに許可します。この許可を悪意のあるアプリに利用されると、メッセージが監視されたり、表示されずに削除されたりする恐れがあります。"</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"緊急放送の受信"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"緊急ブロードキャストメッセージの受信と処理をアプリに許可します。これはシステムアプリのみが利用できる権限です。"</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"SMSメッセージの送信"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"SMSメッセージの送信をアプリに許可します。この許可を悪意のあるアプリに利用されると、ユーザーの確認なしでメッセージが送信され、料金が発生する恐れがあります。"</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"確認せずにSMSメッセージを送信する"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"タスクをフォアグラウンドやバックグラウンドに移動することをアプリに許可します。この許可を悪意のあるアプリに利用されると、悪意のあるアプリが強制的に優先される恐れがあります。"</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"実行中のアプリの停止"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"タスクの削除とアプリの終了をアプリに許可します。この許可を悪意のあるアプリケーションに利用されると、他のアプリの動作が妨害される恐れがあります。"</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"画面互換性の設定"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"他のアプリの画面互換性モードをコントロールすることをアプリに許可します。この許可を悪意のあるアプリに利用されると、他のアプリの動作が中断される恐れがあります。"</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"アプリのデバッグの有効化"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"出荷時試験が失敗"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"文字を挿入"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMSメッセージの送信中"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>が大量のSMSメッセージを送信しています。このアプリにこのままメッセージの送信を許可しますか?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"許可する"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"許可しない"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"ショートコードへのSMSの送信"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"プレミアムSMSを送信しますか?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>が、SMSショートコードと思われる<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>にテキストメッセージを送信しようとしています。<p>一部のショートコードにテキストメッセージを送信すると、プレミアムサービスの料金がモバイルアカウントが請求される場合があります。<p>このアプリにメッセージの送信を許可しますか?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>が、プレミアムSMSショートコード<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>にテキストメッセージを送信しようとしています。<p><b>この宛先にメッセージを送信すると、プレミアムサービスの料金がモバイルアカウントに請求されます。</b><p>このアプリにメッセージの送信を許可しますか?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"メッセージを送信"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"送信しない"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"悪意のあるアプリを報告"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIMカードが取り外されました"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"有効なSIMカードを挿入して再起動するまでは、モバイルネットワークは利用できません。"</string>
<string name="sim_done_button" msgid="827949989369963775">"完了"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 02ab306..384eb03 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"태블릿이 종료됩니다."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"휴대전화가 종료됩니다."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"종료하시겠습니까?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"최근 사용한 앱"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"최근에 사용한 앱이 없습니다."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"태블릿 옵션"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"앱이 MMS 메시지를 받고 처리할 수 있도록 허용합니다. 이 경우 악성 앱이 메시지를 모니터링하거나 사용자가 보기 전에 삭제할 수 있습니다."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"긴급 방송 수신"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"앱이 긴급 브로드캐스트 메시지를 수신하고 처리할 수 있도록 허용합니다. 이 권한은 시스템 앱에만 사용할 수 있습니다."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"SMS 메시지 보내기"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"앱이 SMS 메시지를 보낼 수 있도록 허용합니다. 이 경우 악성 앱이 사용자의 확인 없이 메시지를 전송하여 요금이 부과될 수 있습니다."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"확인 없이 SMS 메시지 보내기"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"앱이 작업을 포그라운드나 백그라운드로 이동할 수 있도록 허용합니다. 이 경우 악성 앱이 사용자의 조작 없이 앞으로 이동할 수 있습니다."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"실행 중인 앱 중지"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"애플리케이션이 작업을 삭제하거나 다른 애플리케이션을 중지시킬 수 있도록 허용합니다. 이 경우 악성 애플리케이션이 다른 애플리케이션의 동작을 멈추게 할 수 있습니다."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"화면 호환성 설정"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"앱이 다른 애플리케이션의 화면 호환성 모드를 제어할 수 있도록 허용합니다. 이 경우 악성 애플리케이션이 다른 애플리케이션의 동작을 멈추게 할 수 있습니다."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"앱 디버깅 사용"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="AMPM">%P</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>시"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="AMPM">%p</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>시"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"출고 테스트 불합격"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"문자 삽입"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS 메시지를 보내는 중"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>이(가) SMS 메시지를 대량으로 보내고 있습니다. 해당 앱이 메시지를 계속 보내도록 하시겠습니까?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"허용"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"거부"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"SMS를 단축 코드로 보내시겠습니까?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"프리미엄 SMS를 보내시겠습니까?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>이(가) SMS 단축 코드로 추정되는 문자 메시지를 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>(으)로 보내려 합니다.<p>문자 메시지를 단축 코드로 보내면 사용자의 모바일 계정에 프리미엄 서비스 요금이 청구될 수 있습니다.<p>해당 앱이 메시지를 보내도록 하시겠습니까?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>이(가) 문자 메시지를 프리미엄 SMS 단축 코드인 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>(으)로 보내려 합니다.<p><b>메시지를 보내면 사용자의 모바일 계정에 프리미엄 서비스 요금이 청구됩니다.</b><p>해당 앱이 메시지를 보내도록 하시겠습니까?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"메시지 보내기"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"보내지 않음"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"악성 앱 신고"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM 카드 제거됨"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"유효한 SIM 카드를 삽입하여 다시 시작할 때까지 모바일 네트워크를 사용할 수 없습니다."</string>
<string name="sim_done_button" msgid="827949989369963775">"완료"</string>
diff --git a/core/res/res/values-large/dimens.xml b/core/res/res/values-large/dimens.xml
index 4f49135..864675a 100644
--- a/core/res/res/values-large/dimens.xml
+++ b/core/res/res/values-large/dimens.xml
@@ -17,13 +17,6 @@
*/
-->
<resources>
- <!-- Height of the status bar -->
- <dimen name="status_bar_height">48dip</dimen>
- <!-- Width and height of a single notification icon in the status bar -->
- <dimen name="status_bar_icon_size">32dip</dimen>
- <!-- Size of the giant number (unread count) in the notifications -->
- <dimen name="status_bar_content_number_size">48sp</dimen>
-
<!-- Default height of a key in the password keyboard for alpha -->
<dimen name="password_keyboard_key_height_alpha">75dip</dimen>
<!-- Default height of a key in the password keyboard for numeric -->
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 3d389d8..38b1095 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Planšetinio kompiuterio veikimas bus sustabdytas."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonas bus išjungtas."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Ar norite išjungti?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Naujos"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Nėra naujausių programų."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Planšetinio kompiuterio parinktys"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Leidžiama programai gauti ir apdoroti MMS pranešimus. Kenkėjiškos programos gali stebėti jūsų pranešimus ar ištrinti juos neparodydamos jų jums."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"gauti kritinės padėties transliacijas"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Leidžiama programai gauti ir apdoroti skubiai pateikiamus pranešimus. Šis leidimas galimas tik sistemos programoms."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"skaityti mobiliuoju transliuojamus pranešimus"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Programai leidžiama skaityti mobiliuoju transliuojamus pranešimus, gaunamus jūsų įrenginyje. Mobiliuoju transliuojami įspėjimai pristatomi kai kuriose vietose, kad įspėtų apie kritines situacijas. Kai gaunamas mobiliuoju transliuojamas pranešimas apie kritinę situaciją, kenkėjiškos programos gali trukdyti įrenginiui veikti ar jį naudoti."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"siųsti SMS pranešimus"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Leidžiama programai siųsti SMS pranešimus. Kenkėjiškos programos gali siųsti mokamus pranešimus be jūsų patvirtinimo."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"siųsti SMS pranešimus be patvirtinimo"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Leidžiama programai užduotis perkelti į priekinį planą ir į foną. Kenkėjiškos programos gali priverstinai persikelti į priekį be jūsų įsikišimo."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"sustabdyti vykdomas programas"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Leidžiama programai pašalinti užduotis ir panaikinti jų programas. Kenkėjiškos programos gali trikdyti kitų programų veikimą."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"pradėti bet kokią veiklą"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Programai leidžiama pradėti bet kokią veiklą, nepaisant leidimo apsaugos ar eksportuotos būsenos."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"nustatyti ekrano suderinamumo režimą"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Programai leidžiama valdyti kitų programų ekrano suderinamumo režimą. Kenkėjiškos programos gali kliudyti veikti kitoms programoms."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"įgalinti programos derinimą"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Gamyklos bandymas nepavyko"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN kodas:"</string>
<string name="select_character" msgid="3365550120617701745">"Įterpti simbolį"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS pranešimų siuntimas"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"Naudojant <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> siunčiama daug SMS pranešimų. Ar norite leisti šiai programai toliau siųsti pranešimus?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Leisti"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Uždrausti"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Siųsti SMS trumpuoju numeriu?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Siųsti brangesnį SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Naudojant <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prašoma išsiųsti teksto pranešimą <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, o tai yra trumpasis SMS numeris.<p><b>Siųsdami pranešimus kai kuriais trumpaisiais numeriais galite būti apmokestinti mobiliojo ryšio sąskaitoje už brangesnes paslaugas.</b><p>Ar norite leisti šiai programai siųsti pranešimą?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Naudojant <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prašoma išsiųsti teksto pranešimą <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, o tai yra brangesnis trumpasis SMS numeris.<p><b>Siųsdami pranešimą šiam gavėjui mobiliojo ryšio sąskaitoje būsite apmokestinti už brangesnes paslaugas.</b><p>Ar norite leisti šiai programai siųsti pranešimą?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Siųsti pranešimą"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nesiųsti"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Pranešti apie kenkėj. programą"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM kortelė pašalinta"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilusis tinklas bus nepasiekiamas, kol nepaleisite iš naujo įdėję tinkamą SIM kortelę."</string>
<string name="sim_done_button" msgid="827949989369963775">"Atlikta"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 05d0dbe..b936782 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Planšetdators tiks beidzēts."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Tālrunis tiks izslēgts."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Vai vēlaties izslēgt?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Nesens"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Nav nesen izmantotu lietotņu."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Planšetdatora opcijas"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Ļauj lietotnei saņemt un apstrādāt multiziņas. Ļaunprātīgas lietotnes var pārraudzīt vai dzēst šos ziņojumus, neparādot tos jums."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Ārkārtas apraižu saņemšana"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Ļauj lietotnei saņemt un apstrādāt ārkārtas apraides ziņojumus. Šī atļauja attiecas tikai uz sistēmas lietotnēm."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"šūnu apraides ziņojumu lasīšana"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ļauj lietotnei lasīt ierīcē saņemtos šūnu apraides ziņojumus. Šūnu apraides brīdinājumi tiek piegādāti dažās atrašanās vietās, lai brīdinātu jūs par ārkārtas situācijām. Ļaunprātīgas lietotnes var traucēt ierīces veiktspēju vai darbības, kad ir saņemts ārkārtas šūnas apraides ziņojums."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"sūtīt īsziņas"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Ļauj lietotnei sūtīt īsziņas. Ļaunprātīgu lietotņu darbības dēļ jums var būt jāmaksā papildus, jo tiks sūtītas īsziņas bez jūsu apstiprinājuma."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"īsziņu sūtīšana bez apstiprinājuma"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Ļauj lietotnei pārvietot uzdevumus priekšplānā un fonā. Ļaunprātīgas lietotnes var tikt izvirzītas priekšplānā bez jūsu vadības."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"apturēt izmantoto lietotņu darbību"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Ļauj lietotnei noņemt uzdevumus un pārtraukt to lietotņu darbību. Ļaunprātīgas lietotnes var traucēt citu lietotņu darbību."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"jebkuras darbības sākšana"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Ļauj lietotnei sākt jebkuru darbību neatkarīgi no atļaujas aizsardzības vai eksportētā stāvokļa."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Ekrāna saderības noteikšana"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Ļauj lietotnei kontrolēt citu lietotņu ekrāna saderības režīmu. Ļaunprātīgas lietojumprogrammas var mainīt citu lietojumprogrammu darbību."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"iespējot lietotnes atkļūdošanu"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> (<xliff:g id="AMPM">%P</xliff:g>)"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> (<xliff:g id="AMPM">%p</xliff:g>)"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Rūpnīcas pārbaude neizdevās"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Ievietojiet rakstzīmi"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Īsziņu sūtīšana"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"Lietotne <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sūta daudz īsziņu. Vai vēlaties, lai šī lietotne turpinātu sūtīt ziņojumus?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Atļaut"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Aizliegt"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Vai sūtīt īsziņu uz īso kodu?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Vai nosūtīt īpašo īsziņu?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Lietotne <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vēlas nosūtīt īsziņu uz adresi <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, kas, iespējams, ir īsziņas īsais kods.<p><b>Sūtot īsziņas uz dažiem īsajiem kodiem, no jūsu mobilā konta var tikt iekasēta maksa par paaugstinātas maksas pakalpojumiem.</b><p>Vai vēlaties atļaut šai lietotnei sūtīt šo ziņojumu?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Lietotne <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vēlas nosūtīt īsziņu uz adresi <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, kas, iespējams, ir paaugstinātas maksas īsziņas īsais kods.<p><b>Sūtot ziņojumu uz šo galamērķi, no jūsu mobilā konta tiks iekasēta maksa par paaugstinātas maksas pakalpojumiem.</b><p>Vai vēlaties atļaut šai lietotnei sūtīt šo ziņojumu?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Sūtīt ziņojumu"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nesūtīt"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Ziņot par ļaunprātīgu lietotni"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM karte ir izņemta."</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilais tīkls nebūs pieejams līdz brīdim, kad restartēsiet ierīci ar ievietotu derīgu SIM karti."</string>
<string name="sim_done_button" msgid="827949989369963775">"Gatavs"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index f0f5630..3f40706d 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet anda akan dimatikan."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon anda akan dimatikan."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Adakah anda mahu menutup?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Baru-baru ini"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Tiada apl terbaharu"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Pilihan tablet"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Membenarkan apl untuk menerima dan memproses mesej MMS. Apl hasad boleh memantau mesej anda atau memadamnya tanpa menunjukkannya kepada anda."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"terima siaran kecemasan"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Membenarkan apl untuk menerima dan memproses mesej siaran kecemasan. Kebenaran ini hanya tersedia kepada apl sistem."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"hantar mesej SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Membenarkan apl untuk menghantar mesej SMS. Apl hasad boleh menyebabkan anda kehilangan wang dengan menghantar mesej tanpa pengesahan anda."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"hantar mesej SMS tanpa pengesahan"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Membenarkan apl untuk memindahkan tugasan ke latar depan dan latar belakang. Apl hasad boleh memaksa diri mereka ke hadapan tanpa kawalan anda."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"hentikan apl yang sedang dijalankan"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Membenarkan apl untuk mengalih keluar tugasan dan melupuskan aplnya. Apl hasad boleh mengganggu tingkah laku apl lain."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"tetapkan keserasian skrin"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Membenarkan apl mengawal mod keserasian skrin aplikasi lain. Aplikasi hasad mungkin mematahkan kelakuan aplikasi lain."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"dayakan penyahpepijatan apl"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Ujian kilang gagal"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Masukkan aksara"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Menghantar mesej SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sedang menghantar banyak mesej SMS. Adakah anda mahu membenarkan apl ini terus menghantar mesej?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Benarkan"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Nafikan"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Hantar SMS ke kod pendek?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Hantar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ingin menghantar mesej teks kepada <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, yang merupakan kod pendek SMS.<p>Menghantar mesej teks ke sesetengah kod pendek boleh menyebabkan akaun mudah alih anda dikenakan bayaran perkhidmatan premium.<p>Adakah anda mahu membenarkan apl ini menghantar mesej itu?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ingin menghantar mesej teks ke <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, yang merupakan kod pendek SMS premium.<p><b>Menghantar mesej ke destinasi ini akan menyebabkan akaun mudah alih anda dikenakan bayaran untuk perkhidmatan premium.</b><p>Adakah anda mahu membenarkan apl ini menghantar mesej itu?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Hantar mesej"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Jangan hantar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Laporkan aplikasi hasad"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Kad SIM dikeluarkan"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Rangkaian mudah alih tidak akan tersedia sehingga anda mula semula dengan kad SIM yang sah dimasukkan."</string>
<string name="sim_done_button" msgid="827949989369963775">"Selesai"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 6609d29..8529c5e 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Nettbrettet slås av."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonen vil bli slått av."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Vil du slå av?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Nylig"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Ingen nylige apper."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Innstillinger for nettbrett"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Lar appen motta og behandle MMS-meldinger. Ondsinnede apper kan overvåke meldingene dine eller slette dem uten å vise dem til deg."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"motta nødkringkastinger"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Lar appen motta og behandle nødkringkastingsmeldinger. Denne tillatelsen er bare tilgjengelig for systemapper."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lesing av kringkastede meldinger"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tillater at appen kan lese kringkastede meldinger enheten din mottar. Kringkastede varsler leveres noen steder for å advare deg om nødsituasjoner. Skadelige apper kan forstyrre ytelsen eller funksjonen til enheten din når en kringkastet nødmelding mottas."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"sende SMS-meldinger"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Lar appen sende SMS-meldinger. Ondsinnede apper kan koste deg penger ved å sende meldinger uten din bekreftelse."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"send tekstmeldinger uten godkjenning"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Lar appen flytte oppgaver til forgrunnen eller bakgrunnen. Ondsinnede apper kan tvinge seg frem til forgrunnen utenfor din kontroll."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"avslutte apper som kjører"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Lar appen fjerne oppgaver og avslutte apper. Ondsinnede apper kan forstyrre atferden til andre apper."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"igangsetting av aktivitet"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Tillater at appen kan starte en aktivitet, uavhengig av tillatelsesbeskyttelse og eksportstatus."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"angi skjermkompatibilitet"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Lar appen kontrollere modus for skjermkompatibilitet i andre apper. Skadelige apper kan ødelegge funksjoner i andre apper."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"aktivere feilsøking av app"</string>
@@ -286,10 +294,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Gir appen tillatelse til når som helst å endre rotasjonen av skjermen. Skal aldri være nødvendig for vanlige apper."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"endre pekerhastighet"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Lar appen når som helst endre markørhastigheten til musen eller styreflaten. Skal aldri være nødvendig for vanlige apper."</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"endre tastaturutformingen"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Lar appen endre tastaturutformingen. Skal ikke være nødvendig for vanlige apper."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"sende Linux-signaler til apper"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Lar appen be om at det leverte signalet sendes til alle vedvarende prosesser."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"angi at appen alltid skal kjøre"</string>
@@ -736,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Fabrikktesten feilet"</string>
@@ -1010,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Sett inn tegn"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Sender SMS-meldinger"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sender et stort antall SMS. Vil du la appen fortsette å sende ut meldinger?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Tillat"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Sperr"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Vil du sende SMS til kortkoden?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Vil du sende premium-SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vil sende en tekstmelding til <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, som ser ut til å være en SMS-kortkode.<p>Hvis du sender en melding til denne destinasjonen, kan mobilkontoen din komme til å belastes for premium-tjenester.<p>Vil du la denne meldingen sendes av appen?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vil sende en tekstmelding til <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, som er en premium SMS-kortkode.<p><b>Hvis du sender en melding til denne destinasjonen, belastes mobilkontoen din for premium-tjenester.</b><p>Vil du la denne meldingen sendes av appen?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Send melding"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ikke send"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Rapportér skadelig app"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kort er fjernet"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Det mobile nettverket forblir utilgjengelig inntil du starter på nytt med et gyldig SIM-kort."</string>
<string name="sim_done_button" msgid="827949989369963775">"Fullført"</string>
@@ -1079,10 +1083,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"Trykk for å deaktivere USB-feilsøking."</string>
<string name="select_input_method" msgid="4653387336791222978">"Velg inndatametode"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inndatametoder"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"Fysisk tastatur"</string>
+ <string name="hardware" msgid="7517821086888990278">"Maskinvare"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 1c8809a..2b08589 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Uw tablet wordt uitgeschakeld."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Uw telefoon wordt uitgeschakeld."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Wilt u afsluiten?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Geen recente apps."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tabletopties"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Hiermee kan de app MMS-berichten ontvangen en verwerken. Schadelijke apps kunnen uw berichten bijhouden of deze verwijderen zonder dat u ze te zien krijgt."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"noodberichten ontvangen"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Hiermee kan de app berichten over noodsituaties ontvangen en verwerken. Deze rechten zijn alleen beschikbaar voor systeemapps."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"infodienstberichten lezen"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Toestaan dat de app infodienstberichten leest die worden ontvangen op uw apparaat. Infodienstmeldingen worden verzonden naar bepaalde locaties om u te waarschuwen voor noodsituaties. Schadelijke apps kunnen de prestaties of verwerking van uw apparaat verstoren wanneer een infodienstbericht wordt ontvangen."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"SMS-berichten verzenden"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Hiermee kan de app sms\'jes verzenden. Schadelijke apps kunnen u geld kosten door zonder uw toestemming berichten te verzenden."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"zonder toestemming sms\'jes verzenden"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Hiermee kan de app taken naar de voor- en achtergrond verplaatsen. Schadelijke apps kunnen zichzelf op de voorgrond plaatsen zonder dat u hier iets aan kunt doen."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"actieve apps stoppen"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Hiermee kan de app taken verwijderen en apps sluiten. Schadelijke apps kunnen het gedrag van andere apps verstoren."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"elke activiteit starten"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Toestaan dat de app elke activiteit start, ongeacht rechtenbeveiliging of geëxporteerde status."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"schermcompatibiliteit instellen"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Toestaan dat de app de schermcompatibiliteitsmodus van andere apps beheert. Schadelijke apps kunnen het gedrag van andere apps verstoren."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"foutopsporing in apps inschakelen"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Fabriekstest mislukt"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"Pincode"</string>
<string name="select_character" msgid="3365550120617701745">"Teken invoegen"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS-berichten verzenden"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> verzendt moment een groot aantal sms-berichten. Wilt u toestaan dat deze app berichten blijft verzenden?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Toestaan"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Weigeren"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Sms verzenden naar shortcode?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Premium-sms verzenden?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wil een sms-bericht verzenden naar <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>. Dit is waarschijnlijk een sms-shortcode.<p>Als u sms-berichten naar bepaalde shortcodes verzendt, worden mogelijk kosten voor premiumservices in rekening gebracht op uw mobiele account.<p>Wilt u toestaan dat deze app het bericht verzendt?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wil een sms-bericht verzenden naar <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>. Dit is premium sms-shortcode.<p><b>Als u een bericht naar deze bestemming verzendt, kosten voor premiumservices in rekening gebracht op uw mobiele account.</b><p>Wilt u toestaan dat deze app het bericht verzendt?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Bericht verzenden"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Niet verzenden"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Kwaadaardige app melden"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Simkaart verwijderd"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Het mobiele netwerk is niet beschikbaar totdat u het apparaat opnieuw start met een geldige simkaart."</string>
<string name="sim_done_button" msgid="827949989369963775">"Gereed"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 83b7aba..f1931a2 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet zostanie wyłączony."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon zostanie wyłączony"</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Czy chcesz wyłączyć?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Najnowsze"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Brak ostatnio uruchomionych aplikacji."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opcje tabletu"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Pozwala aplikacji na odbieranie i przetwarzanie wiadomości MMS. Złośliwe aplikacje mogą monitorować wiadomości lub usuwać je, zanim zostaną wyświetlone."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"odbiór emisji alarmowych"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Pozwala aplikacji na odbieranie i przetwarzanie komunikatów transmisji alarmowych. To pozwolenie jest dostępne tylko dla aplikacji systemowych."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"wysyłanie wiadomości SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Pozwala aplikacji na wysyłanie wiadomości SMS. Złośliwe aplikacje mogą generować koszty, wysyłając wiadomości bez Twojej wiedzy."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"wysyłanie wiadomości SMS bez potwierdzenia"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Pozwala aplikacji na przenoszenie zadań między tłem i pierwszym planem. Złośliwe aplikacje mogą wymusić przeniesienie się na pierwszy plan bez Twojego udziału."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"zatrzymywanie uruchomionych aplikacji"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Umożliwia aplikacji usuwanie zadań i kończenie powiązanych z nimi aplikacji. Złośliwe aplikacje mogą zakłócić działanie innych aplikacji."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ustaw zgodność ekranu"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Pozwala aplikacji na sterowanie trybem zgodności ekranu innych aplikacji. Złośliwe aplikacje mogą zmienić zachowanie innych programów."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"włączenie debugowania aplikacji"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Nieudany test fabryczny"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"Kod PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Wstaw znak"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Wysyłanie wiadomości SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wysyła wiele SMS-ów. Chcesz pozwolić tej aplikacji dalej wysyłać SMS-y?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Pozwól"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Odmów"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Wysłać droższego SMS-a?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Wysłać droższego SMS-a?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce wysłać SMS-a pod numer <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, który wygląda na dodatkowo płatny.<p>Może to spowodować doliczenie do Twojego rachunku za komórkę opłaty za usługę dodatkową.<p>Chcesz pozwolić tej aplikacji na wysłanie SMS-a?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce wysłać SMS-a pod numer <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, który jest dodatkowo płatny.<p><b>To spowoduje doliczenie do Twojego rachunku za komórkę opłaty za usługę dodatkową.</b><p>Chcesz pozwolić tej aplikacji na wysłanie SMS-a?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Wyślij wiadomość"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nie wysyłaj"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Zgłoś złośliwą aplikację"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Karta SIM wyjęta"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Sieć komórkowa będzie niedostępna do chwili ponownego uruchomienia urządzenia z użyciem ważnej karty SIM."</string>
<string name="sim_done_button" msgid="827949989369963775">"Gotowe"</string>
diff --git a/core/res/res/values-port/bools.xml b/core/res/res/values-port/bools.xml
new file mode 100644
index 0000000..fc62b69b
--- /dev/null
+++ b/core/res/res/values-port/bools.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <bool name="action_bar_embed_tabs">false</bool>
+</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 8f2f78f..67428c9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"O seu tablet irá encerrar."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"O seu telefone irá encerrar."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Pretende encerrar?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Não existem aplicações recentes"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opções do tablet"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Permite que a aplicação receba e processe mensagens MMS. As aplicações maliciosas podem monitorizar as mensagens ou eliminá-las sem mostrá-las ao utilizador."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"receber transmissões de emergência"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Permite à aplicação receber e processar mensagens de difusão de emergência. Esta permissão só está disponível para aplicações do sistema."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"enviar mensagens SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Permite que a aplicação envie mensagens SMS. As aplicações maliciosas podem custar-lhe dinheiro com o envio de mensagens sem a sua confirmação."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"enviar mensagens SMS sem confirmação"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Permite à aplicação mover tarefas para primeiro e segundo plano. As aplicações maliciosas podem impor-se em primeiro plano sem o controlo do utilizador."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"parar aplicações em execução"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite que a aplicação remova tarefas e elimine as respetivas aplicações. As aplicações maliciosas podem perturbar o comportamento de outras aplicações."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"definir compatibilidade de ecrã"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Permite que a aplicação controle o modo de compatibilidade de ecrã de outras aplicações. As aplicações maliciosas poderão afetar o comportamento de outras aplicações."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"ativar depuração da aplicação"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"O teste de fábrica falhou"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Introduzir carácter"</string>
<string name="sms_control_title" msgid="7296612781128917719">"A enviar mensagens SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> está a enviar um grande número de mensagens SMS. Pretende autorizar que a aplicação continue a enviar mensagens?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Recusar"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Enviar SMS ao código pequeno?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Enviar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pretende enviar um SMS para <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que parece ser um código SMS pequeno.<p>Enviar esta mensagem a alguns códigos pequenos pode fazer com que sejam faturados serviços premium na sua conta de telemóvel.<p>Pretende autorizar que a aplicação envie a mensagem?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pretende enviar um SMS a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que é um pequeno código de SMS premium.<p><b>Enviar uma mensagem para este destino irá fazer com que sejam faturados serviços premium na sua conta de telemóvel.</b><p>Pretende autorizar que a aplicação envie a mensagem?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Enviar mensagem"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Não enviar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Comunicar aplicação maliciosa"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Cartão SIM removido"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"A rede de telemóvel estará indisponível até que reinicie o aparelho com um cartão SIM válido inserido."</string>
<string name="sim_done_button" msgid="827949989369963775">"Concluído"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4d770b5..ec31b00 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Seu tablet será desligado."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"O seu telefone será desligado."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Deseja desligar?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Nenhum aplicativo recente"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opções do tablet"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Permite que o aplicativo receba e processe mensagens MMS. Aplicativos maliciosos podem monitorar suas mensagens ou excluí-las sem mostrá-las a você."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"receber transmissões de emergência"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Permite que o aplicativo receba e processe mensagens de transmissão de emergência. Esta permissão só está disponível para aplicativos do sistema."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"enviar mensagens SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Permite que o aplicativo envie mensagens SMS. Aplicativos maliciosos podem gerar gastos ao enviar mensagens sem sua confirmação."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"enviar mensagens SMS sem confirmação"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Permite que o aplicativo mova tarefas para o primeiro plano e para o plano de fundo. Aplicativos maliciosos podem forçar-se para a primeiro plano sem que você tenha controle sobre a ação."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"parar os aplicativos em execução"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite que um aplicativo remova tarefas e elimine seus aplicativos. Aplicativos maliciosos podem interferir no comportamento de outros aplicativos."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"definir a compatibilidade de tela"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Permite que o aplicativo controle o modo de compatibilidade de tela de outros aplicativos. Aplicativos maliciosos podem interromper o comportamento de outros aplicativos."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"ativar depuração do aplicativo"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Falha no teste de fábrica"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Inserir caractere"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Enviando mensagens SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> envia uma grande quantidade de mensagens SMS. Deseja permitir que este aplicativo continue enviando mensagens?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Negar"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Enviar SMS para código curto?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Enviar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> deseja enviar uma mensagem de texto para <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que parece ser um código curto SMS.<p>O envio de mensagens de texto a alguns códigos curtos pode fazer com que a conta seja cobrada por serviços premium.<p>Deseja permitir que este aplicativo envie a mensagem?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> deseja enviar uma mensagem de texto para <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que é um código curto SMS premium.<p><b>O envio de uma mensagem a esse destino fará com que a conta seja cobrada por serviços premium.</b><p>Deseja permitir que este aplicativo envie a mensagem?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Enviar mensagem"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Não enviar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Denunciar aplicativo malicioso"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Cartão SIM removido"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"A rede móvel ficará indisponível até que você reinicie com um cartão SIM válido inserido."</string>
<string name="sim_done_button" msgid="827949989369963775">"Concluído"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 6f066de..159a148 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -180,6 +180,10 @@
<skip />
<!-- no translation found for shutdown_confirm_question (2906544768881136183) -->
<skip />
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Utilisà sco ultim"</string>
<!-- no translation found for no_recent_tasks (8794906658732193473) -->
<skip />
@@ -251,6 +255,10 @@
<skip />
<!-- no translation found for permdesc_receiveEmergencyBroadcast (848524070262431974) -->
<skip />
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"trametter messadis SMS"</string>
<!-- no translation found for permdesc_sendSms (906546667507626156) -->
<skip />
@@ -283,6 +291,10 @@
<skip />
<!-- no translation found for permdesc_removeTasks (1394714352062635493) -->
<skip />
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<!-- no translation found for permlab_setScreenCompatibility (6975387118861842061) -->
<skip />
<!-- no translation found for permdesc_setScreenCompatibility (692043618693917374) -->
@@ -1107,6 +1119,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<!-- no translation found for hour_ampm (4584338083529355982) -->
<skip />
<!-- no translation found for hour_cap_ampm (2083465992940444366) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 3772861..0d2a4e9 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Computerul dvs. tablet PC se va închide."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonul dvs. se va închide."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Doriţi să închideţi?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Nu există aplicaţii recente."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opţiuni tablet PC"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Permite aplicaţiei să primească şi să proceseze mesaje MMS. Aplicaţiile rău intenţionate pot să monitorizeze mesajele sau să le şteargă fără să vi le arate."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"primeşte mesaje difuzate de urgenţă"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Permite aplicaţiei să primească şi să proceseze mesajele difuzate de urgenţă. Această permisiune este disponibilă numai pentru aplicaţiile de sistem."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"trimitere mesaje SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Permite aplicaţiei să trimită mesaje SMS. Aplicaţiile rău intenţionate pot să vă genereze costuri, deoarece trimit mesaje fără confirmarea dvs."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"trimitere mesaje SMS fără confirmare"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Permite aplicaţiei să mute activităţile în prim-plan şi în fundal. Aplicaţiile rău intenţionate pot să apară forţat în prim-plan, fără ca dvs. să puteţi controla acest lucru."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"oprire aplicaţii care rulează"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite aplicaţiei să elimine sarcini şi să închidă aplicaţiile corespunzătoare acestora. Aplicaţiile rău intenţionate pot perturba comportamentul altor aplicaţii."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"setaţi compatibilitatea ecranului"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Permite aplicaţiei să controleze modul de compatibilitate a ecranului pentru alte aplicaţii. Aplicaţiile rău intenţionate pot afecta comportamentul altor aplicaţii."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"activare depanare aplicaţie"</string>
@@ -286,10 +298,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite aplicaţiei să modifice rotaţia ecranului în orice moment. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"modifică viteza indicatorului"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permite aplicaţiei să modifice oricând viteza indicatorului mouse-ului sau al trackpadului. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"modificaţi aspectul tastaturii"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Permite aplicaţiei să modifice aspectul tastaturii. Nu ar trebui să fie niciodată necesară pentru aplicaţii obişnuite."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"trimitere semnale Linux către aplicaţii"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permite aplicaţiei să solicite trimiterea semnalului furnizat către toate procesele persistente."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"rulare continuă a aplicaţiei"</string>
@@ -736,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Testarea de fabrică nu a reuşit"</string>
@@ -1010,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"Cod PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Introduceţi caracterul"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Se trimit mesaje SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> trimite un număr mare de mesaje SMS. Permiteţi acestei aplicaţii să trimită în continuare mesaje?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Permiteţi"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Refuzaţi"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Trimiteţi SMS la codul scurt?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Trimiteţi SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> intenţionează să trimită un mesaj text la <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, care pare a fi un cod scurt SMS.<p>Trimiterea de mesaje text la unele coduri scurte poate determina taxarea contului dvs. mobil pentru servicii premium.<p>Permiteţi acestei aplicaţii să trimită mesajul?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> intenţionează să trimită un mesaj text la <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, care este un cod scurt SMS premium.<p><b>Trimiterea unui mesaj la această destinaţie va determina taxarea contului dvs. mobil pentru servicii premium.</b><p>Permiteţi acestei aplicaţii să trimită mesajul?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Trimiteţi mesajul"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nu trimiteţi"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Raport. aplic.rău intenţionată"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Card SIM eliminat"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Reţeaua mobilă va fi indisponibilă până când reporniţi cu o cartelă SIM validă introdusă."</string>
<string name="sim_done_button" msgid="827949989369963775">"Terminat"</string>
@@ -1079,10 +1087,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"Atingeţi pentru a dezactiva depanarea USB."</string>
<string name="select_input_method" msgid="4653387336791222978">"Alegeţi metoda de introducere"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Configurare metode introducere"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"Tastatură fizică"</string>
+ <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidaţi"</u></string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index b967620..7cef102 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет отключен."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Телефон будет выключен."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Завершить работу?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Недавние"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Список пуст"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Настройки планшетного ПК"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Приложение сможет получать и обрабатывать MMS. Вредоносные программы смогут отслеживать и удалять сообщения, не показывая их."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"принимать экстренные вызовы"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Приложение сможет получать и обрабатывать экстренные сообщения рассылок. Это разрешение доступно только для системных приложений."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Читать сообщения рассылки"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Приложение сможет считывать сообщения рассылки, полученные вашим устройством. В ряде стран вам будут приходить уведомления об экстренных ситуациях. В этом случае вредоносные программы могут помешать работе вашего устройства."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"отправлять SMS-сообщения"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Приложение сможет отправлять SMS. Вредоносные программы смогут отправлять SMS без вашего подтверждения, что приведет к непредвиденным расходам."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"отправка SMS без подтверждения"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Приложение сможет перемещать задачи в режим активного или фонового выполнения. Вредоносные программы смогут переводить себя в активный режим без вашего ведома."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"остановка запущенных приложений"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Приложение сможет удалять задачи и собственные программы. Вредоносное ПО при этом сможет нарушать работу других приложений."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"Совершать любые действия"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Приложение сможет совершать любые действия независимо от наличия разрешений и состояния."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Установка режима совместимости"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Приложение сможет управлять режимом совместимости экрана других приложений. Вредоносное ПО может привести к сбоям в работе других программ."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"включение отладки приложений"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Не удалось провести стандартный тест"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-код:"</string>
<string name="select_character" msgid="3365550120617701745">"Введите символ"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Отправка SMS-сообщений"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> отправляет большое количество SMS. Разрешить приложению и дальше отправлять сообщения?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Разрешить"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Запретить"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Отправить SMS?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Отправить SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> собирается отправить SMS-сообщение на короткий номер <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b><p> За отправку сообщений на некоторые короткие номера с вашего счета могут списываться дополнительные средства.<p>Разрешить отправку?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> собирается отправить SMS на короткий номер <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>.<p><b> Если это произойдет, с вашего счета будут списаны дополнительные средства.</b><p>Разрешить отправку?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Отправить сообщение"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Не отправлять"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Сообщить о вредоносном ПО"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-карта удалена"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Пока вы не вставите действующую SIM-карту, мобильная сеть будет недоступна."</string>
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 1bf7a17..237b9fc 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Váš tablet bude vypnutý."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Váš telefón bude vypnutý."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Chcete zariadenie vypnúť?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Najnovšie"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Žiadne nedávne aplikácie"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Možnosti tabletu"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Umožňuje aplikácii prijímať a spracovávať správy MMS. Škodlivé aplikácie môžu sledovať vaše správy alebo ich odstrániť bez toho, aby ich zobrazili."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"príjem núdzového vysielania"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Umožňuje aplikácii prijímať a spracovávať správy núdzového vysielania. Toto povolenie je k dispozícii len pre systémové aplikácie."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"odosielať správy SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Umožňuje aplikácii odosielať správy SMS. Škodlivé aplikácie môžu bez vášho potvrdenia odosielať spoplatnené správy."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"posielať správy SMS bez potvrdenia"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Umožňuje aplikácii presúvať úlohy do popredia a pozadia. Škodlivé aplikácie sa môžu pretlačiť do popredia bez vášho vedomia."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"zastaviť spustené aplikácie"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Umožňuje aplikácii odstrániť úlohy a ukončiť ich aplikácie. Škodlivé aplikácie môžu narušiť správanie iných aplikácií."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"nastaviť kompatibilitu obrazovky"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Umožňuje aplikácii ovládať režim kompatibility obrazovky v ostatných aplikáciách. Škodlivé aplikácie môžu narušiť správanie ostatných aplikácií."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"povoliť ladenie aplikácií"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Továrenský test zlyhal"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Vkladanie znakov"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Odosielanie správ SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"Aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> posiela veľký počet správ SMS. Chcete tejto aplikácií povoliť, aby aj naďalej posielala správy?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Povoliť"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Odmietnuť"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Odoslať SMS na skrátené číslo?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Odoslať prémiovú správu SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce odoslať textovú správu na číslo <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ktoré sa zdá byť skráteným číslom SMS.<p>Odoslanie správy na skrátené číslo môže spôsobiť, že na účet vášho mobilného zariadenia budú účtované poplatky za prémiové služby.<p>Chcete aplikácií povoliť túto správu odoslať?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce odoslať textovú správu na číslo <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ktoré je prémiovým skráteným číslom SMS.<p><b>Odoslanie správy na toto číslo spôsobí, že na účet vášho mobilného zariadenia budú účtované poplatky za prémiové služby.</b><p>Chcete aplikácii povoliť túto správu odoslať?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Odoslať správu"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Neodoslať"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Nahlásiť škodlivú aplikáciu"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Karta SIM bola odobraná"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilná sieť nebude k dispozícii, kým nevložíte platnú kartu SIM a zariadenie nereštartujete."</string>
<string name="sim_done_button" msgid="827949989369963775">"Hotovo"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 152d1c1..7f63e6c 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablični računalnik se bo zaustavil."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon bo zaustavljen."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Ali želite izklopiti telefon?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Nedavno"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Ni nedavnih programov"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Možnosti tabličnega računalnika"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Programu omogoča prejemanje in obdelavo sporočil MMS. Zlonamerni programi lahko nadzirajo sporočila ali jih brišejo, ne da bi vam jih pokazali."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"prejemanje oddaj v sili"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Programu omogoča prejemanje in obdelavo sporočil za oddajanje v sili. To dovoljenje je na voljo samo sistemskim programom."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"pošiljanje sporočil SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Programu omogoča pošiljanje SMS-ov. Zlonamerni programi lahko pošiljajo sporočila brez vaše potrditve, kar vas lahko drago stane."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"pošiljanje SMS-ov brez potrditve"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Programu omogoča premikanje opravil v ospredje in ozadje. Zlonamerni programi se lahko brez vašega nadzora vsilijo v ospredje."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"ustavitev programov, ki se izvajajo"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Programu omogoča odstranjevanje opravil in zapiranje njihovih programov. Zlonamerni programi lahko motijo delovanje drugih programov."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"nastavitev združljivosti zaslona"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Programu omogoča nadzor združljivostnega načina zaslona drugih programov. Zlonamerni programi lahko prekinejo delovanje drugih programov."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"omogočanje iskanja in odpravljanja napak v programu"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Tovarniški preskus ni uspel"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Vstavljanje znaka"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Pošiljanje sporočil SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pošilja veliko SMS-ov. Ali želite dovoliti, da jih še naprej pošilja?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Dovoli"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Zavrni"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Pošljem SMS na kratko štev.?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Pošljem SMS za plačlj. stor.?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> želi poslati SMS na številko <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, kar je videti kot kratka številka za plačljive storitve SMS.<p>S pošiljanjem sporočil na to številko bo vaš račun za mobilni telefon bremenjen za plačljive storitve.<p>Ali želite aplikaciji dovoliti, da pošlje sporočilo?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> želi poslati SMS na številko <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, kar je kratka številka za plačljive storitve SMS.<p><b>S pošiljanjem sporočil na to številko bo vaš račun za mobilni telefon bremenjen za plačljive storitve.</b><p>Ali želite aplikaciji dovoliti, da pošlje sporočilo?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Pošlji sporočilo"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ne pošlji"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Prijavi zlonamerno aplikacijo"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Kartica SIM odstranjena"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilno omrežje ne bo na voljo, dokler naprave vnovič ne zaženete z veljavno kartico SIM."</string>
<string name="sim_done_button" msgid="827949989369963775">"Dokončano"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 9e63b31..61768b7 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Таблет ће се искључити."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Телефон ће се искључити."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Да ли желите да искључите телефон?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Недавно"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Нема недавних апликација."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Опције за таблет"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Дозвољава апликацији да прима и обрађује MMS поруке. Злонамерне апликације могу да надгледају поруке или да их бришу, а да вам их не прикажу."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"пријем хитних преноса"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Дозвољава апликацији да прима и обрађује поруке хитног преноса. Ова дозвола је доступна само за системске апликације."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"слање SMS порука"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Дозвољава апликацији да шаље SMS поруке. Злонамерне апликације могу да шаљу поруке без ваше потврде, што вам може изазвати трошкове."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"слање SMS порука без потврде"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Дозвољава апликацији да премешта задатке у први план и у позадину. Злонамерне апликације могу на тај начин да принудно пређу у први план без ваше контроле."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"заустављање покренутих апликација"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Дозвољава апликацији да уклања задатке и уништава њихове апликације. Злонамерне апликације могу да поремете понашање других апликација."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"подешавање компатибилности екрана"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Дозвољава апликацији да контролише режим компатибилности екрана других апликација. Злонамерне апликације могу да угрозе понашање других апликација."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"омогућавање отклањања грешака у апликацији"</string>
@@ -286,10 +298,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Дозвољава апликацији да у сваком тренутку промени ротацију екрана. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"промена брзине показивача"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Дозвољава апликацији да у било ком тренутку промени брзину показивача миша или показивачког уређаја са плочицом. Уобичајене апликације никада не би требало да је користе."</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"промена распореда тастатуре"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Дозвољава апликацији да мења распоред тастатуре. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"слање Linux сигнала апликацијама"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Дозвољава апликацији да захтева да испоручени сигнал буде послат свим трајним процесима."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"омогућавање непрекидне активности апликације"</string>
@@ -736,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Фабричко тестирање није успело"</string>
@@ -1010,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Уметање знака"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Слање SMS порука"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> шаље велики број SMS порука. Желите ли да дозволите овој апликацији да настави са слањем порука?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Дозволи"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Одбиј"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Пошаљи SMS на кратак кôд?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Желите да пошаљете премијум SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> жели да вам пошаље текстуалну поруку на адресу <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, која можда представља кратак кôд SMS-а.<p>Слање порука на неке кратке кодове може да се наплаћује као премијум услуга са налога за мобилни уређај.<p>Желите ли да дозволите овој апликацији да пошаље поруку?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> жели да вам пошаље текстуалну поруку на адресу <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, која представља кратак кôд премијум SMS-а.<p><b>Ако се пошаље порука на ово одредиште, биће вам наплаћена премијум услуга са налога за мобилни уређај.</b><p>Желите ли да дозволите овој апликацији да пошаље поруку?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Пошаљи поруку"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Не шаљи"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Пријави злонамерну апликацију"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM картица је уклоњена"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Мобилна мрежа неће бити доступна док не покренете систем поново уз уметање важеће SIM картице."</string>
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
@@ -1079,10 +1087,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string>
<string name="select_input_method" msgid="4653387336791222978">"Избор метода уноса"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Подеси методе уноса"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"Физичка тастатура"</string>
+ <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 3db9ec7..2c8bfc9 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Din pekdator stängs av."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Din telefon stängs av."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Vill du stänga av?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Inga nya appar."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Alternativ för pekdatorn"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Tillåter att appen tar emot och bearbetar MMS. Skadliga appar kan övervaka dina meddelanden eller ta bort dem innan du har sett dem."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"ta emot sändningar i nödsituationer"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Tillåter att appen tar emot och bearbetar sändningar i nödsituationer. Behörigheten är bara tillgänglig för systemappar."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"läsa SMS-meddelanden"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Appen tillåts läsa SMS som skickas till din enhet. På vissa platser skickas SMS för att varna för nödsituationer. Skadliga appar kan påverka enhetens prestanda eller funktionalitet när du får ett meddelande om en nödsituation via SMS."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"skicka SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Tillåter att appen skickar SMS. Skadliga appar kan skicka meddelanden utan ditt godkännande vilket kan kosta pengar."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"skicka SMS utan bekräftelse"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Tillåter att appen flyttar uppgifter till förgrunden eller bakgrunden. Skadliga appar kan tvinga sig till förgrunden utan att du kan styra det."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"avsluta appar som körs"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Tillåter att appen tar bort uppgifter och avslutar appar. Skadliga appar kan störa funktionen i andra appar."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"starta alla aktiviteter"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Appen tillåts starta alla aktiviteter oavsett behörighetsskydd eller exportstatus."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ange skärmkompatibilitet"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Tillåter att appen styr skärmkompatibilitetsläget i andra appar. Skadliga appar kan störa andra appars funktion."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"aktivera felsökning av appar"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Det gick fel vid fabrikstestet"</string>
@@ -1008,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-kod:"</string>
<string name="select_character" msgid="3365550120617701745">"Infoga tecken"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Skickar SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> skickar ett stort antal SMS. Vill du tillåta att appen fortsätter att skicka meddelanden?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Tillåt"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Neka"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Skicka SMS till kortkod?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Skicka premium-SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vill skicka ett SMS till <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> som verkar vara en kortkod för SMS.<p>När du skickar SMS till kortkoder kan mobilkontot debiteras för premiumtjänster.<p>Vill du tillåta att appen skickar meddelandet?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vill skicka ett SMS till <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> som är en kortkod för SMS.<p><b>Om du skickar ett meddelande till den här mottagaren kommer ditt mobilkonto att debiteras för premiumtjänster.</b><p>Vill du tillåta att appen skickar meddelandet?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Skicka meddelande"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Skicka inte"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Rapportera skadlig app"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kortet togs bort"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Det mobila nätverket kommer inte att vara tillgängligt förrän du startar om med ett giltigt SIM-kort."</string>
<string name="sim_done_button" msgid="827949989369963775">"Klar"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 20bc2c6..736638a 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Kompyuta yako ndogo itazima."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Simu yako itazima."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Unataka kuzima?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Za hivi karibuni"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Hakuna programu za hivi karibuni."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Chaguo za kompyuta ndogo"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Inaruhusu programu kupokea na kuchakata jumbe za MMS. Programu hasidi zinaweza kufuatilia jumbe zako au kuzifuta bila kukuonyesha."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Pokea matangazo ya dharura"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Inaruhusu programu kupokea na kuchakata jumbe za dharura. Ruhusa hii inapatikana tu kwa programu za mfumo."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"tuma ujumbe wa SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Inaruhusu programu kutuma jumbe za SMS. Programu hasidi zinaweza kukugharimu fedha kwa kutuma jumbe bila uthibitisho wako."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"Tuma ujumbe wa SMS bila ya thibitisho"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Inaruhusu programu kusongesha kazi kwenye mandhari-mbele na mandhari-nyuma. Programu hasidi zinaweza kujilazimisha mbele bila udhibiti wako."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"Komesha programu zinazoendeshwa"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Huruhusu programu kuondoa majukumu na kuua programu zao. Programu hasidi zinaweza kutatiza tabia ya programu zingine."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"weka utangamano wa skrini"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Huruhusu programu kudhibiti hali ya utangamano wa skrini ya programu zingine. Programu hasidi zinaweza kuvunja mwenendo wa programu zingine."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"wezesha utatuaji wa programu"</string>
@@ -287,7 +299,7 @@
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"Badilisha kasi ya pointa"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Inaruhusu programu kubadilisha kasi ya kielekezi cha kipanya au pedi ya kufuatilia wakati wowote. Kamwe haitahitajika kwa programu za kawaida."</string>
<string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"badilisha mpangilio wa kibodi"</string>
- <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Inaruhusu programu kubadilisha mpangilio wa kibodi. Haipaswi kamwe kuhitajika kwa rogramu za kawaida."</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Inaruhusu programu kubadilisha mpangilio wa kibodi. Haipaswi kamwe kuhitajika kwa programu za kawaida."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Tuma ishara za Linux kwa programu"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Inaruhusu programu kuomba ishara iliyotolewa kutumwa kwa michakato inyoendelea."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"Fanya programu kuendeshwa kila mara"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Jaribio la kiwanda limeshindikana"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Ingiza kibambo"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Inatuma ujumbe wa SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> inatuma idadi kubwa ya jumbe za SMS. Je, unataka kuruhusu programu hii kuendelea kutuma jumbe?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Ruhusu"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Kataza"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Tuma SMS kwa msimbo mfupi?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Tuma SMS ya ada?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ingependa kutuma ujumbe kwa <b>i<xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ambayo inaonekana kama msimbo mfupi wa ujumbe mfupi.<p>Kutuma ujumbe mfupi kwa baadhi ya misimbo mifupi kunaweza kusababisha akaunti yako ya simu kulipishwa huduma ya ada.<p>Je, unataka kuruhusu programu hii kutuma ujumbe?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ingetaka kutuma ujumbe wa maandishi kwa <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ambayo ni msimbo mfupi wa SMS ya ada.<p><b>Kutuma ujumbe mahali hapa kutasababisha akaunti yako ya simu kulipishwa kwa huduma ya ada.</b><p>Je, unataka kuruhusu programu hii kutuma ujumbe?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Tuma ujumbe"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Usitume"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Ripoti programu hasidi"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Kadi ya SIM imeondolewa"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"mtandao wa simu hutapatika hadi uanzishe upya na SIM kadi halali iliyoingizwa."</string>
<string name="sim_done_button" msgid="827949989369963775">"Kwisha"</string>
diff --git a/core/res/res/values-sw600dp/bools.xml b/core/res/res/values-sw600dp/bools.xml
index 2097049..e74379c 100644
--- a/core/res/res/values-sw600dp/bools.xml
+++ b/core/res/res/values-sw600dp/bools.xml
@@ -17,6 +17,5 @@
<resources>
<bool name="preferences_prefer_dual_pane">true</bool>
<bool name="show_ongoing_ime_switcher">false</bool>
- <bool name="action_bar_expanded_action_views_exclusive">false</bool>
<bool name="target_honeycomb_needs_options_menu">false</bool>
</resources>
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 13acdd6..4514760 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -18,13 +18,6 @@
*/
-->
<resources>
- <!-- Height of the status bar -->
- <dimen name="status_bar_height">48dip</dimen>
- <!-- Width and height of a single notification icon in the status bar -->
- <dimen name="status_bar_icon_size">24dip</dimen>
- <!-- Size of the giant number (unread count) in the notifications -->
- <dimen name="status_bar_content_number_size">48sp</dimen>
-
<!-- The maximum number of action buttons that should be permitted within
an action bar/action mode. This will be used to determine how many
showAsAction="ifRoom" items can fit. "always" items can override this. -->
@@ -82,5 +75,8 @@
(the screen is in landscape). This may be either a fraction or a dimension.-->
<item type="dimen" name="dialog_fixed_height_minor">90%</item>
+ <!-- Height of the bottom navigation bar in portrait; on sw600dp devices
+ this is a bit taller -->
+ <dimen name="navigation_bar_height_portrait">56dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/core/res/res/values-sw720dp/dimens.xml
similarity index 60%
rename from packages/SystemUI/res/values-sw600dp/config.xml
rename to core/res/res/values-sw720dp/dimens.xml
index 24185a4f..cac5aab 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/core/res/res/values-sw720dp/dimens.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/*
-** Copyright 2011, The Android Open Source Project
+**
+** Copyright 2012, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -16,13 +16,10 @@
** limitations under the License.
*/
-->
-
<resources>
- <!-- Whether we're using the tablet-optimized recents interface (we use this
- value at runtime for some things) -->
- <bool name="config_recents_interface_for_tablets">true</bool>
-
- <!-- Whether recents thumbnails should stretch in both x and y to fill their
- ImageView -->
- <bool name="config_recents_thumbnail_image_fits_to_xy">true</bool>
+ <!-- Height of the bottom navigation bar in portrait; on sw720dp devices
+ this is the same as the height in landscape -->
+ <dimen name="navigation_bar_height_portrait">@dimen/navigation_bar_height</dimen>
</resources>
+
+
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0884fb7..6b15b5d5 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"แท็บเล็ตของคุณจะปิดการทำงาน"</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"โทรศัพท์ของคุณจะปิดเครื่อง"</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"คุณต้องการปิดการทำงานหรือไม่"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"เมื่อเร็วๆ นี้"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"ไม่มีแอปพลิเคชันล่าสุด"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"ตัวเลือกของแท็บเล็ต"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"อนุญาตให้แอปพลิเคชันรับและประมวลผลข้อความ MMS แอปพลิเคชันที่เป็นอันตรายอาจตรวจสอบข้อความของคุณหรือลบออกโดยไม่แสดงให้คุณเห็น"</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"ได้รับการกระจายข้อความฉุกเฉิน"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"อนุญาตให้แอปพลิเคชันรับและประมวลผลข้อความที่เผยแพร่กรณีฉุกเฉิน การอนุญาตนี้ใช้ได้เฉพาะกับแอปพลิเคชันระบบเท่านั้น"</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"ส่งข้อความ SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"อนุญาตให้แอปพลิเคชันส่งข้อความ SMS แอปพลิเคชันที่เป็นอันตรายอาจทำให้คุณต้องเสียค่าใช้จ่ายด้วยการส่งข้อความโดยไม่มีการยืนยันจากคุณ"</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"ส่งข้อความ SMS โดยไม่มีการยืนยัน"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"อนุญาตให้แอปพลิเคชันย้ายงานไปยังส่วนหน้าและพื้นหลัง แอปพลิเคชันที่เป็นอันตรายอาจบังคับตัวเองให้ไปที่ส่วนหน้าโดยไม่มีการควบคุมจากคุณ"</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"หยุดแอปพลิเคชันที่ทำงานอยู่"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"อนุญาตให้แอปพลิเคชันลบงานออกและยุติแอปพลิเคชันต่างๆ ของงานนั้น แอปพลิเคชันที่เป็นอันตรายอาจทำให้แอปพลิเคชันอื่นๆ ทำงานได้ไม่ถูกต้อง"</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ตั้งค่าความเข้ากันได้ของหน้าจอ"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"อนุญาตให้แอปพลิเคชันควบคุมโหมดความเข้ากันได้ของหน้าจอของแอปพลิเคชันอื่น แอปพลิเคชันที่เป็นอันตรายอาจทำให้แอปพลิเคชันอื่นทำงานผิดพลาด"</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"เปิดใช้งานการแก้ไขบกพร่องของแอปพลิเคชัน"</string>
@@ -286,10 +298,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"อนุญาตให้แอปพลิเคชันเปลี่ยนการหมุนของหน้าจอได้ตลอดเวลา ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"เปลี่ยนความเร็วของตัวชี้"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"อนุญาตให้แอปพลิเคชันเปลี่ยนความเร็วตัวชี้ของเมาส์หรือแทร็กแพดได้ทุกเมื่อ ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"เปลี่ยนการจัดวางแป้นพิมพ์"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"อนุญาตให้แอปพลิเคชันเปลี่ยนการจัดวางแป้นพิมพ์ ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ส่งสัญญาณ Linux ไปยังแอปพลิเคชัน"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"อนุญาตให้แอปพลิเคชันร้องขอให้ส่งสัญญาณแจ้งไปยังกระบวนการที่ยังทำงานอยู่ทั้งหมด"</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"ทำให้แอปพลิเคชันทำงานเสมอ"</string>
@@ -736,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"การทดสอบจากโรงงานล้มเหลว"</string>
@@ -1010,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"ใส่อักขระ"</string>
<string name="sms_control_title" msgid="7296612781128917719">"กำลังส่งข้อความ SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> กำลังส่งข้อความ SMS จำนวนมาก คุณต้องการอนุญาตให้แอปพลิเคชันนี้ส่งข้อความต่อหรือไม่"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"อนุญาต"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"ปฏิเสธ"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"ส่ง SMS เป็นรหัสสั้นหรือไม่"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"ส่ง SMS พรีเมียมหรือไม่"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ต้องการส่งข้อความให้กับ <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> ซึ่งเป็น SMS รหัสสั้น<p>การส่งข้อความเป็นรหัสสั้นบางอย่างอาจทำให้มีการเรียกเก็บเงินในบัญชีมือถือของคุณสำหรับบริการพรีเมียม<p>คุณต้องการอนุญาตให้แอปพลิเคชันนี้ส่งข้อความหรือไม่"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ต้องการส่งข้อความให้กับ <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> ซึ่งเป็น SMS รหัสสั้นแบบพรีเมียม<p><b>การส่งข้อความไปยังปลายทางนี้จะทำให้มีการเรียกเก็บเงินในบัญชีมือถือของคุณสำหรับบริการพรีเมียม</b><p>คุณต้องการอนุญาตให้แอปพลิเคชันนี้ส่งข้อความหรือไม่"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"ส่งข้อความ"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"ไม่ส่ง"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"รายงานแอปที่เป็นอันตราย"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"นำซิมการ์ดออกแล้ว"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"เครือข่ายมือถือจะไม่สามารถใช้งานได้จนกว่าคุณจะรีสตาร์ทโดยใส่ซิมการ์ดที่ถูกต้องแล้ว"</string>
<string name="sim_done_button" msgid="827949989369963775">"เสร็จสิ้น"</string>
@@ -1079,10 +1087,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"แตะเพื่อปิดใช้งานการแก้ไขข้อบกพร่องของ USB"</string>
<string name="select_input_method" msgid="4653387336791222978">"เลือกวิธีการป้อนข้อมูล"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"ตั้งค่าวิธีการป้อนข้อมูล"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"แป้นพิมพ์บนเครื่อง"</string>
+ <string name="hardware" msgid="7517821086888990278">"ฮาร์ดแวร์"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"ตัวเลือก"</u></string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 26f7d5e..387f8d3 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Mag-shut down ang iyong tablet."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Magsa-shut down ang iyong telepono."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Nais mo bang mag-shut down?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Kamakailan"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Walang kamakailang apps."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Mga pagpipilian sa tablet"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Pinapayagan ang app na tumanggap at magproseso ng mga mensaheng MMS. Maaaring subaybayan ng nakakahamak na apps ang iyong mga mensahe o tanggalin ang mga ito nang hindi ipinapakita ang mga ito sa iyo."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"makatanggap ng mga emergency broadcast"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Pinapayagan ang app na tumanggap at magproseso ng mga mensahe ng broadcast na pang-emergency. Available lamang ang pahintulot na ito sa apps ng system."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"magpadala ng mga SMS na mensahe"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Pinapayagan ang app na magpadala ng mga mensaheng SMS. Maaari kang magastusan ng nakakahamak na apps sa pamamagitan ng pagpapadala ng mga mensahe nang wala ang iyong pagkumpirma."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"magpadala ng mga SMS na mensahe nang walang pagkumpirma"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Pinapayagan ang app na ilipat ang mga gawain sa foreground at background. Maaaring puwersahin ng nakakahamak na apps ang mga sarili nito sa harapan nang wala ang iyong pagkontrol."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"ihinto ang pagpapatakbo ng apps"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Pinapayagan ang app na mag-alis ng mga gawain at i-off ang apps nito. Maaaring maantala ng nakakahamak na apps ang pagkilos ng iba pang apps."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"itakda ang pagkakatugma ng screen"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Pinapayagan ang app na kontrolin ang mode ng pagkakatugma ng screen ng iba pang mga application. Maaaring sirain ng mga nakakahamak na application ang pag-uugali ng iba pang mga application."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"paganahin ang pag-debug ng app"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Nabigo ang factory na pagsubok"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Magpasok ng character"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Nagpapadala ng mga SMS na mensahe"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"Ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ay nagpapadala ng maraming mensaheng SMS. Gusto mo bang payagan ang app na ito na magpatuloy sa pagpapadala ng mga mensahe?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Payagan"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Tanggihan"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Magpadala SMS sa short code?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Ipadala ang premium na SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ay gustong magpadala ng text message sa <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, na lumilitaw na isang SMS na short code.<p>Ang pagpapadala ng mga text message sa ilang short code ay maaaring magdulot ng pagsingil sa iyong mobile account para sa mga premium na serbisyo.<p>Gusto mo bang payagan ang app na ito na ipadala ang mensahe?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ay gustong magpadala ng text message sa <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, na isang premium na SMS na short code.<p><b>Ang pagpapadala ng mensahe sa patutunguhang ito ay magdudulot ng pagsingil sa iyong mobile account para sa mga premium na serbisyo.</b><p>Gusto mo bang payagan ang app na ito na ipadala ang mensahe?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Ipadala ang mensahe"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Huwag ipadala"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Mag-ulat ng nakakapahamak na app"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Naalis ang SIM card"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Hindi magiging available ang mobile network hanggang mag-restart ka gamit ang isang may-bisang SIM card"</string>
<string name="sim_done_button" msgid="827949989369963775">"Tapos na"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 8abf38d..57bb082 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tabletiniz kapanacak."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonunuz kapanacak."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Kapatmak istiyor musunuz?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"En Son Görevler"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Son uygulama yok"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet seçenekleri"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Uygulamaya, MMS mesajlarını alma ve işleme izni verir. Kötü amaçlı uygulamalar mesajlarınızı izleyebilir veya onları size göstermeden silebilir."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"acil durum yayınlarını al"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Uygulamaya, acil yayın mesajları alma ve işleme izni verir. Bu izin, sadece sistem uygulamaları için kullanılabilir."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"SMS mesajları gönder"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Uygulamaya, SMS mesajları gönderme izni verir. Kötü amaçlı uygulamalar onayınızı almadan mesaj göndererek size masraf çıkarabilir."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"SMS mesajlarını onaysız gönder"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Uygulamaya, görevleri ön plana ve arka plana taşıma izni verir. Kötü amaçlı uygulamalar kendilerini sizin denetiminiz dışında ön plana taşıyabilir."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"çalışan uygulamaları durdur"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Uygulamaya, görevleri kaldırma ve bunlara ait uygulamaları kapatma izni verir. Kötü amaçlı uygulamalar diğer uygulamaların çalışmasını bozabilir."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ekran uyumluluğunu ayarla"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Uygulamaya diğer uygulamaların ekran uyumluluk modunu denetleme izni verir. Kötü amaçlı uygulamalar diğer uygulamaların çalışma şeklini bozabilir."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"uygulama hata ayıklamayı etkinleştir"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Fabrika testi yapılamadı"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Karakter ekle"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS mesajları gönderiliyor"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> çok sayıda SMS mesajı gönderiyor. Bu uygulamanın mesaj göndermeye devam etmesine izin veriyor musunuz?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"İzin ver"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Reddet"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Kısa koda SMS gönderilsin mi?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Premium SMS gönderilsin mi?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>, SMS kısa koduna sahip olduğu anlaşılan <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> hedefine bir kısa mesaj göndermek istiyor.<p>Bazı kısa kodlara kısa mesaj göndermek mobil hesabınızın premium hizmetle faturalandırılmasına neden olabilir.</b><p>Bu uygulamanın mesaj göndermesine izin vermek istiyor musunuz?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> premium SMS kısa koduna sahip <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> hedefine kısa mesaj göndermek istiyor.<p><b>Bu hedefe mesaj göndermek mobil hesabınızın premium hizmetle faturalandırılmasına neden olur.</b><p>Bu uygulamanın mesaj göndermesine izin vermek istiyor musunuz?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Mesajı gönder"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Gönderme"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Kötü amaçlı uygulamayı bildir"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM kart çıkarıldı"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Geçerli bir SIM kart yerleştirilmiş olarak yeniden başlatana kadar mobil ağ kullanılamayacak."</string>
<string name="sim_done_button" msgid="827949989369963775">"Tamamlandı"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 5504176..2dda5ea 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ваш пристрій буде вимкнено."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Ваш телефон буде вимкнено."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Вимкнути?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Останні"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Жодних останніх програм"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Парам. пристрою"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Дозволяє програмі отримувати й обробляти MMS повідомлення. Шкідливі програми можуть відстежувати ваші повідомлення чи видаляти їх, навіть не показуючи вам."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"отримувати повідомлення екстрених служб"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Дозволяє програмі отримувати й обробляти повідомлення екстрених служб. Цей дозвіл доступний лише для системних програм."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"читати широкомовні повідомлення мережі"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Дозволяє програмі читати широкомовні повідомлення мережі, отримані пристроєм. Широкомовні сповіщення мережі надсилаються в деяких країнах для попередження про надзвичайні ситуації. Шкідливі програми можуть втручатися у швидкодію чи роботу пристрою під час отримання широкомовного повідомлення мережі про надзвичайну ситуацію."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"надсил. SMS повідом."</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Дозволяє програмі надсилати SMS повідомлення. Шкідливі програми можуть надсилати повідомлення без вашого підтвердження, заставляючи вас платити."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"надсилати SMS-повідомлення без підтвердження"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Дозволяє програмі переміщувати завдання в активні чи фонові вікна. Шкідливі програми можуть примусово ставати активними без вашого відома."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"зупиняти запущені програми"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Дозволяє програмі видаляти завдання та примусово припиняти роботу відповідних програм. Шкідливі програми можуть переривати роботу інших програм."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"розпочинати будь-які дії"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Дозволяє програмі розпочинати будь-які дії, незалежно від захищеного дозволу або стану експорту."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"установити сумісність екрана"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Дозволяє програмі контролювати режим сумісності екрана інших програм. Шкідливі програми можуть переривати роботу інших програм."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"вмикати налагодження програми"</string>
@@ -286,10 +294,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"Дозволяє програмі будь-коли змінювати обертання екрана. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"змінювати швидкість указівника"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Дозволяє програмі будь-коли змінювати швидкість вказівника миші чи сенсорної панелі. Ніколи не застосовується для звичайних програм."</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"змінити розкладку клавіатури"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Дозволяє програмі змінювати розкладку клавіатури. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"надсилати сигнали Linux програмам"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Дозволяє програмі подавати запит щодо надсилання наданого сигналу всім сталим процесам."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"заставляти програму постійно функціонувати"</string>
@@ -736,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Помилка завод. тесту"</string>
@@ -1010,26 +1024,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-код:"</string>
<string name="select_character" msgid="3365550120617701745">"Вставл-ня символу"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Надсил. SMS повідомлень"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"Програма <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> надсилає велику кількість SMS-повідомлень. Дозволити цій програмі й надалі надсилати повідомлення?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Дозволити"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Відмовити"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Надіслати SMS на короткий код?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Надіслати спеціальне SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Програма <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> хоче надіслати текстове повідомлення на адресу <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, яка є коротким кодом SMS.<p><b>Якщо надсилати текстові повідомлення на певні короткі коди, з вашого мобільного рахунку буде стягнено плату за спеціальні послуги.</b><p>Дозволити цій програмі надіслати повідомлення?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Програма <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> хоче надіслати текстове повідомлення на адресу <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, яка є коротким кодом спеціальних SMS.<p><b>Якщо надіслати повідомлення на цю адресу, з вашого мобільного рахунку буде стягнено плату за спеціальні послуги.</b><p>Дозволити цій програмі надіслати повідомлення?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Надіслати повідомлення"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Не надсилати"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Повідом. про шкідливу програму"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-карту вилучено"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Мобільна мережа буде недоступна, поки ви не здійсните перезапуск, вставивши дійсну SIM-карту."</string>
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
@@ -1079,10 +1083,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"Торкніться, щоб вимкнути налагодження USB."</string>
<string name="select_input_method" msgid="4653387336791222978">"Вибрати метод введення"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Налаштувати методи введення"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"Фізична клавіатура"</string>
+ <string name="hardware" msgid="7517821086888990278">"Обладнання"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 96e97f6..0ed28f1 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Máy tính bảng của bạn sẽ tắt."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Điện thoại của bạn sẽ tắt."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Bạn có muốn tắt không?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Gần đây"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Không có ứng dụng nào gần đây."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tùy chọn máy tính bảng"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Cho phép ứng dụng nhận và xử lý tin nhắn MMS. Ứng dụng độc hại có thể theo dõi tin nhắn của bạn hoặc xóa tin nhắn mà không hiển thị chúng cho bạn."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"nhận các truyền phát khẩn cấp"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Cho phép ứng dụng nhận và xử lý tin nhắn truyền phát khẩn cấp. Quyền này chỉ sẵn có cho các ứng dụng hệ thống."</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"gửi tin nhắn SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Cho phép ứng dụng gửi tin nhắn SMS. Ứng dụng độc hại có thể khiến bạn tốn tiền bằng cách gửi tin nhắn mà không cần xác nhận của bạn."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"gửi tin nhắn SMS mà không cần xác nhận"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Cho phép ứng dụng di chuyển công việc sang nền trước và nền sau. Ứng dụng độc hại có thể tự hiển thị ở nền trước mà không chịu sự kiểm soát của bạn."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"dừng các ứng dụng đang chạy"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Cho phép ứng dụng xóa công việc và loại bỏ các ứng dụng của chúng. Ứng dụng độc hại có thể làm gián đoạn hoạt động của các ứng dụng khác."</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"đặt độ tương thích màn hình"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Cho phép ứng dụng kiểm soát chế độ tương thích màn hình của ứng dụng khác. Các ứng dụng độc hại có thể phá vỡ hoạt động của các ứng dụng khác."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"bật gỡ lỗi ứng dụng"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Thử nghiệm ban đầu không thành công"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"Mã PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"Chèn ký tự"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Đang gửi tin nhắn SMS"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> đang gửi rất nhiều tin nhắn SMS. Bạn có muốn cho phép ứng dụng này tiếp tục gửi tin nhắn không?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Cho phép"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Từ chối"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Gửi SMS cho mã ngắn?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Gửi tin nhắn SMS trả phí?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> muốn gửi tin nhắn văn bản cho <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, dường như là một mã ngắn SMS.<p>Việc gửi tin nhắn văn bản cho một số mã ngắn có thể khiến cho tài khoản di động của bạn bị lập hóa đơn cho dịch vụ trả phí.<p>Bạn có muốn cho phép ứng dụng này gửi tin nhắn không?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> muốn gửi tin nhắn văn bản cho <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, là một mã ngắn SMS trả phí.<p><b>Gửi tin nhắn tới địa chỉ này sẽ khiến cho tài khoản di động của bạn bị lập hóa đơn cho dịch vụ trả phí.</b><p>Bạn có muốn cho phép ứng dụng này gửi tin nhắn không?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Gửi tin nhắn"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Không gửi"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Báo cáo ứng dụng độc hại"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Đã xóa thẻ SIM"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mạng di động sẽ không khả dụng cho đến khi bạn khởi động lại với thẻ SIM hợp lệ được lắp."</string>
<string name="sim_done_button" msgid="827949989369963775">"Xong"</string>
diff --git a/core/res/res/values-w480dp/bools.xml b/core/res/res/values-w480dp/bools.xml
index 57a2939..3a463a6 100644
--- a/core/res/res/values-w480dp/bools.xml
+++ b/core/res/res/values-w480dp/bools.xml
@@ -17,6 +17,6 @@
*/
-->
<resources>
- <bool name="action_bar_embed_tabs">true</bool>
+ <bool name="action_bar_embed_tabs_pre_jb">true</bool>
<bool name="split_action_bar_is_narrow">false</bool>
</resources>
diff --git a/core/res/res/values-w720dp/bools.xml b/core/res/res/values-w720dp/bools.xml
new file mode 100644
index 0000000..352c319
--- /dev/null
+++ b/core/res/res/values-w720dp/bools.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <bool name="action_bar_expanded_action_views_exclusive">false</bool>
+</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 08a15e4..0e2d7fc 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"您的平板电脑会关闭。"</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"您的手机会关机。"</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"您要关机吗?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"近期任务"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"最近没有运行任何应用"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"平板电脑选项"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"允许应用接收和处理彩信。恶意应用可能会监视您的短信,或删除短信而不向您显示。"</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"接收紧急广播"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"允许应用接收和处理紧急广播消息。此权限仅适用于系统应用。"</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"发送短信"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"允许应用发送短信。恶意应用可能会未经您的确认而发送短信,由此产生相关费用。"</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"不经确认直接发送短信"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"允许应用将任务移动到前台和后台。恶意应用可能会不受您的控制,强行让自己处于前台。"</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"停止正在运行的应用"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"允许该应用删除任务并终止这些任务的应用。恶意应用可以籍此影响其他应用的行为。"</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"设置屏幕兼容性"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"允许该应用控制其他应用的屏幕兼容模式。恶意应用可以籍此影响其他应用的行为。"</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"启用应用调试"</string>
@@ -734,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="AMPM">%P</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="AMPM">%p</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"出厂测试失败"</string>
@@ -1008,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"插入字符"</string>
<string name="sms_control_title" msgid="7296612781128917719">"正在发送短信"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>在发送大量短信。是否允许该应用继续发送短信?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"允许"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"拒绝"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"是否向短码发送短信?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"是否发送付费短信?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>想要向 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>(这似乎是一个短信短码)发送短信。<p>向某些短码发送短信可能会导致您的移动帐户因使用付费服务而扣费。<p>是否允许该应用发送短信?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>想要向 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>(这是一个付费短信短码)发送短信。<p><b>向该地址发送短信会导致您的移动帐户因使用付费服务而扣费</b>。<p>是否允许该应用发送短信?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"发送短信"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"不发送"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"举报恶意应用"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"已移除 SIM 卡"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"移动网络不可用。请插入有效的 SIM 卡并重新启动。"</string>
<string name="sim_done_button" msgid="827949989369963775">"完成"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 0468534..a5a3a1d 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"您的平板電腦將會關機。"</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"手機即將關機。"</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"您要關機嗎?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"最新的"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"沒有最近用過的應用程式。"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"平板電腦選項"</string>
@@ -199,6 +203,10 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"允許應用程式接收及處理 MMS 簡訊。請注意,惡意應用程式可能利用此功能監視您的訊息,或在您讀取訊息前擅自將其刪除。"</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"接收緊急廣播"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"允許應用程式接收及處理緊急廣播訊息,只有系統應用程式可以具備這項權限。"</string>
+ <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
+ <skip />
+ <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
+ <skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"傳送 SMS 簡訊"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"允許應用程式傳送 SMS 簡訊。請注意,惡意應用程式可能利用此功能擅自傳送簡訊,導致您必須支付大筆費用。"</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"不需經過確認即傳送 SMS 簡訊"</string>
@@ -217,6 +225,10 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"允許應用程式將工作移至前景或背景。請注意,惡意應用程式可能利用此功能自行移動至前景。"</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"停止執行中的應用程式"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"允許應用程式移除工作並終止執行工作的應用程式。請注意,惡意應用程式可能利用此功能干擾其他應用程式的行為。"</string>
+ <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
+ <skip />
+ <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
+ <skip />
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"設定螢幕相容性"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"允許應用程式控制其他應用程式的螢幕相容性模式。惡意應用程式可能藉此破壞其他應用程式的正常運作。"</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"啟用應用程式偵錯"</string>
@@ -286,10 +298,8 @@
<string name="permdesc_setOrientation" msgid="3046126619316671476">"允許應用程式隨時變更螢幕旋轉狀態 (一般應用程式不需使用)。"</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"變更指標速度"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"允許應用程式隨時變更滑鼠或觸控板游標的移動速度 (一般應用程式不需使用)。"</string>
- <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
- <skip />
- <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
- <skip />
+ <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"變更鍵盤配置"</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"允許應用程式變更鍵盤配置 (一般應用程式不需使用)。"</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"將 Linux 訊號傳送給應用程式"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"允許應用程式要求將提供的訊號傳送給所有持續運作中的處理程序。"</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"一律執行應用程式"</string>
@@ -736,6 +746,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"出廠測試失敗"</string>
@@ -1010,26 +1028,16 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"插入字元"</string>
<string name="sms_control_title" msgid="7296612781128917719">"傳送 SMS 簡訊"</string>
- <!-- no translation found for sms_control_message (3867899169651496433) -->
- <skip />
- <!-- no translation found for sms_control_yes (3663725993855816807) -->
- <skip />
- <!-- no translation found for sms_control_no (625438561395534982) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
- <skip />
- <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
- <skip />
+ <string name="sms_control_message" msgid="3867899169651496433">"<b></b>「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在傳送大量簡訊。您要允許這個應用程式繼續傳送簡訊嗎?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"允許"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"拒絕"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"傳送簡訊給短碼?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"傳送付費簡訊?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b></b>「<xliff:g id="APP_NAME">%1$s</xliff:g>」想要傳送簡訊給簡訊短碼 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>。<p>傳送簡訊給簡訊短碼之後,系統即會從您的行動帳戶扣除付費服務的費用。<p>您要允許這個應用程式傳送簡訊嗎?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b></b>「<xliff:g id="APP_NAME">%1$s</xliff:g>」想要傳送簡訊給付費簡訊短碼 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>。<p><b>傳送簡訊給這個對象之後,系統即會從您的行動帳戶扣除付費服務的費用。</b><p>您要允許這個應用程式傳送簡訊嗎?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"傳送簡訊"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"不要傳送"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"檢舉惡意應用程式"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM 卡已移除"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"您必須先插入有效的 SIM 卡再重新啟動手機,才能使用行動網路。"</string>
<string name="sim_done_button" msgid="827949989369963775">"完成"</string>
@@ -1079,10 +1087,8 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
<string name="select_input_method" msgid="4653387336791222978">"選擇輸入法"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"設定輸入法"</string>
- <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
- <skip />
- <!-- no translation found for hardware (7517821086888990278) -->
- <skip />
+ <string name="use_physical_keyboard" msgid="6203112478095117625">"實體鍵盤"</string>
+ <string name="hardware" msgid="7517821086888990278">"硬體"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index c910d4a..d0180e6 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -146,6 +146,10 @@
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ithebhulethi yakho izocima."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Ifoni yakho izocima."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Ingabe ufuna ukucisha?"</string>
+ <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
+ <skip />
+ <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
+ <skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Okwakamuva"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Azikho izinhlelo zokusebenza zakamuva"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Okukhethwa konke kwethebhulethi"</string>
@@ -199,6 +203,8 @@
<string name="permdesc_receiveMms" msgid="1424805308566612086">"Ivumela ukuthi insiza yamukele iphinde isebenze imiyalezo ye-MMS. Izinsiza ezinobungozi zingabheka imiyalezo yakho noma ziyisuse ziyikhombisa wena."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"yamukela ukusakazwa okuphuthumayo"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Ivumela insiza ukuthi yamukele iphinde isebenze ukusakakwa kwemiyalezo yezokuphuthumayo. Imvume itholakla ezinsizeni zesistimu kuphela."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"funda imilayezo yokusakaza yeselula"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ivumela uhlelo lokusebenza ukufunda imilayezo yokusakaza yeselula etholwe idivayisi yakho. Izaziso zokusakaza zeselula zilethwa kwezinye izindawo ukukuxwayisa ngezimo ezisheshayo. Izinhlelo zokusebenza ezingalungile zingaphazamisana nokusebenza noma umsebenzi wedivayisi yakho uma ukusakaza kweselula kwesimo esisheshayo kutholwa."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"thumela imiyalezo ye-SMS"</string>
<string name="permdesc_sendSms" msgid="906546667507626156">"Ivumela insiza ukuthi ithumele imiyalezo ye-SMS. Izinsiza ezinobungozi zingakudla ephaketheni ngokuthi zithuele imiyalezo ngaphandle kokuqinisekisa kwakho."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"thumela i-SMS engenakuqinisekiswa"</string>
@@ -217,6 +223,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Ivumela insiza ukuthi ihambise izenzo ziye ngaphambili kanye nasemumva. Izinsiza ezinobungozi zingaziphoqelela ukuth iziye phambili ngaphandle kokulawula kwakho."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"misa izinsiza ezisebenzayo"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Vumela ukuthi insiza isuse okumele kwenziwe ibulale nezinsiza zakho. Izinsiza eziwubungozi zingaphazamisa ukusebenza kwezinye izinsiza."</string>
+ <string name="permlab_startAnyActivity" msgid="2918768238045206456">"qala noma imuphi umsebenzi"</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Ivumela uhlelo lokusebenza ukuqala umsebenzi, ngaphandle kokuvukeleka kwemvume noma isimo sokukhishiwe."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"setha ukuhambelana kwesikrini"</string>
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Ivumela uhlelo lokusebenza ukulawula imodi yokuhambelana kwesikrini kwezinye izinhlelo zokusebenza. Izinhlelo zokusebenza ezinonya zingase zephule ukuziphatha kwezinye izinhlelo zokusebenza."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"vumela insiza ilungise inkinga"</string>
@@ -287,7 +295,7 @@
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"guqula isivinini sesikhombi"</string>
<string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Ivumela insiza ukuthi iguqule ijubane legundane noma lendawo yokukhomba ngomunwe. Akufanele kudingakele izinsiza ezijwayelekile."</string>
<string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"shintsha isendlalelo sekhibhodi"</string>
- <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Ivumela uhlelo lokusebenza ukushintsha isendlalelo sekhibhodi. Kufanele ingadingi izinhlelo zokusebenzia ezivamile."</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Ivumela uhlelo lokusebenza ukushintsha isendlalelo sekhibhodi. Kufanele ingadingi izinhlelo zokusebenza ezivamile."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Thumela imifanekiso ye-Linu ezinsizeni"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Ivumela insiza ukuthi icele ukuthi isiginali ethunyelwe idluliselwe kuzo zonke izinqubeko ezisalelayo."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"yenza insiza ukuthi ihlale isebenza"</string>
@@ -734,6 +742,14 @@
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for granularity_label_character (7336470535385009523) -->
+ <skip />
+ <!-- no translation found for granularity_label_word (7075570328374918660) -->
+ <skip />
+ <!-- no translation found for granularity_label_link (5815508880782488267) -->
+ <skip />
+ <!-- no translation found for granularity_label_line (5764267235026120888) -->
+ <skip />
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Ukuhlola kwemboni kwehlulekile"</string>
@@ -1011,11 +1027,11 @@
<string name="sms_control_message" msgid="3867899169651496433">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ithumela inombolo enkulu yemilayezo ye-SMS. Ufuna ukuvumela lolu hlelo lokusebenza ukuqhubeka ukuthumela imilayezo?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Vumela"</string>
<string name="sms_control_no" msgid="625438561395534982">"Nqaba"</string>
- <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Thumela ikhodi efushane?"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Thumela i-SMS kukhodi emfushane?"</string>
<string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Ukuthumela i-SMS ye-premium?"</string>
- <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ithanda ukuthumela umlayezo wombhalo ku-<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, okubonakala sengathi ikhodi ye-SMS efushane.<p>Ukuthumela umlayezo wombhalo kungabangela i-akhawunti yeselula yakho ukuthi ikhokheliswe amasevisi e-premium.<p>Ufuna ukuvumela uhlelo lokusebenza ukuthumela umlayezo?"</string>
- <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ithanda ukuthumela umlayezo wombhalo ku-<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, okuyikhodi efushane ye-SMS ye-premium.<p><b>Ukuthumela umlayezo kule ndawo kuzobangela i-akhawunti yeselula yakho ukuthi ikhokheliswe amasevisi e-premium.</b><p>Ufuna ukuvumela lolu hlelo lokusebenza ukuthumela umlayezo?"</string>
- <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Thumela umlayezo?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ithanda ukuthumela umlayezo wombhalo ku-<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, okubonakala sengathi ikhodi ye-SMS emfushane.<p>Ukuthumela umlayezo wombhalo kungabangela i-akhawunti yeselula yakho ukuthi ikhokheliswe amasevisi e-premium.<p>Ufuna ukuvumela uhlelo lokusebenza ukuthumela umlayezo?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ithanda ukuthumela umlayezo wombhalo ku-<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, okuyikhodi emfushane ye-SMS ye-premium.<p><b>Ukuthumela umlayezo kule ndawo kuzobangela i-akhawunti yeselula yakho ukuthi ikhokheliswe amasevisi e-premium.</b><p>Ufuna ukuvumela lolu hlelo lokusebenza ukuthumela umlayezo?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Thumela umlayezo"</string>
<string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ungathumeli"</string>
<string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Bika uhlelo lokusebenza olungalungile"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Ikhadi le-SIM likhishiwe"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 6f489d4..aa47993 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2470,6 +2470,8 @@
<!-- Flag whether the accessibility service wants to be able to retrieve the
active window content. This setting cannot be changed at runtime. -->
<attr name="canRetrieveWindowContent" format="boolean" />
+ <!-- Flag whether the accessibility service can handle gesrures and wants such. -->
+ <attr name="canHandleGestures" format="boolean" />
<!-- Short description of the accessibility serivce purpose or behavior.-->
<attr name="description" />
</declare-styleable>
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index 87a98e2..f9762b1 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -15,7 +15,8 @@
-->
<resources>
- <bool name="action_bar_embed_tabs">false</bool>
+ <bool name="action_bar_embed_tabs">true</bool>
+ <bool name="action_bar_embed_tabs_pre_jb">false</bool>
<bool name="split_action_bar_is_narrow">true</bool>
<bool name="preferences_prefer_dual_pane">false</bool>
<bool name="show_ongoing_ime_switcher">true</bool>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 5ff2c01..e23e3c6 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -22,6 +22,8 @@
<drawable name="screen_background_dark">#ff000000</drawable>
<drawable name="status_bar_closed_default_background">#ff000000</drawable>
<drawable name="status_bar_opened_default_background">#ff000000</drawable>
+ <drawable name="notification_item_background_color">#ff111111</drawable>
+ <drawable name="notification_item_background_color_pressed">#ff257390</drawable>
<drawable name="search_bar_default_color">#ff000000</drawable>
<drawable name="safe_mode_background">#60000000</drawable>
<!-- Background drawable that can be used for a transparent activity to
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 0442be8..392116f 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -34,16 +34,22 @@
<dimen name="status_bar_height">25dip</dimen>
<!-- Height of the bottom navigation / system bar. -->
<dimen name="navigation_bar_height">48dp</dimen>
+ <!-- Height of the bottom navigation bar in portrait -->
+ <dimen name="navigation_bar_height_portrait">@dimen/navigation_bar_height</dimen>
<!-- Width of the navigation bar when it is placed vertically on the screen -->
<dimen name="navigation_bar_width">42dp</dimen>
<!-- Height of notification icons in the status bar -->
<dimen name="status_bar_icon_size">24dip</dimen>
<!-- Size of the giant number (unread count) in the notifications -->
<dimen name="status_bar_content_number_size">48sp</dimen>
+ <!-- Height of the system bar (combined status & navigation); used by
+ SystemUI internally, not respected by the window manager. -->
+ <dimen name="system_bar_height">@dimen/navigation_bar_height</dimen>
<!-- Height of notification icons in the system bar -->
<dimen name="system_bar_icon_size">32dip</dimen>
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
<dimen name="status_bar_edge_ignore">5dp</dimen>
+
<!-- Size of the fastscroll hint letter -->
<dimen name="fastscroll_overlay_size">104dp</dimen>
<!-- Width of the fastscroll thumb -->
@@ -213,4 +219,12 @@
<!-- Minimum width for an action button in the menu area of an action bar -->
<dimen name="action_button_min_width">56dip</dimen>
+
+ <!-- Maximum height for a stacked tab bar as part of an action bar -->
+ <dimen name="action_bar_stacked_max_height">48dp</dimen>
+
+ <!-- Maximum width for a stacked action bar tab. This prevents
+ action bar tabs from becoming too wide on a wide screen when only
+ a few are present. -->
+ <dimen name="action_bar_stacked_tab_max_width">180dp</dimen>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 8ac94fb..1a631ef 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -205,6 +205,11 @@
<java-symbol type="id" name="big_picture" />
<java-symbol type="id" name="big_text" />
<java-symbol type="id" name="chronometer" />
+ <java-symbol type="id" name="inbox_text0" />
+ <java-symbol type="id" name="inbox_text1" />
+ <java-symbol type="id" name="inbox_text2" />
+ <java-symbol type="id" name="inbox_text3" />
+ <java-symbol type="id" name="inbox_text4" />
<java-symbol type="attr" name="actionModeShareDrawable" />
<java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -229,6 +234,7 @@
<java-symbol type="attr" name="accessibilityFocusedDrawable"/>
<java-symbol type="bool" name="action_bar_embed_tabs" />
+ <java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" />
<java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" />
<java-symbol type="bool" name="config_allowActionMenuItemTextWithIcon" />
<java-symbol type="bool" name="config_bluetooth_adapter_quick_switch" />
@@ -287,6 +293,8 @@
<java-symbol type="dimen" name="textview_error_popup_default_width" />
<java-symbol type="dimen" name="toast_y_offset" />
<java-symbol type="dimen" name="volume_panel_top" />
+ <java-symbol type="dimen" name="action_bar_stacked_max_height" />
+ <java-symbol type="dimen" name="action_bar_stacked_tab_max_width" />
<java-symbol type="string" name="addToDictionary" />
<java-symbol type="string" name="action_bar_home_description" />
@@ -700,6 +708,8 @@
<java-symbol type="string" name="preposition_for_time" />
<java-symbol type="string" name="progress_erasing" />
<java-symbol type="string" name="progress_unmounting" />
+ <java-symbol type="string" name="reboot_safemode_confirm" />
+ <java-symbol type="string" name="reboot_safemode_title" />
<java-symbol type="string" name="relationTypeAssistant" />
<java-symbol type="string" name="relationTypeBrother" />
<java-symbol type="string" name="relationTypeChild" />
@@ -857,6 +867,10 @@
<java-symbol type="string" name="yesterday" />
<java-symbol type="string" name="imei" />
<java-symbol type="string" name="meid" />
+ <java-symbol type="string" name="granularity_label_character" />
+ <java-symbol type="string" name="granularity_label_word" />
+ <java-symbol type="string" name="granularity_label_link" />
+ <java-symbol type="string" name="granularity_label_line" />
<java-symbol type="plurals" name="abbrev_in_num_days" />
<java-symbol type="plurals" name="abbrev_in_num_hours" />
@@ -994,6 +1008,7 @@
<java-symbol type="drawable" name="ic_lockscreen_silent" />
<java-symbol type="drawable" name="ic_lockscreen_unlock" />
<java-symbol type="drawable" name="ic_lockscreen_search" />
+ <java-symbol type="drawable" name="notification_bg" />
<java-symbol type="layout" name="action_bar_home" />
<java-symbol type="layout" name="action_bar_title_item" />
@@ -1082,9 +1097,12 @@
<java-symbol type="layout" name="notification_action" />
<java-symbol type="layout" name="notification_intruder_content" />
<java-symbol type="layout" name="notification_template_base" />
+ <java-symbol type="layout" name="notification_template_big_base" />
<java-symbol type="layout" name="notification_template_big_picture" />
+ <java-symbol type="layout" name="notification_template_big_text" />
<java-symbol type="layout" name="notification_template_part_time" />
<java-symbol type="layout" name="notification_template_part_chronometer" />
+ <java-symbol type="layout" name="notification_template_inbox" />
<java-symbol type="anim" name="slide_in_child_bottom" />
<java-symbol type="anim" name="slide_in_right" />
@@ -3589,5 +3607,6 @@
<public type="attr" name="parentActivityName" />
<public type="attr" name="importantForAccessibility"/>
+ <public type="attr" name="canHandleGestures"/>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e00986c..9a16521 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -315,6 +315,15 @@
power off dialog instead of the global actions menu. -->
<string name="shutdown_confirm_question">Do you want to shut down?</string>
+ <!-- Title of dialog to confirm rebooting into safe mode. [CHAR LIMIT=50] -->
+ <string name="reboot_safemode_title">Reboot to safe mode</string>
+
+ <!-- Shutdown Confirmation Dialog. Message in the confirmation dialog
+ when the user asks to reboot into safe mode. [CHAR LIMIT=NONE] -->
+ <string name="reboot_safemode_confirm">Do you want to reboot into safe mode?
+ This will disable all third party applications you have installed.
+ They will be restored when you reboot again.</string>
+
<!-- Recent Tasks dialog: title
TODO: this should move to SystemUI.apk, but the code for the old
recent dialog is still in the framework
@@ -474,6 +483,15 @@
and process emergency broadcast messages. This permission is only available
to system apps.</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_readCellBroadcasts">read cell broadcast messages</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_readCellBroadcasts">Allows the app to read
+ cell broadcast messages received by your device. Cell broadcast alerts
+ are delivered in some locations to warn you of emergency situations.
+ Malicious apps may interfere with the performance or operation of your
+ device when an emergency cell broadcast is received.</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_sendSms">send SMS messages</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -538,6 +556,11 @@
tasks and kill their apps. Malicious apps may disrupt
the behavior of other apps.</string>
+ <!-- Title of an application permission, allowing an application to start any activity, regardless of permission protection or exported state. -->
+ <string name="permlab_startAnyActivity">start any activity</string>
+ <!-- Description of an application permission, allowing an application to start any activity, regardless of permission protection or exported state. -->
+ <string name="permdesc_startAnyActivity">Allows the app to start any activity, regardless of permission protection or exported state.</string>
+
<!-- Title of an application permission, allowing control of app screen compatibility mode -->
<string name="permlab_setScreenCompatibility">set screen compatibility</string>
<!-- Description of an application permission, allowing control of app screen compatibility mode -->
@@ -936,24 +959,33 @@
<string name="permlab_readContacts">read contact data</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_readContacts" product="tablet">Allows the app to read all
- of the contact (address) data stored on your tablet. Malicious apps
- may use this to send your data to other people.</string>
+ the data about your contacts stored on your tablet, including the frequency
+ with which you've called, emailed, or communicated in other ways with specific
+ individuals. This helps with auto-completion of email addresses and other convenient
+ features. Malicious apps can use this permission to send your contact data to
+ other people.</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_readContacts" product="default">Allows the app to read all
- of the contact (address) data stored on your phone. Malicious apps
- may use this to send your data to other people.</string>
+ the data about your contacts stored on your phone, including the frequency
+ with which you've called, emailed, or communicated in other ways with specific
+ individuals. This helps with auto-completion of email addresses and other convenient
+ features. Malicious apps can use this permission to send your contact data to
+ other people.</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_writeContacts">write contact data</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_writeContacts" product="tablet">Allows the app to modify the
- contact (address) data stored on your tablet. Malicious
- apps may use this to erase or modify your contact data.</string>
+ <string name="permdesc_writeContacts" product="tablet">Allows the app to modify
+ the data about your contacts stored on your tablet, including the frequency
+ with which you've called, emailed, or communicated in other ways with specific
+ individuals. This helps with auto-completion of email addresses and other convenient
+ features. Malicious apps may use this to erase or modify your contact data.</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_writeContacts" product="default">Allows the app to modify the
- contact (address) data stored on your phone. Malicious
- apps may use this to erase or modify your contact data.</string>
-
+ <string name="permdesc_writeContacts" product="default">Allows the app to modify
+ the data about your contacts stored on your phone, including the frequency
+ with which you've called, emailed, or communicated in other ways with specific
+ individuals. This helps with auto-completion of email addresses and other convenient
+ features. Malicious apps may use this to erase or modify your contact data.</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_readCallLog">read call log</string>
@@ -2013,6 +2045,15 @@
<!-- Label for ALT modifier key. Must be short to fit on key! -->
<string name="password_keyboard_label_alt_key">ALT</string>
+ <!-- Label for granularity to traverse the content on an AccessibilityNodeInfo by character. Only spoken to the user. [CHAR LIMIT=NONE] -->
+ <string name="granularity_label_character">character</string>
+ <!-- Label for granularity to traverse the content on an AccessibilityNodeInfo by word. Only spoken to the user. [CHAR LIMIT=NONE] -->
+ <string name="granularity_label_word">word</string>
+ <!-- Label for granularity to traverse the content on an AccessibilityNodeInfo by link. Only spoken to the user. [CHAR LIMIT=NONE] -->
+ <string name="granularity_label_link">link</string>
+ <!-- Label for granularity to traverse the content on an AccessibilityNodeInfo by line. Only spoken to the user. [CHAR LIMIT=NONE] -->
+ <string name="granularity_label_line">line</string>
+
<!-- A format string for 12-hour time of day, just the hour, not the minute, with lower-case "am" or "pm" (example: "3pm"). -->
<string name="hour_ampm">"<xliff:g id="hour" example="3">%-l</xliff:g><xliff:g id="ampm" example="pm">%P</xliff:g>"</string>
diff --git a/core/tests/coretests/res/drawable/size_adaptive_statelist.xml b/core/tests/coretests/res/drawable/size_adaptive_statelist.xml
new file mode 100644
index 0000000..aaa2de7
--- /dev/null
+++ b/core/tests/coretests/res/drawable/size_adaptive_statelist.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+ <item android:state_pressed="true" android:drawable="@drawable/blue" />
+ <item android:state_pressed="false" android:drawable="@drawable/red" />
+</selector>
diff --git a/core/tests/coretests/res/layout/size_adaptive_color_statelist.xml b/core/tests/coretests/res/layout/size_adaptive_color_statelist.xml
new file mode 100644
index 0000000..d24df5b
--- /dev/null
+++ b/core/tests/coretests/res/layout/size_adaptive_color_statelist.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<com.android.internal.widget.SizeAdaptiveLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+ android:background="@drawable/size_adaptive_statelist"
+ android:id="@+id/multi1"
+ android:layout_width="match_parent"
+ android:layout_height="64dp" >
+
+ <include
+ android:id="@+id/one_u"
+ layout="@layout/size_adaptive_one_u"
+ android:layout_width="fill_parent"
+ android:layout_height="64dp"
+ internal:layout_minHeight="64dp"
+ internal:layout_maxHeight="64dp"
+ />
+
+ <include
+ android:id="@+id/four_u"
+ layout="@layout/size_adaptive_four_u"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ internal:layout_minHeight="65dp"
+ internal:layout_maxHeight="unbounded"/>
+
+</com.android.internal.widget.SizeAdaptiveLayout>
diff --git a/core/tests/coretests/src/android/animation/EventsTest.java b/core/tests/coretests/src/android/animation/EventsTest.java
index 701a3f0..8df711b 100644
--- a/core/tests/coretests/src/android/animation/EventsTest.java
+++ b/core/tests/coretests/src/android/animation/EventsTest.java
@@ -173,8 +173,7 @@
// This should only be called on an animation that has been started and not
// yet canceled or ended
assertFalse(mCanceled);
- assertTrue(mRunning);
- assertTrue(mStarted);
+ assertTrue(mRunning || mStarted);
mCanceled = true;
}
@@ -182,8 +181,7 @@
public void onAnimationEnd(Animator animation) {
// This should only be called on an animation that has been started and not
// yet ended
- assertTrue(mRunning);
- assertTrue(mStarted);
+ assertTrue(mRunning || mStarted);
mRunning = false;
mStarted = false;
super.onAnimationEnd(animation);
@@ -210,11 +208,12 @@
}
/**
- * Verify that calling end on an unstarted animator does nothing.
+ * Verify that calling end on an unstarted animator starts/ends an animator.
*/
@UiThreadTest
@SmallTest
public void testEnd() throws Exception {
+ mRunning = true; // end() implicitly starts an unstarted animator
mAnimator.end();
}
@@ -496,6 +495,7 @@
mRunning = true;
mAnimator.start();
mAnimator.end();
+ mRunning = true; // end() implicitly starts an unstarted animator
mAnimator.end();
mFuture.release();
} catch (junit.framework.AssertionFailedError e) {
@@ -544,6 +544,7 @@
mRunning = true;
mAnimator.start();
mAnimator.end();
+ mRunning = true; // end() implicitly starts an unstarted animator
mAnimator.end();
mFuture.release();
} catch (junit.framework.AssertionFailedError e) {
diff --git a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
index 73da84f..2e42e5a 100644
--- a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
+++ b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
@@ -45,18 +45,18 @@
public void printBlocks(String message) {
System.out.print(message);
for (int i = 0; i < dl.getNumberOfBlocks(); i++) {
- System.out.print(" " + Integer.toString(dl.getBlockEnds()[i]));
+ System.out.print(" " + Integer.toString(dl.getBlockEndLines()[i]));
}
System.out.println();
}
public void checkInvariants() {
assertTrue(dl.getNumberOfBlocks() > 0);
- assertTrue(dl.getNumberOfBlocks() <= dl.getBlockEnds().length);
- assertEquals(dl.getBlockEnds().length, dl.getBlockIndices().length);
+ assertTrue(dl.getNumberOfBlocks() <= dl.getBlockEndLines().length);
+ assertEquals(dl.getBlockEndLines().length, dl.getBlockIndices().length);
for (int i = 1; i < dl.getNumberOfBlocks(); i++) {
- assertTrue(dl.getBlockEnds()[i] > dl.getBlockEnds()[i-1]);
+ assertTrue(dl.getBlockEndLines()[i] > dl.getBlockEndLines()[i-1]);
}
}
@@ -78,7 +78,7 @@
}
for (int i = 0; i < dl.getNumberOfBlocks(); i++) {
- assertEquals(ends[i], dl.getBlockEnds()[i]);
+ assertEquals(ends[i], dl.getBlockEndLines()[i]);
assertEquals(indices[i], dl.getBlockIndices()[i]);
}
}
diff --git a/core/tests/coretests/src/com/android/internal/os/DebugTest.java b/core/tests/coretests/src/com/android/internal/os/DebugTest.java
new file mode 100644
index 0000000..88c7d1b
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/DebugTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.os.Debug;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import junit.framework.TestCase;
+
+@SmallTest
+public class DebugTest extends TestCase {
+
+ private final static String EXPECTED_GET_CALLER =
+ "com\\.android\\.internal\\.os\\.DebugTest\\.testGetCaller:\\d\\d";
+ private final static String EXPECTED_GET_CALLERS =
+ "com\\.android\\.internal\\.os\\.DebugTest.callDepth3:\\d\\d " +
+ "com\\.android\\.internal\\.os\\.DebugTest.callDepth2:\\d\\d " +
+ "com\\.android\\.internal\\.os\\.DebugTest.callDepth1:\\d\\d ";
+
+ /**
+ * @return String consisting of the caller to this method.
+ */
+ private String callDepth0() {
+ return Debug.getCaller();
+ }
+
+ public void testGetCaller() {
+ assertTrue(callDepth0().matches(EXPECTED_GET_CALLER));
+ }
+
+ /**
+ * @return String consisting of the callers to this method.
+ */
+ private String callDepth4() {
+ return Debug.getCallers(3);
+ }
+
+ private String callDepth3() {
+ return callDepth4();
+ }
+
+ private String callDepth2() {
+ return callDepth3();
+ }
+
+ private String callDepth1() {
+ return callDepth2();
+ }
+
+ public void testGetCallers() {
+ assertTrue(callDepth1().matches(EXPECTED_GET_CALLERS));
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/widget/SizeAdaptiveLayoutTest.java b/core/tests/coretests/src/com/android/internal/widget/SizeAdaptiveLayoutTest.java
index fc83e4a..a937f65 100644
--- a/core/tests/coretests/src/com/android/internal/widget/SizeAdaptiveLayoutTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/SizeAdaptiveLayoutTest.java
@@ -19,6 +19,7 @@
import com.android.frameworks.coretests.R;
import android.content.Context;
+import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -428,6 +429,17 @@
}
@SmallTest
+ public void testModestyPanelTracksStateListColor() {
+ inflate(R.layout.size_adaptive_color_statelist);
+ View panel = mSizeAdaptiveLayout.getModestyPanel();
+ assertEquals("ModestyPanel should have a ColorDrawable background" ,
+ panel.getBackground().getClass(), ColorDrawable.class);
+ ColorDrawable panelColor = (ColorDrawable) panel.getBackground();
+ assertEquals("ModestyPanel color should match the SizeAdaptiveLayout",
+ panelColor.getColor(), Color.RED);
+ }
+
+ @SmallTest
public void testModestyPanelHasDefault() {
inflate(R.layout.size_adaptive);
View panel = mSizeAdaptiveLayout.getModestyPanel();
diff --git a/data/fonts/DroidNaskh-Regular-Shift.ttf b/data/fonts/DroidNaskh-Regular-Shift.ttf
index 0cb843d..bb9c70c 100644
--- a/data/fonts/DroidNaskh-Regular-Shift.ttf
+++ b/data/fonts/DroidNaskh-Regular-Shift.ttf
Binary files differ
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index b5f6897..544076f 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -28,14 +28,12 @@
label: 'A'
base: 'a'
shift, capslock: 'A'
- ctrl, alt, meta: none
}
key B {
label: 'B'
base: 'b'
shift, capslock: 'B'
- ctrl, alt, meta: none
}
key C {
@@ -44,14 +42,12 @@
shift, capslock: 'C'
alt: '\u00e7'
shift+alt: '\u00c7'
- ctrl, meta: none
}
key D {
label: 'D'
base: 'd'
shift, capslock: 'D'
- ctrl, alt, meta: none
}
key E {
@@ -59,28 +55,24 @@
base: 'e'
shift, capslock: 'E'
alt: '\u0301'
- ctrl, meta: none
}
key F {
label: 'F'
base: 'f'
shift, capslock: 'F'
- ctrl, alt, meta: none
}
key G {
label: 'G'
base: 'g'
shift, capslock: 'G'
- ctrl, alt, meta: none
}
key H {
label: 'H'
base: 'h'
shift, capslock: 'H'
- ctrl, alt, meta: none
}
key I {
@@ -88,35 +80,30 @@
base: 'i'
shift, capslock: 'I'
alt: '\u0302'
- ctrl, meta: none
}
key J {
label: 'J'
base: 'j'
shift, capslock: 'J'
- ctrl, alt, meta: none
}
key K {
label: 'K'
base: 'k'
shift, capslock: 'K'
- ctrl, alt, meta: none
}
key L {
label: 'L'
base: 'l'
shift, capslock: 'L'
- ctrl, alt, meta: none
}
key M {
label: 'M'
base: 'm'
shift, capslock: 'M'
- ctrl, alt, meta: none
}
key N {
@@ -124,35 +111,30 @@
base: 'n'
shift, capslock: 'N'
alt: '\u0303'
- ctrl, meta: none
}
key O {
label: 'O'
base: 'o'
shift, capslock: 'O'
- ctrl, alt, meta: none
}
key P {
label: 'P'
base: 'p'
shift, capslock: 'P'
- ctrl, alt, meta: none
}
key Q {
label: 'Q'
base: 'q'
shift, capslock: 'Q'
- ctrl, alt, meta: none
}
key R {
label: 'R'
base: 'r'
shift, capslock: 'R'
- ctrl, alt, meta: none
}
key S {
@@ -160,14 +142,12 @@
base: 's'
shift, capslock: 'S'
alt: '\u00df'
- ctrl, meta: none
}
key T {
label: 'T'
base: 't'
shift, capslock: 'T'
- ctrl, alt, meta: none
}
key U {
@@ -175,338 +155,289 @@
base: 'u'
shift, capslock: 'U'
alt: '\u0308'
- ctrl, meta: none
}
key V {
label: 'V'
base: 'v'
shift, capslock: 'V'
- ctrl, alt, meta: none
}
key W {
label: 'W'
base: 'w'
shift, capslock: 'W'
- ctrl, alt, meta: none
}
key X {
label: 'X'
base: 'x'
shift, capslock: 'X'
- ctrl, alt, meta: none
}
key Y {
label: 'Y'
base: 'y'
shift, capslock: 'Y'
- ctrl, alt, meta: none
}
key Z {
label: 'Z'
base: 'z'
shift, capslock: 'Z'
- ctrl, alt, meta: none
}
key 0 {
- label, number: '0'
+ label: '0'
base: '0'
shift: ')'
- ctrl, alt, meta: none
}
key 1 {
- label, number: '1'
+ label: '1'
base: '1'
shift: '!'
- ctrl, alt, meta: none
}
key 2 {
- label, number: '2'
+ label: '2'
base: '2'
shift: '@'
- ctrl, alt, meta: none
}
key 3 {
- label, number: '3'
+ label: '3'
base: '3'
shift: '#'
- ctrl, alt, meta: none
}
key 4 {
- label, number: '4'
+ label: '4'
base: '4'
shift: '$'
- ctrl, alt, meta: none
}
key 5 {
- label, number: '5'
+ label: '5'
base: '5'
shift: '%'
- ctrl, alt, meta: none
}
key 6 {
- label, number: '6'
+ label: '6'
base: '6'
shift: '^'
- ctrl, alt, meta: none
alt+shift: '\u0302'
}
key 7 {
- label, number: '7'
+ label: '7'
base: '7'
shift: '&'
- ctrl, alt, meta: none
}
key 8 {
- label, number: '8'
+ label: '8'
base: '8'
shift: '*'
- ctrl, alt, meta: none
}
key 9 {
- label, number: '9'
+ label: '9'
base: '9'
shift: '('
- ctrl, alt, meta: none
}
key SPACE {
label: ' '
base: ' '
- ctrl: none
alt, meta: fallback SEARCH
}
key ENTER {
label: '\n'
base: '\n'
- ctrl, alt, meta: none
}
key TAB {
label: '\t'
base: '\t'
- ctrl, alt, meta: none
}
key COMMA {
- label, number: ','
+ label: ','
base: ','
shift: '<'
- ctrl, alt, meta: none
}
key PERIOD {
- label, number: '.'
+ label: '.'
base: '.'
shift: '>'
- ctrl, alt, meta: none
}
key SLASH {
- label, number: '/'
+ label: '/'
base: '/'
shift: '?'
- ctrl, alt, meta: none
}
key GRAVE {
- label, number: '`'
+ label: '`'
base: '`'
shift: '~'
alt: '\u0300'
alt+shift: '\u0303'
- ctrl, meta: none
}
key MINUS {
- label, number: '-'
+ label: '-'
base: '-'
shift: '_'
- ctrl, alt, meta: none
}
key EQUALS {
- label, number: '='
+ label: '='
base: '='
shift: '+'
- ctrl, alt, meta: none
}
key LEFT_BRACKET {
- label, number: '['
+ label: '['
base: '['
shift: '{'
- ctrl, alt, meta: none
}
key RIGHT_BRACKET {
- label, number: ']'
+ label: ']'
base: ']'
shift: '}'
- ctrl, alt, meta: none
}
key BACKSLASH {
- label, number: '\\'
+ label: '\\'
base: '\\'
shift: '|'
- ctrl, alt, meta: none
}
key SEMICOLON {
- label, number: ';'
+ label: ';'
base: ';'
shift: ':'
- ctrl, alt, meta: none
}
key APOSTROPHE {
- label, number: '\''
+ label: '\''
base: '\''
shift: '"'
- ctrl, alt, meta: none
}
### Numeric keypad ###
key NUMPAD_0 {
- label, number: '0'
+ label: '0'
base: fallback INSERT
numlock: '0'
- ctrl, alt, meta: none
}
key NUMPAD_1 {
- label, number: '1'
+ label: '1'
base: fallback MOVE_END
numlock: '1'
- ctrl, alt, meta: none
}
key NUMPAD_2 {
- label, number: '2'
+ label: '2'
base: fallback DPAD_DOWN
numlock: '2'
- ctrl, alt, meta: none
}
key NUMPAD_3 {
- label, number: '3'
+ label: '3'
base: fallback PAGE_DOWN
numlock: '3'
- ctrl, alt, meta: none
}
key NUMPAD_4 {
- label, number: '4'
+ label: '4'
base: fallback DPAD_LEFT
numlock: '4'
- ctrl, alt, meta: none
}
key NUMPAD_5 {
- label, number: '5'
+ label: '5'
base: fallback DPAD_CENTER
numlock: '5'
- ctrl, alt, meta: none
}
key NUMPAD_6 {
- label, number: '6'
+ label: '6'
base: fallback DPAD_RIGHT
numlock: '6'
- ctrl, alt, meta: none
}
key NUMPAD_7 {
- label, number: '7'
+ label: '7'
base: fallback MOVE_HOME
numlock: '7'
- ctrl, alt, meta: none
}
key NUMPAD_8 {
- label, number: '8'
+ label: '8'
base: fallback DPAD_UP
numlock: '8'
- ctrl, alt, meta: none
}
key NUMPAD_9 {
- label, number: '9'
+ label: '9'
base: fallback PAGE_UP
numlock: '9'
- ctrl, alt, meta: none
}
key NUMPAD_LEFT_PAREN {
- label, number: '('
+ label: '('
base: '('
- ctrl, alt, meta: none
}
key NUMPAD_RIGHT_PAREN {
- label, number: ')'
+ label: ')'
base: ')'
- ctrl, alt, meta: none
}
key NUMPAD_DIVIDE {
- label, number: '/'
+ label: '/'
base: '/'
- ctrl, alt, meta: none
}
key NUMPAD_MULTIPLY {
- label, number: '*'
+ label: '*'
base: '*'
- ctrl, alt, meta: none
}
key NUMPAD_SUBTRACT {
- label, number: '-'
+ label: '-'
base: '-'
- ctrl, alt, meta: none
}
key NUMPAD_ADD {
- label, number: '+'
+ label: '+'
base: '+'
- ctrl, alt, meta: none
}
key NUMPAD_DOT {
- label, number: '.'
+ label: '.'
base: fallback FORWARD_DEL
numlock: '.'
- ctrl, alt, meta: none
}
key NUMPAD_COMMA {
- label, number: ','
+ label: ','
base: ','
- ctrl, alt, meta: none
}
key NUMPAD_EQUALS {
- label, number: '='
+ label: '='
base: '='
- ctrl, alt, meta: none
}
key NUMPAD_ENTER {
@@ -518,22 +449,22 @@
### Special keys on phones ###
key AT {
- label, number: '@'
+ label: '@'
base: '@'
}
key STAR {
- label, number: '*'
+ label: '*'
base: '*'
}
key POUND {
- label, number: '#'
+ label: '#'
base: '#'
}
key PLUS {
- label, number: '+'
+ label: '+'
base: '+'
}
diff --git a/data/keyboards/Virtual.kcm b/data/keyboards/Virtual.kcm
index 0ce4a68..e592013 100644
--- a/data/keyboards/Virtual.kcm
+++ b/data/keyboards/Virtual.kcm
@@ -25,14 +25,12 @@
label: 'A'
base: 'a'
shift, capslock: 'A'
- ctrl, alt, meta: none
}
key B {
label: 'B'
base: 'b'
shift, capslock: 'B'
- ctrl, alt, meta: none
}
key C {
@@ -41,14 +39,12 @@
shift, capslock: 'C'
alt: '\u00e7'
shift+alt: '\u00c7'
- ctrl, meta: none
}
key D {
label: 'D'
base: 'd'
shift, capslock: 'D'
- ctrl, alt, meta: none
}
key E {
@@ -56,28 +52,24 @@
base: 'e'
shift, capslock: 'E'
alt: '\u0301'
- ctrl, meta: none
}
key F {
label: 'F'
base: 'f'
shift, capslock: 'F'
- ctrl, alt, meta: none
}
key G {
label: 'G'
base: 'g'
shift, capslock: 'G'
- ctrl, alt, meta: none
}
key H {
label: 'H'
base: 'h'
shift, capslock: 'H'
- ctrl, alt, meta: none
}
key I {
@@ -85,35 +77,30 @@
base: 'i'
shift, capslock: 'I'
alt: '\u0302'
- ctrl, meta: none
}
key J {
label: 'J'
base: 'j'
shift, capslock: 'J'
- ctrl, alt, meta: none
}
key K {
label: 'K'
base: 'k'
shift, capslock: 'K'
- ctrl, alt, meta: none
}
key L {
label: 'L'
base: 'l'
shift, capslock: 'L'
- ctrl, alt, meta: none
}
key M {
label: 'M'
base: 'm'
shift, capslock: 'M'
- ctrl, alt, meta: none
}
key N {
@@ -121,35 +108,30 @@
base: 'n'
shift, capslock: 'N'
alt: '\u0303'
- ctrl, meta: none
}
key O {
label: 'O'
base: 'o'
shift, capslock: 'O'
- ctrl, alt, meta: none
}
key P {
label: 'P'
base: 'p'
shift, capslock: 'P'
- ctrl, alt, meta: none
}
key Q {
label: 'Q'
base: 'q'
shift, capslock: 'Q'
- ctrl, alt, meta: none
}
key R {
label: 'R'
base: 'r'
shift, capslock: 'R'
- ctrl, alt, meta: none
}
key S {
@@ -157,14 +139,12 @@
base: 's'
shift, capslock: 'S'
alt: '\u00df'
- ctrl, meta: none
}
key T {
label: 'T'
base: 't'
shift, capslock: 'T'
- ctrl, alt, meta: none
}
key U {
@@ -172,339 +152,289 @@
base: 'u'
shift, capslock: 'U'
alt: '\u0308'
- ctrl, meta: none
}
key V {
label: 'V'
base: 'v'
shift, capslock: 'V'
- ctrl, alt, meta: none
}
key W {
label: 'W'
base: 'w'
shift, capslock: 'W'
- ctrl, alt, meta: none
}
key X {
label: 'X'
base: 'x'
shift, capslock: 'X'
- ctrl, alt, meta: none
}
key Y {
label: 'Y'
base: 'y'
shift, capslock: 'Y'
- ctrl, alt, meta: none
}
key Z {
label: 'Z'
base: 'z'
shift, capslock: 'Z'
- ctrl, alt, meta: none
}
key 0 {
- label, number: '0'
+ label: '0'
base: '0'
shift: ')'
- ctrl, alt, meta: none
}
key 1 {
- label, number: '1'
+ label: '1'
base: '1'
shift: '!'
- ctrl, alt, meta: none
}
key 2 {
- label, number: '2'
+ label: '2'
base: '2'
shift: '@'
- ctrl, alt, meta: none
}
key 3 {
- label, number: '3'
+ label: '3'
base: '3'
shift: '#'
- ctrl, alt, meta: none
}
key 4 {
- label, number: '4'
+ label: '4'
base: '4'
shift: '$'
- ctrl, alt, meta: none
}
key 5 {
- label, number: '5'
+ label: '5'
base: '5'
shift: '%'
- ctrl, alt, meta: none
}
key 6 {
- label, number: '6'
+ label: '6'
base: '6'
shift: '^'
- ctrl, alt, meta: none
alt+shift: '\u0302'
}
key 7 {
- label, number: '7'
+ label: '7'
base: '7'
shift: '&'
- ctrl, alt, meta: none
}
key 8 {
- label, number: '8'
+ label: '8'
base: '8'
shift: '*'
- ctrl, alt, meta: none
}
key 9 {
- label, number: '9'
+ label: '9'
base: '9'
shift: '('
- ctrl, alt, meta: none
}
key SPACE {
label: ' '
base: ' '
- ctrl, alt: none
- meta: fallback SEARCH
+ alt, meta: fallback SEARCH
}
key ENTER {
label: '\n'
base: '\n'
- ctrl, alt, meta: none
}
key TAB {
label: '\t'
base: '\t'
- ctrl, alt: none
- meta: fallback APP_SWITCH
}
key COMMA {
- label, number: ','
+ label: ','
base: ','
shift: '<'
- ctrl, alt, meta: none
}
key PERIOD {
- label, number: '.'
+ label: '.'
base: '.'
shift: '>'
- ctrl, alt, meta: none
}
key SLASH {
- label, number: '/'
+ label: '/'
base: '/'
shift: '?'
- ctrl, alt, meta: none
}
key GRAVE {
- label, number: '`'
+ label: '`'
base: '`'
shift: '~'
alt: '\u0300'
alt+shift: '\u0303'
- ctrl, meta: none
}
key MINUS {
- label, number: '-'
+ label: '-'
base: '-'
shift: '_'
- ctrl, alt, meta: none
}
key EQUALS {
- label, number: '='
+ label: '='
base: '='
shift: '+'
- ctrl, alt, meta: none
}
key LEFT_BRACKET {
- label, number: '['
+ label: '['
base: '['
shift: '{'
- ctrl, alt, meta: none
}
key RIGHT_BRACKET {
- label, number: ']'
+ label: ']'
base: ']'
shift: '}'
- ctrl, alt, meta: none
}
key BACKSLASH {
- label, number: '\\'
+ label: '\\'
base: '\\'
shift: '|'
- ctrl, alt, meta: none
}
key SEMICOLON {
- label, number: ';'
+ label: ';'
base: ';'
shift: ':'
- ctrl, alt, meta: none
}
key APOSTROPHE {
- label, number: '\''
+ label: '\''
base: '\''
shift: '"'
- ctrl, alt, meta: none
}
### Numeric keypad ###
key NUMPAD_0 {
- label, number: '0'
+ label: '0'
base: fallback INSERT
numlock: '0'
- ctrl, alt, meta: none
}
key NUMPAD_1 {
- label, number: '1'
+ label: '1'
base: fallback MOVE_END
numlock: '1'
- ctrl, alt, meta: none
}
key NUMPAD_2 {
- label, number: '2'
+ label: '2'
base: fallback DPAD_DOWN
numlock: '2'
- ctrl, alt, meta: none
}
key NUMPAD_3 {
- label, number: '3'
+ label: '3'
base: fallback PAGE_DOWN
numlock: '3'
- ctrl, alt, meta: none
}
key NUMPAD_4 {
- label, number: '4'
+ label: '4'
base: fallback DPAD_LEFT
numlock: '4'
- ctrl, alt, meta: none
}
key NUMPAD_5 {
- label, number: '5'
+ label: '5'
base: fallback DPAD_CENTER
numlock: '5'
- ctrl, alt, meta: none
}
key NUMPAD_6 {
- label, number: '6'
+ label: '6'
base: fallback DPAD_RIGHT
numlock: '6'
- ctrl, alt, meta: none
}
key NUMPAD_7 {
- label, number: '7'
+ label: '7'
base: fallback MOVE_HOME
numlock: '7'
- ctrl, alt, meta: none
}
key NUMPAD_8 {
- label, number: '8'
+ label: '8'
base: fallback DPAD_UP
numlock: '8'
- ctrl, alt, meta: none
}
key NUMPAD_9 {
- label, number: '9'
+ label: '9'
base: fallback PAGE_UP
numlock: '9'
- ctrl, alt, meta: none
}
key NUMPAD_LEFT_PAREN {
- label, number: '('
+ label: '('
base: '('
- ctrl, alt, meta: none
}
key NUMPAD_RIGHT_PAREN {
- label, number: ')'
+ label: ')'
base: ')'
- ctrl, alt, meta: none
}
key NUMPAD_DIVIDE {
- label, number: '/'
+ label: '/'
base: '/'
- ctrl, alt, meta: none
}
key NUMPAD_MULTIPLY {
- label, number: '*'
+ label: '*'
base: '*'
- ctrl, alt, meta: none
}
key NUMPAD_SUBTRACT {
- label, number: '-'
+ label: '-'
base: '-'
- ctrl, alt, meta: none
}
key NUMPAD_ADD {
- label, number: '+'
+ label: '+'
base: '+'
- ctrl, alt, meta: none
}
key NUMPAD_DOT {
- label, number: '.'
+ label: '.'
base: fallback FORWARD_DEL
numlock: '.'
- ctrl, alt, meta: none
}
key NUMPAD_COMMA {
- label, number: ','
+ label: ','
base: ','
- ctrl, alt, meta: none
}
key NUMPAD_EQUALS {
- label, number: '='
+ label: '='
base: '='
- ctrl, alt, meta: none
}
key NUMPAD_ENTER {
@@ -516,22 +446,22 @@
### Special keys on phones ###
key AT {
- label, number: '@'
+ label: '@'
base: '@'
}
key STAR {
- label, number: '*'
+ label: '*'
base: '*'
}
key POUND {
- label, number: '#'
+ label: '#'
base: '#'
}
key PLUS {
- label, number: '+'
+ label: '+'
base: '+'
}
@@ -539,6 +469,132 @@
key ESCAPE {
base: fallback BACK
- meta: fallback HOME
- alt: fallback MENU
+ alt, meta: fallback HOME
+ ctrl: fallback MENU
+}
+
+### Gamepad buttons ###
+
+key BUTTON_A {
+ base: fallback BACK
+}
+
+key BUTTON_B {
+ base: fallback BACK
+}
+
+key BUTTON_C {
+ base: fallback BACK
+}
+
+key BUTTON_X {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_Y {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_Z {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_L1 {
+ base: none
+}
+
+key BUTTON_R1 {
+ base: none
+}
+
+key BUTTON_L2 {
+ base: none
+}
+
+key BUTTON_R2 {
+ base: none
+}
+
+key BUTTON_THUMBL {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_THUMBR {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_START {
+ base: fallback HOME
+}
+
+key BUTTON_SELECT {
+ base: fallback MENU
+}
+
+key BUTTON_MODE {
+ base: fallback MENU
+}
+
+key BUTTON_1 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_2 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_3 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_4 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_5 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_6 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_7 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_8 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_9 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_10 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_11 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_12 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_13 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_14 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_15 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_16 {
+ base: fallback DPAD_CENTER
}
diff --git a/docs/html/guide/publishing/preparing.jd b/docs/html/guide/publishing/preparing.jd
index fe56352..8e75728 100644
--- a/docs/html/guide/publishing/preparing.jd
+++ b/docs/html/guide/publishing/preparing.jd
@@ -291,7 +291,7 @@
releasing your app through Google Play.</p>
<p>For more information about Google Play Licensing Service and how to use it in your
-application, see <a href="{@docRoot}guide/market/licensing.html">Application Licensing</a>.</p>
+application, see <a href="{@docRoot}guide/market/licensing/index.html">Application Licensing</a>.</p>
<h2 id="publishing-build">Building Your Application for Release</h2>
diff --git a/docs/html/images/LivePocketGemsTitleCard.png b/docs/html/images/LivePocketGemsTitleCard.png
new file mode 100644
index 0000000..0d70a56
--- /dev/null
+++ b/docs/html/images/LivePocketGemsTitleCard.png
Binary files differ
diff --git a/docs/html/images/training/basic-SDK-manager.png b/docs/html/images/training/basic-SDK-manager.png
new file mode 100644
index 0000000..1f09bdc
--- /dev/null
+++ b/docs/html/images/training/basic-SDK-manager.png
Binary files differ
diff --git a/docs/html/images/training/basic-simple-screen-mock.graffle/QuickLook/Preview.pdf b/docs/html/images/training/basic-simple-screen-mock.graffle/QuickLook/Preview.pdf
new file mode 100644
index 0000000..192bb8d
--- /dev/null
+++ b/docs/html/images/training/basic-simple-screen-mock.graffle/QuickLook/Preview.pdf
Binary files differ
diff --git a/docs/html/images/training/basic-simple-screen-mock.graffle/QuickLook/Thumbnail.tiff b/docs/html/images/training/basic-simple-screen-mock.graffle/QuickLook/Thumbnail.tiff
new file mode 100644
index 0000000..85dd23d
--- /dev/null
+++ b/docs/html/images/training/basic-simple-screen-mock.graffle/QuickLook/Thumbnail.tiff
Binary files differ
diff --git a/docs/html/images/training/basic-simple-screen-mock.graffle/data.plist b/docs/html/images/training/basic-simple-screen-mock.graffle/data.plist
new file mode 100644
index 0000000..3c391df
--- /dev/null
+++ b/docs/html/images/training/basic-simple-screen-mock.graffle/data.plist
@@ -0,0 +1,635 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActiveLayerIndex</key>
+ <integer>0</integer>
+ <key>ApplicationVersion</key>
+ <array>
+ <string>com.omnigroup.OmniGrafflePro</string>
+ <string>138.33.0.157554</string>
+ </array>
+ <key>AutoAdjust</key>
+ <true/>
+ <key>BackgroundGraphic</key>
+ <dict>
+ <key>Bounds</key>
+ <string>{{0, 0}, {576, 733}}</string>
+ <key>Class</key>
+ <string>SolidGraphic</string>
+ <key>ID</key>
+ <integer>2</integer>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <key>CanvasOrigin</key>
+ <string>{0, 0}</string>
+ <key>ColumnAlign</key>
+ <integer>1</integer>
+ <key>ColumnSpacing</key>
+ <real>36</real>
+ <key>CreationDate</key>
+ <string>2012-03-20 17:38:46 -0700</string>
+ <key>Creator</key>
+ <string>Billy Rutledge</string>
+ <key>DisplayScale</key>
+ <string>1 0/72 in = 1 0/72 in</string>
+ <key>GraphDocumentVersion</key>
+ <integer>8</integer>
+ <key>GraphicsList</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{257, 117}, {282, 231}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>200</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.628571</string>
+ <key>g</key>
+ <string>0.768599</string>
+ <key>r</key>
+ <string>1</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.236788</string>
+ <key>g</key>
+ <string>0.532236</string>
+ <key>r</key>
+ <string>0.990271</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.131021</string>
+ <key>g</key>
+ <string>0.363196</string>
+ <key>r</key>
+ <string>0.725948</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Fragment B}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{163, 117}, {92, 231}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>1203</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>1</string>
+ <key>g</key>
+ <string>0.874135</string>
+ <key>r</key>
+ <string>0.71718</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>1</string>
+ <key>g</key>
+ <string>0.662438</string>
+ <key>r</key>
+ <string>0.464468</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.93512</string>
+ <key>g</key>
+ <string>0.472602</string>
+ <key>r</key>
+ <string>0.333854</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Fragment A}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{24, 168}, {92, 152}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>157</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>1</string>
+ <key>g</key>
+ <string>0.874135</string>
+ <key>r</key>
+ <string>0.71718</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>1</string>
+ <key>g</key>
+ <string>0.662438</string>
+ <key>r</key>
+ <string>0.464468</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.93512</string>
+ <key>g</key>
+ <string>0.472602</string>
+ <key>r</key>
+ <string>0.333854</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Fragment A}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{11.96, 141.616}, {117.52, 224.884}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>1202</integer>
+ <key>ImageID</key>
+ <integer>2</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{140, 95}, {422.773, 277}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>1201</integer>
+ <key>ImageID</key>
+ <integer>1</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ </array>
+ <key>GridInfo</key>
+ <dict/>
+ <key>GuidesLocked</key>
+ <string>NO</string>
+ <key>GuidesVisible</key>
+ <string>YES</string>
+ <key>HPages</key>
+ <integer>1</integer>
+ <key>ImageCounter</key>
+ <integer>3</integer>
+ <key>ImageLinkBack</key>
+ <array>
+ <dict/>
+ <dict/>
+ </array>
+ <key>ImageList</key>
+ <array>
+ <string>image2.png</string>
+ <string>image1.png</string>
+ </array>
+ <key>KeepToScale</key>
+ <false/>
+ <key>Layers</key>
+ <array>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Layer 1</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>YES</string>
+ </dict>
+ </array>
+ <key>LayoutInfo</key>
+ <dict>
+ <key>Animate</key>
+ <string>NO</string>
+ <key>circoMinDist</key>
+ <real>18</real>
+ <key>circoSeparation</key>
+ <real>0.0</real>
+ <key>layoutEngine</key>
+ <string>dot</string>
+ <key>neatoSeparation</key>
+ <real>0.0</real>
+ <key>twopiSeparation</key>
+ <real>0.0</real>
+ </dict>
+ <key>LinksVisible</key>
+ <string>NO</string>
+ <key>MagnetsVisible</key>
+ <string>NO</string>
+ <key>MasterSheets</key>
+ <array/>
+ <key>ModificationDate</key>
+ <string>2012-03-20 17:52:44 -0700</string>
+ <key>Modifier</key>
+ <string>Billy Rutledge</string>
+ <key>NotesVisible</key>
+ <string>NO</string>
+ <key>Orientation</key>
+ <integer>2</integer>
+ <key>OriginVisible</key>
+ <string>NO</string>
+ <key>PageBreaks</key>
+ <string>YES</string>
+ <key>PrintInfo</key>
+ <dict>
+ <key>NSBottomMargin</key>
+ <array>
+ <string>float</string>
+ <string>41</string>
+ </array>
+ <key>NSLeftMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSPaperSize</key>
+ <array>
+ <string>coded</string>
+ <string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAx7X05TU2l6ZT1mZn2WgWQCgRgDhg==</string>
+ </array>
+ <key>NSRightMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSTopMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ </dict>
+ <key>PrintOnePage</key>
+ <false/>
+ <key>ReadOnly</key>
+ <string>NO</string>
+ <key>RowAlign</key>
+ <integer>1</integer>
+ <key>RowSpacing</key>
+ <real>36</real>
+ <key>SheetTitle</key>
+ <string>Canvas 1</string>
+ <key>SmartAlignmentGuidesActive</key>
+ <string>YES</string>
+ <key>SmartDistanceGuidesActive</key>
+ <string>YES</string>
+ <key>UniqueID</key>
+ <integer>1</integer>
+ <key>UseEntirePage</key>
+ <false/>
+ <key>VPages</key>
+ <integer>1</integer>
+ <key>WindowInfo</key>
+ <dict>
+ <key>CurrentSheet</key>
+ <integer>0</integer>
+ <key>ExpandedCanvases</key>
+ <array>
+ <dict>
+ <key>name</key>
+ <string>Canvas 1</string>
+ </dict>
+ </array>
+ <key>Frame</key>
+ <string>{{837, 167}, {1214, 1013}}</string>
+ <key>ListView</key>
+ <true/>
+ <key>OutlineWidth</key>
+ <integer>142</integer>
+ <key>RightSidebar</key>
+ <false/>
+ <key>ShowRuler</key>
+ <true/>
+ <key>Sidebar</key>
+ <true/>
+ <key>SidebarWidth</key>
+ <integer>120</integer>
+ <key>VisibleRegion</key>
+ <string>{{-252, -63}, {1079, 859}}</string>
+ <key>Zoom</key>
+ <real>1</real>
+ <key>ZoomValues</key>
+ <array>
+ <array>
+ <string>Canvas 1</string>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ </array>
+ </dict>
+ <key>saveQuickLookFiles</key>
+ <string>YES</string>
+</dict>
+</plist>
diff --git a/docs/html/images/training/basic-simple-screen-mock.graffle/image1.png b/docs/html/images/training/basic-simple-screen-mock.graffle/image1.png
new file mode 100644
index 0000000..80baf14
--- /dev/null
+++ b/docs/html/images/training/basic-simple-screen-mock.graffle/image1.png
Binary files differ
diff --git a/docs/html/images/training/basic-simple-screen-mock.graffle/image2.png b/docs/html/images/training/basic-simple-screen-mock.graffle/image2.png
new file mode 100644
index 0000000..f478d16
--- /dev/null
+++ b/docs/html/images/training/basic-simple-screen-mock.graffle/image2.png
Binary files differ
diff --git a/docs/html/images/training/basic-simple-screen-mock.png b/docs/html/images/training/basic-simple-screen-mock.png
new file mode 100644
index 0000000..72af1d2
--- /dev/null
+++ b/docs/html/images/training/basic-simple-screen-mock.png
Binary files differ
diff --git a/docs/html/images/training/basics/basic-lifecycle-create.png b/docs/html/images/training/basics/basic-lifecycle-create.png
new file mode 100644
index 0000000..01d7328
--- /dev/null
+++ b/docs/html/images/training/basics/basic-lifecycle-create.png
Binary files differ
diff --git a/docs/html/images/training/basics/basic-lifecycle-paused.png b/docs/html/images/training/basics/basic-lifecycle-paused.png
new file mode 100644
index 0000000..fcb8bd2
--- /dev/null
+++ b/docs/html/images/training/basics/basic-lifecycle-paused.png
Binary files differ
diff --git a/docs/html/images/training/basics/basic-lifecycle-savestate.png b/docs/html/images/training/basics/basic-lifecycle-savestate.png
new file mode 100644
index 0000000..d74f1ba
--- /dev/null
+++ b/docs/html/images/training/basics/basic-lifecycle-savestate.png
Binary files differ
diff --git a/docs/html/images/training/basics/basic-lifecycle-stopped.png b/docs/html/images/training/basics/basic-lifecycle-stopped.png
new file mode 100644
index 0000000..26c22ee
--- /dev/null
+++ b/docs/html/images/training/basics/basic-lifecycle-stopped.png
Binary files differ
diff --git a/docs/html/images/training/basics/basic-lifecycle.graffle/QuickLook/Preview.pdf b/docs/html/images/training/basics/basic-lifecycle.graffle/QuickLook/Preview.pdf
new file mode 100644
index 0000000..aa97f22
--- /dev/null
+++ b/docs/html/images/training/basics/basic-lifecycle.graffle/QuickLook/Preview.pdf
Binary files differ
diff --git a/docs/html/images/training/basics/basic-lifecycle.graffle/QuickLook/Thumbnail.tiff b/docs/html/images/training/basics/basic-lifecycle.graffle/QuickLook/Thumbnail.tiff
new file mode 100644
index 0000000..55c1157
--- /dev/null
+++ b/docs/html/images/training/basics/basic-lifecycle.graffle/QuickLook/Thumbnail.tiff
Binary files differ
diff --git a/docs/html/images/training/basics/basic-lifecycle.graffle/data.plist b/docs/html/images/training/basics/basic-lifecycle.graffle/data.plist
new file mode 100644
index 0000000..28c03f5
--- /dev/null
+++ b/docs/html/images/training/basics/basic-lifecycle.graffle/data.plist
@@ -0,0 +1,4835 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActiveLayerIndex</key>
+ <integer>3</integer>
+ <key>ApplicationVersion</key>
+ <array>
+ <string>com.omnigroup.OmniGrafflePro</string>
+ <string>138.9.0.117994</string>
+ </array>
+ <key>AutoAdjust</key>
+ <true/>
+ <key>BackgroundGraphic</key>
+ <dict>
+ <key>Bounds</key>
+ <string>{{0, 0}, {1152, 733}}</string>
+ <key>Class</key>
+ <string>SolidGraphic</string>
+ <key>ID</key>
+ <integer>2</integer>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <key>CanvasOrigin</key>
+ <string>{0, 0}</string>
+ <key>ColumnAlign</key>
+ <integer>1</integer>
+ <key>ColumnSpacing</key>
+ <real>36</real>
+ <key>CreationDate</key>
+ <string>2012-04-12 14:32:59 -0700</string>
+ <key>Creator</key>
+ <string>Scott Main</string>
+ <key>DisplayScale</key>
+ <string>1 0/72 in = 1 0/72 in</string>
+ <key>GraphDocumentVersion</key>
+ <integer>6</integer>
+ <key>GraphicsList</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{178.858, 130.553}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37924</integer>
+ <key>Layer</key>
+ <integer>0</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 3}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{13.5321, 282.081}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37921</integer>
+ <key>Layer</key>
+ <integer>0</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 1}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{105.929, 216.712}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37920</integer>
+ <key>Layer</key>
+ <integer>0</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 2}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{26, 76}, {406, 301}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37925</integer>
+ <key>Layer</key>
+ <integer>0</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.578326</string>
+ <key>g</key>
+ <string>0.578615</string>
+ <key>r</key>
+ <string>0.578453</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>15</real>
+ <key>Pattern</key>
+ <integer>1</integer>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>VerticalPad</key>
+ <integer>10</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{178.777, 131.562}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37923</integer>
+ <key>Layer</key>
+ <integer>1</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 4}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{221.214, 231.078}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37918</integer>
+ <key>Layer</key>
+ <integer>1</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 3}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{302.633, 267.492}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37916</integer>
+ <key>Layer</key>
+ <integer>1</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37896</integer>
+ <key>Position</key>
+ <real>0.58431947231292725</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 2}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{507.453, 217.065}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37917</integer>
+ <key>Layer</key>
+ <integer>1</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 1}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{194, 76}, {403, 238}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37915</integer>
+ <key>Layer</key>
+ <integer>1</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.578326</string>
+ <key>g</key>
+ <string>0.578615</string>
+ <key>r</key>
+ <string>0.578453</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>15</real>
+ <key>Pattern</key>
+ <integer>1</integer>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>VerticalPad</key>
+ <integer>10</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{422, 131.562}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37835</integer>
+ <key>Layer</key>
+ <integer>2</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 1}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{298.238, 144.062}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37834</integer>
+ <key>Layer</key>
+ <integer>2</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 2}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{288, 76}, {230, 152}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37830</integer>
+ <key>Layer</key>
+ <integer>2</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.578326</string>
+ <key>g</key>
+ <string>0.578615</string>
+ <key>r</key>
+ <string>0.578453</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>15</real>
+ <key>Pattern</key>
+ <integer>1</integer>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>VerticalPad</key>
+ <integer>10</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{385.187, 177.401}, {120.813, 35.3802}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37913</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>RoundRect</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.253268</string>
+ <key>g</key>
+ <string>0.930286</string>
+ <key>r</key>
+ <string>0.950739</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.238892</string>
+ <key>g</key>
+ <string>0.757587</string>
+ <key>r</key>
+ <string>0.782828</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.165602</string>
+ <key>g</key>
+ <string>0.586124</string>
+ <key>r</key>
+ <string>0.428309</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Paused\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\b0 \cf0 (partially visible)}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{618.773, 318.895}, {71.5931, 46.105}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37914</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Destroyed}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{203.073, 137.553}, {77, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37909</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37892</integer>
+ <key>Position</key>
+ <real>0.26310518383979797</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwpvblJlc3VtZSgphoQCaUkBCpKEhIQMTlNE
+ aWN0aW9uYXJ5AJSEAWkDkoSWlgdOU0NvbG9yhpKEhIQH
+ TlNDb2xvcgCUhAFjA4QCZmYAg2ZmJj+GkoSWlgZOU0Zv
+ bnSGkoSEhAZOU0ZvbnQelJkchAVbMjhjXQYAAAAUAAAA
+ //5IAGUAbAB2AGUAdABpAGMAYQCEAWYMmwCbAZsAmwCG
+ koSWlhBOU1BhcmFncmFwaFN0eWxlhpKEhIQQTlNQYXJh
+ Z3JhcGhTdHlsZQCUhARDQ0BTAgCEhIQHTlNBcnJheQCU
+ mQyShISECU5TVGV4dFRhYgCUhAJDZgAchpKEpaQAOIaS
+ hKWkAFSGkoSlpABwhpKEpaQAgYwAhpKEpaQAgagAhpKE
+ paQAgcQAhpKEpaQAgeAAhpKEpaQAgfwAhpKEpaQAgRgB
+ hpKEpaQAgTQBhpKEpaQAgVABhoYAhoaG
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onResume()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{44, 313.237}, {54.2626, 54.2626}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>37908</integer>
+ <key>ImageID</key>
+ <integer>1</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{322.237, 149.062}, {77, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37907</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37906</integer>
+ <key>Position</key>
+ <real>0.67048442363739014</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwpvblJlc3VtZSgphoQCaUkBCpKEhIQMTlNE
+ aWN0aW9uYXJ5AJSEAWkDkoSWlgdOU0NvbG9yhpKEhIQH
+ TlNDb2xvcgCUhAFjA4QCZmYAg2ZmJj+GkoSWlgZOU0Zv
+ bnSGkoSEhAZOU0ZvbnQelJkchAVbMjhjXQYAAAAUAAAA
+ //5IAGUAbAB2AGUAdABpAGMAYQCEAWYMmwCbAZsAmwCG
+ koSWlhBOU1BhcmFncmFwaFN0eWxlhpKEhIQQTlNQYXJh
+ Z3JhcGhTdHlsZQCUhARDQ0BTAgCEhIQHTlNBcnJheQCU
+ mQyShISECU5TVGV4dFRhYgCUhAJDZgAchpKEpaQAOIaS
+ hKWkAFSGkoSlpABwhpKEpaQAgYwAhpKEpaQAgagAhpKE
+ paQAgcQAhpKEpaQAgeAAhpKEpaQAgfwAhpKEpaQAgRgB
+ hpKEpaQAgTQBhpKEpaQAgVABhoYAhoaG
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onResume()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37888</integer>
+ <key>Info</key>
+ <integer>5</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37906</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{385.187, 195.091}</string>
+ <string>{360.737, 125.38}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37913</integer>
+ <key>Info</key>
+ <integer>8</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{246.213, 236.078}, {57, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37905</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37896</integer>
+ <key>Position</key>
+ <real>0.88071924448013306</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwlvblN0YXJ0KCmGhAJpSQEJkoSEhAxOU0Rp
+ Y3Rpb25hcnkAlIQBaQOShJaWB05TQ29sb3KGkoSEhAdO
+ U0NvbG9yAJSEAWMDhAJmZgCDZmYmP4aShJaWBk5TRm9u
+ dIaShISEBk5TRm9udB6UmRyEBVsyOGNdBgAAABQAAAD/
+ /kgAZQBsAHYAZQB0AGkAYwBhAIQBZgybAJsBmwCbAIaS
+ hJaWEE5TUGFyYWdyYXBoU3R5bGWGkoSEhBBOU1BhcmFn
+ cmFwaFN0eWxlAJSEBENDQFMCAISEhAdOU0FycmF5AJSZ
+ DJKEhIQJTlNUZXh0VGFiAJSEAkNmAByGkoSlpAA4hpKE
+ paQAVIaShKWkAHCGkoSlpACBjACGkoSlpACBqACGkoSl
+ pACBxACGkoSlpACB4ACGkoSlpACB/ACGkoSlpACBGAGG
+ koSlpACBNAGGkoSlpACBUAGGhgCGhoY=
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onStart()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{42.1313, 287.256}, {58, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>ID</key>
+ <integer>37904</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37893</integer>
+ <key>Position</key>
+ <real>0.20424844324588776</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Pad</key>
+ <integer>0</integer>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwpvbkNyZWF0ZSgphoQCaUkBCpKEhIQMTlNE
+ aWN0aW9uYXJ5AJSEAWkDkoSWlgdOU0NvbG9yhpKEhIQH
+ TlNDb2xvcgCUhAFjA4QCZmYAg2ZmJj+GkoSWlgZOU0Zv
+ bnSGkoSEhAZOU0ZvbnQelJkchAVbMjhjXQYAAAAUAAAA
+ //5IAGUAbAB2AGUAdABpAGMAYQCEAWYMmwCbAZsAmwCG
+ koSWlhBOU1BhcmFncmFwaFN0eWxlhpKEhIQQTlNQYXJh
+ Z3JhcGhTdHlsZQCUhARDQ0BTAgCEhIQHTlNBcnJheQCU
+ mQyShISECU5TVGV4dFRhYgCUhAJDZgAchpKEpaQAOIaS
+ hKWkAFSGkoSlpABwhpKEpaQAgYwAhpKEpaQAgagAhpKE
+ paQAgcQAhpKEpaQAgeAAhpKEpaQAgfwAhpKEpaQAgRgB
+ hpKEpaQAgTQBhpKEpaQAgVABhoYAhoaG
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onCreate()}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{135.136, 222.065}, {47, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>ID</key>
+ <integer>37903</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37898</integer>
+ <key>Position</key>
+ <real>0.27529767155647278</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Pad</key>
+ <integer>0</integer>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwlvblN0YXJ0KCmGhAJpSQEJkoSEhAxOU0Rp
+ Y3Rpb25hcnkAlIQBaQOShJaWB05TQ29sb3KGkoSEhAdO
+ U0NvbG9yAJSEAWMDhAJmZgCDZmYmP4aShJaWBk5TRm9u
+ dIaShISEBk5TRm9udB6UmRyEBVsyOGNdBgAAABQAAAD/
+ /kgAZQBsAHYAZQB0AGkAYwBhAIQBZgybAJsBmwCbAIaS
+ hJaWEE5TUGFyYWdyYXBoU3R5bGWGkoSEhBBOU1BhcmFn
+ cmFwaFN0eWxlAJSEBENDQFMCAISEhAdOU0FycmF5AJSZ
+ DJKEhIQJTlNUZXh0VGFiAJSEAkNmAByGkoSlpAA4hpKE
+ paQAVIaShKWkAHCGkoSlpACBjACGkoSlpACBqACGkoSl
+ pACBxACGkoSlpACB4ACGkoSlpACB/ACGkoSlpACBGAGG
+ koSlpACBNAGGkoSlpACBUAGGhgCGhoY=
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onStart()}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{624.069, 287.081}, {63, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>37902</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37895</integer>
+ <key>Offset</key>
+ <real>1</real>
+ <key>Position</key>
+ <real>0.772480309009552</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Pad</key>
+ <integer>0</integer>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwtvbkRlc3Ryb3koKYaEAmlJAQuShISEDE5T
+ RGljdGlvbmFyeQCUhAFpA5KElpYHTlNDb2xvcoaShISE
+ B05TQ29sb3IAlIQBYwOEAmZmAINmZiY/hpKElpYGTlNG
+ b250hpKEhIQGTlNGb250HpSZHIQFWzI4Y10GAAAAFAAA
+ AP/+SABlAGwAdgBlAHQAaQBjAGEAhAFmDJsAmwGbAJsA
+ hpKElpYQTlNQYXJhZ3JhcGhTdHlsZYaShISEEE5TUGFy
+ YWdyYXBoU3R5bGUAlIQEQ0NAUwIAhISEB05TQXJyYXkA
+ lJkMkoSEhAlOU1RleHRUYWIAlIQCQ2YAHIaShKWkADiG
+ koSlpABUhpKEpaQAcIaShKWkAIGMAIaShKWkAIGoAIaS
+ hKWkAIHEAIaShKWkAIHgAIaShKWkAIH8AIaShKWkAIEY
+ AYaShKWkAIE0AYaShKWkAIFQAYaGAIaGhg==
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onDestroy()}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{332.284, 272.492}, {61, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>ID</key>
+ <integer>37901</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37896</integer>
+ <key>Position</key>
+ <real>0.39474391937255859</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Pad</key>
+ <integer>0</integer>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwtvblJlc3RhcnQoKYaEAmlJAQuShISEDE5T
+ RGljdGlvbmFyeQCUhAFpA5KElpYHTlNDb2xvcoaShISE
+ B05TQ29sb3IAlIQBYwOEAmZmAINmZiY/hpKElpYGTlNG
+ b250hpKEhIQGTlNGb250HpSZHIQFWzI4Y10GAAAAFAAA
+ AP/+SABlAGwAdgBlAHQAaQBjAGEAhAFmDJsAmwGbAJsA
+ hpKElpYQTlNQYXJhZ3JhcGhTdHlsZYaShISEEE5TUGFy
+ YWdyYXBoU3R5bGUAlIQEQ0NAUwIAhISEB05TQXJyYXkA
+ lJkMkoSEhAlOU1RleHRUYWIAlIQCQ2YAHIaShKWkADiG
+ koSlpABUhpKEpaQAcIaShKWkAIGMAIaShKWkAIGoAIaS
+ hKWkAIHEAIaShKWkAIHgAIaShKWkAIH8AIaShKWkAIEY
+ AYaShKWkAIE0AYaShKWkAIFQAYaGAIaGhg==
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onRestart()}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{451.395, 136.562}, {56, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>ID</key>
+ <integer>37900</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37885</integer>
+ <key>Position</key>
+ <real>0.72899174690246582</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Pad</key>
+ <integer>0</integer>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwlvblBhdXNlKCmGhAJpSQEJkoSEhAxOU0Rp
+ Y3Rpb25hcnkAlIQBaQOShJaWB05TQ29sb3KGkoSEhAdO
+ U0NvbG9yAJSEAWMDhAJmZgCDZmYmP4aShJaWBk5TRm9u
+ dIaShISEBk5TRm9udB6UmRyEBVsyOGNdBgAAABQAAAD/
+ /kgAZQBsAHYAZQB0AGkAYwBhAIQBZgybAJsBmwCbAIaS
+ hJaWEE5TUGFyYWdyYXBoU3R5bGWGkoSEhBBOU1BhcmFn
+ cmFwaFN0eWxlAJSEBENDQFMCAISEhAdOU0FycmF5AJSZ
+ DJKEhIQJTlNUZXh0VGFiAJSEAkNmAByGkoSlpAA4hpKE
+ paQAVIaShKWkAHCGkoSlpACBjACGkoSlpACBqACGkoSl
+ pACBxACGkoSlpACB4ACGkoSlpACB/ACGkoSlpACBGAGG
+ koSlpACBNAGGkoSlpACBUAGGhgCGhoY=
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onPause()}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{531.254, 220.712}, {56, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>37899</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37894</integer>
+ <key>Offset</key>
+ <real>2</real>
+ <key>Position</key>
+ <real>0.70384049415588379</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwhvblN0b3AoKYaEAmlJAQiShISEDE5TRGlj
+ dGlvbmFyeQCUhAFpA5KElpYHTlNDb2xvcoaShISEB05T
+ Q29sb3IAlIQBYwOEAmZmAINmZiY/hpKElpYQTlNQYXJh
+ Z3JhcGhTdHlsZYaShISEEE5TUGFyYWdyYXBoU3R5bGUA
+ lIQEQ0NAUwIAhISEB05TQXJyYXkAlJkMkoSEhAlOU1Rl
+ eHRUYWIAlIQCQ2YAHIaShKKhADiGkoSioQBUhpKEoqEA
+ cIaShKKhAIGMAIaShKKhAIGoAIaShKKhAIHEAIaShKKh
+ AIHgAIaShKKhAIH8AIaShKKhAIEYAYaShKKhAIE0AYaS
+ hKKhAIFQAYaGAIaShJaWBk5TRm9udIaShISEBk5TRm9u
+ dB6UmRyEBVsyOGNdBgAAABQAAAD//kQAcgBvAGkAZABT
+ AGEAbgBzAIQBZgybAJsBmwCbAIaGhg==
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 DroidSans;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onStop()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37887</integer>
+ <key>Info</key>
+ <integer>8</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37898</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{158.636, 262.721}</string>
+ <string>{214.307, 195.091}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37890</integer>
+ <key>Info</key>
+ <integer>13</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37887</integer>
+ <key>Info</key>
+ <integer>5</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37896</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>25</real>
+ <key>Points</key>
+ <array>
+ <string>{463.047, 279.492}</string>
+ <string>{274.713, 212.781}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37889</integer>
+ <key>Info</key>
+ <integer>8</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37914</integer>
+ <key>Info</key>
+ <integer>6</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37895</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{583.86, 279.492}</string>
+ <string>{654.569, 318.895}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37889</integer>
+ <key>Info</key>
+ <integer>7</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37889</integer>
+ <key>Info</key>
+ <integer>14</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37894</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{506, 195.091}</string>
+ <string>{557.254, 262.563}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37913</integer>
+ <key>Info</key>
+ <integer>7</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37890</integer>
+ <key>Info</key>
+ <integer>8</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37893</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{71.1313, 313.237}</string>
+ <string>{131.37, 279.492}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37908</integer>
+ <key>Info</key>
+ <integer>2</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37888</integer>
+ <key>Info</key>
+ <integer>8</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37892</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{241.573, 178.32}</string>
+ <string>{300.331, 107.69}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37887</integer>
+ <key>Info</key>
+ <integer>13</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{131.37, 261.802}, {120.813, 35.3802}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37890</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>RoundRect</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.274119</string>
+ <key>g</key>
+ <string>0.950739</string>
+ <key>r</key>
+ <string>0.787494</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.223529</string>
+ <key>g</key>
+ <string>0.776471</string>
+ <key>r</key>
+ <string>0.643137</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.165602</string>
+ <key>g</key>
+ <string>0.586124</string>
+ <key>r</key>
+ <string>0.428309</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Created}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{463.047, 261.802}, {120.813, 35.3802}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37889</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>RoundRect</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.628571</string>
+ <key>g</key>
+ <string>0.768599</string>
+ <key>r</key>
+ <string>1</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.236788</string>
+ <key>g</key>
+ <string>0.532236</string>
+ <key>r</key>
+ <string>0.990271</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.131021</string>
+ <key>g</key>
+ <string>0.363196</string>
+ <key>r</key>
+ <string>0.725948</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Stopped\
+(
+\b0 hidden)}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{300.331, 90}, {120.813, 35.3802}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37888</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>RoundRect</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.274119</string>
+ <key>g</key>
+ <string>0.950739</string>
+ <key>r</key>
+ <string>0.787494</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.223529</string>
+ <key>g</key>
+ <string>0.776471</string>
+ <key>r</key>
+ <string>0.643137</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.165602</string>
+ <key>g</key>
+ <string>0.586124</string>
+ <key>r</key>
+ <string>0.428309</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Resumed\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\b0 \cf0 (visible)}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{214.307, 177.401}, {120.813, 35.3802}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37887</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>RoundRect</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.274119</string>
+ <key>g</key>
+ <string>0.950739</string>
+ <key>r</key>
+ <string>0.787494</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.223529</string>
+ <key>g</key>
+ <string>0.776471</string>
+ <key>r</key>
+ <string>0.643137</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.165602</string>
+ <key>g</key>
+ <string>0.586124</string>
+ <key>r</key>
+ <string>0.428309</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Started\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\b0 \cf0 (visible)}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37913</integer>
+ <key>Info</key>
+ <integer>14</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37885</integer>
+ <key>Layer</key>
+ <integer>3</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{421.144, 107.69}</string>
+ <string>{479.395, 178.162}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37888</integer>
+ <key>Info</key>
+ <integer>7</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{231.032, 115.791}, {123, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>ID</key>
+ <integer>37928</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37869</integer>
+ <key>Position</key>
+ <real>0.56808090209960938</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Pad</key>
+ <integer>0</integer>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKxVvblNhdmVJbnN0YW5jZVN0YXRlKCmGhAJp
+ SQEVkoSEhAxOU0RpY3Rpb25hcnkAlIQBaQOShJaWB05T
+ Q29sb3KGkoSEhAdOU0NvbG9yAJSEAWMDhAJmZgCDZmYm
+ P4aShJaWBk5TRm9udIaShISEBk5TRm9udB6UmRyEBVsy
+ OGNdBgAAABQAAAD//kgAZQBsAHYAZQB0AGkAYwBhAIQB
+ ZgybAJsBmwCbAIaShJaWEE5TUGFyYWdyYXBoU3R5bGWG
+ koSEhBBOU1BhcmFncmFwaFN0eWxlAJSEBENDQFMCAISE
+ hAdOU0FycmF5AJSZDJKEhIQJTlNUZXh0VGFiAJSEAkNm
+ AByGkoSlpAA4hpKEpaQAVIaShKWkAHCGkoSlpACBjACG
+ koSlpACBqACGkoSlpACBxACGkoSlpACB4ACGkoSlpACB
+ /ACGkoSlpACBGAGGkoSlpACBNAGGkoSlpACBUAGGhgCG
+ hoY=
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onSaveInstanceState()}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{87.191, 169.914}, {54.2626, 54.2626}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>37884</integer>
+ <key>ImageID</key>
+ <integer>1</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{85.3224, 232.867}, {58, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>ID</key>
+ <integer>37883</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37882</integer>
+ <key>Position</key>
+ <real>0.35843163728713989</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Pad</key>
+ <integer>0</integer>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKwpvbkNyZWF0ZSgphoQCaUkBCpKEhIQMTlNE
+ aWN0aW9uYXJ5AJSEAWkDkoSWlgdOU0NvbG9yhpKEhIQH
+ TlNDb2xvcgCUhAFjA4QCZmYAg2ZmJj+GkoSWlgZOU0Zv
+ bnSGkoSEhAZOU0ZvbnQelJkchAVbMjhjXQYAAAAUAAAA
+ //5IAGUAbAB2AGUAdABpAGMAYQCEAWYMmwCbAZsAmwCG
+ koSWlhBOU1BhcmFncmFwaFN0eWxlhpKEhIQQTlNQYXJh
+ Z3JhcGhTdHlsZQCUhARDQ0BTAgCEhIQHTlNBcnJheQCU
+ mQyShISECU5TVGV4dFRhYgCUhAJDZgAchpKEpaQAOIaS
+ hKWkAFSGkoSlpABwhpKEpaQAgYwAhpKEpaQAgagAhpKE
+ paQAgcQAhpKEpaQAgeAAhpKEpaQAgfwAhpKEpaQAgRgB
+ hpKEpaQAgTQBhpKEpaQAgVABhoYAhoaG
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onCreate()}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>ID</key>
+ <integer>37882</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{114.322, 224.177}</string>
+ <string>{114.323, 267.951}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37884</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{188, 277.661}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37879</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37872</integer>
+ <key>Position</key>
+ <real>0.1218617856502533</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 3}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{54, 227.803}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37878</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 2}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{199.077, 110.791}, {23.9998, 24}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37877</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37869</integer>
+ <key>Position</key>
+ <real>0.17527788877487183</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Circle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.938075</string>
+ <key>g</key>
+ <string>0.938269</string>
+ <key>r</key>
+ <string>0.938154</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.727869</string>
+ <key>g</key>
+ <string>0.728019</string>
+ <key>r</key>
+ <string>0.72793</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.472997</string>
+ <key>g</key>
+ <string>0.473094</string>
+ <key>r</key>
+ <string>0.473036</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 1}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{382.099, 272.231}, {120.813, 35.3802}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37876</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>RoundRect</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.274119</string>
+ <key>g</key>
+ <string>0.950739</string>
+ <key>r</key>
+ <string>0.787494</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.223529</string>
+ <key>g</key>
+ <string>0.776471</string>
+ <key>r</key>
+ <string>0.643137</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.165602</string>
+ <key>g</key>
+ <string>0.586124</string>
+ <key>r</key>
+ <string>0.428309</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Resumed\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\b0 \cf0 (visible)}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37851</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37869</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{174.729, 122.791}</string>
+ <string>{382.099, 122.791}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37848</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{221.032, 282.798}, {137, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.65</string>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>ID</key>
+ <integer>37873</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>37872</integer>
+ <key>Position</key>
+ <real>0.55361413955688477</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Pad</key>
+ <integer>0</integer>
+ <key>RTFD</key>
+ <data>
+ BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0
+ ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp
+ bmcBlIQBKxhvblJlc3RvcmVJbnN0YW5jZVN0YXRlKCmG
+ hAJpSQEYkoSEhAxOU0RpY3Rpb25hcnkAlIQBaQOShJaW
+ B05TQ29sb3KGkoSEhAdOU0NvbG9yAJSEAWMDhAJmZgCD
+ ZmYmP4aShJaWBk5TRm9udIaShISEBk5TRm9udB6UmRyE
+ BVsyOGNdBgAAABQAAAD//kgAZQBsAHYAZQB0AGkAYwBh
+ AIQBZgybAJsBmwCbAIaShJaWEE5TUGFyYWdyYXBoU3R5
+ bGWGkoSEhBBOU1BhcmFncmFwaFN0eWxlAJSEBENDQFMC
+ AISEhAdOU0FycmF5AJSZDJKEhIQJTlNUZXh0VGFiAJSE
+ AkNmAByGkoSlpAA4hpKEpaQAVIaShKWkAHCGkoSlpACB
+ jACGkoSlpACBqACGkoSlpACBxACGkoSlpACB4ACGkoSl
+ pACB/ACGkoSlpACBGAGGkoSlpACBNAGGkoSlpACBUAGG
+ hgCGhoY=
+ </data>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf2 onRestoreInstanceState()}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>37876</integer>
+ <key>Info</key>
+ <integer>8</integer>
+ </dict>
+ <key>ID</key>
+ <integer>37872</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{174.729, 289.641}</string>
+ <string>{382.099, 289.921}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>37850</integer>
+ <key>Info</key>
+ <integer>7</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{382.099, 105.101}, {120.813, 35.3802}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37851</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>RoundRect</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.628571</string>
+ <key>g</key>
+ <string>0.768599</string>
+ <key>r</key>
+ <string>1</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.236788</string>
+ <key>g</key>
+ <string>0.532236</string>
+ <key>r</key>
+ <string>0.990271</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.131021</string>
+ <key>g</key>
+ <string>0.363196</string>
+ <key>r</key>
+ <string>0.725948</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Destroyed}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{53.9165, 271.951}, {120.813, 35.3802}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37850</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>RoundRect</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.274119</string>
+ <key>g</key>
+ <string>0.950739</string>
+ <key>r</key>
+ <string>0.787494</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.223529</string>
+ <key>g</key>
+ <string>0.776471</string>
+ <key>r</key>
+ <string>0.643137</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.165602</string>
+ <key>g</key>
+ <string>0.586124</string>
+ <key>r</key>
+ <string>0.428309</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Created}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{53.9165, 105.101}, {120.813, 35.3802}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>37848</integer>
+ <key>Layer</key>
+ <integer>4</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>RoundRect</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.274119</string>
+ <key>g</key>
+ <string>0.950739</string>
+ <key>r</key>
+ <string>0.787494</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.223529</string>
+ <key>g</key>
+ <string>0.776471</string>
+ <key>r</key>
+ <string>0.643137</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.165602</string>
+ <key>g</key>
+ <string>0.586124</string>
+ <key>r</key>
+ <string>0.428309</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Resumed\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\b0 \cf0 (visible)}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ </array>
+ <key>GridInfo</key>
+ <dict/>
+ <key>GuidesLocked</key>
+ <string>NO</string>
+ <key>GuidesVisible</key>
+ <string>YES</string>
+ <key>HPages</key>
+ <integer>2</integer>
+ <key>ImageCounter</key>
+ <integer>2</integer>
+ <key>ImageLinkBack</key>
+ <array>
+ <dict/>
+ </array>
+ <key>ImageList</key>
+ <array>
+ <string>image1.png</string>
+ </array>
+ <key>KeepToScale</key>
+ <false/>
+ <key>Layers</key>
+ <array>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Create</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Stopped</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Paused</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Base</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>SaveState</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>YES</string>
+ </dict>
+ </array>
+ <key>LayoutInfo</key>
+ <dict>
+ <key>Animate</key>
+ <string>NO</string>
+ <key>circoMinDist</key>
+ <real>18</real>
+ <key>circoSeparation</key>
+ <real>0.0</real>
+ <key>layoutEngine</key>
+ <string>dot</string>
+ <key>neatoSeparation</key>
+ <real>0.0</real>
+ <key>twopiSeparation</key>
+ <real>0.0</real>
+ </dict>
+ <key>LinksVisible</key>
+ <string>NO</string>
+ <key>MagnetsVisible</key>
+ <string>NO</string>
+ <key>MasterSheets</key>
+ <array/>
+ <key>ModificationDate</key>
+ <string>2012-04-13 14:55:43 -0700</string>
+ <key>Modifier</key>
+ <string>Scott Main</string>
+ <key>NotesVisible</key>
+ <string>NO</string>
+ <key>Orientation</key>
+ <integer>2</integer>
+ <key>OriginVisible</key>
+ <string>NO</string>
+ <key>PageBreaks</key>
+ <string>YES</string>
+ <key>PrintInfo</key>
+ <dict>
+ <key>NSBottomMargin</key>
+ <array>
+ <string>float</string>
+ <string>41</string>
+ </array>
+ <key>NSLeftMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSPaperSize</key>
+ <array>
+ <string>size</string>
+ <string>{612, 792}</string>
+ </array>
+ <key>NSRightMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSTopMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ </dict>
+ <key>PrintOnePage</key>
+ <false/>
+ <key>ReadOnly</key>
+ <string>NO</string>
+ <key>RowAlign</key>
+ <integer>1</integer>
+ <key>RowSpacing</key>
+ <real>36</real>
+ <key>SheetTitle</key>
+ <string>Canvas 1</string>
+ <key>SmartAlignmentGuidesActive</key>
+ <string>YES</string>
+ <key>SmartDistanceGuidesActive</key>
+ <string>YES</string>
+ <key>UniqueID</key>
+ <integer>1</integer>
+ <key>UseEntirePage</key>
+ <false/>
+ <key>VPages</key>
+ <integer>1</integer>
+ <key>WindowInfo</key>
+ <dict>
+ <key>CurrentSheet</key>
+ <integer>0</integer>
+ <key>ExpandedCanvases</key>
+ <array>
+ <dict>
+ <key>name</key>
+ <string>Canvas 1</string>
+ </dict>
+ </array>
+ <key>Frame</key>
+ <string>{{231, 4}, {950, 874}}</string>
+ <key>ListView</key>
+ <true/>
+ <key>OutlineWidth</key>
+ <integer>142</integer>
+ <key>RightSidebar</key>
+ <false/>
+ <key>ShowRuler</key>
+ <true/>
+ <key>Sidebar</key>
+ <true/>
+ <key>SidebarWidth</key>
+ <integer>120</integer>
+ <key>VisibleRegion</key>
+ <string>{{0, 0}, {801, 705}}</string>
+ <key>Zoom</key>
+ <real>1</real>
+ <key>ZoomValues</key>
+ <array>
+ <array>
+ <string>Canvas 1</string>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ </array>
+ </dict>
+ <key>saveQuickLookFiles</key>
+ <string>YES</string>
+</dict>
+</plist>
diff --git a/docs/html/images/training/basics/basic-lifecycle.graffle/image1.png b/docs/html/images/training/basics/basic-lifecycle.graffle/image1.png
new file mode 100644
index 0000000..cc606c9
--- /dev/null
+++ b/docs/html/images/training/basics/basic-lifecycle.graffle/image1.png
Binary files differ
diff --git a/docs/html/images/training/basics/basic-lifecycle.png b/docs/html/images/training/basics/basic-lifecycle.png
new file mode 100644
index 0000000..61eb422
--- /dev/null
+++ b/docs/html/images/training/basics/basic-lifecycle.png
Binary files differ
diff --git a/docs/html/images/training/basics/fragments-screen-mock.graffle/QuickLook/Preview.pdf b/docs/html/images/training/basics/fragments-screen-mock.graffle/QuickLook/Preview.pdf
new file mode 100644
index 0000000..19ccd0f
--- /dev/null
+++ b/docs/html/images/training/basics/fragments-screen-mock.graffle/QuickLook/Preview.pdf
Binary files differ
diff --git a/docs/html/images/training/basics/fragments-screen-mock.graffle/QuickLook/Thumbnail.tiff b/docs/html/images/training/basics/fragments-screen-mock.graffle/QuickLook/Thumbnail.tiff
new file mode 100644
index 0000000..8d5c9c6
--- /dev/null
+++ b/docs/html/images/training/basics/fragments-screen-mock.graffle/QuickLook/Thumbnail.tiff
Binary files differ
diff --git a/docs/html/images/training/basics/fragments-screen-mock.graffle/data.plist b/docs/html/images/training/basics/fragments-screen-mock.graffle/data.plist
new file mode 100644
index 0000000..5602c16
--- /dev/null
+++ b/docs/html/images/training/basics/fragments-screen-mock.graffle/data.plist
@@ -0,0 +1,848 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActiveLayerIndex</key>
+ <integer>0</integer>
+ <key>ApplicationVersion</key>
+ <array>
+ <string>com.omnigroup.OmniGrafflePro</string>
+ <string>138.9.0.117994</string>
+ </array>
+ <key>AutoAdjust</key>
+ <true/>
+ <key>BackgroundGraphic</key>
+ <dict>
+ <key>Bounds</key>
+ <string>{{0, 0}, {1152, 733}}</string>
+ <key>Class</key>
+ <string>SolidGraphic</string>
+ <key>ID</key>
+ <integer>2</integer>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <key>CanvasOrigin</key>
+ <string>{0, 0}</string>
+ <key>ColumnAlign</key>
+ <integer>1</integer>
+ <key>ColumnSpacing</key>
+ <real>36</real>
+ <key>CreationDate</key>
+ <string>2012-03-20 17:38:46 -0700</string>
+ <key>Creator</key>
+ <string>Billy Rutledge</string>
+ <key>DisplayScale</key>
+ <string>1 0/72 in = 1.0000 in</string>
+ <key>GraphDocumentVersion</key>
+ <integer>6</integer>
+ <key>GraphicsList</key>
+ <array>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Font</key>
+ <string>DroidSans</string>
+ <key>Size</key>
+ <real>11</real>
+ </dict>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>1205</integer>
+ </dict>
+ <key>ID</key>
+ <integer>196</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <false/>
+ <key>OrthogonalBarPosition</key>
+ <real>4.1290435791015625</real>
+ <key>Points</key>
+ <array>
+ <string>{457.98, 171.696}</string>
+ <string>{490.023, 171.696}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.7</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>4</real>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>1202</integer>
+ <key>Info</key>
+ <integer>3</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{500.158, 103.347}, {73.0685, 120.722}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>1206</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.628571</string>
+ <key>g</key>
+ <string>0.768599</string>
+ <key>r</key>
+ <string>1</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.236788</string>
+ <key>g</key>
+ <string>0.532236</string>
+ <key>r</key>
+ <string>0.990271</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.131021</string>
+ <key>g</key>
+ <string>0.363196</string>
+ <key>r</key>
+ <string>0.725948</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\fs24 \cf0 Fragment B}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{490.023, 82.3917}, {93.3371, 178.608}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>1205</integer>
+ <key>ImageID</key>
+ <integer>2</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{99.4737, 58.4729}, {223.971, 183.465}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>200</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.628571</string>
+ <key>g</key>
+ <string>0.768599</string>
+ <key>r</key>
+ <string>1</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>0.236788</string>
+ <key>g</key>
+ <string>0.532236</string>
+ <key>r</key>
+ <string>0.990271</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.131021</string>
+ <key>g</key>
+ <string>0.363196</string>
+ <key>r</key>
+ <string>0.725948</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\fs24 \cf0 Fragment B}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{24.8166, 58.4729}, {73.0685, 183.465}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>1203</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>1</string>
+ <key>g</key>
+ <string>0.874135</string>
+ <key>r</key>
+ <string>0.71718</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>1</string>
+ <key>g</key>
+ <string>0.662438</string>
+ <key>r</key>
+ <string>0.464468</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.93512</string>
+ <key>g</key>
+ <string>0.472602</string>
+ <key>r</key>
+ <string>0.333854</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\fs24 \cf0 Fragment A}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{374.205, 103.347}, {73.0685, 120.722}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>DroidSans-Bold</string>
+ <key>Size</key>
+ <real>10</real>
+ </dict>
+ <key>ID</key>
+ <integer>157</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 1}</string>
+ <string>{1, -1}</string>
+ <string>{-1, -1}</string>
+ <string>{-1, 1}</string>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ <string>{-0.5, -0.233518}</string>
+ <string>{-0.491442, 0.260063}</string>
+ <string>{0.507118, -0.224086}</string>
+ <string>{0.507118, 0.267179}</string>
+ <string>{-0.27431, -0.474028}</string>
+ <string>{0.27978, -0.478478}</string>
+ <string>{0.293938, 0.543044}</string>
+ <string>{-0.286232, 0.553804}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>1</string>
+ <key>g</key>
+ <string>0.874135</string>
+ <key>r</key>
+ <string>0.71718</string>
+ </dict>
+ <key>FillType</key>
+ <integer>2</integer>
+ <key>GradientAngle</key>
+ <real>90</real>
+ <key>GradientColor</key>
+ <dict>
+ <key>b</key>
+ <string>1</string>
+ <key>g</key>
+ <string>0.662438</string>
+ <key>r</key>
+ <string>0.464468</string>
+ </dict>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>a</key>
+ <string>0.35</string>
+ <key>b</key>
+ <string>0</string>
+ <key>g</key>
+ <string>0</string>
+ <key>r</key>
+ <string>0</string>
+ </dict>
+ <key>Fuzziness</key>
+ <real>2.3972222805023193</real>
+ <key>ShadowVector</key>
+ <string>{0, 1}</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>b</key>
+ <string>0.93512</string>
+ <key>g</key>
+ <string>0.472602</string>
+ <key>r</key>
+ <string>0.333854</string>
+ </dict>
+ <key>CornerRadius</key>
+ <real>3</real>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\fs24 \cf0 Fragment A}</string>
+ <key>VerticalPad</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{364.643, 82.3917}, {93.3371, 178.608}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>1202</integer>
+ <key>ImageID</key>
+ <integer>2</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{6.54947, 41}, {335.776, 220}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>ID</key>
+ <integer>1201</integer>
+ <key>ImageID</key>
+ <integer>1</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{0, 1}</string>
+ <string>{0, -1}</string>
+ <string>{1, 0}</string>
+ <string>{-1, 0}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ </dict>
+ </array>
+ <key>GridInfo</key>
+ <dict/>
+ <key>GuidesLocked</key>
+ <string>NO</string>
+ <key>GuidesVisible</key>
+ <string>YES</string>
+ <key>HPages</key>
+ <integer>2</integer>
+ <key>ImageCounter</key>
+ <integer>3</integer>
+ <key>ImageLinkBack</key>
+ <array>
+ <dict/>
+ <dict/>
+ </array>
+ <key>ImageList</key>
+ <array>
+ <string>image2.png</string>
+ <string>image1.png</string>
+ </array>
+ <key>KeepToScale</key>
+ <false/>
+ <key>Layers</key>
+ <array>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Layer 1</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>YES</string>
+ </dict>
+ </array>
+ <key>LayoutInfo</key>
+ <dict>
+ <key>Animate</key>
+ <string>NO</string>
+ <key>circoMinDist</key>
+ <real>18</real>
+ <key>circoSeparation</key>
+ <real>0.0</real>
+ <key>layoutEngine</key>
+ <string>dot</string>
+ <key>neatoSeparation</key>
+ <real>0.0</real>
+ <key>twopiSeparation</key>
+ <real>0.0</real>
+ </dict>
+ <key>LinksVisible</key>
+ <string>NO</string>
+ <key>MagnetsVisible</key>
+ <string>NO</string>
+ <key>MasterSheets</key>
+ <array/>
+ <key>ModificationDate</key>
+ <string>2012-04-17 18:01:13 -0700</string>
+ <key>Modifier</key>
+ <string>Scott Main</string>
+ <key>NotesVisible</key>
+ <string>NO</string>
+ <key>Orientation</key>
+ <integer>2</integer>
+ <key>OriginVisible</key>
+ <string>NO</string>
+ <key>PageBreaks</key>
+ <string>YES</string>
+ <key>PrintInfo</key>
+ <dict>
+ <key>NSBottomMargin</key>
+ <array>
+ <string>float</string>
+ <string>41</string>
+ </array>
+ <key>NSLeftMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSPaperSize</key>
+ <array>
+ <string>size</string>
+ <string>{612, 792}</string>
+ </array>
+ <key>NSRightMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ <key>NSTopMargin</key>
+ <array>
+ <string>float</string>
+ <string>18</string>
+ </array>
+ </dict>
+ <key>PrintOnePage</key>
+ <false/>
+ <key>ReadOnly</key>
+ <string>NO</string>
+ <key>RowAlign</key>
+ <integer>1</integer>
+ <key>RowSpacing</key>
+ <real>36</real>
+ <key>SheetTitle</key>
+ <string>Canvas 1</string>
+ <key>SmartAlignmentGuidesActive</key>
+ <string>YES</string>
+ <key>SmartDistanceGuidesActive</key>
+ <string>YES</string>
+ <key>UniqueID</key>
+ <integer>1</integer>
+ <key>UseEntirePage</key>
+ <false/>
+ <key>VPages</key>
+ <integer>1</integer>
+ <key>WindowInfo</key>
+ <dict>
+ <key>CurrentSheet</key>
+ <integer>0</integer>
+ <key>ExpandedCanvases</key>
+ <array>
+ <dict>
+ <key>name</key>
+ <string>Canvas 1</string>
+ </dict>
+ </array>
+ <key>Frame</key>
+ <string>{{189, -8}, {1214, 874}}</string>
+ <key>ListView</key>
+ <true/>
+ <key>OutlineWidth</key>
+ <integer>142</integer>
+ <key>RightSidebar</key>
+ <false/>
+ <key>ShowRuler</key>
+ <true/>
+ <key>Sidebar</key>
+ <true/>
+ <key>SidebarWidth</key>
+ <integer>120</integer>
+ <key>VisibleRegion</key>
+ <string>{{0, 2}, {1065, 705}}</string>
+ <key>Zoom</key>
+ <real>1</real>
+ <key>ZoomValues</key>
+ <array>
+ <array>
+ <string>Canvas 1</string>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ </array>
+ </dict>
+ <key>saveQuickLookFiles</key>
+ <string>YES</string>
+</dict>
+</plist>
diff --git a/docs/html/images/training/basics/fragments-screen-mock.graffle/image1.png b/docs/html/images/training/basics/fragments-screen-mock.graffle/image1.png
new file mode 100644
index 0000000..80baf14
--- /dev/null
+++ b/docs/html/images/training/basics/fragments-screen-mock.graffle/image1.png
Binary files differ
diff --git a/docs/html/images/training/basics/fragments-screen-mock.graffle/image2.png b/docs/html/images/training/basics/fragments-screen-mock.graffle/image2.png
new file mode 100644
index 0000000..f478d16
--- /dev/null
+++ b/docs/html/images/training/basics/fragments-screen-mock.graffle/image2.png
Binary files differ
diff --git a/docs/html/images/training/basics/fragments-screen-mock.png b/docs/html/images/training/basics/fragments-screen-mock.png
new file mode 100644
index 0000000..b170921
--- /dev/null
+++ b/docs/html/images/training/basics/fragments-screen-mock.png
Binary files differ
diff --git a/docs/html/images/training/basics/intent-chooser.png b/docs/html/images/training/basics/intent-chooser.png
new file mode 100644
index 0000000..8a8d33938
--- /dev/null
+++ b/docs/html/images/training/basics/intent-chooser.png
Binary files differ
diff --git a/docs/html/images/training/basics/sdk-manager.png b/docs/html/images/training/basics/sdk-manager.png
new file mode 100644
index 0000000..282318d
--- /dev/null
+++ b/docs/html/images/training/basics/sdk-manager.png
Binary files differ
diff --git a/docs/html/live/index.jd b/docs/html/live/index.jd
new file mode 100644
index 0000000..3885725
--- /dev/null
+++ b/docs/html/live/index.jd
@@ -0,0 +1,64 @@
+page.title=Live
+@jd:body
+
+<div id="mainBodyFixed" style="padding-left:2em;">
+
+<h1>Android Developers Live</h1>
+
+<p>Meet the developers behind successful apps and games on Android. Check back for upcoming
+livecasts on YouTube and videos of past sessions or follow us on
+<a href="https://plus.google.com/108967384991768947849/posts">+Android Developers</a> for updates.</p>
+
+ <div id="interviewBlock" id="pocketgems" style="border-top:1px solid #ddd;margin-top:2em;padding-top:1em;clear:both;">
+
+ <div id="mainBodyLeft" class="videoPlayer">
+
+ <h3>Developer Interview: Pocket Gems</h3>
+
+ <p>19 April 2012<br />2PM PST</p>
+ <p><span itemprop="description">Pocket Gems, a top game developer on Android, joins
+ <a href="https://plus.google.com/108967384991768947849/posts">+Android Developers</a>
+ to give a short talk on "Defragging Your Android Development." The talk highlights some
+ of the techniques they've used to ensure quality while distributing their apps to hundreds
+ of devices worldwide. </p>
+
+ <p>After the talk, they'll take a few questions from developers in the hangout or from
+ developers joining on air via the moderator queue. </p>
+
+ <div id="objectWrapper">
+ <iframe width="560" height="315" src="http://www.youtube.com/embed/-wkXan-xNqA" frameborder="0" allowfullscreen></iframe>
+ </div>
+
+ </div><!-- end mainBodyLeft -->
+
+ <div id="mainBodyRight" class="videoPlayer">
+
+ <div style="padding-left:1.5em;font-size:12px;">
+ <div style="padding-bottom:1em;"><img itemprop="image" src="http://pocketgems.com/images/pocket-gems-logo-blue.png"></div>
+
+ <h3 style="color:#000;font-size:12px;">About Pocket Gems</h3>
+ <p>
+ Web: <a style="text-decoration:none" href="http://www.pocketgems.com">www.pocketgems.com</a><br />
+ Google+: <a style="text-decoration:none" href="https://plus.google.com/b/102436156807338888308/">+Pocket Gems</a><br />
+ Twitter: <a style="text-decoration:none" href="https://twitter.com/#!/PocketGems">@PocketGems</a><br />
+ </p>
+
+ <h3 style="color:#000;font-size:12px;">Published on Google Play</h3>
+ <p style="line-height:1.5em;">
+ <a style="text-decoration:none" href="https://play.google.com/store/apps/developer?id=Pocket+Gems">Apps by Pocket Gems</a>
+ </p>
+
+ <h3 style="color:#000;font-size:12px;">Join</h3>
+ <p style="line-height:1.5em;">
+ <a style="text-decoration:none" href="http://youtu.be/-wkXan-xNqA">Watch on YouTube</a><br />
+ <a style="text-decoration:none" href="http://www.google.com/moderator/#15/e=1fd27e&t=1fd27e.40">Submit a question</a><br />
+ <a style="text-decoration:none" href="https://www.google.com/calendar/ical/g2ilcr0iki4olp10aluid7gl70%40group.calendar.google.com/public/basic.ics">Add to calendar</a> (iCal)
+ </p>
+
+ </li></ul>
+
+</div>
+ </div><!-- end mainBodyRight -->
+</div><!-- interviewBlock -->
+
+ </div><!-- end mainBodyFixed -->
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index 686bde3..9752d99 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -1,7 +1,7 @@
<ul>
<li>
<span class="heading">
- <span class="en">Android Training</span>
+ <span class="en">Basic Training</span>
</span>
<ul>
@@ -11,6 +11,148 @@
</li>
<li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>training/basics/firstapp/index.html">
+ <span class="en">Building Your First App<span class="new"> new!</span></span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/firstapp/creating-project.html">
+ <span class="en">Creating an Android Project</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/firstapp/running-app.html">
+ <span class="en">Running Your Application</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/firstapp/building-ui.html">
+ <span class="en">Building a Simple User Interface</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/firstapp/starting-activity.html">
+ <span class="en">Starting Another Activity</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/index.html">
+ <span class="en">Managing the Activity Lifecycle<span class="new"> new!</span></span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/starting.html">
+ <span class="en">Starting an Activity</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/pausing.html">
+ <span class="en">Pausing and Resuming an Activity</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/stopping.html">
+ <span class="en">Stopping and Restarting an Activity</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/recreating.html">
+ <span class="en">Recreating an Activity</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>training/basics/supporting-devices/index.html">
+ <span class="en">Supporting Different Devices<span class="new"> new!</span></span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/supporting-devices/languages.html">
+ <span class="en">Supporting Different Languages</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/supporting-devices/screens.html">
+ <span class="en">Supporting Different Screens</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/supporting-devices/platforms.html">
+ <span class="en">Supporting Different Platform Versions</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>training/basics/fragments/index.html">
+ <span class="en">Building a Dynamic UI with Fragments<span class="new"> new!</span></span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/fragments/support-lib.html">
+ <span class="en">Using the Support Library</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/fragments/creating.html">
+ <span class="en">Creating a Fragment</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/fragments/fragment-ui.html">
+ <span class="en">Building a Flexible UI</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/fragments/communicating.html">
+ <span class="en">Communicating with Other Fragments</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>training/basics/intents/index.html">
+ <span class="en">Interacting with Other Apps<span class="new"> new!</span></span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/intents/sending.html">
+ <span class="en">Sending the User to Another App</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/intents/result.html">
+ <span class="en">Getting a Result from the Activity</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/intents/filters.html">
+ <span class="en">Allowing Other Apps to Start Your Activity</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>training/basics/location/index.html">
+ <span class="en">Making Your App Location Aware<span class="new"> new!</span></span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/basics/location/locationmanager.html">
+ <span class="en">Using the Location Manager</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/location/currentlocation.html">
+ <span class="en">Obtaining the Current Location</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/basics/location/geocoding.html">
+ <span class="en">Displaying a Location Address</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ </ul>
+ </li>
+
+
+ <li>
+ <span class="heading">
+ <span class="en">Advanced Training</span>
+ </span>
+ <ul>
+
+ <li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/multiscreen/index.html">
<span class="en">Designing for Multiple Screens</span>
</a></div>
@@ -124,6 +266,23 @@
</li>
<li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>training/cloudsync/index.html">
+ <span class="en">Syncing to the Cloud<span class="new"> new!</span></span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/cloudsync/aesync.html">
+ <span class="en">Syncing with App Engine</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/cloudsync/backupapi.html">
+ <span class="en">Using the Backup API</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+
+
+ <li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/search/index.html">
<span class="en">Adding Search Functionality<span class="new"> new!</span></span>
</a>
@@ -369,11 +528,11 @@
</li>
<li><a href="<?cs var:toroot ?>training/displaying-bitmaps/display-bitmap.html">
<span class="en">Displaying Bitmaps in Your UI</span>
- </a>
- </li>
+ </a></li>
</ul>
</li>
+
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/accessibility/index.html">
<span class="en">Implementing Accessibility<span class="new"> new!</span></span>
@@ -391,9 +550,11 @@
</li>
</ul>
- </li>
-
-
+ </li>
+
+
+
+
<li>
<span class="heading">
<span class="en">Technical Resources</span>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index a70b0f3..e994d95 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -151,7 +151,7 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r18</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r19</a></li>
<li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li>
<li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Support Package, r7</a></li>
</ul>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index f4e9d4d..062f8f1 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -68,6 +68,40 @@
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
width="9px" />
+ SDK Tools, Revision 19</a> <em>(April 2012)</em>
+
+ <div class="toggleme">
+ <p class="note"><strong>Note:</strong> This update of SDK Tools is only available through
+the <a href="{@docRoot}sdk/adding-components.html">Android SDK Manager</a>. Use this tool to
+download and install this update.</p>
+
+ <dl>
+ <dt>Dependencies:</dt>
+ <dd>
+ <ul>
+ <li>Android SDK Platform-tools revision 9 or later.</li>
+ <li>If you are developing in Eclipse with ADT, note that the SDK Tools r19 is designed for
+ use with ADT 18.0.0 and later. If you haven't already, we highly recommend updating your
+ <a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin</a> to 18.0.0.</li>
+ <li>If you are developing outside Eclipse, you must have
+ <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+ </ul>
+ </dd>
+ <dt>Bug fixes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed an issue that prevented some developers from running the emulator with GPU
+acceleration.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+ width="9px" />
SDK Tools, Revision 18</a> <em>(April 2012)</em>
<div class="toggleme">
diff --git a/docs/html/shareables/training/ActivityLifecycle.zip b/docs/html/shareables/training/ActivityLifecycle.zip
new file mode 100644
index 0000000..1cbed44
--- /dev/null
+++ b/docs/html/shareables/training/ActivityLifecycle.zip
Binary files differ
diff --git a/docs/html/shareables/training/FragmentBasics.zip b/docs/html/shareables/training/FragmentBasics.zip
new file mode 100644
index 0000000..ff5b7f1
--- /dev/null
+++ b/docs/html/shareables/training/FragmentBasics.zip
Binary files differ
diff --git a/docs/html/training/accessibility/accessible-app.jd b/docs/html/training/accessibility/accessible-app.jd
index f4087b8..dd26feb 100644
--- a/docs/html/training/accessibility/accessible-app.jd
+++ b/docs/html/training/accessibility/accessible-app.jd
@@ -50,11 +50,14 @@
<p>Fortunately, it's easy to add labels to UI elements in your application that
can be read out loud to your user by a speech-based accessibility service like <a
- href="https://market.android.com/details?id=com.google.android.marvin.talkback">TalkBack</a>.
+href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a>
+.
If you have a label that's likely not to change during the lifecycle of the
application (such as "Pause" or "Purchase"), you can add it via the XML layout,
by setting a UI element's <a
- href="{@docRoot}reference/android/view.View#attr_android:contentDescription">android:contentDescription</a> attribute, like in this
+
+href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription"
+>{@code android:contentDescription}</a> attribute, like in this
example:</p>
<pre>
<Button
@@ -83,7 +86,7 @@
interface.</p>
<p>Try it out! Download <a
- href="https://market.android.com/details?id=com.google.android.marvin.talkback">TalkBack</a>
+href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a>
(an accessibility service published by Google) and enable it in <strong>Settings
> Accessibility > TalkBack</strong>. Then navigate around your own
application and listen for the audible cues provided by TalkBack.</p>
@@ -101,21 +104,21 @@
done at runtime using the
{@link android.view.View#setFocusable View.setFocusable()} method on that UI
control, or by setting the <a
- href="{@docRoot}android.view.View#attr_android:focusable">{@code
+ href="{@docRoot}reference/android/view/View.html#attr_android:focusable">{@code
android:focusable}</a>
attrubute in your XML layout files.</p>
<p>Also, each UI control has 4 attributes,
-<a href="{@docRoot}reference/android/view/View#attr_android:nextFocusUp">{@code
+<a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp">{@code
android:nextFocusUp}</a>,
<a
- href="{@docRoot}reference/android/view/View#attr_android:nextFocusDown">{@code
+ href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown">{@code
android:nextFocusDown}</a>,
<a
- href="{@docRoot}reference/android/view/View#attr_android:nextFocusLeft">{@code
+ href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft">{@code
android:nextFocusLeft}</a>,
and <a
- href="{@docRoot}reference/android/view/View#attr_android:nextFocusRight">{@code
+ href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight">{@code
android:nextFocusRight}</a>,
which you can use to designate
the next view to receive focus when the user navigates in that direction. While
@@ -178,7 +181,8 @@
<p>Be sure to test the accessibility functionality as you add it to your
application. In order to test the content descriptions and Accessibility
events, install and enable an accessibility service. One option is <a
- href="https://play.google.com/store/details?id=com.google.android.marvin.talkback">Talkback</a>,
+href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">Talkback</a>
+,
a free, open source screen reader available on Google Play. With the service
enabled, test all the navigation flows through your application and listen to
the spoken feedback.</p>
diff --git a/docs/html/training/basics/activity-lifecycle/index.jd b/docs/html/training/basics/activity-lifecycle/index.jd
new file mode 100644
index 0000000..d278f04
--- /dev/null
+++ b/docs/html/training/basics/activity-lifecycle/index.jd
@@ -0,0 +1,74 @@
+page.title=Managing the Activity Lifecycle
+
+trainingnavtop=true
+startpage=true
+next.title=Launching an Activity
+next.link=starting.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+<h2>Dependencies and prerequisites</h2>
+<ul>
+ <li>How to create an Android project (see <a
+href="{@docRoot}training/basics/firstapp/creating-project.html">Creating an Android
+Project</a>)</li>
+</ul>
+
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a></li>
+</ul>
+
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip"
+class="button">Download the demo</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>As a user navigates through, out of, and back to your app, the
+{@link android.app.Activity} instances in your app transition between different states in their
+lifecycle. For instance, when your
+activity starts for the first time, it comes to the foreground of the system and receives user
+focus. During this process, the Android system calls a series of lifecycle methods on the
+activity in which you set up the user interface and other components. If the user performs an
+action that starts another activity or switches to another app, the system calls another set of
+lifecycle methods on your activity as it moves into the background (where the activity is no
+longer visible, but the instance and its state remains intact).</p>
+
+<p>Within the lifecycle callback methods, you can declare how your activity behaves when the
+user leaves and re-enters the activity. For example, if you're building a streaming video player,
+you might pause the video and terminate the network connection when the user switches to another
+app. When the user returns, you can reconnect to the network and allow the user to resume the video
+from the same spot.</p>
+
+<p>This class explains important lifecycle callback methods that each {@link
+android.app.Activity} instance receives and how you can use them so your activity does what the
+user expects and does not consume system resources when your activity doesn't need them.</p>
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><b><a href="starting.html">Starting an Activity</a></b></dt>
+ <dd>Learn the basics about the activity lifecycle, how the user can launch your app, and how
+to perform basic activity creation.</dd>
+ <dt><b><a href="pausing.html">Pausing and Resuming an Activity</a></b></dt>
+ <dd>Learn what happens when your activity is paused (partially obscured) and resumed and what you
+should do during these state changes.</dd>
+ <dt><b><a href="stopping.html">Stopping and Restarting an Activity</a></b></dt>
+ <dd>Learn what happens when the user completely leaves your activity and returns to it.</dd>
+ <dt><b><a href="recreating.html">Recreating an Activity</a></b></dt>
+ <dd>Learn what happens when your activity is destroyed and how you can rebuild the activity
+state when necessary.</dd>
+</dl>
+
diff --git a/docs/html/training/basics/activity-lifecycle/pausing.jd b/docs/html/training/basics/activity-lifecycle/pausing.jd
new file mode 100644
index 0000000..216d55e1
--- /dev/null
+++ b/docs/html/training/basics/activity-lifecycle/pausing.jd
@@ -0,0 +1,152 @@
+page.title=Pausing and Resuming an Activity
+parent.title=Managing the Activity Lifecycle
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Starting an Activity
+previous.link=starting.html
+next.title=Stopping and Restarting an Activity
+next.link=stopping.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#Pause">Pause Your Activity</a></li>
+ <li><a href="#Resume">Resume Your Activity</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
+ </li>
+ </ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip"
+class="button">Download the demo</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>During normal app use, the foreground activity is sometimes obstructed by other
+visual components that cause the activity to <em>pause</em>. For example, when a semi-transparent
+activity opens (such as one in the style of a dialog), the previous activity pauses. As long as the
+activity is still partially visible but currently not the activity in focus, it remains paused.</p>
+
+<p>However, once the activity is fully-obstructed and not visible, it <em>stops</em> (which is
+discussed in the next lesson).</p>
+
+<p>As your activity enters the paused state, the system calls the {@link
+android.app.Activity#onPause onPause()} method on your {@link android.app.Activity}, which allows
+you to stop ongoing actions that should not continue while paused (such as a video) or persist
+any information that should be permanently saved in case the user continues to leave your app. If
+the user returns to your activity from the paused state, the system resumes it and calls the
+{@link android.app.Activity#onResume onResume()} method.</p>
+
+<p class="note"><strong>Note:</strong> When your activity receives a call to {@link
+android.app.Activity#onPause()}, it may be an indication that the activity will be paused for a
+moment and the user may return focus to your activity. However, it's usually the first indication
+that the user is leaving your activity.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" />
+<p class="img-caption"><strong>Figure 1.</strong> When a semi-transparent activity obscures
+your activity, the system calls {@link android.app.Activity#onPause onPause()} and the activity
+waits in the Paused state (1). If the user returns to the activity while it's still paused, the
+system calls {@link android.app.Activity#onResume onResume()} (2).</p>
+
+
+<h2 id="Pause">Pause Your Activity</h2>
+
+<p>When the system calls {@link android.app.Activity#onPause()} for your activity, it
+technically means your activity is still partially visible, but most often is an indication that
+the user is leaving the activity and it will soon enter the Stopped state. You should usually use
+the {@link android.app.Activity#onPause()} callback to:</p>
+
+<ul>
+ <li>Stop animations or other ongoing actions that could consume CPU.</li>
+ <li>Commit unsaved changes, but only if users expect such changes to be permanently saved when
+they leave (such as a draft email).</li>
+ <li>Release system resources, such as broadcast receivers, handles to sensors (like
+GPS), or any resources that may affect battery life while your activity is paused and the user
+does not need them.</li>
+</ul>
+
+<p>For example, if your application uses the {@link android.hardware.Camera}, the
+{@link android.app.Activity#onPause()} method is a good place to release it.</p>
+
+<pre>
+@Override
+public void onPause() {
+ super.onPause(); // Always call the superclass method first
+
+ // Release the Camera because we don't need it when paused
+ // and other activities might need to use it.
+ if (mCamera != null) {
+ mCamera.release()
+ mCamera = null;
+ }
+}
+</pre>
+
+<p>Generally, you should <strong>not</strong> use {@link android.app.Activity#onPause()} to store
+user changes (such as personal information entered into a form) to permanent storage. The only time
+you should persist user changes to permanent storage within {@link android.app.Activity#onPause()}
+is when you're certain users expect the changes to be auto-saved (such as when drafting an email).
+However, you should avoid performing CPU-intensive work during {@link
+android.app.Activity#onPause()}, such as writing to a database, because it can slow the visible
+transition to the next activity (you should instead perform heavy-load shutdown operations during
+{@link android.app.Activity#onStop onStop()}).</p>
+
+<p>You should keep the amount of operations done in the {@link android.app.Activity#onPause
+onPause()} method relatively simple in order to allow for a speedy transition to the user's next
+destination if your activity is actually being stopped.</p>
+
+<p class="note"><strong>Note:</strong> When your activity is paused, the {@link
+android.app.Activity} instance is kept resident in memory and is recalled when the activity resumes.
+You don’t need to re-initialize components that were created during any of the callback methods
+leading up to the Resumed state.</p>
+
+
+
+<h2 id="Resume">Resume Your Activity</h2>
+
+<p>When the user resumes your activity from the Paused state, the system calls the {@link
+android.app.Activity#onResume()} method.</p>
+
+<p>Be aware that the system calls this method every time your activity comes into the foreground,
+including when it's created for the first time. As such, you should implement {@link
+android.app.Activity#onResume()} to initialize components that you release during {@link
+android.app.Activity#onPause()} and perform any other initializations that must occur each time the
+activity enters the Resumed state (such as begin animations and initialize components only used
+while the actiivty has user focus).</p>
+
+<p>The following example of {@link android.app.Activity#onResume()} is the counterpart to
+the {@link android.app.Activity#onPause()} example above, so it initializes the camera that's
+released when the activity pauses.</p>
+
+<pre>
+@Override
+public void onResume() {
+ super.onResume(); // Always call the superclass method first
+
+ // Get the Camera instance as the activity achieves full user focus
+ if (mCamera == null) {
+ initializeCamera(); // Local method to handle camera init
+ }
+}
+</pre>
+
+
+
+
+
+
+
diff --git a/docs/html/training/basics/activity-lifecycle/recreating.jd b/docs/html/training/basics/activity-lifecycle/recreating.jd
new file mode 100644
index 0000000..941f1fd11
--- /dev/null
+++ b/docs/html/training/basics/activity-lifecycle/recreating.jd
@@ -0,0 +1,177 @@
+page.title=Recreating an Activity
+parent.title=Managing the Activity Lifecycle
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Stopping and Restarting an Activity
+previous.link=stopping.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#SaveState">Save Your Activity State</a></li>
+ <li><a href="#RestoreState">Restore Your Activity State</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">Supporting
+Different Screens</a></li>
+ <li><a
+href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a></li>
+ <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
+ </li>
+ </ul>
+
+ </div>
+</div>
+
+<p>There are a few scenarios in which your activity is destroyed due to normal app behavior, such as
+when the user presses the <em>Back</em> button or your activity signals its own destruction by
+calling {@link android.app.Activity#finish()}. The system may also destory your activity if it's
+currently stopped and hasn't been used in a long time or the foreground activity requires more
+resources so the system must shut down background processes to recover memory.</p>
+
+<p>When your activity is destroyed because the user presses <em>Back</em> or the activity finishes
+itself, the system's concept of that {@link android.app.Activity} instance is gone forever because
+the behavior indicates the activity is no longer needed. However, if the system destroys
+the activity due to system constraints (rather than normal app behavior), then althought the actual
+{@link android.app.Activity} instance is gone, the system remembers that it existed such that if
+the user navigates back to it, the system creates a new instance of the activity using a set of
+saved data that describes the state of the activity when it was destroyed. The saved data that the
+system uses to restore the previous state is called the "instance state" and is a collection of
+key-value pairs stored in a {@link android.os.Bundle} object.</p>
+
+<p class="caution"><strong>Caution:</strong> Your activity will be destroyed and recreated each time
+the user rotates the screen. When the screen changes orientation, the system destroys and recreates
+the foreground activity because the screen configuration has changed and your activity might need to
+load alternative resources (such as the layout).</p>
+
+<p>By default, the system uses the {@link android.os.Bundle} instance state to saves information
+about each {@link android.view.View} object in your activity layout (such as the text value entered
+into an {@link android.widget.EditText} object). So, if your activity instance is destroyed and
+recreated, the state of the layout is automatically restored to its previous state. However, your
+activity might have more state information that you'd like to restore, such as member variables that
+track the user's progress in the activity.</p>
+
+<p>In order for you to add additional data to the saved instance state for your activity, there's an
+additional callback method in the activity lifecycle that's not shown in the illustration from
+previous lessons. The method is {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()} and the system calls it when the user is leaving your activity. When the
+system calls this method, it passes the {@link android.os.Bundle} object that will be saved in the
+event that your activity is destroyed unexpectedly so you can add additional information to it. Then
+if the system must recreate the activity instance after it was destroyed, it passes the same {@link
+android.os.Bundle} object to your activity's {@link android.app.Activity#onRestoreInstanceState
+onRestoreInstanceState()} method and also to your {@link android.app.Activity#onCreate onCreate()}
+method.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" />
+<p class="img-caption"><strong>Figure 2.</strong> As the system begins to stop your activity, it
+calls {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} (1) so you can specify
+additional state data you'd like to save in case the {@link android.app.Activity} instance must be
+recreated.
+If the activity is destroyed and the same instance must be recreated, the system passes the state
+data defined at (1) to both the {@link android.app.Activity#onCreate onCreate()} method
+(2) and the {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} method
+(3).</p>
+
+
+
+<h2 id="SaveState">Save Your Activity State</h2>
+
+<p>As your activity begins to stop, the system calls {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()} so your activity can save state information with a collection of key-value
+pairs. The default implementation of this method saves information about the state of the activity's
+view hierarchy, such as the text in an {@link android.widget.EditText} widget or the scroll position
+of a {@link android.widget.ListView}.</p>
+
+<p>To save additional state information for your activity, you must
+implement {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} and add
+key-value pairs to the {@link android.os.Bundle} object. For example:</p>
+
+<pre>
+static final String STATE_SCORE = "playerScore";
+static final String STATE_LEVEL = "playerLevel";
+...
+
+@Override
+public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save the user's current game state
+ savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
+ savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
+
+ // Always call the superclass so it can save the view hierarchy state
+ super.onSaveInstanceState(savedInstanceState);
+}
+</pre>
+
+<p class="caution"><strong>Caution:</strong> Always call the superclass implementation of {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} so the default implementation
+can save the state of the view hierarchy.</p>
+
+
+
+<h2 id="RestoreState">Restore Your Activity State</h2>
+
+<p>When your activity is recreated after it was previously destroyed, you can recover your saved
+state from the {@link android.os.Bundle} that the system
+passes your activity. Both the {@link android.app.Activity#onCreate onCreate()} and {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} callback methods receive
+the same {@link android.os.Bundle} that containes the instance state information.</p>
+
+<p>Because the {@link android.app.Activity#onCreate onCreate()} method is called whether the
+system is creating a new instance of your activity or recreating a previous one, you must check
+whether the state {@link android.os.Bundle} is null before you attempt to read it. If it is null,
+then the system is creating a new instance of the activity, instead of restoring a previous one
+that was destroyed.</p>
+
+<p>For example, here's how you can restore some state data in {@link android.app.Activity#onCreate
+onCreate()}:</p>
+
+<pre>
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState); // Always call the superclass first
+
+ // Check whether we're recreating a previously destroyed instance
+ if (savedInstanceState != null) {
+ // Restore value of members from saved state
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+ } else {
+ // Probably initialize members with default values for a new instance
+ }
+ ...
+}
+</pre>
+
+<p>Instead of restoring the state during {@link android.app.Activity#onCreate onCreate()} you
+may choose to implement {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}, which the system calls
+after the {@link android.app.Activity#onStart()} method. The system calls {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} only if there is a saved
+state to restore, so you do not need to check whether the {@link android.os.Bundle} is null:</p>
+
+<pre>
+public void onRestoreInstanceState(Bundle savedInstanceState) {
+ // Always call the superclass so it can restore the view hierarchy
+ super.onRestoreInstanceState(savedInstanceState);
+
+ // Restore state members from saved instance
+ mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
+ mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
+}
+</pre>
+
+<p class="caution"><strong>Caution:</strong> Always call the superclass implementation of {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} so the default implementation
+can restore the state of the view hierarchy.</p>
+
+<p>To learn more about recreating your activity due to a
+restart event at runtime (such as when the screen rotates), read <a
+href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a>.</p>
+
diff --git a/docs/html/training/basics/activity-lifecycle/starting.jd b/docs/html/training/basics/activity-lifecycle/starting.jd
new file mode 100644
index 0000000..d3266ae
--- /dev/null
+++ b/docs/html/training/basics/activity-lifecycle/starting.jd
@@ -0,0 +1,290 @@
+page.title=Starting an Activity
+parent.title=Managing the Activity Lifecycle
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Pausing and Resuming an Activity
+next.link=pausing.html
+
+@jd:body
+
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#lifecycle-states">Understand the Lifecycle Callbacks</a></li>
+ <li><a href="#launching-activity">Specify Your App's Launcher Activity</a></li>
+ <li><a href="#Create">Create a New Instance</a></li>
+ <li><a href="#Destroy">Destroy the Activity</a></li>
+</ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a></li>
+ </ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip"
+class="button">Download the demo</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>Unlike other programming paradigms in which apps are launched with a {@code main()} method, the
+Android system initiates code in an {@link android.app.Activity} instance by invoking specific
+callback methods that correspond to specific stages of its
+lifecycle. There is a sequence of callback methods that start up an activity and a sequence of
+callback methods that tear down an activity.</p>
+
+<p>This lesson provides an overview of the most important lifecycle methods and shows you how to
+handle the first lifecycle callback that creates a new instance of your activity.</p>
+
+
+
+<h2 id="lifecycle-states">Understand the Lifecycle Callbacks</h2>
+
+<p>During the life of an activity, the system calls a core set of lifecycle methods in
+a sequence similar to a step pyramid. That is, each stage of the
+activity lifecycle is a separate step on the pyramid. As the system creates a new activity instance,
+each callback method moves the activity state one step toward the top. The top of the pyramid is the
+point at which the activity is running in the foreground and the user can interact with it.</p>
+
+<p>As the user begins to leave the activity, the system calls other methods that move the activity
+state back down the pyramid in order to dismantle the activity. In some cases, the activity will
+move only part way down the pyramid and wait (such as when the user switches to another app), from
+which point the activity can move back to the top (if the user returns to the activity) and
+resume where the user left off.</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle.png" />
+<p class="img-caption"><strong>Figure 1.</strong> A simplified illustration of the Activity
+lifecycle, expressed as a step pyramid. This shows how, for every callback used to take
+the activity a step toward the Resumed state at the top, there's a callback method
+that takes the activity a step down. The activity can also return to the resumed state from the
+Paused and Stopped state.</p>
+
+
+<p>Depending on the complexity of your activity, you probably don't need to implement all the
+lifecycle methods. However, it's important that you understand each one and implement those that
+ensure your app behaves the way users expect. Implementing your activity lifecycle methods properly
+ensures your app behaves well in several ways, including that it:</p>
+<ul>
+ <li>Does not crash if the user receives a phone call or switches to another app
+while using your app.</li>
+ <li>Does not consume valuable system resources when the user is not actively using
+it.</li>
+ <li>Does not loose the user's progress if they leave your app and return to it at a
+later time.</li>
+ <li>Does not crash of loose the user's progress when the screen rotates between
+landscape and portrait orientation.</li>
+</ul>
+
+<!--
+<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback
+methods.</p>
+<table>
+ <tr>
+ <th scope="col">Lifecycle State</th>
+ <th scope="col">Startup Method</th>
+ <th scope="col">Teardown Method</th>
+ </tr>
+ <tr>
+ <td>Created / Destroyed</td>
+ <td>{@link android.app.Activity#onCreate onCreate()}</td>
+ <td>{@link android.app.Activity#onDestroy()}</td>
+ </tr>
+ <tr>
+ <td>Started / Stopped</td>
+ <td>{@link android.app.Activity#onStart()}</td>
+ <td>{@link android.app.Activity#onStop()}</td>
+ </tr>
+ <tr>
+ <td>Resumed / Resumed</td>
+ <td>{@link android.app.Activity#onResume()}</td>
+ <td>{@link android.app.Activity#onPause()}</td>
+ </tr>
+</table>
+-->
+
+<p>As you'll learn in the following lessons, there are several situtations in which an activity
+transitions between different states that are illustrated in figure 1. However, only three of
+these states can be static. That is, the activity can exist in one of only three states for an
+extended period of time:</p>
+<dl>
+ <dt>Resumed</dt>
+ <dd>In this state, the activity is in the foreground and the user can interact with it.
+(Also sometimes referred to as the "running" state.)</dd>
+ <dt>Paused</dt>
+ <dd>In this state, the activity is partially obscured by another activity—the
+other activity that's in the foreground is semi-transparent or doesn't cover the entire screen. The
+paused activity does not receive user input and cannot execute any code.
+ <dt>Stopped</dt>
+ <dd>In this state, the activity is completely hidden and not visible to the user; it is
+considered to be in the background. While stopped, the activity instance and all its state
+information such as member variables is retained, but it cannot execute any code.</dd>
+</dl>
+
+<p>The other states (Created and Started) are transient and the system quickly moves from them to
+the next state by calling the next lifecycle callback method. That is, after the system calls
+{@link android.app.Activity#onCreate onCreate()}, it quickly calls {@link
+android.app.Activity#onStart()}, which is quickly followed by {@link
+android.app.Activity#onResume()}.</p>
+
+<p>That's it for the basic activity lifecycle. Now you'll start learning about some of the
+specific lifecycle behaviors.</p>
+
+
+
+<h2 id="launching-activity">Specify Your App's Launcher Activity</h2>
+
+<p>When the user selects your app icon from the Home screen, the system calls the {@link
+android.app.Activity#onCreate onCreate()} method for the {@link android.app.Activity} in your app
+that you've declared to be the "launcher" (or "main") activity. This is the activity that serves as
+the main entry point to your app's user interface.</p>
+
+<p>You can define which activity to use as the main activity in the Android manifest file, <a
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a>, which is
+at the root of your project directory.</p>
+
+<p>The main activity for your app must be declared in the manifest with an <a
+href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+<intent-filter>}</a> that includes the {@link
+android.content.Intent#ACTION_MAIN MAIN} action and
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} category. For example:</p>
+
+<pre>
+<activity android:name=".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>
+</pre>
+
+<p class="note"><strong>Note:</strong> When you create a new Android project with the Android SDK
+tools, the default project files include an {@link android.app.Activity} class that's declared in
+the manifest with this filter.</p>
+
+<p>If either the {@link android.content.Intent#ACTION_MAIN MAIN} action or
+{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} category are not declared for one of your
+activities, then your app icon will not appear in the Home screen's list of apps.</p>
+
+
+
+<h2 id="Create">Create a New Instance</h2>
+
+<p>Most apps include several different activities that allow the user to perform different actions.
+Whether an activity is the main activity that's created when the user clicks your app icon or a
+different activity that your app starts in response to a user action, the system creates
+every new instance of {@link android.app.Activity} by calling its {@link
+android.app.Activity#onCreate onCreate()} method.</p>
+
+<p>You must implement the {@link android.app.Activity#onCreate onCreate()} method to perform basic
+application startup logic that should happen only once for the entire life of the activity. For
+example, your implementation of {@link android.app.Activity#onCreate onCreate()} should define the
+user interface and possibly instantiate some class-scope variables.</p>
+
+<p>For example, the following example of the {@link android.app.Activity#onCreate onCreate()}
+method shows some code that performs some fundamental setup for the activity, such as
+declaring the user interface (defined in an XML layout file), defining member variables,
+and configuring some of the UI.</p>
+
+<pre>
+TextView mTextView; // Member variable for text view in the layout
+
+@Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set the user interface layout for this Activity
+ // The layout file is defined in the project res/layout/main_activity.xml file
+ setContentView(R.layout.main_activity);
+
+ // Initialize member TextView so we can manipulate it later
+ mTextView = (TextView) findViewById(R.id.text_message);
+
+ // Make sure we're running on Honeycomb or higher to use ActionBar APIs
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // For the main activity, make sure the app icon in the action bar
+ // does not behave as a button
+ ActionBar actionBar = getActionBar();
+ actionBar.setHomeButtonEnabled(false);
+ }
+}
+</pre>
+
+<p class="caution"><strong>Caution:</strong> Using the {@link android.os.Build.VERSION#SDK_INT} to
+prevent older system's from executing new APIs works in this way on Android 2.0 (API level
+5) and higher only. Older versions will encounter a runtime exception.</p>
+
+<p>Once the {@link android.app.Activity#onCreate onCreate()} finishes execution, the system
+calls the {@link android.app.Activity#onStart()} and {@link android.app.Activity#onResume()} methods
+in quick succession. Your activity never resides in the Created or Started states. Technically, the
+activity becomes visible to the user when {@link android.app.Activity#onStart()} is called, but
+{@link android.app.Activity#onResume()} quickly follows and the activity remains in the Resumed
+state until something occurs to change that, such as when a phone call is received, the user
+navigates to another activity, or the device screen turns off.</p>
+
+<p>In the other lessons that follow, you'll see how the other start up methods, {@link
+android.app.Activity#onStart()} and {@link android.app.Activity#onResume()}, are useful during your
+activity's lifecycle when used to resume the activity from the Paused or Stopped states.</p>
+
+<p class="note"><strong>Note:</strong> The {@link android.app.Activity#onCreate onCreate()}
+method includes a parameter called <code>savedInstanceState</code> that's discussed in the
+latter lesson about <a href="recreating.html">Recreating an Activity</a>.</p>
+
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" />
+<p class="img-caption"><strong>Figure 2.</strong> Another illustration of the activity lifecycle
+structure with an emphasis on the three main callbacks that the system calls in sequence when
+creating a new instance of the activity: {@link android.app.Activity#onCreate onCreate()}, {@link
+android.app.Activity#onStart()}, and {@link android.app.Activity#onResume()}. Once this sequence of
+callbacks complete, the activity reaches the Resumed state where users can interact with the
+activity until they switch to a different activity.</p>
+
+
+
+
+
+
+
+<h2 id="Destroy">Destroy the Activity</h2>
+
+<p>While the activity's first lifecycle callback is {@link android.app.Activity#onCreate
+onCreate()}, it's very last callback is {@link android.app.Activity#onDestroy}. The system calls
+this method on your activity as the final
+signal that your activity instance is being completely removed from the system memory.</p>
+
+<p>Most apps don't need to implement this method because local class references are destroyed
+with the activity and your activity should perform most cleanup during {@link
+android.app.Activity#onPause} and {@link android.app.Activity#onStop}. However, if your
+activity includes background threads that you created during {@link
+android.app.Activity#onCreate onCreate()} or other other long-running resources that could
+potentially leak memory if not properly closed, you should kill them during {@link
+android.app.Activity#onDestroy}.</p>
+
+<pre>
+@Override
+public void onDestroy() {
+ super.onDestroy(); // Always call the superclass
+
+ // Stop method tracing that the activity started during onCreate()
+ android.os.Debug.stopMethodTracing();
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> The system calls {@link android.app.Activity#onDestroy}
+after it has already called {@link android.app.Activity#onPause} and {@link
+android.app.Activity#onStop} in all situations except one: when you call {@link
+android.app.Activity#finish()} from within the {@link android.app.Activity#onCreate onCreate()}
+method. In some cases, such as when your activity operates as a temporary decision maker to
+launch another activity, you might call {@link android.app.Activity#finish()} from within {@link
+android.app.Activity#onCreate onCreate()} to destory the activity. In this case, the system
+immediately calls {@link android.app.Activity#onDestroy} without calling any of the other
+lifecycle methods.</p>
diff --git a/docs/html/training/basics/activity-lifecycle/stopping.jd b/docs/html/training/basics/activity-lifecycle/stopping.jd
new file mode 100644
index 0000000..7dfc6d3
--- /dev/null
+++ b/docs/html/training/basics/activity-lifecycle/stopping.jd
@@ -0,0 +1,193 @@
+page.title=Stopping and Restarting an Activity
+parent.title=Managing the Activity Lifecycle
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Pausing and Resuming an Activity
+previous.link=pausing.html
+next.title=Recreating an Activity
+next.link=recreating.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#Stop">Stop Your Activity</a></li>
+ <li><a href="#Start">Start/Restart Your Activity</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
+ </li>
+ </ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip"
+class="button">Download the demo</a>
+ <p class="filename">ActivityLifecycle.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>Properly stopping and restarting your activity is an important process in the activity lifecycle
+that ensures your users perceive that your app is always alive and doesn't loose their progress.
+There are a few of key scenarios in which your activity is stopped and restarted:</p>
+
+<ul>
+ <li>The user opens the Recent Apps window and switches from your app to another app. The
+activity in your app that's currently in the foreground is stopped. If the user returns to your
+app from the Home screen launcher icon or the Recent Apps window, the activity restarts.</li>
+ <li>The user performs an action in your app that starts a new activity. The current activity
+is stopped when the second activity is created. If the user then presses the <em>Back</em>
+button, the first activity is restarted.</li>
+ <li>The user receives a phone call while using your app on his or her phone.</li>
+</ul>
+
+<p>The {@link android.app.Activity} class provides two lifecycle methods, {@link
+android.app.Activity#onStop()} and {@link android.app.Activity#onRestart()}, which allow you to
+specifically handle how your activity handles being stopped and restarted. Unlike the paused state,
+which identifies a partial UI obstruction, the stopped state guarantees that the UI is no longer
+visible and the user's focus is in a separate activity (or an entirely separate app).</p>
+
+<p class="note"><strong>Note:</strong> Because the system retains your {@link android.app.Activity}
+instance in system memory when it is stopped, it's possible that you don't need to implement the
+{@link android.app.Activity#onStop()} and {@link android.app.Activity#onRestart()} (or even {@link
+android.app.Activity#onStart()} methods at all. For most activities that are relatively simple, the
+activity will stop and restart just fine and you might only need to use {@link
+android.app.Activity#onPause()} to pause ongoing actions and disconnect from system resources.</p>
+
+<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" />
+<p class="img-caption"><strong>Figure 1.</strong> When the user leaves your activity, the system
+calls {@link android.app.Activity#onStop onStop()} to stop the activity (1). If the user returns
+while the activity is stopped, the system calls {@link android.app.Activity#onRestart onRestart()}
+(2), quickly followed by {@link android.app.Activity#onStart onStart()} (3) and {@link
+android.app.Activity#onResume()} (4). Notice that no matter what scenario causes the activity to
+stop, the system always calls {@link android.app.Activity#onPause onPause()} before calling {@link
+android.app.Activity#onStop onStop()}.</p>
+
+
+
+<h2 id="Stop">Stop Your Activity</h2>
+
+<p>When your activity receives a call to the {@link android.app.Activity#onStop()} method, it's no
+longer visible and should release almost all resources that aren't needed while the user is not
+using it. Once your activity is stopped, the system might destroy the instance if it needs to
+recover system memory. In extreme cases, the system might simply kill your app process without
+calling the activity's final {@link android.app.Activity#onDestroy()} callback, so it's important
+you use {@link android.app.Activity#onStop()} to release resources that might leak memory.</p>
+
+<p>Although the {@link android.app.Activity#onPause onPause()} method is called before
+{@link android.app.Activity#onStop()}, you should use {@link android.app.Activity#onStop onStop()}
+to perform larger, more CPU intensive shut-down operations, such as writing information to a
+database.</p>
+
+<p>For example, here's an implementation of {@link android.app.Activity#onStop onStop()} that
+saves the contents of a draft note to persistent storage:</p>
+
+<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a
+separate thread but that's too complicated to show here. -->
+<pre>
+@Override
+protected void onStop() {
+ super.onStop(); // Always call the superclass method first
+
+ // Save the note's current draft, because the activity is stopping
+ // and we want to be sure the current note progress isn't lost.
+ ContentValues values = new ContentValues();
+ values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
+ values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
+
+ getContentResolver().update(
+ mUri, // The URI for the note to update.
+ values, // The map of column names and new values to apply to them.
+ null, // No SELECT criteria are used.
+ null // No WHERE columns are used.
+ );
+}
+</pre>
+
+<p>When your activity is stopped, the {@link android.app.Activity} object is kept resident in memory
+and is recalled when the activity resumes. You don’t need to re-initialize components that were
+created during any of the callback methods leading up to the Resumed state. The system also
+keeps track of the current state for each {@link android.view.View} in the layout, so if the user
+entered text into an {@link android.widget.EditText} widget, that content is retained so you don't
+need to save and restore it.</p>
+
+<p class="note"><strong>Note:</strong> Even if the system destroys your activity while it's stopped,
+it still retains the state of the {@link android.view.View} objects (such as text in an {@link
+android.widget.EditText}) in a {@link android.os.Bundle} (a blob of key-value pairs) and restores
+them if the user navigates back to the same instance of the activity (the <a
+href="recreating.html">next lesson</a> talks more about using a {@link android.os.Bundle} to save
+other state data in case your activity is destroyed and recreated).</p>
+
+
+
+<h2 id="Start">Start/Restart Your Activity</h2>
+
+<p>When your activity comes back to the foreground from the stopped state, it receives a call to
+{@link android.app.Activity#onRestart()}. The system also calls the {@link
+android.app.Activity#onStart()} method, which happens every time your activity becomes visible
+(whether being restarted or created for the first time). The {@link
+android.app.Activity#onRestart()} method, however, is called only when the activity resumes from the
+stopped state, so you can use it to perform special restoration work that might be necessary only if
+the activity was previously stopped, but not destroyed.</p>
+
+<p>It's uncommon that an app needs to use {@link android.app.Activity#onRestart()} to restore
+the activity's state, so there aren't any guidelines for this method that apply to
+the general population of apps. However, because your {@link android.app.Activity#onStop()}
+method should essentially clean up all your activity's resources, you'll need to re-instantiate them
+when the activity restarts. Yet, you also need to instantiate them when your activity is created
+for the first time (when there's no existing instance of the activity). For this reason, you
+should usually use the {@link android.app.Activity#onStart()} callback method as the counterpart
+to the {@link android.app.Activity#onStop()} method, because the system calls {@link
+android.app.Activity#onStart()} both when it creates your activity and when it restarts the
+activity from the stopped state.</p>
+
+<p>For example, because the user might have been away from your app for a long time before
+coming back it, the {@link android.app.Activity#onStart()} method is a good place to verify that
+required system features are enabled:</p>
+
+<pre>
+@Override
+protected void onStart() {
+ super.onStart(); // Always call the superclass method first
+
+ // The activity is either being restarted or started for the first time
+ // so this is where we should make sure that GPS is enabled
+ LocationManager locationManager =
+ (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+ boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ if (!gpsEnabled) {
+ // Create a dialog here that requests the user to enable GPS, and use an intent
+ // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
+ // to take the user to the Settings screen to enable GPS when they click "OK"
+ }
+}
+
+@Override
+protected void onRestart() {
+ super.onRestart(); // Always call the superclass method first
+
+ // Activity being restarted from stopped state
+}
+</pre>
+
+
+
+
+<p>When the system destroys your activity, it calls the {@link android.app.Activity#onDestroy()}
+method for your {@link android.app.Activity}. Because you should generally have released most of
+your resources with {@link android.app.Activity#onStop()}, by the time you receive a call to {@link
+android.app.Activity#onDestroy()}, there's not much that most apps need to do. This method is your
+last chance to clean out resources that could lead to a memory leak, so you should be sure that
+additional threads are destroyed and other long-running actions like method tracing are also
+stopped.</p>
+
diff --git a/docs/html/training/basics/firstapp/building-ui.jd b/docs/html/training/basics/firstapp/building-ui.jd
index 847163a..dae70a2 100644
--- a/docs/html/training/basics/firstapp/building-ui.jd
+++ b/docs/html/training/basics/firstapp/building-ui.jd
@@ -56,7 +56,8 @@
different screen sizes. For example, you can create two versions of a layout and tell
the system to use one on "small" screens and the other on "large" screens. For more information,
see the class about <a
-href="{@docRoot}training/supporting-hardware/index.html">Supporting Various Hardware</a>.</p>
+href="{@docRoot}training/basics/supporting-devices/index.html">Supporting Different
+Hardware</a>.</p>
</div>
</div>
diff --git a/docs/html/training/basics/firstapp/index.jd b/docs/html/training/basics/firstapp/index.jd
index a95ed8e..9ff5b18 100644
--- a/docs/html/training/basics/firstapp/index.jd
+++ b/docs/html/training/basics/firstapp/index.jd
@@ -1,4 +1,5 @@
page.title=Building Your First App
+page.metaDescription=If you're new to Android app development, this where you should begin. This series of lessons shows you how to create a new project, build a simple app, and run it on a device or emulator.
trainingnavtop=true
startpage=true
diff --git a/docs/html/training/basics/firstapp/running-app.jd b/docs/html/training/basics/firstapp/running-app.jd
index 2398fa0..43b8983 100644
--- a/docs/html/training/basics/firstapp/running-app.jd
+++ b/docs/html/training/basics/firstapp/running-app.jd
@@ -35,7 +35,7 @@
</div>
-<p>If you followed the <a href="{@docRoot}creating-project.html">previous lesson</a> to create an
+<p>If you followed the <a href="creating-project.html">previous lesson</a> to create an
Android project, it includes a default set of "Hello World" source files that allow you to
run the app right away.</p>
diff --git a/docs/html/training/basics/firstapp/starting-activity.jd b/docs/html/training/basics/firstapp/starting-activity.jd
index 16a6fd8..c548c1d 100644
--- a/docs/html/training/basics/firstapp/starting-activity.jd
+++ b/docs/html/training/basics/firstapp/starting-activity.jd
@@ -128,7 +128,7 @@
the desired component, but allows any app installed on the device to respond to the intent
as long as it satisfies the meta-data specifications for the action that's specified in various
{@link android.content.Intent} parameters. For more informations, see the class about <a
-href="{@docRoot}training/intents/index.html">Interacting with Other Apps</a>.</p>
+href="{@docRoot}training/basics/intents/index.html">Interacting with Other Apps</a>.</p>
</div>
</div>
@@ -301,7 +301,8 @@
<p>To learn more about building Android apps, continue to follow the
basic training classes. The next class is <a
-href="{@docRoot}training/activity-lifecycle/index.html">Managing the Activity Lifecycle</a>.</p>
+href="{@docRoot}training/basics/activity-lifecycle/index.html">Managing the Activity
+Lifecycle</a>.</p>
diff --git a/docs/html/training/basics/fragments/communicating.jd b/docs/html/training/basics/fragments/communicating.jd
new file mode 100644
index 0000000..e3e308f
--- /dev/null
+++ b/docs/html/training/basics/fragments/communicating.jd
@@ -0,0 +1,179 @@
+page.title=Communicating with Other Fragments
+parent.title=Building a Dynamic UI with Fragments
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Building a Flexible UI
+previous.link=fragment-ui.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+ <h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#DefineInterface">Define an Interface</a></li>
+ <li><a href="#Implement">Implement the Interface</a></li>
+ <li><a href="#Deliver">Deliver a Message to a Fragment</a></li>
+</ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+ </ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/FragmentBasics.zip"
+class="button">Download the sample</a>
+ <p class="filename">FragmentBasics.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>In order to reuse the Fragment UI components, you should build each as a completely
+self-contained, modular component that defines its own layout and behavior. Once you
+have defined these reusable Fragments, you can associate them with an Activity and
+connect them with the application logic to realize the overall composite UI.</p>
+
+<p>Often you will want one Fragment to communicate with another, for example to change
+the content based on a user event. All Fragment-to-Fragment communication is done
+through the associated Activity. Two Fragments should never communicate directly.</p>
+
+
+<h2 id="DefineInterface">Define an Interface</h2>
+
+<p>To allow a Fragment to communicate up to its Activity, you can define an interface
+in the Fragment class and implement it within the Activity. The Fragment captures
+the interface implementation during its onAttach() lifecycle method and can then call
+the Interface methods in order to communicate with the Activity.</p>
+
+<p>Here is an example of Fragment to Activity communication:</p>
+
+<pre>
+public class HeadlinesFragment extends ListFragment {
+ OnHeadlineSelectedListener mCallback;
+
+ // Container Activity must implement this interface
+ public interface OnHeadlineSelectedListener {
+ public void onArticleSelected(int position);
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ // This makes sure that the container activity has implemented
+ // the callback interface. If not, it throws an exception
+ try {
+ mCallback = (OnHeadlineSelectedListener) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString()
+ + " must implement OnHeadlineSelectedListener");
+ }
+ }
+
+ ...
+}
+</pre>
+
+<p>Now the fragment can deliver messages to the activity by calling the {@code
+onArticleSelected()} method (or other methods in the interface) using the {@code mCallback}
+instance of the {@code OnHeadlineSelectedListener} interface.</p>
+
+<p>For example, the following method in the fragment is called when the user clicks on a list
+item. The fragment uses the callback interface to deliver the event to the parent activity.</p>
+
+<pre>
+ @Override
+ public void onListItemClick(ListView l, View v, int position, long id) {
+ // Send the event to the host activity
+ mCallback.onArticleSelected(position);
+ }
+</pre>
+
+
+
+<h2 id="Implement">Implement the Interface</h2>
+
+<p>In order to receive event callbacks from the fragment, the activity that hosts it must
+implement the interface defined in the fragment class.</p>
+
+<p>For example, the following activity implements the interface from the above example.</p>
+
+<pre>
+public static class MainActivity extends Activity
+ implements HeadlinesFragment.OnHeadlineSelectedListener{
+ ...
+
+ public void onArticleSelected(Uri articleUri) {
+ // The user selected the headline of an article from the HeadlinesFragment
+ // Do something here to display that article
+ }
+}
+</pre>
+
+
+
+<h2 id="Deliver">Deliver a Message to a Fragment</h2>
+
+<p>The host activity can deliver messages to a fragment by capturing the {@link
+android.support.v4.app.Fragment} instance
+with {@link android.support.v4.app.FragmentManager#findFragmentById findFragmentById()}, then
+directly call the fragment's public methods.</p>
+
+<p>For instance, imagine that the activity shown above may contain another fragment that's used to
+display the item specified by the data returned in the above callback method. In this case,
+the activity can pass the information received in the callback method to the other fragment that
+will display the item:</p>
+
+<pre>
+public static class MainActivity extends Activity
+ implements HeadlinesFragment.OnHeadlineSelectedListener{
+ ...
+
+ public void onArticleSelected(int position) {
+ // The user selected the headline of an article from the HeadlinesFragment
+ // Do something here to display that article
+
+ ArticleFragment articleFrag = (ArticleFragment)
+ getSupportFragmentManager().findFragmentById(R.id.article_fragment);
+
+ if (articleFrag != null) {
+ // If article frag is available, we're in two-pane layout...
+
+ // Call a method in the ArticleFragment to update its content
+ articleFrag.updateArticleView(position);
+ } else {
+ // Otherwise, we're in the one-pane layout and must swap frags...
+
+ // Create fragment and give it an argument for the selected article
+ ArticleFragment newFragment = new ArticleFragment();
+ Bundle args = new Bundle();
+ args.putInt(ArticleFragment.ARG_POSITION, position);
+ newFragment.setArguments(args);
+
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+
+ // Replace whatever is in the fragment_container view with this fragment,
+ // and add the transaction to the back stack so the user can navigate back
+ transaction.replace(R.id.fragment_container, newFragment);
+ transaction.addToBackStack(null);
+
+ // Commit the transaction
+ transaction.commit();
+ }
+ }
+}
+</pre>
+
+
+
+
+
+
+
+
+
diff --git a/docs/html/training/basics/fragments/creating.jd b/docs/html/training/basics/fragments/creating.jd
new file mode 100644
index 0000000..c4a9b46
--- /dev/null
+++ b/docs/html/training/basics/fragments/creating.jd
@@ -0,0 +1,155 @@
+page.title=Creating a Fragment
+parent.title=Building a Dynamic UI with Fragments
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Using the Android Support Library
+previous.link=support-lib.html
+next.title=Building a Flexible UI
+next.link=fragment-ui.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+
+ <h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#Create">Create a Fragment Class</a></li>
+ <li><a href="#AddInLayout">Add a Fragment to an Activity using XML</a></li>
+</ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+ </ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/FragmentBasics.zip"
+class="button">Download the sample</a>
+ <p class="filename">FragmentBasics.zip</p>
+</div>
+
+ </div>
+</div>
+
+<p>You can think of a fragment as a modular section of an activity, which has its own lifecycle,
+receives its own input events, and which you can add or remove while the activity is running (sort
+of like a "sub activity" that you can reuse in different activities). This lesson shows how to
+extend the {@link android.support.v4.app.Fragment} class using the Support Library so your app
+remains compatible with devices running system versions as old as Android 1.6.</p>
+
+<p class="note"><strong>Note:</strong> If you decide for other reasons that the minimum
+API level your app requires is 11 or higher, you don't need to use the Support
+Library and can instead use the framework's built in {@link android.app.Fragment} class and related
+APIs. Just be aware that this lesson is focused on using the APIs from the Support Library, which
+use a specific package signature and sometimes slightly different API names than the versions
+included in the platform.</p>
+
+
+
+<h2 id="Create">Create a Fragment Class</h2>
+
+<p>To create a fragment, extend the {@link android.support.v4.app.Fragment} class, then override
+key lifecycle methods to insert your app logic, similar to the way you would with an {@link
+android.app.Activity} class.</p>
+
+<p>One difference when creating a {@link android.support.v4.app.Fragment} is that you must use the
+{@link android.support.v4.app.Fragment#onCreateView onCreateView()} callback to define the layout.
+In fact, this is the only callback you need in order to get a fragment running. For
+example, here's a simple fragment that specifies its own layout:</p>
+
+<pre>
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+public class ArticleFragment extends Fragment {
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.article_view, container, false);
+ }
+}
+</pre>
+
+<p>Just like an activity, a fragment should implement other lifecycle callbacks that allow you to
+manage its state as it is added or removed from the activity and as the activity transitions
+between its lifecycle states. For instance, when the activity's {@link
+android.app.Activity#onPause()} method is called, any fragments in the activity also receive a call
+to {@link android.support.v4.app.Fragment#onPause()}.</p>
+
+<p>More information about the fragment lifecycle and callback methods is available in the <a
+href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+
+
+
+<h2 id="AddInLayout">Add a Fragment to an Activity using XML</h2>
+
+<p>While fragments are reusable, modular UI components, each instance of a {@link
+android.support.v4.app.Fragment} class must be associated with a parent {@link
+android.support.v4.app.FragmentActivity}. You can achieve this association by defining each
+fragment within your activity layout XML file.</p>
+
+<p class="note"><strong>Note:</strong> {@link android.support.v4.app.FragmentActivity} is a
+special activity provided in the Support Library to handle fragments on system versions older than
+API level 11. If the lowest system version you support is API level 11 or higher, then you can use a
+regular {@link android.app.Activity}.</p>
+
+<p>Here is an example layout file that adds two fragments to an activity when the device
+screen is considered "large" (specified by the <code>large</code> qualifier in the directory
+name).</p>
+
+<p><code>res/layout-large/news_articles.xml:</code></p>
+<pre>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <fragment android:name="com.example.android.fragments.HeadlinesFragment"
+ android:id="@+id/headlines_fragment"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" />
+
+ <fragment android:name="com.example.android.fragments.ArticleFragment"
+ android:id="@+id/article_fragment"
+ android:layout_weight="2"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
+</pre>
+
+<p class="note"><strong>Tip:</strong> For more information about creating layouts for different
+screen sizes, read <a href="{@docRoot}training/multiscreen/screensizes.html">Supporting Different
+Screen Sizes</a>.</p>
+
+<p>Here's how an activity applies this layout:</p>
+
+<pre>
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+public class MainActivity extends FragmentActivity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.news_articles);
+ }
+}
+</pre>
+
+
+<p class="note"><strong>Note:</strong> When you add a fragment to an activity layout by defining
+the fragment in the layout XML file, you <em>cannot</em> remove the fragment at runtime. If you plan
+to swap your fragments in and out during user interaction, you must add the fragment to the activity
+when the activity first starts, as shown in the next lesson.</p>
+
+
+
diff --git a/docs/html/training/basics/fragments/fragment-ui.jd b/docs/html/training/basics/fragments/fragment-ui.jd
new file mode 100644
index 0000000..f906f46
--- /dev/null
+++ b/docs/html/training/basics/fragments/fragment-ui.jd
@@ -0,0 +1,196 @@
+page.title=Building a Flexible UI
+parent.title=Building a Dynamic UI with Fragments
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Create a Fragment
+previous.link=creating.html
+next.title=Communicating with Other Fragments
+next.link=communicating.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+ <h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#AddAtRuntime">Add a Fragment to an Activity at Runtime</a></li>
+ <li><a href="#Replace">Replace One Fragment with Another</a></li>
+</ol>
+
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+ <li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">Supporting Tablets and
+Handsets</a></li>
+ </ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/FragmentBasics.zip"
+class="button">Download the sample</a>
+ <p class="filename">FragmentBasics.zip</p>
+</div>
+
+ </div>
+</div>
+
+
+<p>When designing your application to support a wide range of screen sizes, you can reuse your
+fragments in different layout configurations to optimize the user experience based on the available
+screen space.</p>
+
+<p>For example, on a handset device it might be appropriate to display just one fragment at a time
+for a single-pane user interface. Conversely, you may want to set fragments side-by-side on a
+tablet which has a wider screen size to display more information to the user.</p>
+
+<img src="{@docRoot}images/training/basics/fragments-screen-mock.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> Two fragments, displayed in different
+configurations for the same activity on different screen sizes. On a large screen, both fragment
+fit side by side, but on a handset device, only one fragment fits at a time so the fragments must
+replace each other as the user navigates.</p>
+
+<p>The {@link android.support.v4.app.FragmentManager} class provides methods that allow you to add,
+remove, and replace fragments to an activity at runtime in order to create a dynamic experience.</p>
+
+
+
+<h2 id="AddAtRuntime">Add a Fragment to an Activity at Runtime</h2>
+
+<p>Rather than defining the fragments for an activity in the layout file—as shown in the
+<a href="creating.html">previous lesson</a> with the {@code <fragment>} element—you can add
+a fragment to the activity during the activity runtime. This is necessary
+if you plan to change fragments during the life of the activity.</p>
+
+<p>To perform a transaction such as add or
+remove a fragment, you must use the {@link android.support.v4.app.FragmentManager} to create a
+{@link android.support.v4.app.FragmentTransaction}, which provides APIs to add, remove, replace,
+and perform other fragment transactions.</p>
+
+<p>If your activity allows the fragments to be removed and replaced, you should add the
+initial fragment(s) to the activity during the activity's
+{@link android.app.Activity#onCreate onCreate()} method.</p>
+
+<p>An important rule when dealing with fragments—especially those that you add at
+runtime—is that the fragment must have a container {@link android.view.View} in the layout in
+which the fragment's layout will reside.</p>
+
+<p>The following layout is an alternative to the layout shown in the <a
+href="creating.html">previous lesson</a> that shows only one fragment at a time. In order to replace
+one fragment with another, the activity's layout
+includes an empty {@link android.widget.FrameLayout} that acts as the fragment container.</p>
+
+<p>Notice that the filename is the same as the layout file in the previous lesson, but the layout
+directory does <em>not</em> have the <code>large</code> qualifier, so this layout is used when the
+device screen is smaller than <em>large</em> because the screen does not fit both fragments at
+the same time.</p>
+
+<p><code>res/layout/news_articles.xml:</code></p>
+<pre>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</pre>
+
+<p>Inside your activity, call {@link
+android.support.v4.app.FragmentActivity#getSupportFragmentManager()} to get a {@link
+android.support.v4.app.FragmentManager} using the Support Library APIs. Then call {@link
+android.support.v4.app.FragmentManager#beginTransaction} to create a {@link
+android.support.v4.app.FragmentTransaction} and call {@link
+android.support.v4.app.FragmentTransaction#add add()} to add a fragment.</p>
+
+<p>You can perform multiple fragment transaction for the activity using the same {@link
+android.support.v4.app.FragmentTransaction}. When you're ready to make the changes, you must call
+{@link android.support.v4.app.FragmentTransaction#commit()}.</p>
+
+<p>For example, here's how to add a fragment to the previous layout:</p>
+
+<pre>
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+public class MainActivity extends FragmentActivity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.news_articles);
+
+ // Check that the activity is using the layout version with
+ // the fragment_container FrameLayout
+ if (findViewById(R.id.fragment_container) != null) {
+
+ // However, if we're being restored from a previous state,
+ // then we don't need to do anything and should return or else
+ // we could end up with overlapping fragments.
+ if (savedInstanceState != null) {
+ return;
+ }
+
+ // Create an instance of ExampleFragment
+ HeadlinesFragment firstFragment = new HeadlinesFragment();
+
+ // In case this activity was started with special instructions from an Intent,
+ // pass the Intent's extras to the fragment as arguments
+ firstFragment.setArguments(getIntent().getExtras());
+
+ // Add the fragment to the 'fragment_container' FrameLayout
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.fragment_container, firstFragment).commit();
+ }
+ }
+}
+</pre>
+
+<p>Because the fragment has been added to the {@link android.widget.FrameLayout} container at
+runtime—instead of defining it in the activity's layout with a {@code <fragment>}
+element—the activity can remove the fragment and replace it with a different one.</p>
+
+
+
+<h2 id="Replace">Replace One Fragment with Another</h2>
+
+<p>The procedure to replace a fragment is similar to adding one, but requires the {@link
+android.support.v4.app.FragmentTransaction#replace replace()} method instead of {@link
+android.support.v4.app.FragmentTransaction#add add()}.</p>
+
+<p>Keep in mind that when you perform fragment transactions, such as replace or remove one, it's
+often appropriate to allow the user to navigate backward and "undo" the change. To allow the user
+to navigate backward through the fragment transactions, you must call {@link
+android.support.v4.app.FragmentTransaction#addToBackStack addToBackStack()} before you commit the
+{@link android.support.v4.app.FragmentTransaction}.</p>
+
+<p class="note"><strong>Note:</strong> When you remove or replace a fragment and add the transaction
+to the back stack, the fragment that is removed is stopped (not destroyed). If the user navigates
+back to restore the fragment, it restarts. If you <em>do not</em> add the transaction to the back
+stack, then the fragment is destroyed when removed or replaced.</p>
+
+<p>Example of replacing one fragment with another:</p>
+
+<pre>
+// Create fragment and give it an argument specifying the article it should show
+ArticleFragment newFragment = new ArticleFragment();
+Bundle args = new Bundle();
+args.putInt(ArticleFragment.ARG_POSITION, position);
+newFragment.setArguments(args);
+
+FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+
+// Replace whatever is in the fragment_container view with this fragment,
+// and add the transaction to the back stack so the user can navigate back
+transaction.replace(R.id.fragment_container, newFragment);
+transaction.addToBackStack(null);
+
+// Commit the transaction
+transaction.commit();
+</pre>
+
+<p>The {@link android.support.v4.app.FragmentTransaction#addToBackStack addToBackStack()} method
+takes an optional string parameter that specifies a unique name for the transaction. The name isn't
+needed unless you plan to perform advanced fragment operations using the {@link
+android.support.v4.app.FragmentManager.BackStackEntry} APIs.</p>
+
+
+
+
diff --git a/docs/html/training/basics/fragments/index.jd b/docs/html/training/basics/fragments/index.jd
new file mode 100644
index 0000000..dcdcd31
--- /dev/null
+++ b/docs/html/training/basics/fragments/index.jd
@@ -0,0 +1,74 @@
+page.title=Building a Dynamic UI with Fragments
+
+trainingnavtop=true
+startpage=true
+next.title=Using the Android Support Library
+next.link=support-lib.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+
+<h2>Dependencies and prerequisites</h2>
+<ul>
+ <li>Basic knowledge of the Activity lifecycle (see <a
+href="{@docRoot}training/basics/activity-lifecycle/index.html">Managing the Activity
+Lifecycle</a>)</li>
+ <li>Experience building <a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML
+layouts</a></li>
+</ul>
+
+
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+ <li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">Supporting Tablets and
+Handsets</a></li>
+</ul>
+
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/FragmentBasics.zip"
+class="button">Download the sample</a>
+ <p class="filename">FragmentBasics.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>To create a dynamic and multi-pane user interface on Android, you need to encapsulate
+UI components and activity behaviors into modules that you can swap into and out of
+your activities. You can create these modules with the {@link android.app.Fragment} class, which
+behaves somewhat like a nested activity that can define its own layout and manage its own
+lifecycle.</p>
+
+<p>When a fragment specifies its own layout, it can be configured in different combinations with
+other fragments inside an activity to modify your layout configuration for different screen
+sizes (a small screen might show one fragment at a time, but a large screen can show two or
+more).</p>
+
+<p>This class shows you how to create a dynamic user experience with fragments and optimize your
+app's user experience for devices with different screen sizes, all while continuing to support
+devices running versions as old as Android 1.6.</p>
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><b><a href="support-lib.html">Using the Android Support Library</a></b></dt>
+ <dd>Learn how to use more recent framework APIs in earlier versions of Android by bundling
+the Android Support Library into your app.</dd>
+ <dt><b><a href="creating.html">Creating a Fragment</a></b></dt>
+ <dd>Learn how to build a fragment and implement basic behaviors within its callback
+methods.</dd>
+ <dt><b><a href="fragment-ui.html">Building a Flexible UI</a></b></dt>
+ <dd>Learn how to build your app with layouts that provide different fragment configurations for
+different screens.</dd>
+ <dt><b><a href="communicating.html">Communicating with Other Fragments</a></b></dt>
+ <dd>Learn how to set up communication paths from a fragment to the activity and other
+fragments.</dd>
+</dl>
+
diff --git a/docs/html/training/basics/fragments/support-lib.jd b/docs/html/training/basics/fragments/support-lib.jd
new file mode 100644
index 0000000..e2166f5
--- /dev/null
+++ b/docs/html/training/basics/fragments/support-lib.jd
@@ -0,0 +1,85 @@
+page.title=Using the Support Library
+parent.title=Building a Dynamic UI with Fragments
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Creating a Fragment
+next.link=creating.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#Setup">Set Up Your Project With the Support Library</a></li>
+ <li><a href="#Apis">Import the Support Library APIs</a></li>
+ </ol>
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}sdk/compatibility-library.html">Support Library</a></li>
+ </ul>
+ </div>
+</div>
+
+<p>The Android <a href="{@docRoot}sdk/compatibility-library.html">Support Library</a> provides a JAR
+file with an API library that allow you to use some of the more recent Android APIs in your app
+while running on earlier versions of Android. For instance, the Support Library provides a version
+of the {@link android.app.Fragment} APIs that you can use on Android 1.6 (API level 4) and
+higher.</p>
+
+<p>This lesson shows how to set up your app to use the Support Library in order to use fragments
+to build a dynamic app UI.</p>
+
+
+<h2 id="Setup">Set Up Your Project With the Support Library</h2>
+
+<div class="figure" style="width:527px">
+<img src="{@docRoot}images/training/basics/sdk-manager.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> The Android SDK Manager with the
+Android Support package selected.</p>
+</div>
+
+<p>To set up your project:</p>
+
+<ol>
+ <li>Downlad the Android Support package using the SDK Manager</li>
+
+ <li>Create a <code>libs</code> directory at the top level of your Android project.</li>
+ <li>Locate the JAR file for the library you want to use and copy it into the <code>libs/</code>
+directory.
+<p>For example, the library that supports API level 4 and up is located at
+<code><sdk>/extras/android/support/v4/android-support-v4.jar</code>.</p></li>
+ <li>Update your manifest file to set the minimum API level to <code>4</code> and the target
+API level to the latest release:
+ <pre><uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15" /></pre>
+ </li>
+</ol>
+
+
+<h2 id="Apis">Import the Support Library APIs</h2>
+
+<p>The Support Library includes a variety of APIs that were either added in recent versions of
+Android or don't exist in the platform at all and merely provide additional support to you when
+developing specific application features.</p>
+
+<p>You can find all the API reference documentation for the Support Library in the
+platform docs at {@link android.support.v4.app android.support.v4.*}.</p>
+
+<div class="warning"><p><strong>Warning:</strong> To be sure that you don't accidentally use new
+APIs on an older system version, be certain that you import the {@link
+android.support.v4.app.Fragment} class and related APIs from the {@link android.support.v4.app}
+package:</p>
+<pre>
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+...
+</pre>
+</div>
+
+
+<p>When creating an activity that hosts fragments while using the Support Library, you must also
+extend the {@link android.support.v4.app.FragmentActivity} class instead of the traditional {@link
+android.app.Activity} class. You'll see sample code for the fragment and activity in the next
+lesson.</p>
+
diff --git a/docs/html/training/basics/intents/sending.jd b/docs/html/training/basics/intents/sending.jd
index a71c8f9..bfd8f9b 100644
--- a/docs/html/training/basics/intents/sending.jd
+++ b/docs/html/training/basics/intents/sending.jd
@@ -17,6 +17,7 @@
<li><a href="#Build">Build an Implicit Intent</a></li>
<li><a href="#Verify">Verify There is an App to Receive the Intent</a></li>
<li><a href="#StartActivity">Start an Activity with the Intent</a></li>
+ <li><a href="#AppChooser">Show an App Chooser</a></li>
</ol>
<h2>You should also read</h2>
@@ -208,4 +209,45 @@
+<h2 id="AppChooser">Show an App Chooser</h2>
+
+<div class="figure" style="width:200px">
+ <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" />
+ <p class="img-caption"><strong>Figure 2.</strong> Example of the chooser dialog that appears
+when you use {@link android.content.Intent#createChooser createChooser()} to ensure
+that the user is always shown a list of apps that respond to your intent.</p>
+</div>
+
+<p>Notice that when you start an activity by passing your {@link android.content.Intent} to {@link
+android.app.Activity#startActivity startActivity()} and there is more than one app that responds to
+the intent, the user can select which app to use by default (by selecting a checkbox at the bottom
+of the dialog; see figure 1). This is nice when performing an action for which the user
+generally wants to use the same app every time, such as when opening a web page (users
+likely use just one web browser) or taking a photo (users likely prefer one camera). However, if
+the action to be performed could be handled by multiple apps and the user might
+prefer a different app each time—such as a "share" action, for which users might have several
+apps through which they might share an item—you should explicitly show a chooser dialog,
+which forces the user to select which app to use for the action every time (the user cannot select a
+default app for the action).</p>
+
+<p>To show the chooser, create an {@link android.content.Intent} using {@link
+android.content.Intent#createChooser createChooser()} and pass it to {@link
+android.app.Activity#startActivity startActivity()}. For example:</p>
+
+<pre>
+Intent intent = new Intent(Intent.ACTION_SEND);
+...
+
+// Always use string resources for UI text. This says something like "Share this photo with"
+String title = getResources().getText(R.string.chooser_title);
+// Create and start the chooser
+Intent chooser = Intent.createChooser(intent, title);
+startActivity(chooser);
+</pre>
+
+<p>This displays a dialog with a list of apps that respond to the intent passed to the {@link
+android.content.Intent#createChooser createChooser()} method and uses the supplied text as the
+dialog title.</p>
+
+
diff --git a/docs/html/training/location/currentlocation.jd b/docs/html/training/basics/location/currentlocation.jd
similarity index 91%
rename from docs/html/training/location/currentlocation.jd
rename to docs/html/training/basics/location/currentlocation.jd
index 4692530..29b0fa6 100644
--- a/docs/html/training/location/currentlocation.jd
+++ b/docs/html/training/basics/location/currentlocation.jd
@@ -143,7 +143,15 @@
<h2 id="TaskTerminateUpdates">Terminate Location Updates</h2>
-<p>When you are done with using location data, you should terminate location update to reduce unnecessary consumption of power and network bandwidth. For example, if the user navigates away from an activity where location updates are displayed, you should stop location update by calling {@link android.location.LocationManager#removeUpdates(android.location.LocationListener) removeUpdates()} in {@link android.app.Activity#onStop()}. ({@link android.app.Activity#onStop()} is called when the activity is no longer visible. If you want to learn more about activity lifecycle, read up on the <a href="/training/basic-activity-lifecycle/stopping.html">Starting and Stopping an Activity</a> lesson.</p>
+<p>When you are done with using location data, you should terminate location update to reduce
+unnecessary consumption of power and network bandwidth. For example, if the user navigates away
+from an activity where location updates are displayed, you should stop location update by calling
+{@link android.location.LocationManager#removeUpdates(android.location.LocationListener)
+removeUpdates()} in {@link android.app.Activity#onStop()}. ({@link android.app.Activity#onStop()}
+is called when the activity is no longer visible. If you want to learn more about activity
+lifecycle, read up on the <a
+href="{@docRoot}training/basics/activity-lifecycle/stopping.html">Stopping and Restarting an
+Activity</a> lesson.</p>
<pre>
protected void onStop() {
diff --git a/docs/html/training/location/geocoding.jd b/docs/html/training/basics/location/geocoding.jd
similarity index 100%
rename from docs/html/training/location/geocoding.jd
rename to docs/html/training/basics/location/geocoding.jd
diff --git a/docs/html/training/location/index.jd b/docs/html/training/basics/location/index.jd
similarity index 100%
rename from docs/html/training/location/index.jd
rename to docs/html/training/basics/location/index.jd
diff --git a/docs/html/training/location/locationmanager.jd b/docs/html/training/basics/location/locationmanager.jd
similarity index 100%
rename from docs/html/training/location/locationmanager.jd
rename to docs/html/training/basics/location/locationmanager.jd
diff --git a/docs/html/training/cloudsync/aesync.jd b/docs/html/training/cloudsync/aesync.jd
new file mode 100644
index 0000000..c60d28b
--- /dev/null
+++ b/docs/html/training/cloudsync/aesync.jd
@@ -0,0 +1,432 @@
+page.title=Syncing with App Engine
+parent.title=Syncing to the Cloud
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Using the Backup API
+next.link=backupapi.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you how to</h2>
+<ol>
+ <li><a href="#prepare">Prepare Your Environment</a></li>
+ <li><a href="#project">Create Your Project</a></li>
+ <li><a href="#data">Create the Data Layer</a></li>
+ <li><a href="#persistence">Create the Persistence Layer</a></li>
+ <li><a href="#androidapp">Query and Update from the Android App</a></li>
+ <li><a href="#serverc2dm">Configure the C2DM Server-Side</a></li>
+ <li><a href="#clientc2dm">Configure the C2DM Client-Side</a></li>
+</ol>
+<h2>You should also read</h2>
+ <ul>
+ <li><a
+ href="http://developers.google.com/appengine/">App Engine</a></li>
+ <li><a href="http://code.google.com/android/c2dm/">Android Cloud to Device
+ Messaging Framework</a></li>
+ </ul>
+<h2>Try it out</h2>
+
+<p>This lesson uses the Cloud Tasks sample code, originally shown at the
+<a href="http://www.youtube.com/watch?v=M7SxNNC429U">Android + AppEngine: A Developer's Dream Combination</a>
+talk at Google I/O. You can use the sample application as a source of reusable code for your own
+application, or simply as a reference for how the Android and cloud pieces of the overall
+application fit together. You can also build the sample application and see how it runs
+on your own device or emulator.</p>
+<p>
+ <a href="http://code.google.com/p/cloud-tasks-io/" class="button">Cloud Tasks
+ App</a>
+</p>
+
+</div>
+</div>
+
+<p>Writing an app that syncs to the cloud can be a challenge. There are many little
+details to get right, like server-side auth, client-side auth, a shared data
+model, and an API. One way to make this much easier is to use the Google Plugin
+for Eclipse, which handles a lot of the plumbing for you when building Android
+and App Engine applications that talk to each other. This lesson walks you through building such a project.</p>
+
+<p>Following this lesson shows you how to:</p>
+<ul>
+ <li>Build Android and Appengine apps that can communicate with each other</li>
+ <li>Take advantage of Cloud to Device Messaging (C2DM) so your Android app doesn't have to poll for updates</li>
+</ul>
+
+<p>This lesson focuses on local development, and does not cover distribution
+(i.e, pushing your App Engine app live, or publishing your Android App to
+market), as those topics are covered extensively elsewhere.</p>
+
+<h2 id="prepare">Prepare Your Environment</h2>
+<p>If you want to follow along with the code example in this lesson, you must do
+the following to prepare your development environment:</p>
+<ul>
+<li>Install the <a href="http://code.google.com/eclipse/">Google Plugin for
+ Eclipse.</a></li>
+<li>Install the <a
+ href="http://code.google.com/webtoolkit/download.html">GWT SDK</a> and the <a
+ href="http://code.google.com/appengine/">Java App Engine SDK</a>. The <a
+ href="http://code.google.com/eclipse/docs/getting_started.html">Quick Start
+ Guide</a> shows you how to install these components.</li>
+<li>Sign up for <a href="http://code.google.com/android/c2dm/signup.html">C2DM
+ access</a>. We strongly recommend <a
+ href="https://accounts.google.com/SignUp">creating a new Google account</a> specifically for
+connecting to C2DM. The server component in this lesson uses this <em>role
+ account</em> repeatedly to authenticate with Google servers.
+</li>
+</ul>
+
+<h2 id="project">Create Your Projects</h2>
+<p>After installing the Google Plugin for Eclipse, notice that a new kind of Android project
+exists when you create a new Eclipse project: The <strong>App Engine Connected
+ Android Project</strong> (under the <strong>Google</strong> project category).
+A wizard guides you through creating this project,
+during the course of which you are prompted to enter the account credentials for the role
+account you created.</p>
+
+<p class="note"><strong>Note:</strong> Remember to enter the credentials for
+your <i>role account</i> (the one you created to access C2DM services), not an
+account you'd log into as a user, or as an admin.</p>
+
+<p>Once you're done, you'll see two projects waiting for you in your
+workspace—An Android application and an App Engine application. Hooray!
+These two applications are already fully functional— the wizard has
+created a sample application which lets you authenticate to the App Engine
+application from your Android device using AccountManager (no need to type in
+your credentials), and an App Engine app that can send messages to any logged-in
+device using C2DM. In order to spin up your application and take it for a test
+drive, do the following:</p>
+
+<p>To spin up the Android application, make sure you have an AVD with a platform
+version of <em>at least</em> Android 2.2 (API Level 8). Right click on the Android project in
+Eclipse, and go to <strong>Debug As > Local App Engine Connected Android
+ Application</strong>. This launches the emulator in such a way that it can
+test C2DM functionality (which typically works through Google Play). It'll
+also launch a local instance of App Engine containing your awesome
+application.</p>
+
+<h2 id="data">Create the Data Layer</h2>
+
+<p>At this point you have a fully functional sample application running. Now
+it's time to start changing the code to create your own application.</p>
+
+<p>First, create the data model that defines the data shared between
+the App Engine and Android applications. To start, open up the source folder of
+your App Engine project, and navigate down to the <strong>(yourApp)-AppEngine
+ > src > (yourapp) > server</strong> package. Create a new class in there containing some data you want to
+store server-side. The code ends up looking something like this:</p>
+<pre>
+package com.cloudtasks.server;
+
+import javax.persistence.*;
+
+@Entity
+public class Task {
+
+ private String emailAddress;
+ private String name;
+ private String userId;
+ private String note;
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ public Task() {
+ }
+
+ public String getEmailAddress() {
+ return this.emailAddress;
+ }
+
+ public Long getId() {
+ return this.id;
+ }
+ ...
+}
+</pre>
+<p>Note the use of annotations: <code>Entity</code>, <code>Id</code> and
+<code>GeneratedValue</code> are all part of the <a
+ href="http://www.oracle.com/technetwork/articles/javaee/jpa-137156.html">Java
+ Persistence API</a>. Essentially, the <code>Entity</code> annotation goes
+above the class declaration, and indicates that this class represents an entity
+in your data layer. The <code>Id</code> and <code>GeneratedValue</code>
+annotations, respectively, indicate the field used as a lookup key for this
+class, and how that id is generated (in this case,
+<code>GenerationType.IDENTITY</code> indicates that the is generated by
+the database). You can find more on this topic in the App Engine documentation,
+on the page <a
+ href="http://code.google.com/appengine/docs/java/datastore/jpa/overview.html">Using
+ JPA with App Engine</a>.</p>
+
+<p>Once you've written all the classes that represent entities in your data
+layer, you need a way for the Android and App Engine applications to communicate
+about this data. This communication is enabled by creating a Remote Procedure
+Call (RPC) service.
+Typically, this involves a lot of monotonous code. Fortunately, there's an easy way! Right
+click on the server project in your App Engine source folder, and in the context
+menu, navigate to <strong>New > Other</strong> and then, in the resulting
+screen, select <strong>Google > RPC Service.</strong> A wizard appears, pre-populated
+with all the Entities you created in the previous step,
+which it found by seeking out the <code>@Entity</code> annotation in the
+source files you added. Pretty neat, right? Click <strong>Finish</strong>, and the wizard
+creates a Service class with stub methods for the Create, Retrieve, Update and
+Delete (CRUD) operations of all your entities.</p>
+
+<h2 id="persistence">Create the Persistence Layer</h2>
+
+<p>The persistence layer is where your application data is stored
+long-term, so any information you want to keep for your users needs to go here.
+You have several options for writing your persistence layer, depending on
+what kind of data you want to store. A few of the options hosted by Google
+(though you don't have to use these services) include <a
+ href="http://code.google.com/apis/storage/">Google Storage for Developers</a>
+and App Engine's built-in <a
+ href="http://code.google.com/appengine/docs/java/gettingstarted/usingdatastore.html">Datastore</a>.
+The sample code for this lesson uses DataStore code.</p>
+
+<p>Create a class in your <code>com.cloudtasks.server</code> package to handle
+persistence layer input and output. In order to access the data store, use the <a
+ href="http://db.apache.org/jdo/api20/apidocs/javax/jdo/PersistenceManager.html">PersistenceManager</a>
+class. You can generate an instance of this class using the PMF class in the
+<code>com.google.android.c2dm.server.PMF</code> package, and then use that to
+perform basic CRUD operations on your data store, like this:</p>
+<pre>
+/**
+* Remove this object from the data store.
+*/
+public void delete(Long id) {
+ PersistenceManager pm = PMF.get().getPersistenceManager();
+ try {
+ Task item = pm.getObjectById(Task.class, id);
+ pm.deletePersistent(item);
+ } finally {
+ pm.close();
+ }
+}
+</pre>
+
+<p>You can also use <a
+ href="http://code.google.com/appengine/docs/python/datastore/queryclass.html">Query</a>
+objects to retrieve data from your Datastore. Here's an example of a method
+that searches out an object by its ID.</p>
+
+<pre>
+public Task find(Long id) {
+ if (id == null) {
+ return null;
+ }
+
+ PersistenceManager pm = PMF.get().getPersistenceManager();
+ try {
+ Query query = pm.newQuery("select from " + Task.class.getName()
+ + " where id==" + id.toString() + " && emailAddress=='" + getUserEmail() + "'");
+ List<Task> list = (List<Task>) query.execute();
+ return list.size() == 0 ? null : list.get(0);
+ } catch (RuntimeException e) {
+ System.out.println(e);
+ throw e;
+ } finally {
+ pm.close();
+ }
+}
+</pre>
+
+<p>For a good example of a class that encapsulates the persistence layer for
+you, check out the <a
+ href="http://code.google.com/p/cloud-tasks-io/source/browse/trunk/CloudTasks-AppEngine/src/com/cloudtasks/server/DataStore.java">DataStore</a>
+class in the Cloud Tasks app.</p>
+
+
+
+<h2 id="androidapp">Query and Update from the Android App</h2>
+
+<p>In order to keep in sync with the App Engine application, your Android application
+needs to know how to do two things: Pull data from the cloud, and send data up
+to the cloud. Much of the plumbing for this is generated by the
+plugin, but you need to wire it up to your Android user interface yourself.</p>
+
+<p>Pop open the source code for the main Activity in your project and look for
+<code><YourProjectName> Activity.java</code>, then for the method
+<code>setHelloWorldScreenContent()</code>. Obviously you're not building a
+HelloWorld app, so delete this method entirely and replace it
+with something relevant. However, the boilerplate code has some very important
+characteristics. For one, the code that communicates with the cloud is wrapped
+in an {@link android.os.AsyncTask} and therefore <em>not</em> hitting the
+network on the UI thread. Also, it gives an easy template for how to access
+the cloud in your own code, using the <a
+ href="http://code.google.com/webtoolkit/doc/latest/DevGuideRequestFactory.html">RequestFactory</a>
+class generated that was auto-generated for you by the Eclipse plugin (called
+MyRequestFactory in the example below), and various {@code Request} types.</p>
+
+<p>For instance, if your server-side data model included an object called {@code
+Task} when you generated an RPC layer it automatically created a
+{@code TaskRequest} class for you, as well as a {@code TaskProxy} representing the individual
+task. In code, requesting a list of all these tasks from the server looks
+like this:</p>
+
+<pre>
+public void fetchTasks (Long id) {
+ // Request is wrapped in an AsyncTask to avoid making a network request
+ // on the UI thread.
+ new AsyncTask<Long, Void, List<TaskProxy>>() {
+ @Override
+ protected List<TaskProxy> doInBackground(Long... arguments) {
+ final List<TaskProxy> list = new ArrayList<TaskProxy>();
+ MyRequestFactory factory = Util.getRequestFactory(mContext,
+ MyRequestFactory.class);
+ TaskRequest taskRequest = factory.taskNinjaRequest();
+
+ if (arguments.length == 0 || arguments[0] == -1) {
+ factory.taskRequest().queryTasks().fire(new Receiver<List<TaskProxy>>() {
+ @Override
+ public void onSuccess(List<TaskProxy> arg0) {
+ list.addAll(arg0);
+ }
+ });
+ } else {
+ newTask = true;
+ factory.taskRequest().readTask(arguments[0]).fire(new Receiver<TaskProxy>() {
+ @Override
+ public void onSuccess(TaskProxy arg0) {
+ list.add(arg0);
+ }
+ });
+ }
+ return list;
+ }
+
+ @Override
+ protected void onPostExecute(List<TaskProxy> result) {
+ TaskNinjaActivity.this.dump(result);
+ }
+
+ }.execute(id);
+}
+...
+
+public void dump (List<TaskProxy> tasks) {
+ for (TaskProxy task : tasks) {
+ Log.i("Task output", task.getName() + "\n" + task.getNote());
+ }
+}
+</pre>
+
+<p>This {@link android.os.AsyncTask} returns a list of
+<code>TaskProxy</code> objects, and sends it to the debug {@code dump()} method
+upon completion. Note that if the argument list is empty, or the first argument
+is a -1, all tasks are retrieved from the server. Otherwise, only the ones with
+IDs in the supplied list are returned. All the fields you added to the task
+entity when building out the App Engine application are available via get/set
+methods in the <code>TaskProxy</code> class.</p>
+
+<p>In order to create new tasks and send them to the cloud, create a request
+object and use it to create a proxy object. Then populate the proxy object and
+call its update method. Once again, this should be done in an
+<code>AsyncTask</code> to avoid doing networking on the UI thread. The end
+result looks something like this.</p>
+
+<pre>
+new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... arg0) {
+ MyRequestFactory factory = (MyRequestFactory)
+ Util.getRequestFactory(TasksActivity.this,
+ MyRequestFactory.class);
+ TaskRequest request = factory.taskRequest();
+
+ // Create your local proxy object, populate it
+ TaskProxy task = request.create(TaskProxy.class);
+ task.setName(taskName);
+ task.setNote(taskDetails);
+ task.setDueDate(dueDate);
+
+ // To the cloud!
+ request.updateTask(task).fire();
+ return null;
+ }
+}.execute();
+</pre>
+
+<h2 id="serverc2dm">Configure the C2DM Server-Side</h2>
+
+<p>In order to set up C2DM messages to be sent to your Android device, go back
+into your App Engine codebase, and open up the service class that was created
+when you generated your RPC layer. If the name of your project is Foo,
+this class is called FooService. Add a line to each of the methods for
+adding, deleting, or updating data so that a C2DM message is sent to the
+user's device. Here's an example of an update task:
+</p>
+
+<pre>
+public static Task updateTask(Task task) {
+ task.setEmailAddress(DataStore.getUserEmail());
+ task = db.update(task);
+ DataStore.sendC2DMUpdate(TaskChange.UPDATE + TaskChange.SEPARATOR + task.getId());
+ return task;
+}
+
+// Helper method. Given a String, send it to the current user's device via C2DM.
+public static void sendC2DMUpdate(String message) {
+ UserService userService = UserServiceFactory.getUserService();
+ User user = userService.getCurrentUser();
+ ServletContext context = RequestFactoryServlet.getThreadLocalRequest().getSession().getServletContext();
+ SendMessage.sendMessage(context, user.getEmail(), message);
+}
+</pre>
+
+<p>In the following example, a helper class, {@code TaskChange}, has been created with a few
+constants. Creating such a helper class makes managing the communication
+between App Engine and Android apps much easier. Just create it in the shared
+folder, define a few constants (flags for what kind of message you're sending
+and a seperator is typically enough), and you're done. By way of example,
+the above code works off of a {@code TaskChange} class defined as this:</p>
+
+<pre>
+public class TaskChange {
+ public static String UPDATE = "Update";
+ public static String DELETE = "Delete";
+ public static String SEPARATOR = ":";
+}
+</pre>
+
+<h2 id="clientc2dm">Configure the C2DM Client-Side</h2>
+
+<p>In order to define the Android applications behavior when a C2DM is recieved,
+open up the <code>C2DMReceiver</code> class, and browse to the
+<code>onMessage()</code> method. Tweak this method to update based on the content
+of the message.</p>
+<pre>
+//In your C2DMReceiver class
+
+public void notifyListener(Intent intent) {
+ if (listener != null) {
+ Bundle extras = intent.getExtras();
+ if (extras != null) {
+ String message = (String) extras.get("message");
+ String[] messages = message.split(Pattern.quote(TaskChange.SEPARATOR));
+ listener.onTaskUpdated(messages[0], Long.parseLong(messages[1]));
+ }
+ }
+}
+</pre>
+
+<pre>
+// Elsewhere in your code, wherever it makes sense to perform local updates
+public void onTasksUpdated(String messageType, Long id) {
+ if (messageType.equals(TaskChange.DELETE)) {
+ // Delete this task from your local data store
+ ...
+ } else {
+ // Call that monstrous Asynctask defined earlier.
+ fetchTasks(id);
+ }
+}
+</pre>
+<p>
+Once you have C2DM set up to trigger local updates, you're all done.
+Congratulations, you have a cloud-connected Android application!</p>
diff --git a/docs/html/training/cloudsync/backupapi.jd b/docs/html/training/cloudsync/backupapi.jd
new file mode 100644
index 0000000..3055596
--- /dev/null
+++ b/docs/html/training/cloudsync/backupapi.jd
@@ -0,0 +1,193 @@
+page.title=Using the Backup API
+parent.title=Syncing to the Cloud
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Syncing with App Engine
+previous.link=aesync.html
+
+@jd:body
+
+<div id="tb-wrapper">
+ <div id="tb">
+ <h2>This lesson teaches you to</h2>
+ <ol>
+ <li><a href="#register">Register for the Android Backup Service</a></li>
+ <li><a href="#manifest">Configure Your Manifest</a></li>
+ <li><a href="#agent">Write Your Backup Agent</a></li>
+ <li><a href="#backup">Request a Backup</a></li>
+ <li><a href="#restore">Restore from a Backup</a></li>
+ </ol>
+ <h2>You should also read</h2>
+ <ul>
+ <li><a
+ href="http://developer.android.com/guide/topics/data/backup.html">Data
+ Backup</a></li>
+ </ul>
+ </div>
+</div>
+
+<p>When a user purchases a new device or resets their existing one, they might
+expect that when Google Play restores your app back to their device during the
+initial setup, the previous data associated with the app restores as well. By
+default, that doesn't happen and all the user's accomplishments or settings in
+your app are lost.</p>
+<p>For situations where the volume of data is relatively light (less than a
+megabyte), like the user's preferences, notes, game high scores or other
+stats, the Backup API provides a lightweight solution. This lesson walks you
+through integrating the Backup API into your application, and restoring data to
+new devices using the Backup API.</p>
+
+<h2 id="register">Register for the Android Backup Service</h2>
+<p>This lesson requires the use of the <a
+ href="http://code.google.com/android/backup/index.html">Android Backup
+ Service</a>, which requires registration. Go ahead and <a
+ href="http://code.google.com/android/backup/signup.html">register here</a>. Once
+that's done, the service pre-populates an XML tag for insertion in your Android
+Manifest, which looks like this:</p>
+<pre>
+<meta-data android:name="com.google.android.backup.api_key"
+android:value="ABcDe1FGHij2KlmN3oPQRs4TUvW5xYZ" />
+</pre>
+<p>Note that each backup key works with a specific package name. If you have
+different applications, register separate keys for each one.</p>
+
+
+<h2 id="manifest">Configure Your Manifest</h2>
+<p>Use of the Android Backup Service requires two additions to your application
+manifest. First, declare the name of the class that acts as your backup agent,
+then add the snippet above as a child element of the Application tag. Assuming
+your backup agent is going to be called {@code TheBackupAgent}, here's an example of
+what the manifest looks like with this tag included:</p>
+
+<pre>
+<application android:label="MyApp"
+ android:backupAgent="TheBackupAgent">
+ ...
+ <meta-data android:name="com.google.android.backup.api_key"
+ android:value="ABcDe1FGHij2KlmN3oPQRs4TUvW5xYZ" />
+ ...
+</application>
+</pre>
+<h2 id="agent">Write Your Backup Agent</h2>
+<p>The easiest way to create your backup agent is by extending the wrapper class
+{@link android.app.backup.BackupAgentHelper}. Creating this helper class is
+actually a very simple process. Just create a class with the same name as you
+used in the manifest in the previous step (in this example, {@code
+TheBackupAgent}),
+and extend {@code BackupAgentHelper}. Then override the {@link
+android.app.backup.BackupAgent#onCreate()}.</p>
+
+<p>Inside the {@link android.app.backup.BackupAgent#onCreate()} method, create a {@link
+android.app.backup.BackupHelper}. These helpers are
+specialized classes for backing up certain kinds of data. The Android framework
+currently includes two such helpers: {@link
+android.app.backup.FileBackupHelper} and {@link
+android.app.backup.SharedPreferencesBackupHelper}. After you create the helper
+and point it at the data you want to back up, just add it to the
+BackupAgentHelper using the {@link android.app.backup.BackupAgentHelper#addHelper(String, BackupHelper) addHelper()}
+method, adding a key which is used to
+retrieve the data later. In most cases the entire
+implementation is perhaps 10 lines of code.</p>
+
+<p>Here's an example that backs up a high scores file.</p>
+
+<pre>
+ import android.app.backup.BackupAgentHelper;
+ import android.app.backup.FileBackupHelper;
+
+
+ public class TheBackupAgent extends BackupAgentHelper {
+ // The name of the SharedPreferences file
+ static final String HIGH_SCORES_FILENAME = "scores";
+
+ // A key to uniquely identify the set of backup data
+ static final String FILES_BACKUP_KEY = "myfiles";
+
+ // Allocate a helper and add it to the backup agent
+ @Override
+ void onCreate() {
+ FileBackupHelper helper = new FileBackupHelper(this, HIGH_SCORES_FILENAME);
+ addHelper(FILES_BACKUP_KEY, helper);
+ }
+}
+</pre>
+<p>For added flexibility, {@link android.app.backup.FileBackupHelper}'s
+constructor can take a variable number of filenames. You could just as easily
+have backed up both a high scores file and a game progress file just by adding
+an extra parameter, like this:</p>
+<pre>
+ @Override
+ void onCreate() {
+ FileBackupHelper helper = new FileBackupHelper(this, HIGH_SCORES_FILENAME, PROGRESS_FILENAME);
+ addHelper(FILES_BACKUP_KEY, helper);
+ }
+</pre>
+<p>Backing up preferences is similarly easy. Create a {@link
+android.app.backup.SharedPreferencesBackupHelper} the same way you did a {@link
+android.app.backup.FileBackupHelper}. In this case, instead of adding filenames
+to the constructor, add the names of the shared preference groups being used by
+your application. Here's an example of how your backup agent helper might look if
+high scores are implemented as preferences instead of a flat file:</p>
+
+<pre>
+ import android.app.backup.BackupAgentHelper;
+ import android.app.backup.SharedPreferencesBackupHelper;
+
+ public class TheBackupAgent extends BackupAgentHelper {
+ // The names of the SharedPreferences groups that the application maintains. These
+ // are the same strings that are passed to getSharedPreferences(String, int).
+ static final String PREFS_DISPLAY = "displayprefs";
+ static final String PREFS_SCORES = "highscores";
+
+ // An arbitrary string used within the BackupAgentHelper implementation to
+ // identify the SharedPreferencesBackupHelper's data.
+ static final String MY_PREFS_BACKUP_KEY = "myprefs";
+
+ // Simply allocate a helper and install it
+ void onCreate() {
+ SharedPreferencesBackupHelper helper =
+ new SharedPreferencesBackupHelper(this, PREFS_DISPLAY, PREFS_SCORES);
+ addHelper(MY_PREFS_BACKUP_KEY, helper);
+ }
+ }
+</pre>
+
+<p>You can add as many backup helper instances to your backup agent helper as you
+like, but remember that you only need one of each type. One {@link
+android.app.backup.FileBackupHelper} handles all the files that you need to back up, and one
+{@link android.app.backup.SharedPreferencesBackupHelper} handles all the shared
+preferencegroups you need backed up.
+</p>
+
+
+<h2 id="backup">Request a Backup</h2>
+<p>In order to request a backup, just create an instance of the {@link
+android.app.backup.BackupManager}, and call it's {@link
+android.app.backup.BackupManager#dataChanged()} method.</p>
+
+<pre>
+ import android.app.backup.BackupManager;
+ ...
+
+ public void requestBackup() {
+ BackupManager bm = new BackupManager(this);
+ bm.dataChanged();
+ }
+</pre>
+
+<p>This call notifies the backup manager that there is data ready to be backed
+up to the cloud. At some point in the future, the backup manager then calls
+your backup agent's {@link
+android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput,
+ParcelFileDescriptor) onBackup()} method. You can make
+the call whenever your data has changed, without having to worry about causing
+excessive network activity. If you request a backup twice before a backup
+occurs, the backup only occurs once.</p>
+
+
+<h2 id="restore">Restore from a Backup</h2>
+<p>Typically you shouldn't ever have to manually request a restore, as it
+happens automatically when your application is installed on a device. However,
+if it <em>is</em> necessary to trigger a manual restore, just call the
+{@link android.app.backup.BackupManager#requestRestore(RestoreObserver) requestRestore()} method.</p>
diff --git a/docs/html/training/cloudsync/index.jd b/docs/html/training/cloudsync/index.jd
new file mode 100644
index 0000000..e53844b
--- /dev/null
+++ b/docs/html/training/cloudsync/index.jd
@@ -0,0 +1,34 @@
+page.title=Syncing to the Cloud
+
+trainingnavtop=true
+startpage=true
+next.title=Syncing with App Engine
+next.link=aesync.html
+
+@jd:body
+
+<p>By providing powerful APIs for internet connectivity, the Android framework
+helps you build rich cloud-enabled apps that sync their data to a remote web
+service, making sure all your devices always stay in sync, and your valuable
+data is always backed up to the cloud.</p>
+
+<p>This class covers different strategies for cloud enabled applications. It
+covers syncing data with the cloud using your own back-end web application, and
+backing up data using the cloud so that users can restore their data when
+installing your application on a new device.
+</p>
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><strong><a href="aesync.html">Syncing with App Engine.</a></strong></dt>
+ <dd>Learn how to create a paired App Engine app and Android app which share a
+ data model, authenticates using the AccountManager, and communicate with each
+ other via REST and C2DM.</dd>
+ <dt><strong><a href="backupapi.html">Using the Backup
+ API</a></strong></dt>
+ <dd>Learn how to integrate the Backup API into your Android Application, so
+ that user data such as preferences, notes, and high scores update seamlessly
+ across all of a user's devices</dd>
+</dl>
+
diff --git a/docs/html/training/displaying-bitmaps/display-bitmap.jd b/docs/html/training/displaying-bitmaps/display-bitmap.jd
index 7a93313..5eac04c 100644
--- a/docs/html/training/displaying-bitmaps/display-bitmap.jd
+++ b/docs/html/training/displaying-bitmaps/display-bitmap.jd
@@ -315,7 +315,8 @@
<p>The same asynchronous processing and caching methods from the previous section can be implemented
here. However, you also need to wary of concurrency issues as the {@link android.widget.GridView}
recycles its children views. To handle this, use the techniques discussed in the <a
-href="process-bitmap#concurrency">Processing Bitmaps Off the UI Thread</a> lesson. Here is the updated
+href="process-bitmap.html#concurrency">Processing Bitmaps Off the UI Thread</a> lesson. Here is the
+updated
solution:</p>
<pre>
diff --git a/docs/html/training/index.jd b/docs/html/training/index.jd
index 5e85924..8bf32bb 100644
--- a/docs/html/training/index.jd
+++ b/docs/html/training/index.jd
@@ -1,4 +1,5 @@
page.title=Orientation to Android Training
+page.metaDescription=Android Training provides a collection of classes that aim to help you build great apps for Android. Each class explains the steps required to solve a problem or implement a feature using code snippets and sample code for you to use in your apps.
@jd:body
diff --git a/docs/html/training/search/backward-compat.jd b/docs/html/training/search/backward-compat.jd
index 0894fa9..11473a0 100644
--- a/docs/html/training/search/backward-compat.jd
+++ b/docs/html/training/search/backward-compat.jd
@@ -1,7 +1,7 @@
page.title=Remaining Backward Compatible
trainingnavtop=true
previous.title=Storing and Searching for Data
-previous.link=search.html
+previous.link=search.html
@jd:body
diff --git a/docs/html/training/sharing/receive.jd b/docs/html/training/sharing/receive.jd
index a0a5bc8..9c932b1 100644
--- a/docs/html/training/sharing/receive.jd
+++ b/docs/html/training/sharing/receive.jd
@@ -34,7 +34,7 @@
from applications. Think about how users interact with your application, and what data types you
want to receive from other applications. For example, a social networking application would likely
be interested in receiving text content, like an interesting web URL, from another app. The
-<a href="https://play.google.com/store/details?id=com.google.android.apps.plus">Google+ Android
+<a href="https://play.google.com/store/apps/details?id=com.google.android.apps.plus">Google+ Android
application</a>
accepts both text <em>and</em> single or multiple images. With this app, a user can easily start a
new Google+ post with photos from the Android Gallery app.</p>
diff --git a/docs/html/training/tv/optimizing-layouts-tv.jd b/docs/html/training/tv/optimizing-layouts-tv.jd
index e4a8e69..49c278c 100644
--- a/docs/html/training/tv/optimizing-layouts-tv.jd
+++ b/docs/html/training/tv/optimizing-layouts-tv.jd
@@ -186,8 +186,8 @@
{@link android.graphics.Bitmap} views that are no longer needed.
</li>
<li>Use {@link java.lang.ref.WeakReference} for storing references
- to {@link android.graphics.Bitmap} objects in a in-memory
- <a href="{@link java.util.Collection}.</li>
+ to {@link android.graphics.Bitmap} objects in an in-memory
+ {@link java.util.Collection}.</li>
<li>If you fetch images from the network, use {@link android.os.AsyncTask}
to fetch them and store them on the SD card for faster access.
Never do network transactions on the application's UI thread.
diff --git a/docs/html/training/tv/unsupported-features-tv.jd b/docs/html/training/tv/unsupported-features-tv.jd
index 6b0f8c8..a9f090b 100644
--- a/docs/html/training/tv/unsupported-features-tv.jd
+++ b/docs/html/training/tv/unsupported-features-tv.jd
@@ -82,8 +82,9 @@
and interacting with a TV using a touchscreen is not consistent with the 10 foot environment. For
these reasons, users interact with Android-powered TVs using a remote. In consideration of this,
ensure that every control in your app can be accessed with the D-pad. Refer back to the previous two lessons
-<a href="{@docRoot}training/tv/optimizing-layouts-tv">Optimizing Layouts for TV</a> and
-<a href="{@docRoot}training/tv/optimizing-navigation-tv">Optimize Navigation for TV</a> for more details
+<a href="{@docRoot}training/tv/optimizing-layouts-tv.html">Optimizing Layouts for TV</a> and
+<a href="{@docRoot}training/tv/optimizing-navigation-tv.html">Optimize Navigation for TV</a> for
+more details
on this topic. The Android system assumes that a device has a touchscreen, so if you want your application
to run on a TV, you must <strong>explicitly</strong> disable the touchscreen requirement in your manifest file:
<pre>
diff --git a/graphics/java/android/graphics/Insets.java b/graphics/java/android/graphics/Insets.java
index c570cd4..156f990 100644
--- a/graphics/java/android/graphics/Insets.java
+++ b/graphics/java/android/graphics/Insets.java
@@ -67,7 +67,7 @@
* @return an Insets instance with the appropriate values
*/
public static Insets of(Rect r) {
- return of(r.left, r.top, r.right, r.bottom);
+ return (r == null) ? NONE : of(r.left, r.top, r.right, r.bottom);
}
/**
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 7d1942a..6193ca7 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -16,6 +16,7 @@
package android.graphics.drawable;
+import android.graphics.Insets;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -706,16 +707,12 @@
/**
* Return in insets the layout insets suggested by this Drawable for use with alignment
- * operations during layout. Positive values move toward the
- * center of the Drawable. Returns true if this drawable
- * actually has a layout insets, else false. When false is returned, the padding
- * is always set to 0.
+ * operations during layout.
*
* @hide
*/
- public boolean getLayoutInsets(Rect insets) {
- insets.set(0, 0, 0, 0);
- return false;
+ public Insets getLayoutInsets() {
+ return Insets.NONE;
}
/**
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index e10f9e8..15b2c0b 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -19,6 +19,7 @@
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.SystemClock;
@@ -94,12 +95,8 @@
* @hide
*/
@Override
- public boolean getLayoutInsets(Rect insets) {
- if (mCurrDrawable != null) {
- return mCurrDrawable.getLayoutInsets(insets);
- } else {
- return super.getLayoutInsets(insets);
- }
+ public Insets getLayoutInsets() {
+ return (mCurrDrawable == null) ? Insets.NONE : mCurrDrawable.getLayoutInsets();
}
@Override
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index e502b7a..006baa7 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -22,6 +22,7 @@
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.Insets;
import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.PixelFormat;
@@ -224,13 +225,8 @@
* @hide
*/
@Override
- public boolean getLayoutInsets(Rect insets) {
- Rect layoutInsets = mNinePatchState.mLayoutInsets;
- if (layoutInsets == null) {
- return super.getLayoutInsets(insets);
- }
- insets.set(layoutInsets);
- return true;
+ public Insets getLayoutInsets() {
+ return mNinePatchState.mLayoutInsets;
}
@Override
@@ -390,7 +386,7 @@
private final static class NinePatchState extends ConstantState {
final NinePatch mNinePatch;
final Rect mPadding;
- final Rect mLayoutInsets;
+ final Insets mLayoutInsets;
final boolean mDither;
int mChangingConfigurations;
int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -406,7 +402,7 @@
NinePatchState(NinePatch ninePatch, Rect rect, Rect layoutInsets, boolean dither) {
mNinePatch = ninePatch;
mPadding = rect;
- mLayoutInsets = layoutInsets;
+ mLayoutInsets = Insets.of(layoutInsets);
mDither = dither;
}
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 10ccb87..6b1d66f 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -27,7 +27,7 @@
import android.util.Log;
import android.util.TypedValue;
-/**
+/** @deprecated renderscript is deprecated in J
* <p>
* Memory allocation class for renderscript. An allocation combines a
* {@link android.renderscript.Type} with the memory to provide storage for user data and objects.
@@ -93,7 +93,7 @@
int mCurrentCount;
- /**
+ /** @deprecated renderscript is deprecated in J
* The usage of the allocation. These signal to renderscript
* where to place the allocation in memory.
*
@@ -102,14 +102,14 @@
*/
public static final int USAGE_SCRIPT = 0x0001;
- /**
+ /** @deprecated renderscript is deprecated in J
* GRAPHICS_TEXTURE The allocation will be used as a texture
* source by one or more graphics programs.
*
*/
public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
- /**
+ /** @deprecated renderscript is deprecated in J
* GRAPHICS_VERTEX The allocation will be used as a graphics
* mesh.
*
@@ -117,21 +117,21 @@
public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
- /**
+ /** @deprecated renderscript is deprecated in J
* GRAPHICS_CONSTANTS The allocation will be used as the source
* of shader constants by one or more programs.
*
*/
public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
- /**
+ /** @deprecated renderscript is deprecated in J
* USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a
* target for offscreen rendering
*
*/
public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
- /**
+ /** @hide renderscript is deprecated in J
* USAGE_IO_INPUT The allocation will be used as SurfaceTexture
* consumer. This usage will cause the allocation to be created
* read only.
@@ -139,7 +139,7 @@
*/
public static final int USAGE_IO_INPUT = 0x0020;
- /**
+ /** @hide renderscript is deprecated in J
* USAGE_IO_OUTPUT The allocation will be used as a
* SurfaceTexture producer. The dimensions and format of the
* SurfaceTexture will be forced to those of the allocation.
@@ -147,25 +147,25 @@
*/
public static final int USAGE_IO_OUTPUT = 0x0040;
- /**
+ /** @deprecated renderscript is deprecated in J
* Controls mipmap behavior when using the bitmap creation and
* update functions.
*/
public enum MipmapControl {
- /**
+ /** @deprecated renderscript is deprecated in J
* No mipmaps will be generated and the type generated from the
* incoming bitmap will not contain additional LODs.
*/
MIPMAP_NONE(0),
- /**
+ /** @deprecated renderscript is deprecated in J
* A Full mipmap chain will be created in script memory. The
* type of the allocation will contain a full mipmap chain. On
* upload to graphics the full chain will be transfered.
*/
MIPMAP_FULL(1),
- /**
+ /** @deprecated renderscript is deprecated in J
* The type of the allocation will be the same as MIPMAP_NONE.
* It will not contain mipmaps. On upload to graphics the
* graphics copy of the allocation data will contain a full
@@ -188,7 +188,7 @@
}
- /**
+ /** @hide renderscript is deprecated in J
* Get the element of the type of the Allocation.
*
* @return Element that describes the structure of data in the
@@ -199,7 +199,7 @@
return mType.getElement();
}
- /**
+ /** @hide renderscript is deprecated in J
* Get the usage flags of the Allocation.
*
* @return usage flags associated with the allocation. e.g.
@@ -210,7 +210,7 @@
return mUsage;
}
- /**
+ /** @hide renderscript is deprecated in J
* Get the size of the Allocation in bytes.
*
* @return size of the Allocation in bytes.
@@ -326,7 +326,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Get the type of the Allocation.
*
* @return Type
@@ -336,7 +336,7 @@
return mType;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Propagate changes from one usage of the allocation to the
* remaining usages of the allocation.
*
@@ -355,7 +355,7 @@
mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
}
- /**
+ /** @hide renderscript is deprecated in J
* Send a buffer to the output stream. The contents of the
* Allocation will be undefined after this operation.
*
@@ -369,7 +369,7 @@
mRS.nAllocationIoSend(getID(mRS));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Delete once code is updated.
* @hide
*/
@@ -377,7 +377,7 @@
ioSend();
}
- /**
+ /** @hide renderscript is deprecated in J
* Receive the latest input into the Allocation.
*
*/
@@ -390,7 +390,7 @@
mRS.nAllocationIoReceive(getID(mRS));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an array of RS objects to the allocation.
*
* @param d Source array.
@@ -461,7 +461,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an allocation from an array. This variant is not type
* checked which allows an application to fill in structured
* data from an array.
@@ -472,7 +472,7 @@
mRS.validate();
copy1DRangeFromUnchecked(0, mCurrentCount, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an allocation from an array. This variant is not type
* checked which allows an application to fill in structured
* data from an array.
@@ -483,7 +483,7 @@
mRS.validate();
copy1DRangeFromUnchecked(0, mCurrentCount, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an allocation from an array. This variant is not type
* checked which allows an application to fill in structured
* data from an array.
@@ -494,7 +494,7 @@
mRS.validate();
copy1DRangeFromUnchecked(0, mCurrentCount, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an allocation from an array. This variant is not type
* checked which allows an application to fill in structured
* data from an array.
@@ -506,7 +506,7 @@
copy1DRangeFromUnchecked(0, mCurrentCount, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an allocation from an array. This variant is type
* checked and will generate exceptions if the Allocation type
* is not a 32 bit integer type.
@@ -518,7 +518,7 @@
copy1DRangeFrom(0, mCurrentCount, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an allocation from an array. This variant is type
* checked and will generate exceptions if the Allocation type
* is not a 16 bit integer type.
@@ -530,7 +530,7 @@
copy1DRangeFrom(0, mCurrentCount, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an allocation from an array. This variant is type
* checked and will generate exceptions if the Allocation type
* is not a 8 bit integer type.
@@ -542,7 +542,7 @@
copy1DRangeFrom(0, mCurrentCount, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an allocation from an array. This variant is type
* checked and will generate exceptions if the Allocation type
* is not a 32 bit float type.
@@ -554,7 +554,7 @@
copy1DRangeFrom(0, mCurrentCount, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy an allocation from a bitmap. The height, width, and
* format of the bitmap must match the existing allocation.
*
@@ -567,7 +567,7 @@
mRS.nAllocationCopyFromBitmap(getID(mRS), b);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* This is only intended to be used by auto-generate code reflected from the
* renderscript script files.
*
@@ -587,7 +587,7 @@
copy1DRangeFromUnchecked(xoff, count, data);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* This is only intended to be used by auto-generate code reflected from the
* renderscript script files.
*
@@ -634,7 +634,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Generate a mipmap chain. Requires the type of the allocation
* include mipmaps.
*
@@ -648,7 +648,7 @@
mRS.nAllocationGenerateMipmaps(getID(mRS));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy part of an allocation from an array. This variant is
* not type checked which allows an application to fill in
* structured data from an array.
@@ -662,7 +662,7 @@
data1DChecks(off, count, d.length * 4, dataSize);
mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy part of an allocation from an array. This variant is
* not type checked which allows an application to fill in
* structured data from an array.
@@ -676,7 +676,7 @@
data1DChecks(off, count, d.length * 2, dataSize);
mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy part of an allocation from an array. This variant is
* not type checked which allows an application to fill in
* structured data from an array.
@@ -690,7 +690,7 @@
data1DChecks(off, count, d.length, dataSize);
mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy part of an allocation from an array. This variant is
* not type checked which allows an application to fill in
* structured data from an array.
@@ -705,7 +705,7 @@
mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy part of an allocation from an array. This variant is
* type checked and will generate exceptions if the Allocation
* type is not a 32 bit integer type.
@@ -719,7 +719,7 @@
copy1DRangeFromUnchecked(off, count, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy part of an allocation from an array. This variant is
* type checked and will generate exceptions if the Allocation
* type is not a 16 bit integer type.
@@ -733,7 +733,7 @@
copy1DRangeFromUnchecked(off, count, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy part of an allocation from an array. This variant is
* type checked and will generate exceptions if the Allocation
* type is not a 8 bit integer type.
@@ -747,7 +747,7 @@
copy1DRangeFromUnchecked(off, count, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy part of an allocation from an array. This variant is
* type checked and will generate exceptions if the Allocation
* type is not a 32 bit float type.
@@ -761,7 +761,7 @@
copy1DRangeFromUnchecked(off, count, d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy part of an allocation from another allocation.
*
* @param off The offset of the first element to be copied.
@@ -794,7 +794,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy a rectangular region from the array into the allocation.
* The incoming array is assumed to be tightly packed.
*
@@ -811,6 +811,8 @@
w, h, data, data.length);
}
+ /** @deprecated renderscript is deprecated in J
+ */
public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
mRS.validate();
validate2DRange(xoff, yoff, w, h);
@@ -818,6 +820,8 @@
w, h, data, data.length * 2);
}
+ /** @deprecated renderscript is deprecated in J
+ */
public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
mRS.validate();
validate2DRange(xoff, yoff, w, h);
@@ -825,6 +829,8 @@
w, h, data, data.length * 4);
}
+ /** @deprecated renderscript is deprecated in J
+ */
public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
mRS.validate();
validate2DRange(xoff, yoff, w, h);
@@ -832,7 +838,7 @@
w, h, data, data.length * 4);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy a rectangular region into the allocation from another
* allocation.
*
@@ -854,7 +860,7 @@
data.mSelectedLOD, data.mSelectedFace.mID);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy a bitmap into an allocation. The height and width of
* the update will use the height and width of the incoming
* bitmap.
@@ -871,7 +877,7 @@
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy from the Allocation into a Bitmap. The bitmap must
* match the dimensions of the Allocation.
*
@@ -884,7 +890,7 @@
mRS.nAllocationCopyToBitmap(getID(mRS), b);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy from the Allocation into a byte array. The array must
* be at least as large as the Allocation. The allocation must
* be of an 8 bit elemental type.
@@ -897,7 +903,7 @@
mRS.nAllocationRead(getID(mRS), d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy from the Allocation into a short array. The array must
* be at least as large as the Allocation. The allocation must
* be of an 16 bit elemental type.
@@ -910,7 +916,7 @@
mRS.nAllocationRead(getID(mRS), d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy from the Allocation into a int array. The array must be
* at least as large as the Allocation. The allocation must be
* of an 32 bit elemental type.
@@ -923,7 +929,7 @@
mRS.nAllocationRead(getID(mRS), d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Copy from the Allocation into a float array. The array must
* be at least as large as the Allocation. The allocation must
* be of an 32 bit float elemental type.
@@ -936,7 +942,7 @@
mRS.nAllocationRead(getID(mRS), d);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Resize a 1D allocation. The contents of the allocation are
* preserved. If new elements are allocated objects are created
* with null contents and the new region is otherwise undefined.
@@ -961,7 +967,7 @@
updateCacheInfo(mType);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Resize a 2D allocation. The contents of the allocation are
* preserved. If new elements are allocated objects are created
* with null contents and the new region is otherwise undefined.
@@ -1002,7 +1008,7 @@
mBitmapOptions.inScaled = false;
}
- /**
+ /** @deprecated renderscript is deprecated in J
*
* @param type renderscript type describing data layout
* @param mips specifies desired mipmap behaviour for the
@@ -1022,7 +1028,7 @@
return new Allocation(id, rs, type, usage);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a renderscript allocation with the size specified by
* the type and no mipmaps generated by default
*
@@ -1037,7 +1043,7 @@
return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a renderscript allocation for use by the script with
* the size specified by the type and no mipmaps generated by
* default
@@ -1051,7 +1057,7 @@
return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a renderscript allocation with a specified number of
* given elements
*
@@ -1077,7 +1083,7 @@
return new Allocation(id, rs, t, usage);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a renderscript allocation with a specified number of
* given elements
*
@@ -1118,7 +1124,7 @@
return tb.create();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a renderscript allocation from a bitmap
*
* @param rs Context to which the allocation will belong.
@@ -1144,7 +1150,7 @@
return new Allocation(id, rs, t, usage);
}
- /**
+ /** @deprecated renderscript is deprecated in J
*
*
* @hide
@@ -1162,7 +1168,7 @@
return st;
}
- /**
+ /** @hide renderscript is deprecated in J
* For allocations used with io operations, returns the handle
* onto a raw buffer that is being managed by the screen
* compositor.
@@ -1174,7 +1180,7 @@
return new Surface(getSurfaceTexture());
}
- /**
+ /** @hide renderscript is deprecated in J
* Associate a surface for io output with this allocation
*
* @param sur Surface to associate with allocation
@@ -1188,7 +1194,7 @@
mRS.nAllocationSetSurface(getID(mRS), sur);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @hide
*/
public void setSurfaceTexture(SurfaceTexture st) {
@@ -1201,7 +1207,7 @@
mRS.nAllocationSetSurface(getID(mRS), s);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a non-mipmapped renderscript allocation to use as a
* graphics texture
*
@@ -1216,7 +1222,7 @@
USAGE_GRAPHICS_TEXTURE);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a cubemap allocation from a bitmap containing the
* horizontal list of cube faces. Each individual face must be
* the same size and power of 2
@@ -1264,7 +1270,7 @@
return new Allocation(id, rs, t, usage);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a non-mipmapped cubemap allocation for use as a
* graphics texture from a bitmap containing the horizontal list
* of cube faces. Each individual face must be the same size and
@@ -1283,7 +1289,7 @@
USAGE_GRAPHICS_TEXTURE);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a cubemap allocation from 6 bitmaps containing
* the cube faces. All the faces must be the same size and
* power of 2
@@ -1350,7 +1356,7 @@
return cubemap;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a non-mipmapped cubemap allocation for use as a
* graphics texture from 6 bitmaps containing
* the cube faces. All the faces must be the same size and
@@ -1379,7 +1385,7 @@
USAGE_GRAPHICS_TEXTURE);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a renderscript allocation from the bitmap referenced
* by resource id
*
@@ -1407,7 +1413,7 @@
return alloc;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a non-mipmapped renderscript allocation to use as a
* graphics texture from the bitmap referenced by resource id
*
@@ -1426,7 +1432,7 @@
USAGE_GRAPHICS_TEXTURE);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a renderscript allocation containing string data
* encoded in UTF-8 format
*
diff --git a/graphics/java/android/renderscript/AllocationAdapter.java b/graphics/java/android/renderscript/AllocationAdapter.java
index 85d86e5..3b5993a 100644
--- a/graphics/java/android/renderscript/AllocationAdapter.java
+++ b/graphics/java/android/renderscript/AllocationAdapter.java
@@ -21,7 +21,7 @@
import android.graphics.BitmapFactory;
import android.util.TypedValue;
-/**
+/** @deprecated renderscript is deprecated in J
*
**/
public class AllocationAdapter extends Allocation {
@@ -129,7 +129,7 @@
mSelectedZ = 0;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the active LOD. The LOD must be within the range for the
* type being adapted. The base allocation must have mipmaps.
*
@@ -149,7 +149,7 @@
initLOD(lod);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the active Face. The base allocation must be of a type
* that includes faces.
*
@@ -169,7 +169,7 @@
mSelectedFace = cf;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the active Y. The y value must be within the range for
* the allocation being adapted. The base allocation must
* contain the Y dimension.
@@ -190,7 +190,7 @@
mSelectedY = y;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the active Z. The z value must be within the range for
* the allocation being adapted. The base allocation must
* contain the Z dimension.
@@ -211,6 +211,8 @@
mSelectedZ = z;
}
+ /** @deprecated renderscript is deprecated in J
+ */
static public AllocationAdapter create1D(RenderScript rs, Allocation a) {
rs.validate();
AllocationAdapter aa = new AllocationAdapter(0, rs, a);
@@ -222,6 +224,8 @@
return aa;
}
+ /** @deprecated renderscript is deprecated in J
+ */
static public AllocationAdapter create2D(RenderScript rs, Allocation a) {
android.util.Log.e("rs", "create2d " + a);
rs.validate();
@@ -235,7 +239,7 @@
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Override the Allocation resize. Resizing adapters is not
* allowed and will throw a RSInvalidStateException.
*
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index f464f9b..0d74212 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -18,7 +18,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* BaseObj is the base class for interfacing with native renderscript objects.
* It primarly contains code for tracking the native object ID and forcably
* disconecting the object from the native allocation for early cleanup.
@@ -39,7 +39,7 @@
mID = id;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Lookup the native object ID for this object. Primarily used by the
* generated reflected code.
*
@@ -73,7 +73,7 @@
private String mName;
RenderScript mRS;
- /**
+ /** @deprecated renderscript is deprecated in J
* setName assigns a name to an object. This object can later be looked up
* by this name. This name will also be retained if the object is written
* to an A3D file.
@@ -103,7 +103,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @return name of the renderscript object
*/
public String getName() {
@@ -124,7 +124,7 @@
super.finalize();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* destroy disconnects the object from the native object effectively
* rendering this java object dead. The primary use is to force immediate
* cleanup of resources when it is believed the GC will not respond quickly
@@ -138,7 +138,7 @@
mRS.nObjDestroy(mID);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* If an object came from an a3d file, java fields need to be
* created with objects from the native layer
*/
@@ -147,7 +147,7 @@
mName = mRS.nGetName(getID(mRS));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Calculates the hash code value for a BaseObj.
*
* @return int
@@ -157,7 +157,7 @@
return mID;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Compare the current BaseObj with another BaseObj for equality.
*
* @param obj The object to check equality with.
diff --git a/graphics/java/android/renderscript/Byte2.java b/graphics/java/android/renderscript/Byte2.java
index 7df5f2e..163b8bd 100644
--- a/graphics/java/android/renderscript/Byte2.java
+++ b/graphics/java/android/renderscript/Byte2.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript byte2 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Byte3.java b/graphics/java/android/renderscript/Byte3.java
index 02a01c1..eaa1d5f9 100644
--- a/graphics/java/android/renderscript/Byte3.java
+++ b/graphics/java/android/renderscript/Byte3.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript byte3 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Byte4.java b/graphics/java/android/renderscript/Byte4.java
index a55a696..e162f9d 100644
--- a/graphics/java/android/renderscript/Byte4.java
+++ b/graphics/java/android/renderscript/Byte4.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript byte4 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Double2.java b/graphics/java/android/renderscript/Double2.java
index 9f4f328..0ef2f2b 100644
--- a/graphics/java/android/renderscript/Double2.java
+++ b/graphics/java/android/renderscript/Double2.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript double2 type back
* to the Android system.
*
diff --git a/graphics/java/android/renderscript/Double3.java b/graphics/java/android/renderscript/Double3.java
index eb55142..09aba18 100644
--- a/graphics/java/android/renderscript/Double3.java
+++ b/graphics/java/android/renderscript/Double3.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript double3 type back
* to the Android system.
*
diff --git a/graphics/java/android/renderscript/Double4.java b/graphics/java/android/renderscript/Double4.java
index 4755a76..c5211be 100644
--- a/graphics/java/android/renderscript/Double4.java
+++ b/graphics/java/android/renderscript/Double4.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript double4 type back
* to the Android system.
*
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 28914ce..babe57e 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -19,7 +19,7 @@
import java.lang.reflect.Field;
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* <p>The most basic data type. An element represents one cell of a memory allocation.
* Element is the basic data type of Renderscript. An element can be of two forms: Basic elements or Complex forms.
* Examples of basic elements are:</p>
@@ -84,12 +84,12 @@
}
}
- /**
+ /** @hide renderscript is deprecated in J
* @return element size in bytes
*/
public int getBytesSize() {return mSize;}
- /**
+ /** @hide renderscript is deprecated in J
* Returns the number of vector components. 2 for float2, 4 for
* float4, etc.
* @return element vector size
@@ -97,7 +97,7 @@
public int getVectorSize() {return mVectorSize;}
- /**
+ /** @deprecated renderscript is deprecated in J
* DataType represents the basic type information for a basic element. The
* naming convention follows. For numeric types it is FLOAT,
* SIGNED, or UNSIGNED followed by the _BITS where BITS is the
@@ -114,6 +114,8 @@
* RS_* objects. 32 bit opaque handles.
*/
public enum DataType {
+ /** @hide
+ */
NONE (0, 0),
//FLOAT_16 (1, 2),
FLOAT_32 (2, 4),
@@ -147,6 +149,8 @@
RS_PROGRAM_VERTEX (1007, 4),
RS_PROGRAM_RASTER (1008, 4),
RS_PROGRAM_STORE (1009, 4),
+ /** @hide
+ */
RS_FONT (1010, 4);
int mID;
@@ -157,7 +161,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* The special interpretation of the data if required. This is primarly
* useful for graphical data. USER indicates no special interpretation is
* expected. PIXEL is used in conjunction with the standard data types for
@@ -179,7 +183,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return if a element is too complex for use as a data source for a Mesh or
* a Program.
*
@@ -197,7 +201,7 @@
return false;
}
- /**
+ /** @hide renderscript is deprecated in J
* Elements could be simple, such as an int or a float, or a
* structure with multiple sub elements, such as a collection of
* floats, float2, float4. This function returns zero for simple
@@ -211,7 +215,7 @@
return mVisibleElementMap.length;
}
- /**
+ /** @hide renderscript is deprecated in J
* For complex elements, this function will return the
* sub-element at index
* @param index index of the sub-element to return
@@ -227,7 +231,7 @@
return mElements[mVisibleElementMap[index]];
}
- /**
+ /** @hide renderscript is deprecated in J
* For complex elements, this function will return the
* sub-element name at index
* @param index index of the sub-element
@@ -243,7 +247,7 @@
return mElementNames[mVisibleElementMap[index]];
}
- /**
+ /** @hide renderscript is deprecated in J
* For complex elements, some sub-elements could be statically
* sized arrays. This function will return the array size for
* sub-element at index
@@ -260,7 +264,7 @@
return mArraySizes[mVisibleElementMap[index]];
}
- /**
+ /** @hide renderscript is deprecated in J
* This function specifies the location of a sub-element within
* the element
* @param index index of the sub-element
@@ -276,21 +280,21 @@
return mOffsetInBytes[mVisibleElementMap[index]];
}
- /**
+ /** @hide renderscript is deprecated in J
* @return element data type
*/
public DataType getDataType() {
return mType;
}
- /**
+ /** @hide renderscript is deprecated in J
* @return element data kind
*/
public DataKind getDataKind() {
return mKind;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Utility function for returning an Element containing a single Boolean.
*
* @param rs Context to which the element will belong.
@@ -304,7 +308,7 @@
return rs.mElement_BOOLEAN;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Utility function for returning an Element containing a single UNSIGNED_8.
*
* @param rs Context to which the element will belong.
@@ -318,7 +322,7 @@
return rs.mElement_U8;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Utility function for returning an Element containing a single SIGNED_8.
*
* @param rs Context to which the element will belong.
@@ -332,6 +336,8 @@
return rs.mElement_I8;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U16(RenderScript rs) {
if(rs.mElement_U16 == null) {
rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16);
@@ -339,6 +345,8 @@
return rs.mElement_U16;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I16(RenderScript rs) {
if(rs.mElement_I16 == null) {
rs.mElement_I16 = createUser(rs, DataType.SIGNED_16);
@@ -346,6 +354,8 @@
return rs.mElement_I16;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U32(RenderScript rs) {
if(rs.mElement_U32 == null) {
rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32);
@@ -353,6 +363,8 @@
return rs.mElement_U32;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I32(RenderScript rs) {
if(rs.mElement_I32 == null) {
rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
@@ -360,6 +372,8 @@
return rs.mElement_I32;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U64(RenderScript rs) {
if(rs.mElement_U64 == null) {
rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
@@ -367,6 +381,8 @@
return rs.mElement_U64;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I64(RenderScript rs) {
if(rs.mElement_I64 == null) {
rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
@@ -374,6 +390,8 @@
return rs.mElement_I64;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element F32(RenderScript rs) {
if(rs.mElement_F32 == null) {
rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
@@ -381,6 +399,8 @@
return rs.mElement_F32;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element F64(RenderScript rs) {
if(rs.mElement_F64 == null) {
rs.mElement_F64 = createUser(rs, DataType.FLOAT_64);
@@ -388,6 +408,8 @@
return rs.mElement_F64;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element ELEMENT(RenderScript rs) {
if(rs.mElement_ELEMENT == null) {
rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
@@ -395,6 +417,8 @@
return rs.mElement_ELEMENT;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element TYPE(RenderScript rs) {
if(rs.mElement_TYPE == null) {
rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE);
@@ -402,6 +426,8 @@
return rs.mElement_TYPE;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element ALLOCATION(RenderScript rs) {
if(rs.mElement_ALLOCATION == null) {
rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
@@ -409,6 +435,8 @@
return rs.mElement_ALLOCATION;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element SAMPLER(RenderScript rs) {
if(rs.mElement_SAMPLER == null) {
rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
@@ -416,6 +444,8 @@
return rs.mElement_SAMPLER;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element SCRIPT(RenderScript rs) {
if(rs.mElement_SCRIPT == null) {
rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
@@ -423,6 +453,8 @@
return rs.mElement_SCRIPT;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element MESH(RenderScript rs) {
if(rs.mElement_MESH == null) {
rs.mElement_MESH = createUser(rs, DataType.RS_MESH);
@@ -430,6 +462,8 @@
return rs.mElement_MESH;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element PROGRAM_FRAGMENT(RenderScript rs) {
if(rs.mElement_PROGRAM_FRAGMENT == null) {
rs.mElement_PROGRAM_FRAGMENT = createUser(rs, DataType.RS_PROGRAM_FRAGMENT);
@@ -437,6 +471,8 @@
return rs.mElement_PROGRAM_FRAGMENT;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element PROGRAM_VERTEX(RenderScript rs) {
if(rs.mElement_PROGRAM_VERTEX == null) {
rs.mElement_PROGRAM_VERTEX = createUser(rs, DataType.RS_PROGRAM_VERTEX);
@@ -444,6 +480,8 @@
return rs.mElement_PROGRAM_VERTEX;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element PROGRAM_RASTER(RenderScript rs) {
if(rs.mElement_PROGRAM_RASTER == null) {
rs.mElement_PROGRAM_RASTER = createUser(rs, DataType.RS_PROGRAM_RASTER);
@@ -451,6 +489,8 @@
return rs.mElement_PROGRAM_RASTER;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element PROGRAM_STORE(RenderScript rs) {
if(rs.mElement_PROGRAM_STORE == null) {
rs.mElement_PROGRAM_STORE = createUser(rs, DataType.RS_PROGRAM_STORE);
@@ -458,6 +498,8 @@
return rs.mElement_PROGRAM_STORE;
}
+ /** @hide
+ */
public static Element FONT(RenderScript rs) {
if(rs.mElement_FONT == null) {
rs.mElement_FONT = createUser(rs, DataType.RS_FONT);
@@ -465,7 +507,8 @@
return rs.mElement_FONT;
}
-
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element A_8(RenderScript rs) {
if(rs.mElement_A_8 == null) {
rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A);
@@ -473,6 +516,8 @@
return rs.mElement_A_8;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element RGB_565(RenderScript rs) {
if(rs.mElement_RGB_565 == null) {
rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB);
@@ -480,6 +525,8 @@
return rs.mElement_RGB_565;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element RGB_888(RenderScript rs) {
if(rs.mElement_RGB_888 == null) {
rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB);
@@ -487,6 +534,8 @@
return rs.mElement_RGB_888;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element RGBA_5551(RenderScript rs) {
if(rs.mElement_RGBA_5551 == null) {
rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA);
@@ -494,6 +543,8 @@
return rs.mElement_RGBA_5551;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element RGBA_4444(RenderScript rs) {
if(rs.mElement_RGBA_4444 == null) {
rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA);
@@ -501,6 +552,8 @@
return rs.mElement_RGBA_4444;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element RGBA_8888(RenderScript rs) {
if(rs.mElement_RGBA_8888 == null) {
rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA);
@@ -508,6 +561,8 @@
return rs.mElement_RGBA_8888;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element F32_2(RenderScript rs) {
if(rs.mElement_FLOAT_2 == null) {
rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2);
@@ -515,6 +570,8 @@
return rs.mElement_FLOAT_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element F32_3(RenderScript rs) {
if(rs.mElement_FLOAT_3 == null) {
rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
@@ -522,6 +579,8 @@
return rs.mElement_FLOAT_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element F32_4(RenderScript rs) {
if(rs.mElement_FLOAT_4 == null) {
rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
@@ -529,6 +588,8 @@
return rs.mElement_FLOAT_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element F64_2(RenderScript rs) {
if(rs.mElement_DOUBLE_2 == null) {
rs.mElement_DOUBLE_2 = createVector(rs, DataType.FLOAT_64, 2);
@@ -536,6 +597,8 @@
return rs.mElement_DOUBLE_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element F64_3(RenderScript rs) {
if(rs.mElement_DOUBLE_3 == null) {
rs.mElement_DOUBLE_3 = createVector(rs, DataType.FLOAT_64, 3);
@@ -543,6 +606,8 @@
return rs.mElement_DOUBLE_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element F64_4(RenderScript rs) {
if(rs.mElement_DOUBLE_4 == null) {
rs.mElement_DOUBLE_4 = createVector(rs, DataType.FLOAT_64, 4);
@@ -550,6 +615,8 @@
return rs.mElement_DOUBLE_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U8_2(RenderScript rs) {
if(rs.mElement_UCHAR_2 == null) {
rs.mElement_UCHAR_2 = createVector(rs, DataType.UNSIGNED_8, 2);
@@ -557,6 +624,8 @@
return rs.mElement_UCHAR_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U8_3(RenderScript rs) {
if(rs.mElement_UCHAR_3 == null) {
rs.mElement_UCHAR_3 = createVector(rs, DataType.UNSIGNED_8, 3);
@@ -564,6 +633,8 @@
return rs.mElement_UCHAR_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U8_4(RenderScript rs) {
if(rs.mElement_UCHAR_4 == null) {
rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
@@ -571,6 +642,8 @@
return rs.mElement_UCHAR_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I8_2(RenderScript rs) {
if(rs.mElement_CHAR_2 == null) {
rs.mElement_CHAR_2 = createVector(rs, DataType.SIGNED_8, 2);
@@ -578,6 +651,8 @@
return rs.mElement_CHAR_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I8_3(RenderScript rs) {
if(rs.mElement_CHAR_3 == null) {
rs.mElement_CHAR_3 = createVector(rs, DataType.SIGNED_8, 3);
@@ -585,6 +660,8 @@
return rs.mElement_CHAR_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I8_4(RenderScript rs) {
if(rs.mElement_CHAR_4 == null) {
rs.mElement_CHAR_4 = createVector(rs, DataType.SIGNED_8, 4);
@@ -592,6 +669,8 @@
return rs.mElement_CHAR_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U16_2(RenderScript rs) {
if(rs.mElement_USHORT_2 == null) {
rs.mElement_USHORT_2 = createVector(rs, DataType.UNSIGNED_16, 2);
@@ -599,6 +678,8 @@
return rs.mElement_USHORT_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U16_3(RenderScript rs) {
if(rs.mElement_USHORT_3 == null) {
rs.mElement_USHORT_3 = createVector(rs, DataType.UNSIGNED_16, 3);
@@ -606,6 +687,8 @@
return rs.mElement_USHORT_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U16_4(RenderScript rs) {
if(rs.mElement_USHORT_4 == null) {
rs.mElement_USHORT_4 = createVector(rs, DataType.UNSIGNED_16, 4);
@@ -613,6 +696,8 @@
return rs.mElement_USHORT_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I16_2(RenderScript rs) {
if(rs.mElement_SHORT_2 == null) {
rs.mElement_SHORT_2 = createVector(rs, DataType.SIGNED_16, 2);
@@ -620,6 +705,8 @@
return rs.mElement_SHORT_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I16_3(RenderScript rs) {
if(rs.mElement_SHORT_3 == null) {
rs.mElement_SHORT_3 = createVector(rs, DataType.SIGNED_16, 3);
@@ -627,6 +714,8 @@
return rs.mElement_SHORT_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I16_4(RenderScript rs) {
if(rs.mElement_SHORT_4 == null) {
rs.mElement_SHORT_4 = createVector(rs, DataType.SIGNED_16, 4);
@@ -634,6 +723,8 @@
return rs.mElement_SHORT_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U32_2(RenderScript rs) {
if(rs.mElement_UINT_2 == null) {
rs.mElement_UINT_2 = createVector(rs, DataType.UNSIGNED_32, 2);
@@ -641,6 +732,8 @@
return rs.mElement_UINT_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U32_3(RenderScript rs) {
if(rs.mElement_UINT_3 == null) {
rs.mElement_UINT_3 = createVector(rs, DataType.UNSIGNED_32, 3);
@@ -648,6 +741,8 @@
return rs.mElement_UINT_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U32_4(RenderScript rs) {
if(rs.mElement_UINT_4 == null) {
rs.mElement_UINT_4 = createVector(rs, DataType.UNSIGNED_32, 4);
@@ -655,6 +750,8 @@
return rs.mElement_UINT_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I32_2(RenderScript rs) {
if(rs.mElement_INT_2 == null) {
rs.mElement_INT_2 = createVector(rs, DataType.SIGNED_32, 2);
@@ -662,6 +759,8 @@
return rs.mElement_INT_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I32_3(RenderScript rs) {
if(rs.mElement_INT_3 == null) {
rs.mElement_INT_3 = createVector(rs, DataType.SIGNED_32, 3);
@@ -669,6 +768,8 @@
return rs.mElement_INT_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I32_4(RenderScript rs) {
if(rs.mElement_INT_4 == null) {
rs.mElement_INT_4 = createVector(rs, DataType.SIGNED_32, 4);
@@ -676,6 +777,8 @@
return rs.mElement_INT_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U64_2(RenderScript rs) {
if(rs.mElement_ULONG_2 == null) {
rs.mElement_ULONG_2 = createVector(rs, DataType.UNSIGNED_64, 2);
@@ -683,6 +786,8 @@
return rs.mElement_ULONG_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U64_3(RenderScript rs) {
if(rs.mElement_ULONG_3 == null) {
rs.mElement_ULONG_3 = createVector(rs, DataType.UNSIGNED_64, 3);
@@ -690,6 +795,8 @@
return rs.mElement_ULONG_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element U64_4(RenderScript rs) {
if(rs.mElement_ULONG_4 == null) {
rs.mElement_ULONG_4 = createVector(rs, DataType.UNSIGNED_64, 4);
@@ -697,6 +804,8 @@
return rs.mElement_ULONG_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I64_2(RenderScript rs) {
if(rs.mElement_LONG_2 == null) {
rs.mElement_LONG_2 = createVector(rs, DataType.SIGNED_64, 2);
@@ -704,6 +813,8 @@
return rs.mElement_LONG_2;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I64_3(RenderScript rs) {
if(rs.mElement_LONG_3 == null) {
rs.mElement_LONG_3 = createVector(rs, DataType.SIGNED_64, 3);
@@ -711,6 +822,8 @@
return rs.mElement_LONG_3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element I64_4(RenderScript rs) {
if(rs.mElement_LONG_4 == null) {
rs.mElement_LONG_4 = createVector(rs, DataType.SIGNED_64, 4);
@@ -718,16 +831,22 @@
return rs.mElement_LONG_4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element MATRIX_4X4(RenderScript rs) {
if(rs.mElement_MATRIX_4X4 == null) {
rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
}
return rs.mElement_MATRIX_4X4;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element MATRIX4X4(RenderScript rs) {
return MATRIX_4X4(rs);
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element MATRIX_3X3(RenderScript rs) {
if(rs.mElement_MATRIX_3X3 == null) {
rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3);
@@ -735,6 +854,8 @@
return rs.mElement_MATRIX_3X3;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static Element MATRIX_2X2(RenderScript rs) {
if(rs.mElement_MATRIX_2X2 == null) {
rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2);
@@ -824,7 +945,7 @@
updateVisibleSubElements();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a custom Element of the specified DataType. The DataKind will be
* set to USER and the vector size to 1 indicating non-vector.
*
@@ -840,7 +961,7 @@
return new Element(id, rs, dt, dk, norm, vecSize);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a custom vector element of the specified DataType and vector size.
* DataKind will be set to USER. Only primitive types (FLOAT_32, FLOAT_64,
* SIGNED_8, SIGNED_16, SIGNED_32, SIGNED_64, UNSIGNED_8, UNSIGNED_16,
@@ -884,7 +1005,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a new pixel Element type. A matching DataType and DataKind must
* be provided. The DataType and DataKind must contain the same number of
* components. Vector size will be set to 1.
@@ -947,7 +1068,7 @@
return new Element(id, rs, dt, dk, norm, size);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Check if the current Element is compatible with another Element.
* Primitive Elements are compatible if they share the same underlying
* size and type (i.e. U8 is compatible with A_8). User-defined Elements
@@ -974,7 +1095,7 @@
(mVectorSize == e.mVectorSize));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Builder class for producing complex elements with matching field and name
* pairs. The builder starts empty. The order in which elements are added
* is retained for the layout in memory.
@@ -988,7 +1109,7 @@
int mCount;
int mSkipPadding;
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a builder object.
*
* @param rs
@@ -1001,7 +1122,7 @@
mArraySizes = new int[8];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Add an array of elements to this element.
*
* @param element
@@ -1045,7 +1166,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Add a single element to this Element.
*
* @param element
@@ -1055,7 +1176,7 @@
return add(element, name, 1);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Create the element from this builder.
*
*
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index a215a57..9d36e33 100644
--- a/graphics/java/android/renderscript/FieldPacker.java
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -17,7 +17,7 @@
package android.renderscript;
-/**
+/** @deprecated renderscript is deprecated in J
* Utility class for packing arguments and structures from Android system objects to
* Renderscript objects.
*
diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java
index 61793171..1158061 100644
--- a/graphics/java/android/renderscript/FileA3D.java
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -27,7 +27,7 @@
import android.util.Log;
import android.util.TypedValue;
-/**
+/** @deprecated renderscript is deprecated in J
* FileA3D allows users to load Renderscript objects from files
* or resources stored on disk. It could be used to load items
* such as 3D geometry data converted to a Renderscript format from
@@ -40,17 +40,17 @@
**/
public class FileA3D extends BaseObj {
- /**
+ /** @deprecated renderscript is deprecated in J
* Specifies what renderscript object type is contained within
* the FileA3D IndexEntry
**/
public enum EntryType {
- /**
+ /** @deprecated renderscript is deprecated in J
* Unknown or or invalid object, nothing will be loaded
**/
UNKNOWN (0),
- /**
+ /** @deprecated renderscript is deprecated in J
* Renderscript Mesh object
**/
MESH (1);
@@ -65,7 +65,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* IndexEntry contains information about one of the Renderscript
* objects inside the file's index. It could be used to query the
* object's type and also name and load the object itself if
@@ -79,7 +79,7 @@
EntryType mEntryType;
BaseObj mLoadedObj;
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns the name of a renderscript object the index entry
* describes
*
@@ -91,7 +91,7 @@
return mName;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns the type of a renderscript object the index entry
* describes
* @return type of a renderscript object the index entry
@@ -101,7 +101,7 @@
return mEntryType;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Used to load the object described by the index entry
* @return base renderscript object described by the entry
*/
@@ -111,7 +111,7 @@
return obj;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Used to load the mesh described by the index entry, object
* described by the index entry must be a renderscript mesh
*
@@ -181,7 +181,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns the number of objects stored inside the a3d file
*
* @return the number of objects stored inside the a3d file
@@ -193,7 +193,7 @@
return mFileEntries.length;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns an index entry from the list of all objects inside
* FileA3D
*
@@ -208,7 +208,7 @@
return mFileEntries[index];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a FileA3D object from an asset stored on disk
*
* @param rs Context to which the object will belong.
@@ -229,7 +229,7 @@
return fa3d;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a FileA3D object from a file stored on disk
*
* @param rs Context to which the object will belong.
@@ -248,7 +248,7 @@
return fa3d;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a FileA3D object from a file stored on disk
*
* @param rs Context to which the object will belong.
@@ -260,7 +260,7 @@
return createFromFile(rs, path.getAbsolutePath());
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a FileA3D object from an application resource
*
* @param rs Context to which the object will belong.
diff --git a/graphics/java/android/renderscript/Float2.java b/graphics/java/android/renderscript/Float2.java
index 1d4ce36..a89a5df 100644
--- a/graphics/java/android/renderscript/Float2.java
+++ b/graphics/java/android/renderscript/Float2.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript float2 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Float3.java b/graphics/java/android/renderscript/Float3.java
index ffd1135..909a897 100644
--- a/graphics/java/android/renderscript/Float3.java
+++ b/graphics/java/android/renderscript/Float3.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript float2 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Float4.java b/graphics/java/android/renderscript/Float4.java
index c7cc3ae..3be6dbc 100644
--- a/graphics/java/android/renderscript/Float4.java
+++ b/graphics/java/android/renderscript/Float4.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript float2 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java
index 18dacac..cd1010c 100644
--- a/graphics/java/android/renderscript/Font.java
+++ b/graphics/java/android/renderscript/Font.java
@@ -29,8 +29,8 @@
import android.util.Log;
import android.util.TypedValue;
-/**
- * <p>This class gives users a simple way to draw hardware accelerated text.
+/** @deprecated renderscript is deprecated in J
+ * <p>This class gives users a simple way to draw hardware accelerated text.
* Internally, the glyphs are rendered using the Freetype library and an internal cache of
* rendered glyph bitmaps is maintained. Each font object represents a combination of a typeface,
* and point size. You can create multiple font objects to represent styles such as bold or italic text,
@@ -42,7 +42,7 @@
* render large batches of text in sequence. It is also more efficient to render multiple
* characters at once instead of one by one to improve draw call batching.</p>
* <p>Font color and transparency are not part of the font object and you can freely modify
- * them in the script to suit the user's rendering needs. Font colors work as a state machine.
+ * them in the script to suit the user's rendering needs. Font colors work as a state machine.
* Every new call to draw text uses the last color set in the script.</p>
**/
public class Font extends BaseObj {
@@ -71,10 +71,20 @@
private static Map<String, FontFamily> sFontFamilyMap;
+ /** @deprecated renderscript is deprecated in J
+ */
public enum Style {
+ /** @deprecated renderscript is deprecated in J
+ */
NORMAL,
+ /** @deprecated renderscript is deprecated in J
+ */
BOLD,
+ /** @deprecated renderscript is deprecated in J
+ */
ITALIC,
+ /** @deprecated renderscript is deprecated in J
+ */
BOLD_ITALIC;
}
@@ -138,7 +148,7 @@
super(id, rs);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Takes a specific file name as an argument
*/
static public Font createFromFile(RenderScript rs, Resources res, String path, float pointSize) {
@@ -154,10 +164,14 @@
return rsFont;
}
+ /** @deprecated renderscript is deprecated in J
+ */
static public Font createFromFile(RenderScript rs, Resources res, File path, float pointSize) {
return createFromFile(rs, res, path.getAbsolutePath(), pointSize);
}
+ /** @deprecated renderscript is deprecated in J
+ */
static public Font createFromAsset(RenderScript rs, Resources res, String path, float pointSize) {
rs.validate();
AssetManager mgr = res.getAssets();
@@ -171,6 +185,8 @@
return rsFont;
}
+ /** @deprecated renderscript is deprecated in J
+ */
static public Font createFromResource(RenderScript rs, Resources res, int id, float pointSize) {
String name = "R." + Integer.toString(id);
@@ -199,7 +215,7 @@
return rsFont;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Accepts one of the following family names as an argument
* and will attempt to produce the best match with a system font:
*
diff --git a/graphics/java/android/renderscript/Int2.java b/graphics/java/android/renderscript/Int2.java
index 434af21..4e2d344 100644
--- a/graphics/java/android/renderscript/Int2.java
+++ b/graphics/java/android/renderscript/Int2.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript int2 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Int3.java b/graphics/java/android/renderscript/Int3.java
index 333ccf8..1ffc129 100644
--- a/graphics/java/android/renderscript/Int3.java
+++ b/graphics/java/android/renderscript/Int3.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript int3 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Int4.java b/graphics/java/android/renderscript/Int4.java
index 8734c95..555d431 100644
--- a/graphics/java/android/renderscript/Int4.java
+++ b/graphics/java/android/renderscript/Int4.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript int4 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Long2.java b/graphics/java/android/renderscript/Long2.java
index 95ea18c..aad6bd6 100644
--- a/graphics/java/android/renderscript/Long2.java
+++ b/graphics/java/android/renderscript/Long2.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript long2 type back to the Android system.
**/
public class Long2 {
diff --git a/graphics/java/android/renderscript/Long3.java b/graphics/java/android/renderscript/Long3.java
index 96ee885..9c03d5c 100644
--- a/graphics/java/android/renderscript/Long3.java
+++ b/graphics/java/android/renderscript/Long3.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript long3 type back to the Android system.
**/
public class Long3 {
diff --git a/graphics/java/android/renderscript/Long4.java b/graphics/java/android/renderscript/Long4.java
index 50e664c..6611cdf 100644
--- a/graphics/java/android/renderscript/Long4.java
+++ b/graphics/java/android/renderscript/Long4.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript long4 type back to the Android system.
**/
public class Long4 {
diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java
index acc5bd8..38b5316 100644
--- a/graphics/java/android/renderscript/Matrix2f.java
+++ b/graphics/java/android/renderscript/Matrix2f.java
@@ -20,13 +20,13 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript rs_matrix2x2 type back to the Android system.
*
**/
public class Matrix2f {
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a new identity 2x2 matrix
*/
public Matrix2f() {
@@ -34,7 +34,7 @@
loadIdentity();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a new matrix and sets its values from the given
* parameter
*
@@ -46,7 +46,7 @@
System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return a reference to the internal array representing matrix
* values. Modifying this array will also change the matrix
*
@@ -56,7 +56,7 @@
return mMat;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns the value for a given row and column
*
* @param i row of the value to return
@@ -68,7 +68,7 @@
return mMat[i*2 + j];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the value for a given row and column
*
* @param i row of the value to set
@@ -78,7 +78,7 @@
mMat[i*2 + j] = v;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the matrix values to identity
*/
public void loadIdentity() {
@@ -89,7 +89,7 @@
mMat[3] = 1;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the values of the matrix to those of the parameter
*
* @param src matrix to load the values from
@@ -98,7 +98,7 @@
System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a rotation matrix of given angle
*
* @param rot rotation angle
@@ -114,7 +114,7 @@
mMat[3] = c;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a scale matrix of given dimensions
*
* @param x scale component x
@@ -126,7 +126,7 @@
mMat[3] = y;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be the result of multiplying two given
* matrices
*
@@ -147,7 +147,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Post-multiplies the current matrix by a given parameter
*
* @param rhs right hand side to multiply by
@@ -157,7 +157,7 @@
tmp.loadMultiply(this, rhs);
load(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the current matrix by post-multiplying it with a
* rotation matrix of given angle
*
@@ -168,7 +168,7 @@
tmp.loadRotate(rot);
multiply(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the current matrix by post-multiplying it with a
* scale matrix of given dimensions
*
@@ -180,7 +180,7 @@
tmp.loadScale(x, y);
multiply(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the current matrix to its transpose
*/
public void transpose() {
diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java
index 253506d..b821742 100644
--- a/graphics/java/android/renderscript/Matrix3f.java
+++ b/graphics/java/android/renderscript/Matrix3f.java
@@ -20,13 +20,13 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript rs_matrix3x3 type back to the Android system.
*
**/
public class Matrix3f {
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a new identity 3x3 matrix
*/
public Matrix3f() {
@@ -34,7 +34,7 @@
loadIdentity();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a new matrix and sets its values from the given
* parameter
*
@@ -46,7 +46,7 @@
System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return a reference to the internal array representing matrix
* values. Modifying this array will also change the matrix
*
@@ -56,7 +56,7 @@
return mMat;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns the value for a given row and column
*
* @param i row of the value to return
@@ -68,7 +68,7 @@
return mMat[i*3 + j];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the value for a given row and column
*
* @param i row of the value to set
@@ -78,7 +78,7 @@
mMat[i*3 + j] = v;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the matrix values to identity
*/
public void loadIdentity() {
@@ -95,7 +95,7 @@
mMat[8] = 1;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the values of the matrix to those of the parameter
*
* @param src matrix to load the values from
@@ -104,7 +104,7 @@
System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a rotation matrix of certain angle
* about a given axis
*
@@ -144,7 +144,7 @@
mMat[8] = z*z*nc + c;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Makes the upper 2x2 a rotation matrix of the given angle
*
* @param rot rotation angle
@@ -161,7 +161,7 @@
mMat[4] = c;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Makes the upper 2x2 a scale matrix of given dimensions
*
* @param x scale component x
@@ -173,7 +173,7 @@
mMat[4] = y;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a scale matrix of given dimensions
*
* @param x scale component x
@@ -187,7 +187,7 @@
mMat[8] = z;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a translation matrix of given
* dimensions
*
@@ -200,7 +200,7 @@
mMat[7] = y;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be the result of multiplying two given
* matrices
*
@@ -224,7 +224,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Post-multiplies the current matrix by a given parameter
*
* @param rhs right hand side to multiply by
@@ -235,7 +235,7 @@
load(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the current matrix by post-multiplying it with a
* rotation matrix of certain angle about a given axis
*
@@ -250,7 +250,7 @@
multiply(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the upper 2x2 of the current matrix by
* post-multiplying it with a rotation matrix of given angle
*
@@ -262,7 +262,7 @@
multiply(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the upper 2x2 of the current matrix by
* post-multiplying it with a scale matrix of given dimensions
*
@@ -275,7 +275,7 @@
multiply(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the current matrix by post-multiplying it with a
* scale matrix of given dimensions
*
@@ -289,7 +289,7 @@
multiply(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the current matrix by post-multiplying it with a
* translation matrix of given dimensions
*
@@ -302,7 +302,7 @@
multiply(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the current matrix to its transpose
*/
public void transpose() {
diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java
index adc1806..8b7a0df 100644
--- a/graphics/java/android/renderscript/Matrix4f.java
+++ b/graphics/java/android/renderscript/Matrix4f.java
@@ -20,13 +20,13 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript rs_matrix4x4 type back to the Android system.
*
**/
public class Matrix4f {
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a new identity 4x4 matrix
*/
public Matrix4f() {
@@ -34,7 +34,7 @@
loadIdentity();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a new matrix and sets its values from the given
* parameter
*
@@ -46,7 +46,7 @@
System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return a reference to the internal array representing matrix
* values. Modifying this array will also change the matrix
*
@@ -56,7 +56,7 @@
return mMat;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns the value for a given row and column
*
* @param i row of the value to return
@@ -68,7 +68,7 @@
return mMat[i*4 + j];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the value for a given row and column
*
* @param i row of the value to set
@@ -78,7 +78,7 @@
mMat[i*4 + j] = v;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the matrix values to identity
*/
public void loadIdentity() {
@@ -103,7 +103,7 @@
mMat[15] = 1;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the values of the matrix to those of the parameter
*
* @param src matrix to load the values from
@@ -112,7 +112,7 @@
System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a rotation matrix of certain angle
* about a given axis
*
@@ -159,7 +159,7 @@
mMat[10] = z*z*nc + c;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a scale matrix of given dimensions
*
* @param x scale component x
@@ -173,7 +173,7 @@
mMat[10] = z;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a translation matrix of given
* dimensions
*
@@ -188,7 +188,7 @@
mMat[14] = z;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be the result of multiplying two given
* matrices
*
@@ -215,7 +215,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set current values to be an orthographic projection matrix
*
* @param l location of the left vertical clipping plane
@@ -235,7 +235,7 @@
mMat[14]= -(f + n) / (f - n);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set current values to be an orthographic projection matrix
* with the right and bottom clipping planes set to the given
* values. Left and top clipping planes are set to 0. Near and
@@ -249,7 +249,7 @@
loadOrtho(0,w, h,0, -1,1);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a perspective projection matrix
*
* @param l location of the left vertical clipping plane
@@ -272,7 +272,7 @@
mMat[15]= 0;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets current values to be a perspective projection matrix
*
* @param fovy vertical field of view angle in degrees
@@ -288,7 +288,7 @@
loadFrustum(left, right, bottom, top, near, far);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Helper function to set the current values to a perspective
* projection matrix with aspect ratio defined by the parameters
* and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
@@ -321,7 +321,7 @@
load(m1);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Post-multiplies the current matrix by a given parameter
*
* @param rhs right hand side to multiply by
@@ -331,7 +331,7 @@
tmp.loadMultiply(this, rhs);
load(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the current matrix by post-multiplying it with a
* rotation matrix of certain angle about a given axis
*
@@ -346,7 +346,7 @@
multiply(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the current matrix by post-multiplying it with a
* scale matrix of given dimensions
*
@@ -360,7 +360,7 @@
multiply(tmp);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Modifies the current matrix by post-multiplying it with a
* translation matrix of given dimensions
*
@@ -392,7 +392,7 @@
return cofactor;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the current matrix to its inverse
*/
public boolean inverse() {
@@ -421,7 +421,7 @@
return true;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the current matrix to its inverse transpose
*/
public boolean inverseTranspose() {
@@ -449,7 +449,7 @@
return true;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the current matrix to its transpose
*/
public void transpose() {
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index ffbb41d..bc32038 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* <p>This class is a container for geometric data displayed with
* Renderscript. Internally, a mesh is a collection of allocations that
* represent vertex data (positions, normals, texture
@@ -39,34 +39,34 @@
**/
public class Mesh extends BaseObj {
- /**
+ /** @deprecated renderscript is deprecated in J
* Describes the way mesh vertex data is interpreted when rendering
*
**/
public enum Primitive {
- /**
+ /** @deprecated renderscript is deprecated in J
* Vertex data will be rendered as a series of points
*/
POINT (0),
- /**
+ /** @deprecated renderscript is deprecated in J
* Vertex pairs will be rendered as lines
*/
LINE (1),
- /**
+ /** @deprecated renderscript is deprecated in J
* Vertex data will be rendered as a connected line strip
*/
LINE_STRIP (2),
- /**
+ /** @deprecated renderscript is deprecated in J
* Vertices will be rendered as individual triangles
*/
TRIANGLE (3),
- /**
+ /** @deprecated renderscript is deprecated in J
* Vertices will be rendered as a connected triangle strip
* defined by the first three vertices with each additional
* triangle defined by a new vertex
*/
TRIANGLE_STRIP (4),
- /**
+ /** @deprecated renderscript is deprecated in J
* Vertices will be rendered as a sequence of triangles that all
* share first vertex as the origin
*/
@@ -86,7 +86,7 @@
super(id, rs);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @return number of allocations containing vertex data
*
**/
@@ -96,7 +96,7 @@
}
return mVertexBuffers.length;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @param slot index in the list of allocations to return
* @return vertex data allocation at the given index
*
@@ -105,7 +105,7 @@
return mVertexBuffers[slot];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @return number of primitives or index sets in the mesh
*
**/
@@ -116,7 +116,7 @@
return mIndexBuffers.length;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @param slot locaton within the list of index set allocation
* @return allocation containing primtive index data or null if
* the index data is not specified explicitly
@@ -125,7 +125,7 @@
public Allocation getIndexSetAllocation(int slot) {
return mIndexBuffers[slot];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @param slot locaiton within the list of index set primitives
* @return index set primitive type
*
@@ -167,7 +167,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Mesh builder object. It starts empty and requires you to
* add the types necessary to create vertex and index
* allocations.
@@ -189,7 +189,7 @@
Entry[] mVertexTypes;
Vector mIndexTypes;
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates builder object
* @param rs Context to which the mesh will belong.
* @param usage specifies how the mesh allocations are to be
@@ -204,7 +204,7 @@
mIndexTypes = new Vector();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @return internal index of the last vertex buffer type added to
* builder
**/
@@ -212,7 +212,7 @@
return mVertexTypeCount - 1;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @return internal index of the last index set added to the
* builder
**/
@@ -220,7 +220,7 @@
return mIndexTypes.size() - 1;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds a vertex data type to the builder object
*
* @param t type of the vertex data allocation to be created
@@ -239,7 +239,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds a vertex data type to the builder object
*
* @param e element describing the vertex data layout
@@ -260,7 +260,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds an index set data type to the builder object
*
* @param t type of the index set data, could be null
@@ -278,7 +278,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds an index set primitive type to the builder object
*
* @param p primitive type
@@ -295,7 +295,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds an index set data type to the builder object
*
* @param e element describing the index set data layout
@@ -320,7 +320,7 @@
return tb.create();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a Mesh object from the current state of the builder
*
**/
@@ -372,7 +372,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Mesh builder object. It starts empty and requires the user to
* add all the vertex and index allocations that comprise the
* mesh
@@ -391,6 +391,8 @@
Vector mIndexTypes;
+ /** @deprecated renderscript is deprecated in J
+ */
public AllocationBuilder(RenderScript rs) {
mRS = rs;
mVertexTypeCount = 0;
@@ -398,7 +400,7 @@
mIndexTypes = new Vector();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @return internal index of the last vertex buffer type added to
* builder
**/
@@ -406,7 +408,7 @@
return mVertexTypeCount - 1;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* @return internal index of the last index set added to the
* builder
**/
@@ -414,7 +416,7 @@
return mIndexTypes.size() - 1;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds an allocation containing vertex buffer data to the
* builder
*
@@ -433,7 +435,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds an allocation containing index buffer data and index type
* to the builder
*
@@ -450,7 +452,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds an index set type to the builder
*
* @param p index set primitive type
@@ -465,7 +467,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a Mesh object from the current state of the builder
*
**/
@@ -506,7 +508,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Builder that allows creation of a mesh object point by point
* and triangle by triangle
*
@@ -533,11 +535,17 @@
int mVtxSize;
int mFlags;
+ /** @deprecated renderscript is deprecated in J
+ */
public static final int COLOR = 0x0001;
+ /** @deprecated renderscript is deprecated in J
+ */
public static final int NORMAL = 0x0002;
+ /** @deprecated renderscript is deprecated in J
+ */
public static final int TEXTURE_0 = 0x0100;
- /**
+ /** @deprecated renderscript is deprecated in J
* @param rs Context to which the mesh will belong.
* @param vtxSize specifies whether the vertex is a float2 or
* float3
@@ -592,7 +600,7 @@
mMaxIndex ++;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds a float2 vertex to the mesh
*
* @param x position x
@@ -612,7 +620,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds a float3 vertex to the mesh
*
* @param x position x
@@ -635,7 +643,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the texture coordinate for the vertices that are added after this method call.
*
* @param s texture coordinate s
@@ -652,7 +660,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the normal vector for the vertices that are added after this method call.
*
* @param x normal vector x
@@ -671,7 +679,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the color for the vertices that are added after this method call.
*
* @param r red component
@@ -692,7 +700,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds a new triangle to the mesh builder
*
* @param idx1 index of the first vertex in the triangle
@@ -718,7 +726,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates the mesh object from the current state of the builder
*
* @param uploadToBufferObject specifies whether the vertex data
diff --git a/graphics/java/android/renderscript/Path.java b/graphics/java/android/renderscript/Path.java
index 9c4d41b..ec34d7c 100644
--- a/graphics/java/android/renderscript/Path.java
+++ b/graphics/java/android/renderscript/Path.java
@@ -19,7 +19,7 @@
import java.util.Vector;
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* @hide
*
*/
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index d9f64c6..16186fa 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -25,7 +25,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
*
* Program is a base class for all the objects that modify
* various stages of the graphics pipeline
@@ -37,14 +37,18 @@
static final int MAX_CONSTANT = 8;
static final int MAX_TEXTURE = 8;
- /**
+ /** @deprecated renderscript is deprecated in J
*
* TextureType specifies what textures are attached to Program
* objects
*
**/
public enum TextureType {
+ /** @deprecated renderscript is deprecated in J
+ */
TEXTURE_2D (0),
+ /** @deprecated renderscript is deprecated in J
+ */
TEXTURE_CUBE (1);
int mID;
@@ -77,7 +81,7 @@
super(id, rs);
}
- /**
+ /** @hide renderscript is deprecated in J
* Program object can have zero or more constant allocations
* associated with it. This method returns the total count.
* @return number of constant input types
@@ -86,7 +90,7 @@
return mConstants != null ? mConstants.length : 0;
}
- /**
+ /** @hide renderscript is deprecated in J
* Returns the type of the constant buffer used in the program
* object. It could be used to query internal elements or create
* an allocation to store constant data.
@@ -100,7 +104,7 @@
return mConstants[slot];
}
- /**
+ /** @hide renderscript is deprecated in J
* Returns the number of textures used in this program object
* @return number of texture inputs
*/
@@ -108,7 +112,7 @@
return mTextureCount;
}
- /**
+ /** @hide renderscript is deprecated in J
* Returns the type of texture at a given slot. e.g. 2D or Cube
* @param slot index of the texture input
* @return texture input type
@@ -120,7 +124,7 @@
return mTextures[slot];
}
- /**
+ /** @hide renderscript is deprecated in J
* Returns the name of the texture input at a given slot. e.g.
* tex0, diffuse, spec
* @param slot index of the texture input
@@ -133,7 +137,7 @@
return mTextureNames[slot];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Binds a constant buffer to be used as uniform inputs to the
* program
*
@@ -153,7 +157,7 @@
mRS.nProgramBindConstants(getID(mRS), slot, id);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Binds a texture to be used in the program
*
* @param va allocation containing texture data
@@ -175,7 +179,7 @@
mRS.nProgramBindTexture(getID(mRS), slot, id);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Binds an object that describes how a texture at the
* corresponding location is sampled
*
@@ -210,7 +214,8 @@
int mTextureCount;
String mShader;
-
+ /** @deprecated renderscript is deprecated in J
+ */
protected BaseProgramBuilder(RenderScript rs) {
mRS = rs;
mInputs = new Element[MAX_INPUT];
@@ -224,7 +229,7 @@
mTextureNames = new String[MAX_TEXTURE];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the GLSL shader code to be used in the program
*
* @param s GLSL shader string
@@ -235,7 +240,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the GLSL shader code to be used in the program
*
* @param resources application resources
@@ -281,7 +286,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Queries the index of the last added constant buffer type
*
*/
@@ -289,7 +294,7 @@
return mConstantCount - 1;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Queries the index of the last added texture type
*
*/
@@ -297,7 +302,7 @@
return mTextureCount - 1;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds constant (uniform) inputs to the program
*
* @param t Type that describes the layout of the Allocation
@@ -317,7 +322,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds a texture input to the Program
*
* @param texType describes that the texture to append it (2D,
@@ -329,7 +334,7 @@
return this;
}
- /**
+ /** @hide renderscript is deprecated in J
* Adds a texture input to the Program
*
* @param texType describes that the texture to append it (2D,
@@ -349,6 +354,8 @@
return this;
}
+ /** @deprecated renderscript is deprecated in J
+ */
protected void initProgram(Program p) {
p.mInputs = new Element[mInputCount];
System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index fa6e2d4..0427c19 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* <p>The Renderscript fragment program, also known as fragment shader is responsible
* for manipulating pixel data in a user defined way. It's constructed from a GLSL
* shader string containing the program body, textures inputs, and a Type object
@@ -42,7 +42,7 @@
}
public static class Builder extends BaseProgramBuilder {
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a builder object.
*
* @param rs Context to which the program will belong.
@@ -51,7 +51,7 @@
super(rs);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates ProgramFragment from the current state of the builder
*
* @return ProgramFragment
diff --git a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
index 14f10f1..19fca58 100644
--- a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* <p>ProgramFragmentFixedFunction is a helper class that provides
* a way to make a simple fragment shader without writing any
* GLSL code. This class allows for display of constant color, interpolated
@@ -38,7 +38,7 @@
super(rs);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates ProgramFragmentFixedFunction from the current state
* of the builder
*
@@ -76,6 +76,8 @@
}
public static class Builder {
+ /** @deprecated renderscript is deprecated in J
+ */
public static final int MAX_TEXTURE = 2;
int mNumTextures;
boolean mPointSpriteEnable;
@@ -83,14 +85,20 @@
String mShader;
RenderScript mRS;
- /**
+ /** @deprecated renderscript is deprecated in J
* EnvMode describes how textures are combined with the existing
* color in the fixed function fragment shader
*
**/
public enum EnvMode {
+ /** @deprecated renderscript is deprecated in J
+ */
REPLACE (1),
+ /** @deprecated renderscript is deprecated in J
+ */
MODULATE (2),
+ /** @deprecated renderscript is deprecated in J
+ */
DECAL (3);
int mID;
@@ -99,15 +107,23 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Format describes the pixel format of textures in the fixed
* function fragment shader and how they are sampled
*
**/
public enum Format {
+ /** @deprecated renderscript is deprecated in J
+ */
ALPHA (1),
+ /** @deprecated renderscript is deprecated in J
+ */
LUMINANCE_ALPHA (2),
+ /** @deprecated renderscript is deprecated in J
+ */
RGB (3),
+ /** @deprecated renderscript is deprecated in J
+ */
RGBA (4);
int mID;
@@ -190,7 +206,7 @@
mShader += "}\n";
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a builder for fixed function fragment program
*
* @param rs Context to which the program will belong.
@@ -201,7 +217,7 @@
mPointSpriteEnable = false;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Adds a texture to be fetched as part of the fixed function
* fragment program
*
@@ -223,7 +239,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Specifies whether the texture coordinate passed from the
* vertex program is replaced with an openGL internal point
* sprite texture coordinate
@@ -234,7 +250,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Specifies whether the varying color passed from the vertex
* program or the constant color set on the fragment program is
* used in the final color calculation in the fixed function
@@ -246,7 +262,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates the fixed function fragment program from the current
* state of the builder.
*
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index e40751f..26fcafe 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -20,15 +20,23 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Program raster is primarily used to specify whether point sprites are enabled and to control
* the culling mode. By default, back faces are culled.
**/
public class ProgramRaster extends BaseObj {
+ /** @deprecated renderscript is deprecated in J
+ */
public enum CullMode {
+ /** @deprecated renderscript is deprecated in J
+ */
BACK (0),
+ /** @deprecated renderscript is deprecated in J
+ */
FRONT (1),
+ /** @deprecated renderscript is deprecated in J
+ */
NONE (2);
int mID;
@@ -47,7 +55,7 @@
mCullMode = CullMode.BACK;
}
- /**
+ /** @hide renderscript is deprecated in J
* Specifies whether vertices are rendered as screen aligned
* elements of a specified size
* @return whether point sprites are enabled
@@ -56,7 +64,7 @@
return mPointSprite;
}
- /**
+ /** @hide renderscript is deprecated in J
* Specifies how triangles are culled based on their orientation
* @return cull mode
*/
@@ -64,6 +72,8 @@
return mCullMode;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static ProgramRaster CULL_BACK(RenderScript rs) {
if(rs.mProgramRaster_CULL_BACK == null) {
ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -73,6 +83,8 @@
return rs.mProgramRaster_CULL_BACK;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static ProgramRaster CULL_FRONT(RenderScript rs) {
if(rs.mProgramRaster_CULL_FRONT == null) {
ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -82,6 +94,8 @@
return rs.mProgramRaster_CULL_FRONT;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static ProgramRaster CULL_NONE(RenderScript rs) {
if(rs.mProgramRaster_CULL_NONE == null) {
ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -91,27 +105,37 @@
return rs.mProgramRaster_CULL_NONE;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public static class Builder {
RenderScript mRS;
boolean mPointSprite;
CullMode mCullMode;
+ /** @deprecated renderscript is deprecated in J
+ */
public Builder(RenderScript rs) {
mRS = rs;
mPointSprite = false;
mCullMode = CullMode.BACK;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public Builder setPointSpriteEnabled(boolean enable) {
mPointSprite = enable;
return this;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public Builder setCullMode(CullMode m) {
mCullMode = m;
return this;
}
+ /** @deprecated renderscript is deprecated in J
+ */
public ProgramRaster create() {
mRS.validate();
int id = mRS.nProgramRasterCreate(mPointSprite, mCullMode.mID);
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index d0fd6e5..20043f2 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* <p>ProgramStore contains a set of parameters that control how
* the graphics hardware handles writes to the framebuffer.
* It could be used to:</p>
@@ -35,7 +35,7 @@
*
**/
public class ProgramStore extends BaseObj {
- /**
+ /** @deprecated renderscript is deprecated in J
* Specifies the function used to determine whether a fragment
* will be drawn during the depth testing stage in the rendering
* pipeline by comparing its value with that already in the depth
@@ -44,36 +44,36 @@
*/
public enum DepthFunc {
- /**
+ /** @deprecated renderscript is deprecated in J
* Always drawn
*/
ALWAYS (0),
- /**
+ /** @deprecated renderscript is deprecated in J
* Drawn if the incoming depth value is less than that in the
* depth buffer
*/
LESS (1),
- /**
+ /** @deprecated renderscript is deprecated in J
* Drawn if the incoming depth value is less or equal to that in
* the depth buffer
*/
LESS_OR_EQUAL (2),
- /**
+ /** @deprecated renderscript is deprecated in J
* Drawn if the incoming depth value is greater than that in the
* depth buffer
*/
GREATER (3),
- /**
+ /** @deprecated renderscript is deprecated in J
* Drawn if the incoming depth value is greater or equal to that
* in the depth buffer
*/
GREATER_OR_EQUAL (4),
- /**
+ /** @deprecated renderscript is deprecated in J
* Drawn if the incoming depth value is equal to that in the
* depth buffer
*/
EQUAL (5),
- /**
+ /** @deprecated renderscript is deprecated in J
* Drawn if the incoming depth value is not equal to that in the
* depth buffer
*/
@@ -85,7 +85,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Specifies the functions used to combine incoming pixels with
* those already in the frame buffer.
*
@@ -94,14 +94,32 @@
*
*/
public enum BlendSrcFunc {
+ /** @deprecated renderscript is deprecated in J
+ */
ZERO (0),
+ /** @deprecated renderscript is deprecated in J
+ */
ONE (1),
+ /** @deprecated renderscript is deprecated in J
+ */
DST_COLOR (2),
+ /** @deprecated renderscript is deprecated in J
+ */
ONE_MINUS_DST_COLOR (3),
+ /** @deprecated renderscript is deprecated in J
+ */
SRC_ALPHA (4),
+ /** @deprecated renderscript is deprecated in J
+ */
ONE_MINUS_SRC_ALPHA (5),
+ /** @deprecated renderscript is deprecated in J
+ */
DST_ALPHA (6),
+ /** @deprecated renderscript is deprecated in J
+ */
ONE_MINUS_DST_ALPHA (7),
+ /** @deprecated renderscript is deprecated in J
+ */
SRC_ALPHA_SATURATE (8);
int mID;
@@ -110,7 +128,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Specifies the functions used to combine incoming pixels with
* those already in the frame buffer.
*
@@ -120,13 +138,29 @@
*
*/
public enum BlendDstFunc {
+ /** @deprecated renderscript is deprecated in J
+ */
ZERO (0),
+ /** @deprecated renderscript is deprecated in J
+ */
ONE (1),
+ /** @deprecated renderscript is deprecated in J
+ */
SRC_COLOR (2),
+ /** @deprecated renderscript is deprecated in J
+ */
ONE_MINUS_SRC_COLOR (3),
+ /** @deprecated renderscript is deprecated in J
+ */
SRC_ALPHA (4),
+ /** @deprecated renderscript is deprecated in J
+ */
ONE_MINUS_SRC_ALPHA (5),
+ /** @deprecated renderscript is deprecated in J
+ */
DST_ALPHA (6),
+ /** @deprecated renderscript is deprecated in J
+ */
ONE_MINUS_DST_ALPHA (7);
int mID;
@@ -149,7 +183,7 @@
super(id, rs);
}
- /**
+ /** @hide renderscript is deprecated in J
* Returns the function used to test writing into the depth
* buffer
* @return depth function
@@ -158,7 +192,7 @@
return mDepthFunc;
}
- /**
+ /** @hide renderscript is deprecated in J
* Queries whether writes are enabled into the depth buffer
* @return depth mask
*/
@@ -166,7 +200,7 @@
return mDepthMask;
}
- /**
+ /** @hide renderscript is deprecated in J
* Queries whether red channel is written
* @return red color channel mask
*/
@@ -174,7 +208,7 @@
return mColorMaskR;
}
- /**
+ /** @hide renderscript is deprecated in J
* Queries whether green channel is written
* @return green color channel mask
*/
@@ -182,7 +216,7 @@
return mColorMaskG;
}
- /**
+ /** @hide renderscript is deprecated in J
* Queries whether blue channel is written
* @return blue color channel mask
*/
@@ -190,7 +224,7 @@
return mColorMaskB;
}
- /**
+ /** @hide renderscript is deprecated in J
* Queries whether alpha channel is written
* @return alpha channel mask
*/
@@ -198,7 +232,7 @@
return mColorMaskA;
}
- /**
+ /** @hide renderscript is deprecated in J
* Specifies how the source blending factor is computed
* @return source blend function
*/
@@ -206,7 +240,7 @@
return mBlendSrc;
}
- /**
+ /** @hide renderscript is deprecated in J
* Specifies how the destination blending factor is computed
* @return destination blend function
*/
@@ -214,7 +248,7 @@
return mBlendDst;
}
- /**
+ /** @hide renderscript is deprecated in J
* Specifies whether colors are dithered before writing into the
* framebuffer
* @return whether dither is enabled
@@ -223,7 +257,7 @@
return mDither;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns a pre-defined program store object with the following
* characteristics:
* - incoming pixels are drawn if their depth value is less than
@@ -245,7 +279,7 @@
}
return rs.mProgramStore_BLEND_NONE_DEPTH_TEST;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns a pre-defined program store object with the following
* characteristics:
* - incoming pixels always pass the depth test and their value
@@ -266,7 +300,7 @@
}
return rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns a pre-defined program store object with the following
* characteristics:
* - incoming pixels are drawn if their depth value is less than
@@ -290,7 +324,7 @@
}
return rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns a pre-defined program store object with the following
* characteristics:
* - incoming pixels always pass the depth test and their value
@@ -313,7 +347,7 @@
return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Builder class for ProgramStore object. If the builder is left
* empty, the equivalent of BLEND_NONE_DEPTH_NONE would be
* returned
@@ -342,7 +376,7 @@
mBlendDst = BlendDstFunc.ZERO;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Specifies the depth testing behavior
*
* @param func function used for depth testing
@@ -354,7 +388,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Enables writes into the depth buffer
*
* @param enable specifies whether depth writes are
@@ -367,7 +401,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Enables writes into the color buffer
*
* @param r specifies whether red channel is written
@@ -385,7 +419,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Specifies how incoming pixels are combined with the pixels
* stored in the framebuffer
*
@@ -402,7 +436,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Enables dithering
*
* @param enable specifies whether dithering is enabled or
@@ -415,7 +449,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a program store from the current state of the builder
*/
public ProgramStore create() {
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 74d666b..c13b9b0 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
- /**
+ /** @deprecated renderscript is deprecated in J
* <p>The Renderscript vertex program, also known as a vertex shader, describes a stage in
* the graphics pipeline responsible for manipulating geometric data in a user-defined way.
* The object is constructed by providing the Renderscript system with the following data:</p>
@@ -42,7 +42,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* ProgramVertex, also know as a vertex shader, describes a
* stage in the graphics pipeline responsible for manipulating
* geometric data in a user-defined way.
@@ -54,14 +54,14 @@
super(id, rs);
}
- /**
+ /** @hide renderscript is deprecated in J
* @return number of input attribute elements
*/
public int getInputCount() {
return mInputs != null ? mInputs.length : 0;
}
- /**
+ /** @hide renderscript is deprecated in J
* @param slot location of the input to return
* @return input attribute element
*/
@@ -72,7 +72,7 @@
return mInputs[slot];
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Builder class for creating ProgramVertex objects.
* The builder starts empty and the user must minimally provide
* the GLSL shader code, and the varying inputs. Constant, or
@@ -81,7 +81,7 @@
*
**/
public static class Builder extends BaseProgramBuilder {
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a builder object.
*
* @param rs Context to which the program will belong.
@@ -90,7 +90,7 @@
super(rs);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Add varying inputs to the program
*
* @param e element describing the layout of the varying input
@@ -109,7 +109,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates ProgramVertex from the current state of the builder
*
* @return ProgramVertex
diff --git a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
index 54f21b8..97444db 100644
--- a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -21,7 +21,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* ProgramVertexFixedFunction is a helper class that provides a
* simple way to create a fixed function emulation vertex shader
* without writing any GLSL code.
@@ -33,7 +33,7 @@
super(id, rs);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Binds the constant buffer containing fixed function emulation
* matrices
*
@@ -61,7 +61,7 @@
return this;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates ProgramVertexFixedFunction from the current state of
* the builder
*
@@ -103,7 +103,7 @@
String mShader;
RenderScript mRS;
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a builder for fixed function vertex program
*
* @param rs Context to which the program will belong.
@@ -112,7 +112,7 @@
mRS = rs;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Specifies whether texture matrix calculations are to be added
* to the shader
*
@@ -152,7 +152,7 @@
mShader += "}\n";
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates ProgramVertexFixedFunction from the current state of
* the builder
*
@@ -176,7 +176,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Helper class to store modelview, projection and texture
* matrices for ProgramVertexFixedFunction
*
@@ -196,7 +196,7 @@
}
private FieldPacker mIOBuffer;
- /**
+ /** @deprecated renderscript is deprecated in J
* Creates a buffer to store fixed function emulation matrices
*
* @param rs Context to which the allocation will belong.
@@ -215,7 +215,7 @@
setTexture(new Matrix4f());
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Forces deallocation of memory backing the contant matrices.
* Normally, this is unnecessary and will be garbage collected
*
@@ -233,7 +233,7 @@
mAlloc.setFromFieldPacker(0, mIOBuffer);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the modelview matrix in the fixed function matrix buffer
*
* @param m modelview matrix
@@ -243,7 +243,7 @@
addToBuffer(MODELVIEW_OFFSET*4, m);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the projection matrix in the fixed function matrix buffer
*
* @param m projection matrix
@@ -253,7 +253,7 @@
addToBuffer(PROJECTION_OFFSET*4, m);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Sets the texture matrix in the fixed function matrix buffer.
* Texture matrix must be enabled in the
* ProgramVertexFixedFunction builder for the shader to utilize
diff --git a/graphics/java/android/renderscript/RSDriverException.java b/graphics/java/android/renderscript/RSDriverException.java
index ce85b53..1784087 100644
--- a/graphics/java/android/renderscript/RSDriverException.java
+++ b/graphics/java/android/renderscript/RSDriverException.java
@@ -17,7 +17,7 @@
package android.renderscript;
-/**
+/** @deprecated renderscript is deprecated in J
* Base class for all exceptions thrown by the Android
* Renderscript
*/
diff --git a/graphics/java/android/renderscript/RSIllegalArgumentException.java b/graphics/java/android/renderscript/RSIllegalArgumentException.java
index 954c0e8..039d8f5 100644
--- a/graphics/java/android/renderscript/RSIllegalArgumentException.java
+++ b/graphics/java/android/renderscript/RSIllegalArgumentException.java
@@ -17,11 +17,13 @@
package android.renderscript;
-/**
+/** @deprecated renderscript is deprecated in J
* Base class for all exceptions thrown by the Android
* Renderscript
*/
public class RSIllegalArgumentException extends RSRuntimeException {
+ /** @deprecated renderscript is deprecated in J
+ */
public RSIllegalArgumentException(String string) {
super(string);
}
diff --git a/graphics/java/android/renderscript/RSInvalidStateException.java b/graphics/java/android/renderscript/RSInvalidStateException.java
index 691aeba..ccbaea1 100644
--- a/graphics/java/android/renderscript/RSInvalidStateException.java
+++ b/graphics/java/android/renderscript/RSInvalidStateException.java
@@ -17,11 +17,13 @@
package android.renderscript;
-/**
+/** @deprecated renderscript is deprecated in J
* Base class for all exceptions thrown by the Android
* Renderscript
*/
public class RSInvalidStateException extends RSRuntimeException {
+ /** @deprecated renderscript is deprecated in J
+ */
public RSInvalidStateException(String string) {
super(string);
}
diff --git a/graphics/java/android/renderscript/RSRuntimeException.java b/graphics/java/android/renderscript/RSRuntimeException.java
index 5a16478..3fb1ea9 100644
--- a/graphics/java/android/renderscript/RSRuntimeException.java
+++ b/graphics/java/android/renderscript/RSRuntimeException.java
@@ -17,12 +17,14 @@
package android.renderscript;
-/**
+/** @deprecated renderscript is deprecated in J
* Base class for all exceptions thrown by the Android
* Renderscript
*/
public class RSRuntimeException
extends java.lang.RuntimeException {
+ /** @deprecated renderscript is deprecated in J
+ */
public RSRuntimeException(String string) {
super(string);
}
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 6756fd0..997b7d0 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -29,7 +29,7 @@
import android.view.SurfaceHolder;
import android.view.SurfaceView;
-/**
+/** @deprecated renderscript is deprecated in J
* The Surface View for a graphics renderscript (RenderScriptGL) to draw on.
*
* <div class="special reference">
@@ -42,7 +42,7 @@
private SurfaceHolder mSurfaceHolder;
private RenderScriptGL mRS;
- /**
+ /** @deprecated renderscript is deprecated in J
* Standard View constructor. In order to render something, you
* must call {@link android.opengl.GLSurfaceView#setRenderer} to
* register a renderer.
@@ -53,7 +53,7 @@
//Log.v(RenderScript.LOG_TAG, "RSSurfaceView");
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Standard View constructor. In order to render something, you
* must call {@link android.opengl.GLSurfaceView#setRenderer} to
* register a renderer.
@@ -71,7 +71,7 @@
holder.addCallback(this);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* This method is part of the SurfaceHolder.Callback interface, and is
* not normally called or subclassed by clients of RSSurfaceView.
*/
@@ -79,7 +79,7 @@
mSurfaceHolder = holder;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* This method is part of the SurfaceHolder.Callback interface, and is
* not normally called or subclassed by clients of RSSurfaceView.
*/
@@ -92,7 +92,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* This method is part of the SurfaceHolder.Callback interface, and is
* not normally called or subclassed by clients of RSSurfaceView.
*/
@@ -104,7 +104,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Inform the view that the activity is paused. The owner of this view must
* call this method when the activity is paused. Calling this method will
* pause the rendering thread.
@@ -116,7 +116,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Inform the view that the activity is resumed. The owner of this view must
* call this method when the activity is resumed. Calling this method will
* recreate the OpenGL display and resume the rendering
diff --git a/graphics/java/android/renderscript/RSTextureView.java b/graphics/java/android/renderscript/RSTextureView.java
index 30b2f99..b40f73c 100644
--- a/graphics/java/android/renderscript/RSTextureView.java
+++ b/graphics/java/android/renderscript/RSTextureView.java
@@ -28,7 +28,7 @@
import android.util.Log;
import android.view.TextureView;
-/**
+/** @deprecated renderscript is deprecated in J
* The Texture View for a graphics renderscript (RenderScriptGL)
* to draw on.
*
@@ -37,7 +37,7 @@
private RenderScriptGL mRS;
private SurfaceTexture mSurfaceTexture;
- /**
+ /** @deprecated renderscript is deprecated in J
* Standard View constructor. In order to render something, you
* must call {@link android.opengl.GLSurfaceView#setRenderer} to
* register a renderer.
@@ -48,7 +48,7 @@
//Log.v(RenderScript.LOG_TAG, "RSSurfaceView");
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Standard View constructor. In order to render something, you
* must call {@link android.opengl.GLSurfaceView#setRenderer} to
* register a renderer.
@@ -102,7 +102,7 @@
mSurfaceTexture = surface;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Inform the view that the activity is paused. The owner of this view must
* call this method when the activity is paused. Calling this method will
* pause the rendering thread.
@@ -114,7 +114,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Inform the view that the activity is resumed. The owner of this view must
* call this method when the activity is resumed. Calling this method will
* recreate the OpenGL display and resume the rendering
@@ -127,7 +127,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a new RenderScriptGL object and attach it to the
* TextureView if present.
*
@@ -145,7 +145,7 @@
return rs;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Destroy the RenderScriptGL object associated with this
* TextureView.
*/
@@ -154,7 +154,7 @@
mRS = null;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set a new RenderScriptGL object. This also will attach the
* new object to the TextureView if present.
*
@@ -167,7 +167,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Returns the previously set RenderScriptGL object.
*
* @return RenderScriptGL
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index abbcdd9..9a5b349 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -32,7 +32,7 @@
-/**
+/** @deprecated renderscript is deprecated in J
* Renderscript base master class. An instance of this class creates native
* worker threads for processing commands from this object. This base class
* does not provide any extended capabilities beyond simple data processing.
@@ -736,7 +736,7 @@
///////////////////////////////////////////////////////////////////////////////////
//
- /**
+ /** @deprecated renderscript is deprecated in J
* Base class application should derive from for handling RS messages
* coming from their scripts. When a script calls sendToClient the data
* fields will be filled in and then the run method called by a message
@@ -751,7 +751,7 @@
public void run() {
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* If an application is expecting messages it should set this field to an
* instance of RSMessage. This instance will receive all the user messages
* sent from sendToClient by scripts from this context.
@@ -766,7 +766,7 @@
return mMessageCallback;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Runtime error base class. An application should derive from this class
* if it wishes to install an error handler. When errors occur at runtime
* the fields in this class will be filled and the run method called.
@@ -779,7 +779,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Application Error handler. All runtime errors will be dispatched to the
* instance of RSAsyncError set here. If this field is null a
* RSRuntimeException will instead be thrown with details about the error.
@@ -795,7 +795,7 @@
return mErrorCallback;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* RenderScript worker threads priority enumeration. The default value is
* NORMAL. Applications wishing to do background processing such as
* wallpapers should set their priority to LOW to avoid starving forground
@@ -818,7 +818,7 @@
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Change the priority of the worker threads for this context.
*
* @param p New priority to be set.
@@ -915,7 +915,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Gets the application context associated with the RenderScript context.
*
* @return The application context.
@@ -924,7 +924,7 @@
return mApplicationContext;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a basic RenderScript context.
*
* @hide
@@ -944,7 +944,7 @@
return rs;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a basic RenderScript context.
*
* @param ctx The context.
@@ -955,7 +955,7 @@
return create(ctx, v);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Print the currently available debugging information about the state of
* the RS context to the log.
*
@@ -965,7 +965,7 @@
nContextDump(0);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Wait for any commands in the fifo between the java bindings and native to
* be processed.
*
@@ -974,7 +974,7 @@
nContextFinish();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Destroy this renderscript context. Once this function is called its no
* longer legal to use this or any objects created by this context.
*
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 1b2ac90..ac1a392 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -28,7 +28,7 @@
import android.view.SurfaceHolder;
import android.view.SurfaceView;
-/**
+/** @deprecated renderscript is deprecated in J
* The Graphics derivitive of Renderscript. Extends the basic context to add a
* root script which is the display window for graphical output. When the
* system needs to update the display the currently bound root script will be
@@ -45,7 +45,7 @@
int mWidth;
int mHeight;
- /**
+ /** @deprecated renderscript is deprecated in J
* Class which is used to describe a pixel format for a graphical buffer.
* This is used to describe the intended format of the display surface.
*
@@ -92,7 +92,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the per-component bit depth for color (red, green, blue). This
* configures the surface for an unsigned integer buffer type.
*
@@ -105,7 +105,7 @@
mColorPref = preferred;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the bit depth for alpha. This configures the surface for
* an unsigned integer buffer type.
*
@@ -118,7 +118,7 @@
mAlphaPref = preferred;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the bit depth for the depth buffer. This configures the
* surface for an unsigned integer buffer type. If a minimum of 0
* is specified then its possible no depth buffer will be
@@ -133,7 +133,7 @@
mDepthPref = preferred;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Configure the multisample rendering.
*
* @param minimum The required number of samples, must be at least 1.
@@ -156,7 +156,7 @@
SurfaceConfig mSurfaceConfig;
- /**
+ /** @deprecated renderscript is deprecated in J
* Construct a new RenderScriptGL context.
*
* @param ctx The context.
@@ -186,7 +186,7 @@
mMessageThread.start();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Bind an os surface
*
*
@@ -205,7 +205,7 @@
nContextSetSurface(w, h, s);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Bind an os surface
*
* @param w
@@ -221,7 +221,7 @@
nContextSetSurfaceTexture(w, h, sur);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* return the height of the last set surface.
*
* @return int
@@ -230,7 +230,7 @@
return mHeight;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* return the width of the last set surface.
*
* @return int
@@ -239,7 +239,7 @@
return mWidth;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Temporarly halt calls to the root rendering script.
*
*/
@@ -248,7 +248,7 @@
nContextPause();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Resume calls to the root rendering script.
*
*/
@@ -258,7 +258,7 @@
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the script to handle calls to render the primary surface.
*
* @param s Graphics script to process rendering requests.
@@ -268,7 +268,7 @@
nContextBindRootScript(safeID(s));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the default ProgramStore object seen as the parent state by the root
* rendering script.
*
@@ -279,7 +279,7 @@
nContextBindProgramStore(safeID(p));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the default ProgramFragment object seen as the parent state by the
* root rendering script.
*
@@ -290,7 +290,7 @@
nContextBindProgramFragment(safeID(p));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the default ProgramRaster object seen as the parent state by the
* root rendering script.
*
@@ -301,7 +301,7 @@
nContextBindProgramRaster(safeID(p));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Set the default ProgramVertex object seen as the parent state by the
* root rendering script.
*
diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java
index 0df1012..6b258ab 100644
--- a/graphics/java/android/renderscript/Sampler.java
+++ b/graphics/java/android/renderscript/Sampler.java
@@ -27,18 +27,32 @@
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-/**
+/** @deprecated renderscript is deprecated in J
* Sampler object which defines how data is extracted from textures. Samplers
* are attached to Program objects (currently only ProgramFragment) when those objects
* need to access texture data.
**/
public class Sampler extends BaseObj {
+ /** @deprecated renderscript is deprecated in J
+ */
public enum Value {
+ /** @deprecated renderscript is deprecated in J
+ */
NEAREST (0),
+ /** @deprecated renderscript is deprecated in J
+ */
LINEAR (1),
+ /** @deprecated renderscript is deprecated in J
+ */
LINEAR_MIP_LINEAR (2),
+ /** @deprecated renderscript is deprecated in J
+ */
LINEAR_MIP_NEAREST (5),
+ /** @deprecated renderscript is deprecated in J
+ */
WRAP (3),
+ /** @deprecated renderscript is deprecated in J
+ */
CLAMP (4);
int mID;
@@ -58,42 +72,42 @@
super(id, rs);
}
- /**
+ /** @hide renderscript is deprecated in J
* @return minification setting for the sampler
*/
public Value getMinification() {
return mMin;
}
- /**
+ /** @hide renderscript is deprecated in J
* @return magnification setting for the sampler
*/
public Value getMagnification() {
return mMag;
}
- /**
+ /** @hide renderscript is deprecated in J
* @return S wrapping mode for the sampler
*/
public Value getWrapS() {
return mWrapS;
}
- /**
+ /** @hide renderscript is deprecated in J
* @return T wrapping mode for the sampler
*/
public Value getWrapT() {
return mWrapT;
}
- /**
+ /** @hide renderscript is deprecated in J
* @return anisotropy setting for the sampler
*/
public float getAnisotropy() {
return mAniso;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Retrieve a sampler with min and mag set to nearest and wrap modes set to
* clamp.
*
@@ -113,7 +127,7 @@
return rs.mSampler_CLAMP_NEAREST;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Retrieve a sampler with min and mag set to linear and wrap modes set to
* clamp.
*
@@ -133,7 +147,7 @@
return rs.mSampler_CLAMP_LINEAR;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Retrieve a sampler with ag set to linear, min linear mipmap linear, and
* to and wrap modes set to clamp.
*
@@ -153,7 +167,7 @@
return rs.mSampler_CLAMP_LINEAR_MIP_LINEAR;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Retrieve a sampler with min and mag set to nearest and wrap modes set to
* wrap.
*
@@ -173,7 +187,7 @@
return rs.mSampler_WRAP_NEAREST;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Retrieve a sampler with min and mag set to nearest and wrap modes set to
* wrap.
*
@@ -193,7 +207,7 @@
return rs.mSampler_WRAP_LINEAR;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Retrieve a sampler with ag set to linear, min linear mipmap linear, and
* to and wrap modes set to wrap.
*
@@ -214,7 +228,7 @@
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Builder for creating non-standard samplers. Usefull if mix and match of
* wrap modes is necesary or if anisotropic filtering is desired.
*
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index 4f59ae3..34d33a9 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -16,11 +16,11 @@
package android.renderscript;
-/**
+/** @deprecated renderscript is deprecated in J
*
**/
public class Script extends BaseObj {
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param slot
@@ -29,7 +29,7 @@
mRS.nScriptInvoke(getID(mRS), slot);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param slot
@@ -43,7 +43,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param slot
@@ -77,7 +77,7 @@
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param va
@@ -92,7 +92,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param index
@@ -102,7 +102,7 @@
mRS.nScriptSetVarF(getID(mRS), index, v);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param index
@@ -112,7 +112,7 @@
mRS.nScriptSetVarD(getID(mRS), index, v);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param index
@@ -122,7 +122,7 @@
mRS.nScriptSetVarI(getID(mRS), index, v);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param index
@@ -132,7 +132,7 @@
mRS.nScriptSetVarJ(getID(mRS), index, v);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param index
@@ -142,7 +142,7 @@
mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param index
@@ -152,7 +152,7 @@
mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS));
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by generated reflected code.
*
* @param index
@@ -162,6 +162,8 @@
mRS.nScriptSetVarV(getID(mRS), index, v.getData());
}
+ /** @deprecated renderscript is deprecated in J
+ */
public void setTimeZone(String timeZone) {
mRS.validate();
try {
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index 108b230..b1d1fa5 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -29,13 +29,13 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-/**
+/** @deprecated renderscript is deprecated in J
*
**/
public class ScriptC extends Script {
private static final String TAG = "ScriptC";
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by the generated derived classes.
*
* @param id
@@ -45,7 +45,7 @@
super(id, rs);
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Only intended for use by the generated derived classes.
*
*
diff --git a/graphics/java/android/renderscript/Short2.java b/graphics/java/android/renderscript/Short2.java
index 617f1f5..21c5f05 100644
--- a/graphics/java/android/renderscript/Short2.java
+++ b/graphics/java/android/renderscript/Short2.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript Short2 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Short3.java b/graphics/java/android/renderscript/Short3.java
index b9ca49b..81a2954 100644
--- a/graphics/java/android/renderscript/Short3.java
+++ b/graphics/java/android/renderscript/Short3.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript short3 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Short4.java b/graphics/java/android/renderscript/Short4.java
index d5f2db5..861c3d7 100644
--- a/graphics/java/android/renderscript/Short4.java
+++ b/graphics/java/android/renderscript/Short4.java
@@ -20,7 +20,7 @@
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* Class for exposing the native Renderscript short4 type back to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index a707df2..9f630e7 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -20,7 +20,7 @@
import java.lang.reflect.Field;
import android.util.Log;
-/**
+/** @deprecated renderscript is deprecated in J
* <p>Type is an allocation template. It consists of an Element and one or more
* dimensions. It describes only the layout of memory but does not allocate any
* storage for the data that is described.</p>
@@ -70,7 +70,7 @@
}
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return the element associated with this Type.
*
* @return Element
@@ -79,7 +79,7 @@
return mElement;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return the value of the X dimension.
*
* @return int
@@ -88,7 +88,7 @@
return mDimX;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return the value of the Y dimension or 0 for a 1D allocation.
*
* @return int
@@ -97,7 +97,7 @@
return mDimY;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return the value of the Z dimension or 0 for a 1D or 2D allocation.
*
* @return int
@@ -106,7 +106,7 @@
return mDimZ;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return if the Type has a mipmap chain.
*
* @return boolean
@@ -115,7 +115,7 @@
return mDimMipmaps;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return if the Type is a cube map.
*
* @return boolean
@@ -124,7 +124,7 @@
return mDimFaces;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Return the total number of accessable cells in the Type.
*
* @return int
@@ -196,7 +196,7 @@
calcElementCount();
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Builder class for Type.
*
*/
@@ -210,7 +210,7 @@
Element mElement;
- /**
+ /** @deprecated renderscript is deprecated in J
* Create a new builder object.
*
* @param rs
@@ -222,7 +222,7 @@
mElement = e;
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Add a dimension to the Type.
*
*
@@ -255,7 +255,7 @@
}
- /**
+ /** @deprecated renderscript is deprecated in J
* Validate structure and create a new type.
*
* @return Type
diff --git a/include/androidfw/InputDevice.h b/include/androidfw/InputDevice.h
index 38203af..d6ecbf0 100644
--- a/include/androidfw/InputDevice.h
+++ b/include/androidfw/InputDevice.h
@@ -66,13 +66,16 @@
float fuzz;
};
- void initialize(int32_t id, int32_t generation,
- const String8& name, const String8& descriptor);
+ void initialize(int32_t id, int32_t generation, const InputDeviceIdentifier& identifier,
+ const String8& alias);
inline int32_t getId() const { return mId; }
inline int32_t getGeneration() const { return mGeneration; }
- inline const String8 getName() const { return mName; }
- inline const String8 getDescriptor() const { return mDescriptor; }
+ inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; }
+ inline const String8& getAlias() const { return mAlias; }
+ inline const String8& getDisplayName() const {
+ return mAlias.isEmpty() ? mIdentifier.name : mAlias;
+ }
inline uint32_t getSources() const { return mSources; }
const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
@@ -103,8 +106,8 @@
private:
int32_t mId;
int32_t mGeneration;
- String8 mName;
- String8 mDescriptor;
+ InputDeviceIdentifier mIdentifier;
+ String8 mAlias;
uint32_t mSources;
int32_t mKeyboardType;
sp<KeyCharacterMap> mKeyCharacterMap;
diff --git a/include/androidfw/KeyCharacterMap.h b/include/androidfw/KeyCharacterMap.h
index 3cc1cb2..06799f9 100644
--- a/include/androidfw/KeyCharacterMap.h
+++ b/include/androidfw/KeyCharacterMap.h
@@ -49,6 +49,17 @@
KEYBOARD_TYPE_ALPHA = 3,
KEYBOARD_TYPE_FULL = 4,
KEYBOARD_TYPE_SPECIAL_FUNCTION = 5,
+ KEYBOARD_TYPE_OVERLAY = 6,
+ };
+
+ enum Format {
+ // Base keyboard layout, may contain device-specific options, such as "type" declaration.
+ FORMAT_BASE = 0,
+ // Overlay keyboard layout, more restrictive, may be published by applications,
+ // cannot override device-specific options.
+ FORMAT_OVERLAY = 1,
+ // Either base or overlay layout ok.
+ FORMAT_ANY = 2,
};
// Substitute key code and meta state for fallback action.
@@ -58,7 +69,15 @@
};
/* Loads a key character map from a file. */
- static status_t load(const String8& filename, sp<KeyCharacterMap>* outMap);
+ static status_t load(const String8& filename, Format format, sp<KeyCharacterMap>* outMap);
+
+ /* Loads a key character map from its string contents. */
+ static status_t loadContents(const String8& filename,
+ const char* contents, Format format, sp<KeyCharacterMap>* outMap);
+
+ /* Combines a base key character map and an overlay. */
+ static sp<KeyCharacterMap> combine(const sp<KeyCharacterMap>& base,
+ const sp<KeyCharacterMap>& overlay);
/* Returns an empty key character map. */
static sp<KeyCharacterMap> empty();
@@ -101,6 +120,10 @@
bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
Vector<KeyEvent>& outEvents) const;
+ /* Maps a scan code and usage code to a key code, in case this key map overrides
+ * the mapping in some way. */
+ status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const;
+
#if HAVE_ANDROID_OS
/* Reads a key map from a parcel. */
static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);
@@ -115,6 +138,7 @@
private:
struct Behavior {
Behavior();
+ Behavior(const Behavior& other);
/* The next behavior in the list, or NULL if none. */
Behavior* next;
@@ -131,6 +155,7 @@
struct Key {
Key();
+ Key(const Key& other);
~Key();
/* The single character label printed on the key, or 0 if none. */
@@ -166,18 +191,22 @@
KeyCharacterMap* mMap;
Tokenizer* mTokenizer;
+ Format mFormat;
State mState;
int32_t mKeyCode;
public:
- Parser(KeyCharacterMap* map, Tokenizer* tokenizer);
+ Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format);
~Parser();
status_t parse();
private:
status_t parseType();
+ status_t parseMap();
+ status_t parseMapKey();
status_t parseKey();
status_t parseKeyProperty();
+ status_t finishKey(Key* key);
status_t parseModifier(const String8& token, int32_t* outMetaState);
status_t parseCharacterLiteral(char16_t* outCharacter);
};
@@ -187,14 +216,21 @@
KeyedVector<int32_t, Key*> mKeys;
int mType;
+ KeyedVector<int32_t, int32_t> mKeysByScanCode;
+ KeyedVector<int32_t, int32_t> mKeysByUsageCode;
+
KeyCharacterMap();
+ KeyCharacterMap(const KeyCharacterMap& other);
bool getKey(int32_t keyCode, const Key** outKey) const;
bool getKeyBehavior(int32_t keyCode, int32_t metaState,
const Key** outKey, const Behavior** outBehavior) const;
+ static bool matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState);
bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;
+ static status_t load(Tokenizer* tokenizer, Format format, sp<KeyCharacterMap>* outMap);
+
static void addKey(Vector<KeyEvent>& outEvents,
int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time);
static void addMetaKeys(Vector<KeyEvent>& outEvents,
diff --git a/libs/androidfw/InputDevice.cpp b/libs/androidfw/InputDevice.cpp
index d6c49f7..928157f 100644
--- a/libs/androidfw/InputDevice.cpp
+++ b/libs/androidfw/InputDevice.cpp
@@ -127,13 +127,12 @@
// --- InputDeviceInfo ---
InputDeviceInfo::InputDeviceInfo() {
- initialize(-1, -1, String8("uninitialized device info"), String8("unknown"));
+ initialize(-1, -1, InputDeviceIdentifier(), String8());
}
InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
- mId(other.mId), mGeneration(other.mGeneration),
- mName(other.mName), mDescriptor(other.mDescriptor),
- mSources(other.mSources),
+ mId(other.mId), mGeneration(other.mGeneration), mIdentifier(other.mIdentifier),
+ mAlias(other.mAlias), mSources(other.mSources),
mKeyboardType(other.mKeyboardType),
mKeyCharacterMap(other.mKeyCharacterMap),
mHasVibrator(other.mHasVibrator),
@@ -144,11 +143,11 @@
}
void InputDeviceInfo::initialize(int32_t id, int32_t generation,
- const String8& name, const String8& descriptor) {
+ const InputDeviceIdentifier& identifier, const String8& alias) {
mId = id;
mGeneration = generation;
- mName = name;
- mDescriptor = descriptor;
+ mIdentifier = identifier;
+ mAlias = alias;
mSources = 0;
mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
mHasVibrator = false;
diff --git a/libs/androidfw/KeyCharacterMap.cpp b/libs/androidfw/KeyCharacterMap.cpp
index 9abbf38..36cb6e1 100644
--- a/libs/androidfw/KeyCharacterMap.cpp
+++ b/libs/androidfw/KeyCharacterMap.cpp
@@ -89,6 +89,14 @@
mType(KEYBOARD_TYPE_UNKNOWN) {
}
+KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) :
+ RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode),
+ mKeysByUsageCode(other.mKeysByUsageCode) {
+ for (size_t i = 0; i < other.mKeys.size(); i++) {
+ mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i)));
+ }
+}
+
KeyCharacterMap::~KeyCharacterMap() {
for (size_t i = 0; i < mKeys.size(); i++) {
Key* key = mKeys.editValueAt(i);
@@ -96,7 +104,8 @@
}
}
-status_t KeyCharacterMap::load(const String8& filename, sp<KeyCharacterMap>* outMap) {
+status_t KeyCharacterMap::load(const String8& filename,
+ Format format, sp<KeyCharacterMap>* outMap) {
outMap->clear();
Tokenizer* tokenizer;
@@ -104,31 +113,87 @@
if (status) {
ALOGE("Error %d opening key character map file %s.", status, filename.string());
} else {
- sp<KeyCharacterMap> map = new KeyCharacterMap();
- if (!map.get()) {
- ALOGE("Error allocating key character map.");
- status = NO_MEMORY;
- } else {
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
- Parser parser(map.get(), tokenizer);
- status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
- ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
- tokenizer->getFilename().string(), tokenizer->getLineNumber(),
- elapsedTime / 1000000.0);
-#endif
- if (!status) {
- *outMap = map;
- }
- }
+ status = load(tokenizer, format, outMap);
delete tokenizer;
}
return status;
}
+status_t KeyCharacterMap::loadContents(const String8& filename, const char* contents,
+ Format format, sp<KeyCharacterMap>* outMap) {
+ outMap->clear();
+
+ Tokenizer* tokenizer;
+ status_t status = Tokenizer::fromContents(filename, contents, &tokenizer);
+ if (status) {
+ ALOGE("Error %d opening key character map.", status);
+ } else {
+ status = load(tokenizer, format, outMap);
+ delete tokenizer;
+ }
+ return status;
+}
+
+status_t KeyCharacterMap::load(Tokenizer* tokenizer,
+ Format format, sp<KeyCharacterMap>* outMap) {
+ status_t status = OK;
+ sp<KeyCharacterMap> map = new KeyCharacterMap();
+ if (!map.get()) {
+ ALOGE("Error allocating key character map.");
+ status = NO_MEMORY;
+ } else {
+#if DEBUG_PARSER_PERFORMANCE
+ nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+ Parser parser(map.get(), tokenizer, format);
+ status = parser.parse();
+#if DEBUG_PARSER_PERFORMANCE
+ nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
+ ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
+ tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+ elapsedTime / 1000000.0);
+#endif
+ if (!status) {
+ *outMap = map;
+ }
+ }
+ return status;
+}
+
+sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base,
+ const sp<KeyCharacterMap>& overlay) {
+ if (overlay == NULL) {
+ return base;
+ }
+ if (base == NULL) {
+ return overlay;
+ }
+
+ sp<KeyCharacterMap> map = new KeyCharacterMap(*base.get());
+ for (size_t i = 0; i < overlay->mKeys.size(); i++) {
+ int32_t keyCode = overlay->mKeys.keyAt(i);
+ Key* key = overlay->mKeys.valueAt(i);
+ ssize_t oldIndex = map->mKeys.indexOfKey(keyCode);
+ if (oldIndex >= 0) {
+ delete map->mKeys.valueAt(oldIndex);
+ map->mKeys.editValueAt(oldIndex) = new Key(*key);
+ } else {
+ map->mKeys.add(keyCode, new Key(*key));
+ }
+ }
+
+ for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) {
+ map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i),
+ overlay->mKeysByScanCode.valueAt(i));
+ }
+
+ for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) {
+ map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i),
+ overlay->mKeysByUsageCode.valueAt(i));
+ }
+ return map;
+}
+
sp<KeyCharacterMap> KeyCharacterMap::empty() {
return sEmpty;
}
@@ -261,6 +326,37 @@
return true;
}
+status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const {
+ if (usageCode) {
+ ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
+ if (index >= 0) {
+#if DEBUG_MAPPING
+ ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
+ scanCode, usageCode, *outKeyCode);
+#endif
+ *outKeyCode = mKeysByUsageCode.valueAt(index);
+ return OK;
+ }
+ }
+ if (scanCode) {
+ ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
+ if (index >= 0) {
+#if DEBUG_MAPPING
+ ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
+ scanCode, usageCode, *outKeyCode);
+#endif
+ *outKeyCode = mKeysByScanCode.valueAt(index);
+ return OK;
+ }
+ }
+
+#if DEBUG_MAPPING
+ ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
+#endif
+ *outKeyCode = AKEYCODE_UNKNOWN;
+ return NAME_NOT_FOUND;
+}
+
bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
ssize_t index = mKeys.indexOfKey(keyCode);
if (index >= 0) {
@@ -276,7 +372,7 @@
if (getKey(keyCode, &key)) {
const Behavior* behavior = key->firstBehavior;
while (behavior) {
- if ((behavior->metaState & metaState) == behavior->metaState) {
+ if (matchesMetaState(metaState, behavior->metaState)) {
*outKey = key;
*outBehavior = behavior;
return true;
@@ -287,6 +383,37 @@
return false;
}
+bool KeyCharacterMap::matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState) {
+ // Behavior must have at least the set of meta states specified.
+ // And if the key event has CTRL, ALT or META then the behavior must exactly
+ // match those, taking into account that a behavior can specify that it handles
+ // one, both or either of a left/right modifier pair.
+ if ((eventMetaState & behaviorMetaState) == behaviorMetaState) {
+ const int32_t EXACT_META_STATES =
+ AMETA_CTRL_ON | AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON
+ | AMETA_ALT_ON | AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON
+ | AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON;
+ int32_t unmatchedMetaState = eventMetaState & ~behaviorMetaState & EXACT_META_STATES;
+ if (behaviorMetaState & AMETA_CTRL_ON) {
+ unmatchedMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON);
+ } else if (behaviorMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
+ unmatchedMetaState &= ~AMETA_CTRL_ON;
+ }
+ if (behaviorMetaState & AMETA_ALT_ON) {
+ unmatchedMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON);
+ } else if (behaviorMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
+ unmatchedMetaState &= ~AMETA_ALT_ON;
+ }
+ if (behaviorMetaState & AMETA_META_ON) {
+ unmatchedMetaState &= ~(AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
+ } else if (behaviorMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
+ unmatchedMetaState &= ~AMETA_META_ON;
+ }
+ return !unmatchedMetaState;
+ }
+ return false;
+}
+
bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
if (!ch) {
return false;
@@ -508,6 +635,11 @@
label(0), number(0), firstBehavior(NULL) {
}
+KeyCharacterMap::Key::Key(const Key& other) :
+ label(other.label), number(other.number),
+ firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : NULL) {
+}
+
KeyCharacterMap::Key::~Key() {
Behavior* behavior = firstBehavior;
while (behavior) {
@@ -524,11 +656,17 @@
next(NULL), metaState(0), character(0), fallbackKeyCode(0) {
}
+KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
+ next(other.next ? new Behavior(*other.next) : NULL),
+ metaState(other.metaState), character(other.character),
+ fallbackKeyCode(other.fallbackKeyCode) {
+}
+
// --- KeyCharacterMap::Parser ---
-KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer) :
- mMap(map), mTokenizer(tokenizer), mState(STATE_TOP) {
+KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format) :
+ mMap(map), mTokenizer(tokenizer), mFormat(format), mState(STATE_TOP) {
}
KeyCharacterMap::Parser::~Parser() {
@@ -551,6 +689,10 @@
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseType();
if (status) return status;
+ } else if (keywordToken == "map") {
+ mTokenizer->skipDelimiters(WHITESPACE);
+ status_t status = parseMap();
+ if (status) return status;
} else if (keywordToken == "key") {
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseKey();
@@ -571,8 +713,8 @@
}
mTokenizer->skipDelimiters(WHITESPACE);
- if (!mTokenizer->isEol()) {
- ALOGE("%s: Expected end of line, got '%s'.",
+ if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+ ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
mTokenizer->getLocation().string(),
mTokenizer->peekRemainderOfLine().string());
return BAD_VALUE;
@@ -589,11 +731,26 @@
}
if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) {
- ALOGE("%s: Missing required keyboard 'type' declaration.",
+ ALOGE("%s: Keyboard layout missing required keyboard 'type' declaration.",
mTokenizer->getLocation().string());
return BAD_VALUE;
}
+ if (mFormat == FORMAT_BASE) {
+ if (mMap->mType == KEYBOARD_TYPE_OVERLAY) {
+ ALOGE("%s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'.",
+ mTokenizer->getLocation().string());
+ return BAD_VALUE;
+ }
+ } else if (mFormat == FORMAT_OVERLAY) {
+ if (mMap->mType != KEYBOARD_TYPE_OVERLAY) {
+ ALOGE("%s: Overlay keyboard layout missing required keyboard "
+ "'type OVERLAY' declaration.",
+ mTokenizer->getLocation().string());
+ return BAD_VALUE;
+ }
+ }
+
return NO_ERROR;
}
@@ -616,6 +773,8 @@
type = KEYBOARD_TYPE_FULL;
} else if (typeToken == "SPECIAL_FUNCTION") {
type = KEYBOARD_TYPE_SPECIAL_FUNCTION;
+ } else if (typeToken == "OVERLAY") {
+ type = KEYBOARD_TYPE_OVERLAY;
} else {
ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(),
typeToken.string());
@@ -629,6 +788,58 @@
return NO_ERROR;
}
+status_t KeyCharacterMap::Parser::parseMap() {
+ String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
+ if (keywordToken == "key") {
+ mTokenizer->skipDelimiters(WHITESPACE);
+ return parseMapKey();
+ }
+ ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(),
+ keywordToken.string());
+ return BAD_VALUE;
+}
+
+status_t KeyCharacterMap::Parser::parseMapKey() {
+ String8 codeToken = mTokenizer->nextToken(WHITESPACE);
+ bool mapUsage = false;
+ if (codeToken == "usage") {
+ mapUsage = true;
+ mTokenizer->skipDelimiters(WHITESPACE);
+ codeToken = mTokenizer->nextToken(WHITESPACE);
+ }
+
+ char* end;
+ int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
+ if (*end) {
+ ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
+ mapUsage ? "usage" : "scan code", codeToken.string());
+ return BAD_VALUE;
+ }
+ KeyedVector<int32_t, int32_t>& map =
+ mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
+ if (map.indexOfKey(code) >= 0) {
+ ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
+ mapUsage ? "usage" : "scan code", codeToken.string());
+ return BAD_VALUE;
+ }
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
+ int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
+ if (!keyCode) {
+ ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
+ keyCodeToken.string());
+ return BAD_VALUE;
+ }
+
+#if DEBUG_PARSER
+ ALOGD("Parsed map key %s: code=%d, keyCode=%d.",
+ mapUsage ? "usage" : "scan code", code, keyCode);
+#endif
+ map.add(code, keyCode);
+ return NO_ERROR;
+}
+
status_t KeyCharacterMap::Parser::parseKey() {
String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
@@ -661,10 +872,11 @@
}
status_t KeyCharacterMap::Parser::parseKeyProperty() {
+ Key* key = mMap->mKeys.valueFor(mKeyCode);
String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
if (token == "}") {
mState = STATE_TOP;
- return NO_ERROR;
+ return finishKey(key);
}
Vector<Property> properties;
@@ -761,10 +973,9 @@
}
mTokenizer->skipDelimiters(WHITESPACE);
- } while (!mTokenizer->isEol());
+ } while (!mTokenizer->isEol() && mTokenizer->peekChar() != '#');
// Add the behavior.
- Key* key = mMap->mKeys.valueFor(mKeyCode);
for (size_t i = 0; i < properties.size(); i++) {
const Property& property = properties.itemAt(i);
switch (property.property) {
@@ -813,6 +1024,28 @@
return NO_ERROR;
}
+status_t KeyCharacterMap::Parser::finishKey(Key* key) {
+ // Fill in default number property.
+ if (!key->number) {
+ char16_t digit = 0;
+ char16_t symbol = 0;
+ for (Behavior* b = key->firstBehavior; b; b = b->next) {
+ char16_t ch = b->character;
+ if (ch) {
+ if (ch >= '0' && ch <= '9') {
+ digit = ch;
+ } else if (ch == '(' || ch == ')' || ch == '#' || ch == '*'
+ || ch == '-' || ch == '+' || ch == ',' || ch == '.'
+ || ch == '\'' || ch == ':' || ch == ';' || ch == '/') {
+ symbol = ch;
+ }
+ }
+ }
+ key->number = digit ? digit : symbol;
+ }
+ return NO_ERROR;
+}
+
status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) {
if (token == "base") {
*outMetaState = 0;
diff --git a/libs/androidfw/KeyLayoutMap.cpp b/libs/androidfw/KeyLayoutMap.cpp
index a7c2199..ae14f23 100644
--- a/libs/androidfw/KeyLayoutMap.cpp
+++ b/libs/androidfw/KeyLayoutMap.cpp
@@ -185,8 +185,8 @@
}
mTokenizer->skipDelimiters(WHITESPACE);
- if (!mTokenizer->isEol()) {
- ALOGE("%s: Expected end of line, got '%s'.",
+ if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+ ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
mTokenizer->getLocation().string(),
mTokenizer->peekRemainderOfLine().string());
return BAD_VALUE;
@@ -199,17 +199,26 @@
}
status_t KeyLayoutMap::Parser::parseKey() {
- String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
+ String8 codeToken = mTokenizer->nextToken(WHITESPACE);
+ bool mapUsage = false;
+ if (codeToken == "usage") {
+ mapUsage = true;
+ mTokenizer->skipDelimiters(WHITESPACE);
+ codeToken = mTokenizer->nextToken(WHITESPACE);
+ }
+
char* end;
- int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
+ int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
if (*end) {
- ALOGE("%s: Expected key scan code number, got '%s'.", mTokenizer->getLocation().string(),
- scanCodeToken.string());
+ ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
+ mapUsage ? "usage" : "scan code", codeToken.string());
return BAD_VALUE;
}
- if (mMap->mKeysByScanCode.indexOfKey(scanCode) >= 0) {
- ALOGE("%s: Duplicate entry for key scan code '%s'.", mTokenizer->getLocation().string(),
- scanCodeToken.string());
+ KeyedVector<int32_t, Key>& map =
+ mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
+ if (map.indexOfKey(code) >= 0) {
+ ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
+ mapUsage ? "usage" : "scan code", codeToken.string());
return BAD_VALUE;
}
@@ -225,7 +234,7 @@
uint32_t flags = 0;
for (;;) {
mTokenizer->skipDelimiters(WHITESPACE);
- if (mTokenizer->isEol()) break;
+ if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break;
String8 flagToken = mTokenizer->nextToken(WHITESPACE);
uint32_t flag = getKeyFlagByLabel(flagToken.string());
@@ -243,12 +252,13 @@
}
#if DEBUG_PARSER
- ALOGD("Parsed key: scanCode=%d, keyCode=%d, flags=0x%08x.", scanCode, keyCode, flags);
+ ALOGD("Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.",
+ mapUsage ? "usage" : "scan code", code, keyCode, flags);
#endif
Key key;
key.keyCode = keyCode;
key.flags = flags;
- mMap->mKeysByScanCode.add(scanCode, key);
+ map.add(code, key);
return NO_ERROR;
}
@@ -322,7 +332,7 @@
for (;;) {
mTokenizer->skipDelimiters(WHITESPACE);
- if (mTokenizer->isEol()) {
+ if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') {
break;
}
String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
diff --git a/libs/androidfw/Keyboard.cpp b/libs/androidfw/Keyboard.cpp
index a84a8c7..4ddbeab 100644
--- a/libs/androidfw/Keyboard.cpp
+++ b/libs/androidfw/Keyboard.cpp
@@ -129,7 +129,8 @@
return NAME_NOT_FOUND;
}
- status_t status = KeyCharacterMap::load(path, &keyCharacterMap);
+ status_t status = KeyCharacterMap::load(path,
+ KeyCharacterMap::FORMAT_BASE, &keyCharacterMap);
if (status) {
return status;
}
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 3910739..7e19932 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -143,18 +143,16 @@
void DisplayList::clearResources() {
sk_free((void*) mReader.base());
- if (USE_DISPLAY_LIST_PROPERTIES) {
- delete mTransformMatrix;
- delete mTransformCamera;
- delete mTransformMatrix3D;
- delete mStaticMatrix;
- delete mAnimationMatrix;
- mTransformMatrix = NULL;
- mTransformCamera = NULL;
- mTransformMatrix3D = NULL;
- mStaticMatrix = NULL;
- mAnimationMatrix = NULL;
- }
+ delete mTransformMatrix;
+ delete mTransformCamera;
+ delete mTransformMatrix3D;
+ delete mStaticMatrix;
+ delete mAnimationMatrix;
+ mTransformMatrix = NULL;
+ mTransformCamera = NULL;
+ mTransformMatrix3D = NULL;
+ mStaticMatrix = NULL;
+ mAnimationMatrix = NULL;
Caches& caches = Caches::getInstance();
@@ -274,6 +272,7 @@
indent[count] = '\0';
ALOGD("%sStart display list (%p, %s)", (char*) indent + 2, this, mName.string());
+ ALOGD("%s%s %d", indent, "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
int saveCount = renderer.getSaveCount() - 1;
outputViewProperties(renderer, (char*) indent);
@@ -377,11 +376,9 @@
break;
case DrawDisplayList: {
DisplayList* displayList = getDisplayList();
- uint32_t width = getUInt();
- uint32_t height = getUInt();
int32_t flags = getInt();
ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
- displayList, width, height, flags, level + 1);
+ displayList, mWidth, mHeight, flags, level + 1);
renderer.outputDisplayList(displayList, level + 1);
}
break;
@@ -664,64 +661,60 @@
}
void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
- if (USE_DISPLAY_LIST_PROPERTIES) {
- updateMatrix();
- if (mLeft != 0 || mTop != 0) {
- ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
- }
- if (mStaticMatrix) {
+ updateMatrix();
+ if (mLeft != 0 || mTop != 0) {
+ ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
+ }
+ if (mStaticMatrix) {
+ ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix (static)", mStaticMatrix,
+ mStaticMatrix->get(0), mStaticMatrix->get(1),
+ mStaticMatrix->get(2), mStaticMatrix->get(3),
+ mStaticMatrix->get(4), mStaticMatrix->get(5),
+ mStaticMatrix->get(6), mStaticMatrix->get(7),
+ mStaticMatrix->get(8));
+ }
+ if (mAnimationMatrix) {
+ ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix (animation)", mAnimationMatrix,
+ mAnimationMatrix->get(0), mAnimationMatrix->get(1),
+ mAnimationMatrix->get(2), mAnimationMatrix->get(3),
+ mAnimationMatrix->get(4), mAnimationMatrix->get(5),
+ mAnimationMatrix->get(6), mAnimationMatrix->get(7),
+ mAnimationMatrix->get(8));
+ }
+ if (mMatrixFlags != 0) {
+ if (mMatrixFlags == TRANSLATION) {
+ ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
+ } else {
ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
- indent, "ConcatMatrix (static)", mStaticMatrix,
- mStaticMatrix->get(0), mStaticMatrix->get(1),
- mStaticMatrix->get(2), mStaticMatrix->get(3),
- mStaticMatrix->get(4), mStaticMatrix->get(5),
- mStaticMatrix->get(6), mStaticMatrix->get(7),
- mStaticMatrix->get(8));
+ indent, "ConcatMatrix", mTransformMatrix,
+ mTransformMatrix->get(0), mTransformMatrix->get(1),
+ mTransformMatrix->get(2), mTransformMatrix->get(3),
+ mTransformMatrix->get(4), mTransformMatrix->get(5),
+ mTransformMatrix->get(6), mTransformMatrix->get(7),
+ mTransformMatrix->get(8));
}
- if (mAnimationMatrix) {
- ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
- indent, "ConcatMatrix (animation)", mAnimationMatrix,
- mAnimationMatrix->get(0), mAnimationMatrix->get(1),
- mAnimationMatrix->get(2), mAnimationMatrix->get(3),
- mAnimationMatrix->get(4), mAnimationMatrix->get(5),
- mAnimationMatrix->get(6), mAnimationMatrix->get(7),
- mAnimationMatrix->get(8));
- }
- if (mMatrixFlags != 0) {
- if (mMatrixFlags == TRANSLATION) {
- ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
- } else {
- ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
- indent, "ConcatMatrix", mTransformMatrix,
- mTransformMatrix->get(0), mTransformMatrix->get(1),
- mTransformMatrix->get(2), mTransformMatrix->get(3),
- mTransformMatrix->get(4), mTransformMatrix->get(5),
- mTransformMatrix->get(6), mTransformMatrix->get(7),
- mTransformMatrix->get(8));
- }
- }
- if (mAlpha < 1 && !mCaching) {
- // TODO: should be able to store the size of a DL at record time and not
- // have to pass it into this call. In fact, this information might be in the
- // location/size info that we store with the new native transform data.
- int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
- if (mClipChildren) {
- flags |= SkCanvas::kClipToLayer_SaveFlag;
- }
- ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
- (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
- mMultipliedAlpha, flags);
- }
+ }
+ if (mAlpha < 1 && !mCaching) {
+ // TODO: should be able to store the size of a DL at record time and not
+ // have to pass it into this call. In fact, this information might be in the
+ // location/size info that we store with the new native transform data.
+ int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
if (mClipChildren) {
- ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
- (float) mRight - mLeft, (float) mBottom - mTop);
+ flags |= SkCanvas::kClipToLayer_SaveFlag;
}
+ ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
+ (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
+ mMultipliedAlpha, flags);
+ }
+ if (mClipChildren) {
+ ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
+ (float) mRight - mLeft, (float) mBottom - mTop);
}
}
-void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
- uint32_t level) {
- if (USE_DISPLAY_LIST_PROPERTIES) {
+void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
#if DEBUG_DISPLAY_LIST
uint32_t count = (level + 1) * 2;
char indent[count + 1];
@@ -730,73 +723,72 @@
}
indent[count] = '\0';
#endif
- updateMatrix();
- if (mLeft != 0 || mTop != 0) {
- DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
- renderer.translate(mLeft, mTop);
- }
- if (mStaticMatrix) {
+ updateMatrix();
+ if (mLeft != 0 || mTop != 0) {
+ DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
+ renderer.translate(mLeft, mTop);
+ }
+ if (mStaticMatrix) {
+ DISPLAY_LIST_LOGD(
+ "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix (static)", mStaticMatrix,
+ mStaticMatrix->get(0), mStaticMatrix->get(1),
+ mStaticMatrix->get(2), mStaticMatrix->get(3),
+ mStaticMatrix->get(4), mStaticMatrix->get(5),
+ mStaticMatrix->get(6), mStaticMatrix->get(7),
+ mStaticMatrix->get(8));
+ renderer.concatMatrix(mStaticMatrix);
+ } else if (mAnimationMatrix) {
+ DISPLAY_LIST_LOGD(
+ "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix (animation)", mAnimationMatrix,
+ mAnimationMatrix->get(0), mAnimationMatrix->get(1),
+ mAnimationMatrix->get(2), mAnimationMatrix->get(3),
+ mAnimationMatrix->get(4), mAnimationMatrix->get(5),
+ mAnimationMatrix->get(6), mAnimationMatrix->get(7),
+ mAnimationMatrix->get(8));
+ renderer.concatMatrix(mAnimationMatrix);
+ }
+ if (mMatrixFlags != 0) {
+ if (mMatrixFlags == TRANSLATION) {
+ DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
+ renderer.translate(mTranslationX, mTranslationY);
+ } else {
DISPLAY_LIST_LOGD(
"%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
- indent, "ConcatMatrix (static)", mStaticMatrix,
- mStaticMatrix->get(0), mStaticMatrix->get(1),
- mStaticMatrix->get(2), mStaticMatrix->get(3),
- mStaticMatrix->get(4), mStaticMatrix->get(5),
- mStaticMatrix->get(6), mStaticMatrix->get(7),
- mStaticMatrix->get(8));
- renderer.concatMatrix(mStaticMatrix);
- } else if (mAnimationMatrix) {
- DISPLAY_LIST_LOGD(
- "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
- indent, "ConcatMatrix (animation)", mAnimationMatrix,
- mAnimationMatrix->get(0), mAnimationMatrix->get(1),
- mAnimationMatrix->get(2), mAnimationMatrix->get(3),
- mAnimationMatrix->get(4), mAnimationMatrix->get(5),
- mAnimationMatrix->get(6), mAnimationMatrix->get(7),
- mAnimationMatrix->get(8));
- renderer.concatMatrix(mAnimationMatrix);
+ indent, "ConcatMatrix", mTransformMatrix,
+ mTransformMatrix->get(0), mTransformMatrix->get(1),
+ mTransformMatrix->get(2), mTransformMatrix->get(3),
+ mTransformMatrix->get(4), mTransformMatrix->get(5),
+ mTransformMatrix->get(6), mTransformMatrix->get(7),
+ mTransformMatrix->get(8));
+ renderer.concatMatrix(mTransformMatrix);
}
- if (mMatrixFlags != 0) {
- if (mMatrixFlags == TRANSLATION) {
- DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
- renderer.translate(mTranslationX, mTranslationY);
- } else {
- DISPLAY_LIST_LOGD(
- "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
- indent, "ConcatMatrix", mTransformMatrix,
- mTransformMatrix->get(0), mTransformMatrix->get(1),
- mTransformMatrix->get(2), mTransformMatrix->get(3),
- mTransformMatrix->get(4), mTransformMatrix->get(5),
- mTransformMatrix->get(6), mTransformMatrix->get(7),
- mTransformMatrix->get(8));
- renderer.concatMatrix(mTransformMatrix);
+ }
+ if (mAlpha < 1 && !mCaching) {
+ if (!mHasOverlappingRendering) {
+ DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
+ renderer.setAlpha(mAlpha);
+ } else {
+ // TODO: should be able to store the size of a DL at record time and not
+ // have to pass it into this call. In fact, this information might be in the
+ // location/size info that we store with the new native transform data.
+ int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
+ if (mClipChildren) {
+ flags |= SkCanvas::kClipToLayer_SaveFlag;
}
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
+ (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
+ mMultipliedAlpha, flags);
+ renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
+ mMultipliedAlpha, flags);
}
- if (mAlpha < 1 && !mCaching) {
- if (!mHasOverlappingRendering) {
- DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
- renderer.setAlpha(mAlpha);
- } else {
- // TODO: should be able to store the size of a DL at record time and not
- // have to pass it into this call. In fact, this information might be in the
- // location/size info that we store with the new native transform data.
- int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
- if (mClipChildren) {
- flags |= SkCanvas::kClipToLayer_SaveFlag;
- }
- DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
- (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
- mMultipliedAlpha, flags);
- renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
- mMultipliedAlpha, flags);
- }
- }
- if (mClipChildren) {
- DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
- (float) mRight - mLeft, (float) mBottom - mTop);
- renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
- SkRegion::kIntersect_Op);
- }
+ }
+ if (mClipChildren) {
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
+ (float) mRight - mLeft, (float) mBottom - mTop);
+ renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
+ SkRegion::kIntersect_Op);
}
}
@@ -805,8 +797,7 @@
* in the output() function, since that function processes the same list of opcodes for the
* purposes of logging display list info for a given view.
*/
-status_t DisplayList::replay(OpenGLRenderer& renderer, uint32_t width,
- uint32_t height, Rect& dirty, int32_t flags, uint32_t level) {
+status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
status_t drawGlStatus = 0;
TextContainer text;
mReader.rewind();
@@ -825,14 +816,11 @@
#endif
renderer.startMark(mName.string());
- int restoreTo = 0;
- if (USE_DISPLAY_LIST_PROPERTIES) {
- DISPLAY_LIST_LOGD("%s%s %d", indent, "Save",
- SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
- restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
- }
- setViewProperties(renderer, width, height, level);
- if (USE_DISPLAY_LIST_PROPERTIES && renderer.quickReject(0, 0, width, height)) {
+ int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+ DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save",
+ SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
+ setViewProperties(renderer, level);
+ if (renderer.quickReject(0, 0, mWidth, mHeight)) {
DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
renderer.restoreToCount(restoreTo);
renderer.endMark();
@@ -963,13 +951,10 @@
break;
case DrawDisplayList: {
DisplayList* displayList = getDisplayList();
- uint32_t width = getUInt();
- uint32_t height = getUInt();
int32_t flags = getInt();
DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
- displayList, width, height, flags, level + 1);
- drawGlStatus |= renderer.drawDisplayList(displayList, width,
- height, dirty, flags, level + 1);
+ displayList, mWidth, mHeight, flags, level + 1);
+ drawGlStatus |= renderer.drawDisplayList(displayList, dirty, flags, level + 1);
}
break;
case DrawLayer: {
@@ -1247,10 +1232,8 @@
}
}
- if (USE_DISPLAY_LIST_PROPERTIES) {
- DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
- renderer.restoreToCount(restoreTo);
- }
+ DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
+ renderer.restoreToCount(restoreTo);
renderer.endMark();
DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
@@ -1437,13 +1420,12 @@
}
status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
- uint32_t width, uint32_t height, Rect& dirty, int32_t flags, uint32_t level) {
+ Rect& dirty, int32_t flags, uint32_t level) {
// dirty is an out parameter and should not be recorded,
// it matters only when replaying the display list
addOp(DisplayList::DrawDisplayList);
addDisplayList(displayList);
- addSize(width, height);
addInt(flags);
return DrawGlInfo::kStatusDone;
}
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index fe0c94d..a7fc23a 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -49,10 +49,6 @@
#define DISPLAY_LIST_LOGD(...)
#endif
-// Set to 1 to enable native processing of View properties. 0 by default. Eventually this
-// will go away and we will always use this approach for accelerated apps.
-#define USE_DISPLAY_LIST_PROPERTIES 1
-
#define TRANSLATION 0x0001
#define ROTATION 0x0002
#define ROTATION_3D 0x0004
@@ -127,8 +123,7 @@
static const char* OP_NAMES[];
- void setViewProperties(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
- uint32_t level);
+ void setViewProperties(OpenGLRenderer& renderer, uint32_t level);
void outputViewProperties(OpenGLRenderer& renderer, char* indent);
ANDROID_API size_t getSize();
@@ -137,8 +132,7 @@
void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
- status_t replay(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
- Rect& dirty, int32_t flags, uint32_t level = 0);
+ status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0);
void output(OpenGLRenderer& renderer, uint32_t level = 0);
@@ -393,6 +387,14 @@
mCaching = caching;
}
+ int getWidth() {
+ return mWidth;
+ }
+
+ int getHeight() {
+ return mHeight;
+ }
+
private:
void init();
@@ -563,8 +565,8 @@
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- virtual status_t drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
- Rect& dirty, int32_t flags, uint32_t level = 0);
+ virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags,
+ uint32_t level = 0);
virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index ebb8eb7..5edaa46 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1372,17 +1372,13 @@
// Drawing
///////////////////////////////////////////////////////////////////////////////
-status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
+status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList,
Rect& dirty, int32_t flags, uint32_t level) {
- if (!USE_DISPLAY_LIST_PROPERTIES && quickReject(0, 0, width, height)) {
- return false;
- }
-
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
- return displayList->replay(*this, width, height, dirty, flags, level);
+ return displayList->replay(*this, dirty, flags, level);
}
return DrawGlInfo::kStatusDone;
@@ -2463,8 +2459,7 @@
interrupt();
renderer->setViewport(layer->layer.getWidth(), layer->layer.getHeight());
renderer->prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, !layer->isBlend());
- renderer->drawDisplayList(layer->displayList, layer->getWidth(), layer->getHeight(),
- dirty, DisplayList::kReplayFlag_ClipChildren);
+ renderer->drawDisplayList(layer->displayList, dirty, DisplayList::kReplayFlag_ClipChildren);
renderer->finish();
resume();
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 47927bb..141e22b 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -103,8 +103,8 @@
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
virtual Rect* getClipRect();
- virtual status_t drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
- Rect& dirty, int32_t flags, uint32_t level = 0);
+ virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags,
+ uint32_t level = 0);
virtual void outputDisplayList(DisplayList* displayList, uint32_t level = 0);
virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 4e112af..81e8028 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -497,7 +497,6 @@
* Returns the audio session ID.
*
* @return the ID of the audio session this AudioRecord belongs to.
- * @hide
*/
public int getAudioSessionId() {
return mSessionId;
@@ -531,7 +530,6 @@
* @throws IllegalStateException
* @param syncEvent event that triggers the capture.
* @see MediaSyncEvent
- * @hide
*/
public void startRecording(MediaSyncEvent syncEvent)
throws IllegalStateException {
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index a65c2aa..258760f 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -280,6 +280,19 @@
*/
public native final void flush();
+ public final static class CryptoException extends RuntimeException {
+ public CryptoException(int errorCode, String detailMessage) {
+ super(detailMessage);
+ mErrorCode = errorCode;
+ }
+
+ public int getErrorCode() {
+ return mErrorCode;
+ }
+
+ private int mErrorCode;
+ }
+
/** After filling a range of the input buffer at the specified index
* submit it to the component.
*
@@ -304,43 +317,67 @@
* @param presentationTimeUs The time at which this buffer should be rendered.
* @param flags A bitmask of flags {@link #FLAG_SYNCFRAME},
* {@link #FLAG_CODECCONFIG} or {@link #FLAG_EOS}.
+ * @throws CryptoException if a crypto object has been specified in
+ * {@link #configure}
*/
public native final void queueInputBuffer(
int index,
- int offset, int size, long presentationTimeUs, int flags);
+ int offset, int size, long presentationTimeUs, int flags)
+ throws CryptoException;
+
+ /** Metadata describing the structure of a (at least partially) encrypted
+ * input sample.
+ * A buffer's data is considered to be partitioned into "subSamples",
+ * each subSample starts with a (potentially empty) run of plain,
+ * unencrypted bytes followed by a (also potentially empty) run of
+ * encrypted bytes.
+ * numBytesOfClearData can be null to indicate that all data is encrypted.
+ */
+ public final static class CryptoInfo {
+ public void set(
+ int newNumSubSamples,
+ int[] newNumBytesOfClearData,
+ int[] newNumBytesOfEncryptedData,
+ byte[] newKey,
+ byte[] newIV,
+ int newMode) {
+ numSubSamples = newNumSubSamples;
+ numBytesOfClearData = newNumBytesOfClearData;
+ numBytesOfEncryptedData = newNumBytesOfEncryptedData;
+ key = newKey;
+ iv = newIV;
+ mode = newMode;
+ }
+
+ /** The number of subSamples that make up the buffer's contents. */
+ public int numSubSamples;
+ /** The number of leading unencrypted bytes in each subSample. */
+ public int[] numBytesOfClearData;
+ /** The number of trailing encrypted bytes in each subSample. */
+ public int[] numBytesOfEncryptedData;
+ /** A 16-byte opaque key */
+ public byte[] key;
+ /** A 16-byte initialization vector */
+ public byte[] iv;
+ /** The type of encryption that has been applied */
+ public int mode;
+ };
/** Similar to {@link #queueInputBuffer} but submits a buffer that is
- * potentially encrypted. The buffer's data is considered to be
- * partitioned into "subSamples", each subSample starts with a
- * (potentially empty) run of plain, unencrypted bytes followed
- * by a (also potentially empty) run of encrypted bytes.
+ * potentially encrypted.
* @param index The index of a client-owned input buffer previously returned
* in a call to {@link #dequeueInputBuffer}.
* @param offset The byte offset into the input buffer at which the data starts.
- * @param numBytesOfClearData The number of leading unencrypted bytes in
- * each subSample.
- * @param numBytesOfEncryptedData The number of trailing encrypted bytes
- * in each subSample.
- * @param numSubSamples The number of subSamples that make up the
- * buffer's contents.
- * @param key A 16-byte opaque key
- * @param iv A 16-byte initialization vector
- * @param mode The type of encryption that has been applied
- *
- * Either numBytesOfClearData or numBytesOfEncryptedData (but not both)
- * can be null to indicate that all respective sizes are 0.
+ * @param presentationTimeUs The time at which this buffer should be rendered.
+ * @param flags A bitmask of flags {@link #FLAG_SYNCFRAME},
+ * {@link #FLAG_CODECCONFIG} or {@link #FLAG_EOS}.
*/
public native final void queueSecureInputBuffer(
int index,
int offset,
- int[] numBytesOfClearData,
- int[] numBytesOfEncryptedData,
- int numSubSamples,
- byte[] key,
- byte[] iv,
- int mode,
+ CryptoInfo info,
long presentationTimeUs,
- int flags);
+ int flags) throws CryptoException;
/** Returns the index of an input buffer to be filled with valid data
* or -1 if no such buffer is currently available.
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index 3f8b2ca..9fdb81f 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -19,6 +19,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
+import android.media.MediaCodec;
import android.net.Uri;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -235,6 +236,29 @@
/** Returns the current sample's flags. */
public native int getSampleFlags();
+ /** If the sample flags indicate that the current sample is at least
+ * partially encrypted, this call returns relevant information about
+ * the structure of the sample data required for decryption.
+ * @param info The android.media.MediaCodec.CryptoInfo structure
+ * to be filled in.
+ * @return true iff the sample flags contain {@link #SAMPLE_FLAG_ENCRYPTED}
+ */
+ public native boolean getSampleCryptoInfo(MediaCodec.CryptoInfo info);
+
+ /** Returns an estimate of how much data is presently cached in memory
+ expressed in microseconds. Returns -1 if that information is unavailable
+ or not applicable (no cache).
+ */
+ public native long getCachedDuration();
+
+ /** Returns true iff we are caching data and the cache has reached the
+ * end of the data stream (for now, a future seek may of course restart
+ * the fetching of data).
+ * This API only returns a meaningful result if {link #getCachedDuration}
+ * indicates the presence of a cache, i.e. does NOT return -1.
+ */
+ public native boolean hasCacheReachedEndOfStream();
+
private static native final void native_init();
private native final void native_setup();
private native final void native_finalize();
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index dd01db6..fae7d0b 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1577,26 +1577,39 @@
/**
* Returns an array of track information.
+ * If it is called in an invalid state, IllegalStateException will be thrown.
*
- * @return Array of track info. null if an error occured.
+ * @return Array of track info. The total number of tracks is the array length.
+ * Must be called again if an external source has been added after any of the
+ * addExternalSource methods are called.
* {@hide}
*/
- // FIXME: It returns timed text tracks' information for now. Other types of tracks will be
- // supported in future.
public TrackInfo[] getTrackInfo() {
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
request.writeInterfaceToken(IMEDIA_PLAYER);
request.writeInt(INVOKE_ID_GET_TRACK_INFO);
- invoke(request, reply);
+ int status = invoke(request, reply);
+ if (status != 0) {
+ throw new IllegalStateException();
+ }
TrackInfo trackInfo[] = reply.createTypedArray(TrackInfo.CREATOR);
return trackInfo;
}
+ /* Do not change these values without updating their counterparts
+ * in include/media/stagefright/MediaDefs.h and media/libstagefright/MediaDefs.cpp!
+ */
+ /**
+ * MIME type for SubRip (SRT) container. Used in addExternalSource APIs.
+ * {@hide}
+ */
+ public static final String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
+
/*
* A helper function to check if the mime type is supported by media framework.
*/
- private boolean availableMimeTypeForExternalSource(String mimeType) {
+ private static boolean availableMimeTypeForExternalSource(String mimeType) {
if (mimeType == MEDIA_MIMETYPE_TEXT_SUBRIP) {
return true;
}
@@ -1614,23 +1627,28 @@
* additional tracks become available after this method call.
*
* @param path The file path of external source file.
+ * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+ * @throws IOException if the file cannot be accessed or is corrupted.
+ * @throws IllegalArgumentException if the mimeType is not supported.
* {@hide}
*/
- // FIXME: define error codes and throws exceptions according to the error codes.
- // (IllegalStateException, IOException).
public void addExternalSource(String path, String mimeType)
- throws IllegalArgumentException {
+ throws IOException, IllegalArgumentException {
if (!availableMimeTypeForExternalSource(mimeType)) {
- throw new IllegalArgumentException("Illegal mimeType for external source: " + mimeType);
+ final String msg = "Illegal mimeType for external source: " + mimeType;
+ throw new IllegalArgumentException(msg);
}
- Parcel request = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- request.writeInterfaceToken(IMEDIA_PLAYER);
- request.writeInt(INVOKE_ID_ADD_EXTERNAL_SOURCE);
- request.writeString(path);
- request.writeString(mimeType);
- invoke(request, reply);
+ File file = new File(path);
+ if (file.exists()) {
+ FileInputStream is = new FileInputStream(file);
+ FileDescriptor fd = is.getFD();
+ addExternalSource(fd, mimeType);
+ is.close();
+ } else {
+ // We do not support the case where the path is not a file.
+ throw new IOException(path);
+ }
}
/**
@@ -1643,10 +1661,11 @@
*
* @param context the Context to use when resolving the Uri
* @param uri the Content URI of the data you want to play
+ * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+ * @throws IOException if the file cannot be accessed or is corrupted.
+ * @throws IllegalArgumentException if the mimeType is not supported.
* {@hide}
*/
- // FIXME: define error codes and throws exceptions according to the error codes.
- // (IllegalStateException, IOException).
public void addExternalSource(Context context, Uri uri, String mimeType)
throws IOException, IllegalArgumentException {
String scheme = uri.getScheme();
@@ -1671,19 +1690,8 @@
fd.close();
}
}
-
- // TODO: try server side.
}
- /* Do not change these values without updating their counterparts
- * in include/media/stagefright/MediaDefs.h and media/libstagefright/MediaDefs.cpp!
- */
- /**
- * MIME type for SubRip (SRT) container. Used in {@link #addExternalSource()} APIs.
- * {@hide}
- */
- public static final String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
-
/**
* Adds an external source file (FileDescriptor).
* It is the caller's responsibility to close the file descriptor.
@@ -1695,14 +1703,10 @@
* additional tracks become available after this method call.
*
* @param fd the FileDescriptor for the file you want to play
- * @param mimeType A MIME type for the content. It can be null.
- * <ul>
- * <li>{@link #MEDIA_MIMETYPE_TEXT_SUBRIP}
- * </ul>
+ * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+ * @throws IllegalArgumentException if the mimeType is not supported.
* {@hide}
*/
- // FIXME: define error codes and throws exceptions according to the error codes.
- // (IllegalStateException, IOException).
public void addExternalSource(FileDescriptor fd, String mimeType)
throws IllegalArgumentException {
// intentionally less than LONG_MAX
@@ -1722,16 +1726,16 @@
* @param fd the FileDescriptor for the file you want to play
* @param offset the offset into the file where the data to be played starts, in bytes
* @param length the length in bytes of the data to be played
- * @param mimeType A MIME type for the content. It can be null.
+ * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+ * @throws IllegalArgumentException if the mimeType is not supported.
* {@hide}
*/
- // FIXME: define error codes and throws exceptions according to the error codes.
- // (IllegalStateException, IOException).
public void addExternalSource(FileDescriptor fd, long offset, long length, String mimeType)
throws IllegalArgumentException {
if (!availableMimeTypeForExternalSource(mimeType)) {
throw new IllegalArgumentException("Illegal mimeType for external source: " + mimeType);
}
+
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
request.writeInterfaceToken(IMEDIA_PLAYER);
@@ -1746,8 +1750,8 @@
/**
* Selects a track.
* <p>
- * If a MediaPlayer is in invalid state, it throws exception.
- * If a MediaPlayer is in Started state, the selected track will be presented immediately.
+ * If a MediaPlayer is in invalid state, it throws an IllegalStateException exception.
+ * If a MediaPlayer is in <em>Started</em> state, the selected track is presented immediately.
* If a MediaPlayer is not in Started state, it just marks the track to be played.
* </p>
* <p>
@@ -1755,38 +1759,58 @@
* Audio, Timed Text), the most recent one will be chosen.
* </p>
* <p>
- * The first audio and video tracks will be selected by default, even though this function is not
- * called. However, no timed text track will be selected until this function is called.
+ * The first audio and video tracks are selected by default if available, even though
+ * this method is not called. However, no timed text track will be selected until
+ * this function is called.
* </p>
+ * <p>
+ * Currently, only timed text tracks or audio tracks can be selected via this method.
+ * In addition, the support for selecting an audio track at runtime is pretty limited
+ * in that an audio track can only be selected in the <em>Prepared</em> state.
+ * </p>
+ * @param index the index of the track to be selected. The valid range of the index
+ * is 0..total number of track - 1. The total number of tracks as well as the type of
+ * each individual track can be found by calling {@link #getTrackInfo()} method.
+ * @see android.media.MediaPlayer.getTrackInfo
* {@hide}
*/
- // FIXME: define error codes and throws exceptions according to the error codes.
- // (IllegalStateException, IOException, IllegalArgumentException).
public void selectTrack(int index) {
- Parcel request = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- request.writeInterfaceToken(IMEDIA_PLAYER);
- request.writeInt(INVOKE_ID_SELECT_TRACK);
- request.writeInt(index);
- invoke(request, reply);
+ selectOrUnselectTrack(index, true /* select */);
}
/**
* Unselect a track.
- * If the track identified by index has not been selected before, it throws an exception.
+ * <p>
+ * Currently, the track must be a timed text track and no audio or video tracks can be
+ * unselected. If the timed text track identified by index has not been
+ * selected before, it throws an exception.
+ * </p>
+ * @param index the index of the track to be unselected. The valid range of the index
+ * is 0..total number of tracks - 1. The total number of tracks as well as the type of
+ * each individual track can be found by calling {@link #getTrackInfo()} method.
+ *
+ * @see android.media.MediaPlayer.getTrackInfo
* {@hide}
*/
- // FIXME: define error codes and throws exceptions according to the error codes.
- // (IllegalStateException, IOException, IllegalArgumentException).
public void unselectTrack(int index) {
+ selectOrUnselectTrack(index, false /* select */);
+ }
+
+ private void selectOrUnselectTrack(int index, boolean select) {
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
request.writeInterfaceToken(IMEDIA_PLAYER);
- request.writeInt(INVOKE_ID_UNSELECT_TRACK);
+ request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_UNSELECT_TRACK);
request.writeInt(index);
- invoke(request, reply);
+ int status = invoke(request, reply);
+ if (status != 0) {
+ String msg = select? "selectTrack ": "unselectTrack ";
+ msg += "failed for track index: " + index;
+ throw new RuntimeException(msg);
+ }
}
+
/**
* @param reply Parcel with audio/video duration info for battery
tracking usage
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 26089ad..c41901b 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1770,8 +1770,10 @@
Iterator<FileEntry> iterator = mPlayLists.iterator();
Cursor fileList = null;
try {
+ // use the files uri and projection because we need the format column,
+ // but restrict the query to just audio files
fileList = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION,
- null, null, null, null);
+ "media_type=2", null, null, null);
while (iterator.hasNext()) {
FileEntry entry = iterator.next();
// only process playlist files if they are new or have been modified since the last scan
diff --git a/media/java/android/media/MediaSyncEvent.java b/media/java/android/media/MediaSyncEvent.java
index d2a0735..31af6b5 100644
--- a/media/java/android/media/MediaSyncEvent.java
+++ b/media/java/android/media/MediaSyncEvent.java
@@ -23,7 +23,6 @@
* only when the playback on a particular audio session is complete.
* The audio session ID is retrieved from a player (e.g {@link MediaPlayer}, {@link AudioTrack} or
* {@link ToneGenerator}) by use of the getAudioSessionId() method.
- * @hide
*/
public class MediaSyncEvent {
@@ -49,7 +48,7 @@
* <p>The type specifies which kind of event is monitored.
* For instance, event {@link #SYNC_EVENT_PRESENTATION_COMPLETE} corresponds to the audio being
* presented to the user on a particular audio session.
- * @param type the synchronization event type.
+ * @param eventType the synchronization event type.
* @return the MediaSyncEvent created.
* @throws java.lang.IllegalArgumentException
*/
diff --git a/media/java/android/media/ToneGenerator.java b/media/java/android/media/ToneGenerator.java
index 4907a13..5592105 100644
--- a/media/java/android/media/ToneGenerator.java
+++ b/media/java/android/media/ToneGenerator.java
@@ -880,7 +880,6 @@
*
* @return the ID of the audio session this ToneGenerator belongs to or 0 if an error
* occured.
- * @hide
*/
public native final int getAudioSessionId();
diff --git a/media/java/android/media/audiofx/AcousticEchoCanceler.java b/media/java/android/media/audiofx/AcousticEchoCanceler.java
index e31f84c..4b59c88 100644
--- a/media/java/android/media/audiofx/AcousticEchoCanceler.java
+++ b/media/java/android/media/audiofx/AcousticEchoCanceler.java
@@ -37,7 +37,6 @@
* state on a particular AudioRecord session.
* <p>See {@link android.media.audiofx.AudioEffect} class for more details on
* controlling audio effects.
- * @hide
*/
public class AcousticEchoCanceler extends AudioEffect {
@@ -90,9 +89,8 @@
* @throws java.lang.IllegalArgumentException
* @throws java.lang.UnsupportedOperationException
* @throws java.lang.RuntimeException
- * @hide
*/
- public AcousticEchoCanceler(int audioSession)
+ private AcousticEchoCanceler(int audioSession)
throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
super(EFFECT_TYPE_AEC, EFFECT_TYPE_NULL, 0, audioSession);
}
diff --git a/media/java/android/media/audiofx/AutomaticGainControl.java b/media/java/android/media/audiofx/AutomaticGainControl.java
index eca7eec..83eb4e9 100644
--- a/media/java/android/media/audiofx/AutomaticGainControl.java
+++ b/media/java/android/media/audiofx/AutomaticGainControl.java
@@ -37,7 +37,6 @@
* state on a particular AudioRecord session.
* <p>See {@link android.media.audiofx.AudioEffect} class for more details on
* controlling audio effects.
- * @hide
*/
public class AutomaticGainControl extends AudioEffect {
@@ -90,9 +89,8 @@
* @throws java.lang.IllegalArgumentException
* @throws java.lang.UnsupportedOperationException
* @throws java.lang.RuntimeException
- * @hide
*/
- public AutomaticGainControl(int audioSession)
+ private AutomaticGainControl(int audioSession)
throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
super(EFFECT_TYPE_AGC, EFFECT_TYPE_NULL, 0, audioSession);
}
diff --git a/media/java/android/media/audiofx/NoiseSuppressor.java b/media/java/android/media/audiofx/NoiseSuppressor.java
index a2d3386c..0ea42ab 100644
--- a/media/java/android/media/audiofx/NoiseSuppressor.java
+++ b/media/java/android/media/audiofx/NoiseSuppressor.java
@@ -38,7 +38,6 @@
* state on a particular AudioRecord session.
* <p>See {@link android.media.audiofx.AudioEffect} class for more details on
* controlling audio effects.
- * @hide
*/
public class NoiseSuppressor extends AudioEffect {
@@ -92,7 +91,6 @@
* @throws java.lang.IllegalArgumentException
* @throws java.lang.UnsupportedOperationException
* @throws java.lang.RuntimeException
- * @hide
*/
private NoiseSuppressor(int audioSession)
throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index 91d0addd..9197ed8 100755
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -81,6 +81,18 @@
*/
public static final int STATE_ENABLED = 2;
+ // to keep in sync with system/media/audio_effects/include/audio_effects/effect_visualizer.h
+ /**
+ * Defines a capture mode where amplification is applied based on the content of the captured
+ * data. This is the default Visualizer mode, and is suitable for music visualization.
+ */
+ public static final int SCALING_MODE_NORMALIZED = 0;
+ /**
+ * Defines a capture mode where the playback volume will affect (scale) the range of the
+ * captured data. A low playback volume will lead to low sample and fft values, and vice-versa.
+ */
+ public static final int SCALING_MODE_AS_PLAYED = 1;
+
// to keep in sync with frameworks/base/media/jni/audioeffect/android_media_Visualizer.cpp
private static final int NATIVE_EVENT_PCM_CAPTURE = 0;
private static final int NATIVE_EVENT_FFT_CAPTURE = 1;
@@ -302,6 +314,42 @@
}
/**
+ * Set the type of scaling applied on the captured visualization data.
+ * @param mode see {@link #SCALING_MODE_NORMALIZED}
+ * and {@link #SCALING_MODE_AS_PLAYED}
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR_BAD_VALUE} in case of failure.
+ * @throws IllegalStateException
+ */
+ public int setScalingMode(int mode)
+ throws IllegalStateException {
+ synchronized (mStateLock) {
+ if (mState == STATE_UNINITIALIZED) {
+ throw(new IllegalStateException("setScalingMode() called in wrong state: "
+ + mState));
+ }
+ return native_setScalingMode(mode);
+ }
+ }
+
+ /**
+ * Returns the current scaling mode on the captured visualization data.
+ * @return the scaling mode, see {@link #SCALING_MODE_NORMALIZED}
+ * and {@link #SCALING_MODE_AS_PLAYED}.
+ * @throws IllegalStateException
+ */
+ public int getScalingMode()
+ throws IllegalStateException {
+ synchronized (mStateLock) {
+ if (mState == STATE_UNINITIALIZED) {
+ throw(new IllegalStateException("getScalingMode() called in wrong state: "
+ + mState));
+ }
+ return native_getScalingMode();
+ }
+ }
+
+ /**
* Returns the sampling rate of the captured audio.
* @return the sampling rate in milliHertz.
*/
@@ -588,6 +636,10 @@
private native final int native_getCaptureSize();
+ private native final int native_setScalingMode(int mode);
+
+ private native final int native_getScalingMode();
+
private native final int native_getSamplingRate();
private native final int native_getWaveForm(byte[] waveform);
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 979ffb0..8009fb5 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -36,6 +36,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/MediaErrors.h>
namespace android {
@@ -49,6 +50,13 @@
struct fields_t {
jfieldID context;
+
+ jfieldID cryptoInfoNumSubSamplesID;
+ jfieldID cryptoInfoNumBytesOfClearDataID;
+ jfieldID cryptoInfoNumBytesOfEncryptedDataID;
+ jfieldID cryptoInfoKeyID;
+ jfieldID cryptoInfoIVID;
+ jfieldID cryptoInfoModeID;
};
static fields_t gFields;
@@ -122,8 +130,10 @@
status_t JMediaCodec::queueInputBuffer(
size_t index,
- size_t offset, size_t size, int64_t timeUs, uint32_t flags) {
- return mCodec->queueInputBuffer(index, offset, size, timeUs, flags);
+ size_t offset, size_t size, int64_t timeUs, uint32_t flags,
+ AString *errorDetailMsg) {
+ return mCodec->queueInputBuffer(
+ index, offset, size, timeUs, flags, errorDetailMsg);
}
status_t JMediaCodec::queueSecureInputBuffer(
@@ -135,10 +145,11 @@
const uint8_t iv[16],
CryptoPlugin::Mode mode,
int64_t presentationTimeUs,
- uint32_t flags) {
+ uint32_t flags,
+ AString *errorDetailMsg) {
return mCodec->queueSecureInputBuffer(
index, offset, subSamples, numSubSamples, key, iv, mode,
- presentationTimeUs, flags);
+ presentationTimeUs, flags, errorDetailMsg);
}
status_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
@@ -244,7 +255,31 @@
setMediaCodec(env, thiz, NULL);
}
-static jint throwExceptionAsNecessary(JNIEnv *env, status_t err) {
+static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) {
+ jclass clazz = env->FindClass("android/media/MediaCodec$CryptoException");
+ CHECK(clazz != NULL);
+
+ jmethodID constructID =
+ env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;)V");
+ CHECK(constructID != NULL);
+
+ jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error");
+
+ jthrowable exception =
+ (jthrowable)env->NewObject(clazz, constructID, err, msgObj);
+
+ env->Throw(exception);
+}
+
+static jint throwExceptionAsNecessary(
+ JNIEnv *env, status_t err, const char *msg = NULL) {
+ if (err >= ERROR_DRM_WV_VENDOR_MIN && err <= ERROR_DRM_WV_VENDOR_MAX) {
+ // We'll throw our custom MediaCodec.CryptoException
+
+ throwCryptoException(env, err, msg);
+ return 0;
+ }
+
switch (err) {
case OK:
return 0;
@@ -376,10 +411,13 @@
return;
}
- status_t err = codec->queueInputBuffer(
- index, offset, size, timestampUs, flags);
+ AString errorDetailMsg;
- throwExceptionAsNecessary(env, err);
+ status_t err = codec->queueInputBuffer(
+ index, offset, size, timestampUs, flags, &errorDetailMsg);
+
+ throwExceptionAsNecessary(
+ env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
}
static void android_media_MediaCodec_queueSecureInputBuffer(
@@ -387,12 +425,7 @@
jobject thiz,
jint index,
jint offset,
- jintArray numBytesOfClearDataObj,
- jintArray numBytesOfEncryptedDataObj,
- jint numSubSamples,
- jbyteArray keyObj,
- jbyteArray ivObj,
- jint mode,
+ jobject cryptoInfoObj,
jlong timestampUs,
jint flags) {
ALOGV("android_media_MediaCodec_queueSecureInputBuffer");
@@ -404,6 +437,25 @@
return;
}
+ jint numSubSamples =
+ env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID);
+
+ jintArray numBytesOfClearDataObj =
+ (jintArray)env->GetObjectField(
+ cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID);
+
+ jintArray numBytesOfEncryptedDataObj =
+ (jintArray)env->GetObjectField(
+ cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID);
+
+ jbyteArray keyObj =
+ (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID);
+
+ jbyteArray ivObj =
+ (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID);
+
+ jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
+
status_t err = OK;
CryptoPlugin::SubSample *subSamples = NULL;
@@ -476,13 +528,17 @@
}
}
+ AString errorDetailMsg;
+
if (err == OK) {
err = codec->queueSecureInputBuffer(
index, offset,
subSamples, numSubSamples,
(const uint8_t *)key, (const uint8_t *)iv,
(CryptoPlugin::Mode)mode,
- timestampUs, flags);
+ timestampUs,
+ flags,
+ &errorDetailMsg);
}
if (iv != NULL) {
@@ -498,7 +554,8 @@
delete[] subSamples;
subSamples = NULL;
- throwExceptionAsNecessary(env, err);
+ throwExceptionAsNecessary(
+ env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
}
static jint android_media_MediaCodec_dequeueInputBuffer(
@@ -612,6 +669,30 @@
gFields.context = env->GetFieldID(clazz, "mNativeContext", "I");
CHECK(gFields.context != NULL);
+
+ clazz = env->FindClass("android/media/MediaCodec$CryptoInfo");
+ CHECK(clazz != NULL);
+
+ gFields.cryptoInfoNumSubSamplesID =
+ env->GetFieldID(clazz, "numSubSamples", "I");
+ CHECK(gFields.cryptoInfoNumSubSamplesID != NULL);
+
+ gFields.cryptoInfoNumBytesOfClearDataID =
+ env->GetFieldID(clazz, "numBytesOfClearData", "[I");
+ CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL);
+
+ gFields.cryptoInfoNumBytesOfEncryptedDataID =
+ env->GetFieldID(clazz, "numBytesOfEncryptedData", "[I");
+ CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL);
+
+ gFields.cryptoInfoKeyID = env->GetFieldID(clazz, "key", "[B");
+ CHECK(gFields.cryptoInfoKeyID != NULL);
+
+ gFields.cryptoInfoIVID = env->GetFieldID(clazz, "iv", "[B");
+ CHECK(gFields.cryptoInfoIVID != NULL);
+
+ gFields.cryptoInfoModeID = env->GetFieldID(clazz, "mode", "I");
+ CHECK(gFields.cryptoInfoModeID != NULL);
}
static void android_media_MediaCodec_native_setup(
@@ -666,7 +747,7 @@
{ "queueInputBuffer", "(IIIJI)V",
(void *)android_media_MediaCodec_queueInputBuffer },
- { "queueSecureInputBuffer", "(II[I[II[B[BIJI)V",
+ { "queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V",
(void *)android_media_MediaCodec_queueSecureInputBuffer },
{ "dequeueInputBuffer", "(J)I",
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 570c33b..e2688be 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -28,6 +28,7 @@
struct ALooper;
struct AMessage;
+struct AString;
struct ICrypto;
struct ISurfaceTexture;
struct MediaCodec;
@@ -52,7 +53,8 @@
status_t queueInputBuffer(
size_t index,
- size_t offset, size_t size, int64_t timeUs, uint32_t flags);
+ size_t offset, size_t size, int64_t timeUs, uint32_t flags,
+ AString *errorDetailMsg);
status_t queueSecureInputBuffer(
size_t index,
@@ -63,7 +65,8 @@
const uint8_t iv[16],
CryptoPlugin::Mode mode,
int64_t presentationTimeUs,
- uint32_t flags);
+ uint32_t flags,
+ AString *errorDetailMsg);
status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs);
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index e2cdbca..0518331 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -25,17 +25,21 @@
#include "jni.h"
#include "JNIHelp.h"
+#include <media/hardware/CryptoAPI.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
#include <media/stagefright/NuMediaExtractor.h>
namespace android {
struct fields_t {
jfieldID context;
+
+ jmethodID cryptoInfoSetID;
};
static fields_t gFields;
@@ -166,7 +170,36 @@
}
status_t JMediaExtractor::getSampleFlags(uint32_t *sampleFlags) {
- return mImpl->getSampleFlags(sampleFlags);
+ *sampleFlags = 0;
+
+ sp<MetaData> meta;
+ status_t err = mImpl->getSampleMeta(&meta);
+
+ if (err != OK) {
+ return err;
+ }
+
+ int32_t val;
+ if (meta->findInt32(kKeyIsSyncFrame, &val) && val != 0) {
+ (*sampleFlags) |= NuMediaExtractor::SAMPLE_FLAG_SYNC;
+ }
+
+ uint32_t type;
+ const void *data;
+ size_t size;
+ if (meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
+ (*sampleFlags) |= NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED;
+ }
+
+ return OK;
+}
+
+status_t JMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) {
+ return mImpl->getSampleMeta(sampleMeta);
+}
+
+bool JMediaExtractor::getCachedDuration(int64_t *durationUs, bool *eos) const {
+ return mImpl->getCachedDuration(durationUs, eos);
}
} // namespace android
@@ -369,6 +402,110 @@
return sampleFlags;
}
+static jboolean android_media_MediaExtractor_getSampleCryptoInfo(
+ JNIEnv *env, jobject thiz, jobject cryptoInfoObj) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return -1ll;
+ }
+
+ sp<MetaData> meta;
+ status_t err = extractor->getSampleMeta(&meta);
+
+ if (err != OK) {
+ return false;
+ }
+
+ uint32_t type;
+ const void *data;
+ size_t size;
+ if (!meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
+ return false;
+ }
+
+ size_t numSubSamples = size / sizeof(size_t);
+
+ if (numSubSamples == 0) {
+ return false;
+ }
+
+ jintArray numBytesOfEncryptedDataObj = env->NewIntArray(numSubSamples);
+ jboolean isCopy;
+ jint *dst = env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy);
+ for (size_t i = 0; i < numSubSamples; ++i) {
+ dst[i] = ((const size_t *)data)[i];
+ }
+ env->ReleaseIntArrayElements(numBytesOfEncryptedDataObj, dst, 0);
+ dst = NULL;
+
+ size_t encSize = size;
+ jintArray numBytesOfPlainDataObj = NULL;
+ if (meta->findData(kKeyPlainSizes, &type, &data, &size)) {
+ if (size != encSize) {
+ // The two must be of the same length.
+ return false;
+ }
+
+ numBytesOfPlainDataObj = env->NewIntArray(numSubSamples);
+ jboolean isCopy;
+ jint *dst = env->GetIntArrayElements(numBytesOfPlainDataObj, &isCopy);
+ for (size_t i = 0; i < numSubSamples; ++i) {
+ dst[i] = ((const size_t *)data)[i];
+ }
+ env->ReleaseIntArrayElements(numBytesOfPlainDataObj, dst, 0);
+ dst = NULL;
+ }
+
+ jbyteArray keyObj = NULL;
+ if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
+ if (size != 16) {
+ // Keys must be 16 bytes in length.
+ return false;
+ }
+
+ keyObj = env->NewByteArray(size);
+ jboolean isCopy;
+ jbyte *dst = env->GetByteArrayElements(keyObj, &isCopy);
+ memcpy(dst, data, size);
+ env->ReleaseByteArrayElements(keyObj, dst, 0);
+ dst = NULL;
+ }
+
+ jbyteArray ivObj = NULL;
+ if (meta->findData(kKeyCryptoIV, &type, &data, &size)) {
+ if (size != 16) {
+ // IVs must be 16 bytes in length.
+ return false;
+ }
+
+ ivObj = env->NewByteArray(size);
+ jboolean isCopy;
+ jbyte *dst = env->GetByteArrayElements(ivObj, &isCopy);
+ memcpy(dst, data, size);
+ env->ReleaseByteArrayElements(ivObj, dst, 0);
+ dst = NULL;
+ }
+
+ int32_t mode;
+ if (!meta->findInt32(kKeyCryptoMode, &mode)) {
+ mode = CryptoPlugin::kMode_AES_CTR;
+ }
+
+ env->CallVoidMethod(
+ cryptoInfoObj,
+ gFields.cryptoInfoSetID,
+ numSubSamples,
+ numBytesOfPlainDataObj,
+ numBytesOfEncryptedDataObj,
+ keyObj,
+ ivObj,
+ mode);
+
+ return true;
+}
+
static void android_media_MediaExtractor_native_init(JNIEnv *env) {
jclass clazz = env->FindClass("android/media/MediaExtractor");
CHECK(clazz != NULL);
@@ -376,6 +513,12 @@
gFields.context = env->GetFieldID(clazz, "mNativeContext", "I");
CHECK(gFields.context != NULL);
+ clazz = env->FindClass("android/media/MediaCodec$CryptoInfo");
+ CHECK(clazz != NULL);
+
+ gFields.cryptoInfoSetID =
+ env->GetMethodID(clazz, "set", "(I[I[I[B[BI)V");
+
DataSource::RegisterDefaultSniffers();
}
@@ -454,6 +597,42 @@
}
}
+static jlong android_media_MediaExtractor_getCachedDurationUs(
+ JNIEnv *env, jobject thiz) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return -1ll;
+ }
+
+ int64_t cachedDurationUs;
+ bool eos;
+ if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
+ return -1ll;
+ }
+
+ return cachedDurationUs;
+}
+
+static jboolean android_media_MediaExtractor_hasCacheReachedEOS(
+ JNIEnv *env, jobject thiz) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return true;
+ }
+
+ int64_t cachedDurationUs;
+ bool eos;
+ if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
+ return true;
+ }
+
+ return eos;
+}
+
static void android_media_MediaExtractor_native_finalize(
JNIEnv *env, jobject thiz) {
android_media_MediaExtractor_release(env, thiz);
@@ -485,6 +664,9 @@
{ "getSampleFlags", "()I",
(void *)android_media_MediaExtractor_getSampleFlags },
+ { "getSampleCryptoInfo", "(Landroid/media/MediaCodec$CryptoInfo;)Z",
+ (void *)android_media_MediaExtractor_getSampleCryptoInfo },
+
{ "native_init", "()V", (void *)android_media_MediaExtractor_native_init },
{ "native_setup", "()V",
@@ -499,6 +681,12 @@
{ "setDataSource", "(Ljava/io/FileDescriptor;JJ)V",
(void *)android_media_MediaExtractor_setDataSourceFd },
+
+ { "getCachedDuration", "()J",
+ (void *)android_media_MediaExtractor_getCachedDurationUs },
+
+ { "hasCacheReachedEndOfStream", "()Z",
+ (void *)android_media_MediaExtractor_hasCacheReachedEOS },
};
int register_android_media_MediaExtractor(JNIEnv *env) {
diff --git a/media/jni/android_media_MediaExtractor.h b/media/jni/android_media_MediaExtractor.h
index 1aacea2..ef0c48b 100644
--- a/media/jni/android_media_MediaExtractor.h
+++ b/media/jni/android_media_MediaExtractor.h
@@ -27,6 +27,7 @@
namespace android {
+struct MetaData;
struct NuMediaExtractor;
struct JMediaExtractor : public RefBase {
@@ -50,6 +51,9 @@
status_t getSampleTrackIndex(size_t *trackIndex);
status_t getSampleTime(int64_t *sampleTimeUs);
status_t getSampleFlags(uint32_t *sampleFlags);
+ status_t getSampleMeta(sp<MetaData> *sampleMeta);
+
+ bool getCachedDuration(int64_t *durationUs, bool *eos) const;
protected:
virtual ~JMediaExtractor();
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index f015afb..c2655c7 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -491,6 +491,27 @@
}
static jint
+android_media_visualizer_native_setScalingMode(JNIEnv *env, jobject thiz, jint mode)
+{
+ Visualizer* lpVisualizer = getVisualizer(env, thiz);
+ if (lpVisualizer == NULL) {
+ return VISUALIZER_ERROR_NO_INIT;
+ }
+
+ return translateError(lpVisualizer->setScalingMode(mode));
+}
+
+static jint
+android_media_visualizer_native_getScalingMode(JNIEnv *env, jobject thiz)
+{
+ Visualizer* lpVisualizer = getVisualizer(env, thiz);
+ if (lpVisualizer == NULL) {
+ return -1;
+ }
+ return lpVisualizer->getScalingMode();
+}
+
+static jint
android_media_visualizer_native_getSamplingRate(JNIEnv *env, jobject thiz)
{
Visualizer* lpVisualizer = getVisualizer(env, thiz);
@@ -582,6 +603,8 @@
{"getMaxCaptureRate", "()I", (void *)android_media_visualizer_native_getMaxCaptureRate},
{"native_setCaptureSize", "(I)I", (void *)android_media_visualizer_native_setCaptureSize},
{"native_getCaptureSize", "()I", (void *)android_media_visualizer_native_getCaptureSize},
+ {"native_setScalingMode", "(I)I", (void *)android_media_visualizer_native_setScalingMode},
+ {"native_getScalingMode", "()I", (void *)android_media_visualizer_native_getScalingMode},
{"native_getSamplingRate", "()I", (void *)android_media_visualizer_native_getSamplingRate},
{"native_getWaveForm", "([B)I", (void *)android_media_visualizer_native_getWaveForm},
{"native_getFft", "([B)I", (void *)android_media_visualizer_native_getFft},
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java
index b0bf654..abf85d7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java
@@ -188,6 +188,37 @@
assertTrue(msg, result);
}
+ //Test case 1.2: check scaling mode
+ @LargeTest
+ public void test1_2ScalingMode() throws Exception {
+ boolean result = false;
+ String msg = "test1_2ScalingMode()";
+ getVisualizer(0);
+ try {
+ int res = mVisualizer.setScalingMode(Visualizer.SCALING_MODE_AS_PLAYED);
+ assertEquals(msg + ": setting SCALING_MODE_AS_PLAYED failed",
+ res, Visualizer.SUCCESS);
+ int mode = mVisualizer.getScalingMode();
+ assertEquals(msg + ": setting SCALING_MODE_AS_PLAYED didn't stick",
+ mode, Visualizer.SCALING_MODE_AS_PLAYED);
+
+ res = mVisualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED);
+ assertEquals(msg + ": setting SCALING_MODE_NORMALIZED failed",
+ res, Visualizer.SUCCESS);
+ mode = mVisualizer.getScalingMode();
+ assertEquals(msg + ": setting SCALING_MODE_NORMALIZED didn't stick",
+ mode, Visualizer.SCALING_MODE_NORMALIZED);
+
+ result = true;
+ } catch (IllegalStateException e) {
+ msg = msg.concat("IllegalStateException");
+ loge(msg, "set/get parameter() called in wrong state: " + e);
+ } finally {
+ releaseVisualizer();
+ }
+ assertTrue(msg, result);
+ }
+
//-----------------------------------------------------------------
// 2 - check capture
//----------------------------------
@@ -403,6 +434,91 @@
assertTrue(msg, result);
}
+ //Test case 2.2: test capture in polling mode with volume scaling
+ @LargeTest
+ public void test2_2PollingCaptureVolumeScaling() throws Exception {
+ // test that when playing a sound, the energy measured with Visualizer in
+ // SCALING_MODE_AS_PLAYED mode decreases when lowering the volume
+ boolean result = false;
+ String msg = "test2_2PollingCaptureVolumeScaling()";
+ AudioEffect vc = null;
+ MediaPlayer mp = null;
+ AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
+ int ringerMode = am.getRingerMode();
+ am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ final int volMax = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ am.setStreamVolume(AudioManager.STREAM_MUSIC, volMax, 0);
+
+ try {
+ // test setup not related to tested functionality:
+ // creating a volume controller on output mix ensures that ro.audio.silent mutes
+ // audio after the effects and not before
+ vc = new AudioEffect(
+ AudioEffect.EFFECT_TYPE_NULL,
+ VOLUME_EFFECT_UUID,
+ 0,
+ 0);
+ vc.setEnabled(true);
+
+ mp = new MediaPlayer();
+ mp.setDataSource(MediaNames.SINE_200_1000);
+ mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ getVisualizer(mp.getAudioSessionId());
+
+ // verify we successfully set the Visualizer in SCALING_MODE_AS_PLAYED mode
+ mVisualizer.setScalingMode(Visualizer.SCALING_MODE_AS_PLAYED);
+ assertTrue(msg + " get volume scaling doesn't return SCALING_MODE_AS_PLAYED",
+ mVisualizer.getScalingMode() == Visualizer.SCALING_MODE_AS_PLAYED);
+ mVisualizer.setEnabled(true);
+ mp.prepare();
+ mp.start();
+ Thread.sleep(500);
+
+ // check capture on sound with music volume at max
+ byte[] data = new byte[mVisualizer.getCaptureSize()];
+ mVisualizer.getWaveForm(data);
+ int energyAtVolMax = computeEnergy(data, true);
+ assertTrue(msg +": getWaveForm reads insufficient level",
+ energyAtVolMax > 0);
+ log(msg, " engergy at max volume = "+energyAtVolMax);
+
+ // check capture on sound with music volume lowered from max
+ am.setStreamVolume(AudioManager.STREAM_MUSIC, (volMax * 2) / 3, 0);
+ Thread.sleep(500);
+ mVisualizer.getWaveForm(data);
+ int energyAtLowerVol = computeEnergy(data, true);
+ assertTrue(msg +": getWaveForm at lower volume reads insufficient level",
+ energyAtLowerVol > 0);
+ log(msg, "energy at lower volume = "+energyAtLowerVol);
+ assertTrue(msg +": getWaveForm didn't report lower energy when volume decreases",
+ energyAtVolMax > energyAtLowerVol);
+
+ result = true;
+ } catch (IllegalArgumentException e) {
+ msg = msg.concat(": IllegalArgumentException");
+ loge(msg, " hit exception " + e);
+ } catch (UnsupportedOperationException e) {
+ msg = msg.concat(": UnsupportedOperationException");
+ loge(msg, " hit exception " + e);
+ } catch (IllegalStateException e) {
+ msg = msg.concat("IllegalStateException");
+ loge(msg, " hit exception " + e);
+ } catch (InterruptedException e) {
+ loge(msg, " sleep() interrupted");
+ }
+ finally {
+ releaseVisualizer();
+ if (mp != null) {
+ mp.release();
+ }
+ if (vc != null) {
+ vc.release();
+ }
+ am.setRingerMode(ringerMode);
+ }
+ assertTrue(msg, result);
+ }
+
//-----------------------------------------------------------------
// private methods
//----------------------------------
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 113f0f7..8e3a3c5 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -50,6 +50,10 @@
import java.io.InputStream;
import java.io.OutputStream;
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import libcore.io.StructStatFs;
+
/*
* This service copies a downloaded apk to a file passed in as
* a ParcelFileDescriptor or to a newly created container specified
@@ -203,6 +207,18 @@
return 0L;
}
}
+
+ @Override
+ public long[] getFileSystemStats(String path) {
+ try {
+ final StructStatFs stat = Libcore.os.statfs(path);
+ final long totalSize = stat.f_blocks * stat.f_bsize;
+ final long availSize = stat.f_bavail * stat.f_bsize;
+ return new long[] { totalSize, availSize };
+ } catch (ErrnoException e) {
+ throw new IllegalStateException(e);
+ }
+ }
};
public DefaultContainerService() {
diff --git a/packages/InputDevices/Android.mk b/packages/InputDevices/Android.mk
index 446b47e..37f2428 100644
--- a/packages/InputDevices/Android.mk
+++ b/packages/InputDevices/Android.mk
@@ -1,3 +1,17 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -12,5 +26,17 @@
include $(BUILD_PACKAGE)
-########################
-include $(call all-makefiles-under,$(LOCAL_PATH))
+# Validate all key maps.
+include $(CLEAR_VARS)
+
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+files := frameworks/base/packages/InputDevices/res/raw/*.kcm
+
+LOCAL_MODULE := validate_input_devices_keymaps
+LOCAL_MODULE_TAGS := optional
+LOCAL_REQUIRED_MODULES := validatekeymaps
+
+validate_input_devices_keymaps: $(files)
+ $(hide) $(validatekeymaps) $(files)
+
+include $(BUILD_PHONY_PACKAGE)
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm
index a7823fd..050b149 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm
@@ -12,4 +12,300 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# PLACEHOLDER CONTENT #
+#
+# English (US) keyboard layout.
+# Unlike the default (generic) keyboard layout, English (US) does not contain any
+# special ALT characters.
+#
+
+type OVERLAY
+
+### ROW 1
+
+key GRAVE {
+ label: '`'
+ base: '`'
+ shift: '~'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '$'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '^'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '&'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '*'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: '('
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: ')'
+}
+
+key MINUS {
+ label: '-'
+ base: '-'
+ shift: '_'
+}
+
+key EQUALS {
+ label: '='
+ base: '='
+ shift: '+'
+}
+
+### ROW 2
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '['
+ base: '['
+ shift: '{'
+}
+
+key RIGHT_BRACKET {
+ label: ']'
+ base: ']'
+ shift: '}'
+}
+
+key BACKSLASH {
+ label: '\\'
+ base: '\\'
+ shift: '|'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key SEMICOLON {
+ label: ';'
+ base: ';'
+ shift: ':'
+}
+
+key APOSTROPHE {
+ label: '\''
+ base: '\''
+ shift: '"'
+}
+
+### ROW 4
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: '<'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: '>'
+}
+
+key SLASH {
+ label: '/'
+ base: '/'
+ shift: '?'
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm
index a7823fd..df6a3fd 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm
@@ -12,4 +12,336 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# PLACEHOLDER CONTENT #
+#
+# English (US), Dvorak keyboard layout.
+# Unlike the default (generic) keyboard layout, English (US) does not contain any
+# special ALT characters.
+#
+
+type OVERLAY
+
+map key 12 LEFT_BRACKET
+map key 13 RIGHT_BRACKET
+map key 16 APOSTROPHE
+map key 17 COMMA
+map key 18 PERIOD
+map key 19 P
+map key 20 Y
+map key 21 F
+map key 22 G
+map key 23 C
+map key 24 R
+map key 25 L
+map key 26 SLASH
+map key 27 EQUALS
+map key 30 A
+map key 31 O
+map key 32 E
+map key 33 U
+map key 34 I
+map key 35 D
+map key 36 H
+map key 37 T
+map key 38 N
+map key 39 S
+map key 40 MINUS
+map key 44 SEMICOLON
+map key 45 Q
+map key 46 J
+map key 47 K
+map key 48 X
+map key 49 B
+map key 50 M
+map key 51 W
+map key 52 V
+map key 53 Z
+
+### ROW 1
+
+key GRAVE {
+ label: '`'
+ base: '`'
+ shift: '~'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '$'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '^'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '&'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '*'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: '('
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: ')'
+}
+
+key LEFT_BRACKET {
+ label: '['
+ base: '['
+ shift: '{'
+}
+
+key RIGHT_BRACKET {
+ label: ']'
+ base: ']'
+ shift: '}'
+}
+
+### ROW 2
+
+key APOSTROPHE {
+ label: '\''
+ base: '\''
+ shift: '"'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: '<'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: '>'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key SLASH {
+ label: '/'
+ base: '/'
+ shift: '?'
+}
+
+key EQUALS {
+ label: '='
+ base: '='
+ shift: '+'
+}
+
+key BACKSLASH {
+ label: '\\'
+ base: '\\'
+ shift: '|'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key MINUS {
+ label: '-'
+ base: '-'
+ shift: '_'
+}
+
+### ROW 4
+
+key SEMICOLON {
+ label: ';'
+ base: ';'
+ shift: ':'
+}
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_german.kcm b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
index a7823fd..9c75973 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_german.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
@@ -12,4 +12,322 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# PLACEHOLDER CONTENT #
+#
+# German keyboard layout, QWERTZ style.
+#
+
+type OVERLAY
+
+map key 12 SLASH # § ? \
+map key 21 Z
+map key 44 Y
+map key 53 MINUS # - _
+map key 86 PLUS # < > |
+
+### ROW 1
+
+key GRAVE {
+ label: '^'
+ base: '^'
+ shift: '\u00b0'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '"'
+ ralt: '\u00b2'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '\u00a7'
+ ralt: '\u00b3'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '$'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '&'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '/'
+ ralt: '{'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '('
+ ralt: '['
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: ')'
+ ralt: ']'
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: '='
+ ralt: '}'
+}
+
+key SLASH {
+ label: '\u00df'
+ base: '\u00df'
+ shift: '?'
+ ralt: '\\'
+}
+
+key EQUALS {
+ label: '\u00b4'
+ base: '\u0301'
+ shift: '\u0300'
+}
+
+### ROW 2
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+ ralt: '@'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+ ralt: '\u20ac'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '\u00dc'
+ base: '\u00fc'
+ shift: '\u00dc'
+}
+
+key RIGHT_BRACKET {
+ label: '+'
+ base: '+'
+ shift: '*'
+ ralt: '~'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key SEMICOLON {
+ label: '\u00d6'
+ base: '\u00f6'
+ shift: '\u00d6'
+}
+
+key APOSTROPHE {
+ label: '\u00c4'
+ base: '\u00e4'
+ shift: '\u00c4'
+}
+
+key BACKSLASH {
+ label: '#'
+ base: '#'
+ shift: '\''
+}
+
+### ROW 4
+
+key PLUS {
+ label: '<'
+ base: '<'
+ shift: '>'
+ ralt: '|'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+ ralt: '\u00b5'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: ';'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: ':'
+}
+
+key MINUS {
+ label: '-'
+ base: '-'
+ shift: '_'
+}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index e937587..f200f43 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -1,15 +1,46 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.systemui"
- coreApp="true"
- android:sharedUserId="android.uid.system"
- android:process="system"
- >
+ coreApp="true">
+
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <uses-permission android:name="android.permission.INJECT_EVENTS" />
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
+ <uses-permission android:name="android.permission.STATUS_BAR" />
+ <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
+
+ <!-- Networking and telephony -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
- <uses-permission android:name="android.permission.GET_TASKS" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+
+ <!-- Physical hardware -->
<uses-permission android:name="android.permission.MANAGE_USB" />
+ <uses-permission android:name="android.permission.DEVICE_POWER" />
+ <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
+ <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
+
+ <!-- ActivityManager -->
+ <uses-permission android:name="android.permission.GET_TASKS" />
+ <uses-permission android:name="android.permission.REORDER_TASKS" />
+ <uses-permission android:name="android.permission.REMOVE_TASKS" />
+ <uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
+ <uses-permission android:name="android.permission.SET_SCREEN_COMPATIBILITY" />
+ <uses-permission android:name="android.permission.START_ANY_ACTIVITY" />
+
+ <!-- WindowManager -->
+ <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
+ <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
+ <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
+ <uses-permission android:name="android.permission.SET_ORIENTATION" />
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<application
android:persistent="true"
diff --git a/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png b/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png
new file mode 100644
index 0000000..e8cfc0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/bottom_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png b/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png
new file mode 100644
index 0000000..89cd10e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/top_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png b/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png
new file mode 100644
index 0000000..7d7868d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/bottom_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png b/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png
new file mode 100644
index 0000000..f93da09
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/top_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_airplane_on.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_airplane_on.png
new file mode 100644
index 0000000..be65c74
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..345aef6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
new file mode 100644
index 0000000..4b8f263
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
new file mode 100644
index 0000000..f5ab80d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_brightness.png
new file mode 100644
index 0000000..316f0e1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_brightness.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png
new file mode 100644
index 0000000..f2de78e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png
new file mode 100644
index 0000000..4da3f7a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
new file mode 100644
index 0000000..8713c06
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
new file mode 100644
index 0000000..05efe0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_ime_default.png
index 47f0745c..2263d5c 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_ime_default.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png
new file mode 100644
index 0000000..a97440e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png
new file mode 100644
index 0000000..7d45617
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
new file mode 100644
index 0000000..d7b9670
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
new file mode 100644
index 0000000..5c1e7cc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_quicksettings.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_quicksettings.png
new file mode 100644
index 0000000..dd88dae
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_quicksettings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..da766c5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
new file mode 100644
index 0000000..c247d28
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_rotate_on.png
new file mode 100644
index 0000000..4c0e80c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_rotate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_wifi_on.png
new file mode 100644
index 0000000..0d833b8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_wifi_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_airplane_on.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_airplane_on.png
new file mode 100644
index 0000000..ecc822f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..ac5841e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
new file mode 100644
index 0000000..a479cc5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
new file mode 100644
index 0000000..4038951
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_brightness.png
new file mode 100644
index 0000000..52f21cc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_brightness.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png
new file mode 100644
index 0000000..6214f08
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png
new file mode 100644
index 0000000..bac44eb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
new file mode 100644
index 0000000..dfecfc9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
new file mode 100644
index 0000000..71f8a36
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_ime_default.png
index 33edce0..1e79859 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_ime_default.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png
new file mode 100644
index 0000000..0ee70861
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png
new file mode 100644
index 0000000..f35c36b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
new file mode 100644
index 0000000..7083de01
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
new file mode 100644
index 0000000..68c10c0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_quicksettings.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_quicksettings.png
new file mode 100644
index 0000000..65e761d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_quicksettings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..67d6796
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
new file mode 100644
index 0000000..def3808
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_rotate_on.png
new file mode 100644
index 0000000..6efef06
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_rotate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_wifi_on.png
new file mode 100644
index 0000000..7efc16163
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_wifi_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_airplane_on.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_airplane_on.png
new file mode 100644
index 0000000..8e5791f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..477df5f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
new file mode 100644
index 0000000..5839fd0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
new file mode 100644
index 0000000..27b7ace
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_brightness.png
new file mode 100644
index 0000000..f3dfb4f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_brightness.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png
new file mode 100644
index 0000000..376e48c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png
new file mode 100644
index 0000000..9a364b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
new file mode 100644
index 0000000..f753383
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
new file mode 100644
index 0000000..b6e898e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_ime_default.png
index d670177..fb34efc 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_ime_default.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png
new file mode 100644
index 0000000..f079b85
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png
new file mode 100644
index 0000000..fa5f001
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
new file mode 100644
index 0000000..7690b47
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
new file mode 100644
index 0000000..8c50621
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_quicksettings.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_quicksettings.png
new file mode 100644
index 0000000..d6afed1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_quicksettings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..f2db326
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
new file mode 100644
index 0000000..93c737b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_rotate_on.png
new file mode 100644
index 0000000..61bcf6e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_rotate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_wifi_on.png
new file mode 100644
index 0000000..a00a9b8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_wifi_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_default.png
new file mode 100644
index 0000000..47f0745c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_pressed.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_ime_pressed.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_default.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_default.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_default.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_pressed.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_pressed.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_pressed.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_normal.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/notify_panel_clock_bg_normal.9.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_pressed.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/notify_panel_clock_bg_pressed.9.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_notify_bg.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/notify_panel_notify_bg.9.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/recents_bg_protect_tile.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/recents_bg_protect_tile.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/recents_bg_protect_tile.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/recents_blue_glow.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/recents_blue_glow.9.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/recents_blue_glow.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_alarm.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_alarm.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_alarm.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_0.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_100.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_100.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_100.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_15.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_15.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_28.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_28.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_28.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_43.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_43.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_43.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_57.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_57.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_57.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_71.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_71.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_71.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_85.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_85.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_85.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim0.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim100.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim100.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim100.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim15.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim15.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim15.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim28.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim28.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim28.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim43.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim43.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim43.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim57.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim57.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim57.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim71.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim71.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim71.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim85.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim85.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_battery_charge_anim85.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_bluetooth.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_bluetooth.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_bluetooth_connected.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_bluetooth_connected.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_bluetooth_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_1x.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_1x.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_3g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_3g.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_4g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_4g.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_e.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_e.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_g.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_h.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_h.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_roam.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_connected_roam.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_1x.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_1x.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_3g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_3g.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_4g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_4g.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_e.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_e.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_g.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_h.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_data_fully_connected_h.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_0.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_0_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_0_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_1.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_1.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_1_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_1_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_2.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_2.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_2_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_2_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_3.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_3.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_3_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_3_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_4.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_4.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_4_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_4_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_flightmode.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_flightmode.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_in.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_inout.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_null.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_null.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_out.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_in.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_inout.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_out.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_0.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_1.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_1.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_1_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_1_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_2.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_2.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_2_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_2_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_3.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_3.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_3_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_3_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_4.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_4.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_4_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_signal_4_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_default.png
new file mode 100644
index 0000000..33edce0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_pressed.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_ime_pressed.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_default.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_default.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_default.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_pressed.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_pressed.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_pressed.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_normal.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/notify_panel_clock_bg_normal.9.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_pressed.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/notify_panel_clock_bg_pressed.9.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_notify_bg.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/notify_panel_notify_bg.9.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/recents_bg_protect_tile.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/recents_bg_protect_tile.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/recents_bg_protect_tile.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/recents_blue_glow.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/recents_blue_glow.9.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/recents_blue_glow.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_alarm.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_alarm.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_alarm.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_0.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_100.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_100.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_100.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_15.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_15.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_28.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_28.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_28.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_43.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_43.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_43.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_57.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_57.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_57.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_71.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_71.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_71.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_85.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_85.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_85.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim0.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim100.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim100.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim100.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim15.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim15.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim15.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim28.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim28.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim28.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim43.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim43.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim43.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim57.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim57.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim57.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim71.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim71.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim71.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim85.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim85.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_battery_charge_anim85.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_bluetooth.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_bluetooth.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_bluetooth_connected.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_bluetooth_connected.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_bluetooth_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_1x.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_1x.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_3g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_3g.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_4g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_4g.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_e.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_e.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_g.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_h.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_h.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_roam.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_connected_roam.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_1x.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_1x.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_3g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_3g.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_4g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_4g.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_e.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_e.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_g.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_h.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_data_fully_connected_h.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_0.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_0_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_0_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_1.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_1.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_1_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_1_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_2.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_2.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_2_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_2_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_3.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_3.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_3_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_3_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_4.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_4.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_4_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_4_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_flightmode.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_flightmode.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_in.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_inout.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_null.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_null.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_out.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_in.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_inout.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_out.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_0.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_1.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_1.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_1_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_1_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_2.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_2.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_2_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_2_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_3.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_3.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_3_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_3_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_4.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_4.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_4_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_signal_4_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_default.png
new file mode 100644
index 0000000..d670177
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_pressed.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_ime_pressed.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_zoom_default.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_default.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_zoom_default.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_zoom_pressed.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_pressed.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_zoom_pressed.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_normal.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/notify_panel_clock_bg_normal.9.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_pressed.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/notify_panel_clock_bg_pressed.9.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_notify_bg.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/notify_panel_notify_bg.9.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_bg_protect_tile.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_bg_protect_tile.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_bg_protect_tile.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_blue_glow.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/recents_blue_glow.9.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_blue_glow.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_alarm.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_alarm.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_alarm.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_0.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_100.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_100.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_100.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_15.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_15.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_28.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_28.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_28.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_43.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_43.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_43.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_57.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_57.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_57.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_71.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_71.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_71.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_85.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_85.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_85.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim0.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim100.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim100.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim100.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim15.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim15.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim15.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim28.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim28.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim28.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim43.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim43.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim43.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim57.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim57.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim57.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim71.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim71.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim71.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim85.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim85.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_battery_charge_anim85.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_bluetooth.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_bluetooth.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_bluetooth_connected.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_bluetooth_connected.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_bluetooth_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_1x.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_1x.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_3g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_3g.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_4g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_4g.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_e.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_e.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_g.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_h.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_h.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_roam.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_connected_roam.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_1x.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_1x.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_3g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_3g.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_4g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_4g.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_e.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_e.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_g.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_g.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_h.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_data_fully_connected_h.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_0.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_0_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_0_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_1.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_1.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_1_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_1_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_2.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_2.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_2_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_2_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_3.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_3.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_3_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_3_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_4.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_4.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_4_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_4_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_flightmode.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_flightmode.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_in.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_inout.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_null.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_null.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_out.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_in.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_inout.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_out.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_0.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_0.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_1.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_1.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_1_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_1_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_2.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_2.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_2_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_2_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_3.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_3.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_3_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_3_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_4.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_4.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_4_fully.png
similarity index 100%
rename from packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_signal_4_fully.png
rename to packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png b/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png
new file mode 100644
index 0000000..bbcea9e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/bottom_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png b/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png
new file mode 100644
index 0000000..56b63d0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/top_divider_glow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml b/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml
index ce3372e..0e1bdd3 100644
--- a/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="@android:integer/config_mediumAnimTime">
- <item android:state_pressed="true" android:drawable="@drawable/notification_item_background_color_pressed" />
+ <item android:state_pressed="true" android:drawable="@*android:drawable/notification_item_background_color_pressed" />
<item android:state_pressed="false" android:drawable="@drawable/notification_item_background_legacy_color" />
</selector>
diff --git a/packages/SystemUI/res/drawable/status_bar_item_background.xml b/packages/SystemUI/res/drawable/status_bar_item_background.xml
index 3a50aa9..b82fed9 100644
--- a/packages/SystemUI/res/drawable/status_bar_item_background.xml
+++ b/packages/SystemUI/res/drawable/status_bar_item_background.xml
@@ -19,7 +19,7 @@
android:opacity="translucent"
>
<item
- android:drawable="@drawable/notification_item_background_color"
+ android:drawable="@*android:drawable/notification_item_background_color"
/>
</layer-list>
diff --git a/packages/SystemUI/res/drawable/system_bar_ticker_background.xml b/packages/SystemUI/res/drawable/system_bar_ticker_background.xml
new file mode 100644
index 0000000..7cb64c0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/system_bar_ticker_background.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<bitmap
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:tileMode="repeat"
+ android:src="@*android:drawable/notify_panel_notification_icon_bg"
+ />
diff --git a/packages/SystemUI/res/drawable/ticker_background.xml b/packages/SystemUI/res/drawable/ticker_background.xml
index 7320fa0..07b44ca 100644
--- a/packages/SystemUI/res/drawable/ticker_background.xml
+++ b/packages/SystemUI/res/drawable/ticker_background.xml
@@ -20,7 +20,7 @@
>
<!-- the large icon extends 12dp beyond the edge of the status bar -->
<item
- android:drawable="@drawable/notification_item_background_color"
+ android:drawable="@*android:drawable/notification_item_background_color"
android:top="12dp"
/>
</layer-list>
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index dba1dd9..fcdd56c 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -20,9 +20,12 @@
<com.android.systemui.recent.RecentsPanelView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/recents_root"
android:layout_height="match_parent"
- android:layout_width="match_parent">
+ android:layout_width="match_parent"
+ systemui:recentItemLayout="@layout/status_bar_recent_item"
+ >
<FrameLayout
android:id="@+id/recents_bg_protect"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
index 73c3da5..216dcb0 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
@@ -20,9 +20,12 @@
<com.android.systemui.recent.RecentsPanelView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/recents_root"
android:layout_height="match_parent"
- android:layout_width="match_parent">
+ android:layout_width="match_parent"
+ systemui:recentItemLayout="@layout/status_bar_recent_item"
+ >
<FrameLayout
android:id="@+id/recents_bg_protect"
diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
new file mode 100644
index 0000000..662c186
--- /dev/null
+++ b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+-->
+
+<!-- navigation bar for sw600dp (small tablets) -->
+<com.android.systemui.statusbar.phone.NavigationBarView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:background="#FF000000"
+ >
+
+ <FrameLayout android:id="@+id/rot0"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ >
+
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/nav_buttons"
+ android:animateLayoutChanges="true"
+ >
+
+ <!-- navigation controls -->
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ <View
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:visibility="invisible"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_back"
+ systemui:keyCode="4"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_back"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_home"
+ systemui:keyCode="3"
+ systemui:keyRepeat="true"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_home"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_recent"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_recent"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_menu"
+ systemui:keyCode="82"
+ android:layout_weight="0"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_menu"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ />
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ </LinearLayout>
+
+ <!-- lights out layout to match exactly -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:id="@+id/lights_out"
+ android:visibility="gone"
+ >
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ <ImageView
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="40dp"
+ android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <ImageView
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <ImageView
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_marginRight="40dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ </LinearLayout>
+
+ <com.android.systemui.statusbar.policy.DeadZone
+ android:id="@+id/deadzone"
+ android:layout_height="@dimen/navigation_bar_deadzone_size"
+ android:layout_width="match_parent"
+ android:layout_gravity="top"
+ />
+ </FrameLayout>
+
+ <FrameLayout android:id="@+id/rot90"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:visibility="gone"
+ android:paddingTop="0dp"
+ >
+
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/nav_buttons"
+ android:animateLayoutChanges="true"
+ >
+
+ <!-- navigation controls -->
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ <View
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:visibility="invisible"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_back"
+ systemui:keyCode="4"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_back"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_home"
+ systemui:keyCode="3"
+ systemui:keyRepeat="true"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_home"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_recent"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_recent"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_menu"
+ systemui:keyCode="82"
+ android:layout_weight="0"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_menu"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ />
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ </LinearLayout>
+
+ <!-- lights out layout to match exactly -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:id="@+id/lights_out"
+ android:visibility="gone"
+ >
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ <ImageView
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="40dp"
+ android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <ImageView
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <ImageView
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_marginRight="40dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ </LinearLayout>
+
+ <com.android.systemui.statusbar.policy.DeadZone
+ android:id="@+id/deadzone"
+ android:layout_height="@dimen/navigation_bar_deadzone_size"
+ android:layout_width="match_parent"
+ android:layout_gravity="top"
+ />
+ </FrameLayout>
+
+ <!-- not used -->
+ <View android:id="@+id/rot270"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:visibility="gone"
+ />
+
+</com.android.systemui.statusbar.phone.NavigationBarView>
diff --git a/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml b/packages/SystemUI/res/layout/compat_mode_help.xml
similarity index 100%
rename from packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml
rename to packages/SystemUI/res/layout/compat_mode_help.xml
diff --git a/packages/SystemUI/res/layout/notification_adaptive_wrapper.xml b/packages/SystemUI/res/layout/notification_adaptive_wrapper.xml
new file mode 100644
index 0000000..15d0890
--- /dev/null
+++ b/packages/SystemUI/res/layout/notification_adaptive_wrapper.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<SizeAdaptiveLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:background="@android:color/background_dark"
+ android:id="@+id/notification_adaptive_wrapper"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index c307c6e..e69cd8a 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -1,8 +1,18 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="@dimen/notification_height"
+ android:layout_height="wrap_content"
+ android:background="@*android:drawable/notification_bg"
>
+ <View
+ android:id="@+id/top_glow"
+ android:alpha="0"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_divider_height"
+ android:layout_gravity="top|center_horizontal"
+ android:background="@drawable/top_divider_glow"
+ />
+
<Button
android:id="@+id/veto"
android:layout_width="48dp"
@@ -18,16 +28,25 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/notification_divider_height"
+ android:layout_marginTop="@dimen/notification_divider_height"
android:focusable="true"
android:clickable="true"
- android:background="@drawable/notification_row_bg"
- />
+ >
+
+ <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/adaptive"
+ android:background="@*android:drawable/notification_bg"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ </com.android.systemui.statusbar.LatestItemView>
<View
+ android:id="@+id/bottom_glow"
+ android:alpha="0"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_divider_height"
- android:gravity="bottom"
- android:background="@drawable/status_bar_notification_row_background_color"
+ android:layout_gravity="bottom|center_horizontal"
+ android:background="@drawable/bottom_divider_glow"
/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar.xml b/packages/SystemUI/res/layout/system_bar.xml
similarity index 96%
rename from packages/SystemUI/res/layout-sw600dp/status_bar.xml
rename to packages/SystemUI/res/layout/system_bar.xml
index 2308bf0..a33d638 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar.xml
+++ b/packages/SystemUI/res/layout/system_bar.xml
@@ -19,13 +19,13 @@
<com.android.systemui.statusbar.tablet.TabletStatusBarView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
- android:background="@drawable/status_bar_background"
+ android:background="@drawable/system_bar_background"
>
<FrameLayout
android:id="@+id/bar_contents_holder"
android:layout_width="match_parent"
- android:layout_height="@*android:dimen/status_bar_height"
+ android:layout_height="@*android:dimen/system_bar_height"
android:layout_gravity="bottom"
>
<RelativeLayout
@@ -36,7 +36,7 @@
>
<!-- notification icons & panel access -->
- <include layout="@layout/status_bar_notification_area"
+ <include layout="@layout/system_bar_notification_area"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml b/packages/SystemUI/res/layout/system_bar_compat_mode_panel.xml
similarity index 100%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_compat_mode_panel.xml
rename to packages/SystemUI/res/layout/system_bar_compat_mode_panel.xml
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_item.xml b/packages/SystemUI/res/layout/system_bar_input_methods_item.xml
similarity index 99%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_item.xml
rename to packages/SystemUI/res/layout/system_bar_input_methods_item.xml
index 41a20fb..5515559 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_item.xml
+++ b/packages/SystemUI/res/layout/system_bar_input_methods_item.xml
@@ -102,4 +102,4 @@
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="@android:drawable/divider_horizontal_dark" />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_panel.xml b/packages/SystemUI/res/layout/system_bar_input_methods_panel.xml
similarity index 99%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_panel.xml
rename to packages/SystemUI/res/layout/system_bar_input_methods_panel.xml
index b712dba..8dede50 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_panel.xml
+++ b/packages/SystemUI/res/layout/system_bar_input_methods_panel.xml
@@ -114,4 +114,4 @@
android:ellipsize="marquee" />
</LinearLayout>
</FrameLayout>
-</com.android.systemui.statusbar.tablet.InputMethodsPanel>
\ No newline at end of file
+</com.android.systemui.statusbar.tablet.InputMethodsPanel>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_no_recent_apps.xml b/packages/SystemUI/res/layout/system_bar_no_recent_apps.xml
similarity index 100%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_no_recent_apps.xml
rename to packages/SystemUI/res/layout/system_bar_no_recent_apps.xml
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml b/packages/SystemUI/res/layout/system_bar_notification_area.xml
similarity index 100%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml
rename to packages/SystemUI/res/layout/system_bar_notification_area.xml
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel.xml b/packages/SystemUI/res/layout/system_bar_notification_panel.xml
similarity index 94%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel.xml
rename to packages/SystemUI/res/layout/system_bar_notification_panel.xml
index 2947bfb..42af147 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout/system_bar_notification_panel.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<!-- android:background="@drawable/status_bar_closed_default_background" -->
+<!-- android:background="@drawable/system_bar_closed_default_background" -->
<com.android.systemui.statusbar.tablet.NotificationPanel
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
@@ -26,7 +26,7 @@
<ImageView android:id="@+id/clear_all_button"
android:layout_width="wrap_content"
- android:layout_height="@*android:dimen/status_bar_height"
+ android:layout_height="@*android:dimen/system_bar_height"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
@@ -46,7 +46,7 @@
android:layout_marginBottom="8dp"
>
- <include layout="@layout/status_bar_notification_panel_title"
+ <include layout="@layout/system_bar_notification_panel_title"
android:layout_width="478dp"
android:layout_height="224dp"
android:layout_alignParentTop="true"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
similarity index 100%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
rename to packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_peek.xml b/packages/SystemUI/res/layout/system_bar_notification_peek.xml
similarity index 92%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_notification_peek.xml
rename to packages/SystemUI/res/layout/system_bar_notification_peek.xml
index 02f9a90..3cff47b 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_peek.xml
+++ b/packages/SystemUI/res/layout/system_bar_notification_peek.xml
@@ -18,7 +18,7 @@
*/
-->
-<!-- android:background="@drawable/status_bar_closed_default_background" -->
+<!-- android:background="@drawable/system_bar_closed_default_background" -->
<com.android.systemui.statusbar.tablet.NotificationPeekPanel
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
@@ -34,7 +34,7 @@
android:gravity="center_horizontal|bottom"
android:animationCache="false"
android:orientation="vertical"
- android:background="@drawable/status_bar_background"
+ android:background="@drawable/system_bar_background"
android:clickable="true"
android:focusable="true"
android:descendantFocusability="afterDescendants"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_pocket_panel.xml b/packages/SystemUI/res/layout/system_bar_pocket_panel.xml
similarity index 100%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_pocket_panel.xml
rename to packages/SystemUI/res/layout/system_bar_pocket_panel.xml
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout/system_bar_recent_item.xml
similarity index 100%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
rename to packages/SystemUI/res/layout/system_bar_recent_item.xml
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml b/packages/SystemUI/res/layout/system_bar_recent_panel.xml
similarity index 88%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
rename to packages/SystemUI/res/layout/system_bar_recent_panel.xml
index 8e231d0..c2b9e51 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout/system_bar_recent_panel.xml
@@ -20,11 +20,14 @@
<com.android.systemui.recent.RecentsPanelView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/recents_root"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:clipToPadding="false"
- android:clipChildren="false">
+ android:clipChildren="false"
+ systemui:recentItemLayout="@layout/system_bar_recent_item"
+ >
<FrameLayout
android:id="@+id/recents_bg_protect"
@@ -32,7 +35,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
- android:layout_marginBottom="@*android:dimen/status_bar_height"
+ android:layout_marginBottom="@*android:dimen/system_bar_height"
android:clipToPadding="false"
android:clipChildren="false">
@@ -59,7 +62,7 @@
</com.android.systemui.recent.RecentsVerticalScrollView>
- <include layout="@layout/status_bar_no_recent_apps"
+ <include layout="@layout/system_bar_no_recent_apps"
android:id="@+id/recents_no_apps"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -72,7 +75,7 @@
<com.android.systemui.recent.StatusBarTouchProxy
android:id="@+id/status_bar_touch_proxy"
android:layout_width="match_parent"
- android:layout_height="@*android:dimen/status_bar_height"
+ android:layout_height="@*android:dimen/system_bar_height"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
/>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel_footer.xml b/packages/SystemUI/res/layout/system_bar_recent_panel_footer.xml
similarity index 100%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel_footer.xml
rename to packages/SystemUI/res/layout/system_bar_recent_panel_footer.xml
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_settings_view.xml b/packages/SystemUI/res/layout/system_bar_settings_view.xml
similarity index 100%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_settings_view.xml
rename to packages/SystemUI/res/layout/system_bar_settings_view.xml
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_compat.xml b/packages/SystemUI/res/layout/system_bar_ticker_compat.xml
similarity index 94%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_ticker_compat.xml
rename to packages/SystemUI/res/layout/system_bar_ticker_compat.xml
index d963de1..0d255e7 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_compat.xml
+++ b/packages/SystemUI/res/layout/system_bar_ticker_compat.xml
@@ -33,9 +33,9 @@
<LinearLayout
android:layout_width="wrap_content"
- android:layout_height="@*android:dimen/status_bar_height"
+ android:layout_height="@*android:dimen/system_bar_height"
android:layout_weight="1"
- android:background="@drawable/status_bar_ticker_background"
+ android:background="@drawable/system_bar_ticker_background"
>
<ImageView android:id="@+id/left_icon"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml b/packages/SystemUI/res/layout/system_bar_ticker_panel.xml
similarity index 89%
rename from packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml
rename to packages/SystemUI/res/layout/system_bar_ticker_panel.xml
index d51f9c8..1738b48 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml
+++ b/packages/SystemUI/res/layout/system_bar_ticker_panel.xml
@@ -22,9 +22,9 @@
>
<View
- android:layout_height="@*android:dimen/status_bar_height"
+ android:layout_height="@*android:dimen/system_bar_height"
android:layout_width="match_parent"
- android:background="@drawable/status_bar_ticker_background"
+ android:background="@drawable/system_bar_ticker_background"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:clickable="false"
@@ -43,7 +43,7 @@
<FrameLayout
android:id="@+id/ticker_expanded"
android:layout_weight="1"
- android:layout_height="@*android:dimen/status_bar_height"
+ android:layout_height="@*android:dimen/system_bar_height"
android:layout_width="match_parent"
android:layout_toRightOf="@id/large_icon"
android:layout_alignParentBottom="true"
diff --git a/packages/SystemUI/res/menu/notification_popup_menu.xml b/packages/SystemUI/res/menu/notification_popup_menu.xml
new file mode 100644
index 0000000..8923fb6
--- /dev/null
+++ b/packages/SystemUI/res/menu/notification_popup_menu.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/notification_inspect_item" android:title="@string/status_bar_notification_inspect_item_title" />
+</menu>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 1654eca..a9810d1 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ligging deur GPS gestel"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Verwyder alle kennisgewings."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktiveer sluimerskerm"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Programinligting"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 42eef13..873dd65 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -118,7 +118,7 @@
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ብሉቱዝ ማያያዝ።"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"የአውሮፕላን ሁነታ።"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"የባትሪ <xliff:g id="NUMBER">%d</xliff:g> መቶኛ።"</string>
- <string name="accessibility_settings_button" msgid="799583911231893380">"የስርዓት ቅንጅቶች"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"የስርዓት ቅንብሮች"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"ማሳወቂያዎች"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"ማሳወቂያ አጥራ"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ነቅቷል።"</string>
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"በ GPS የተዘጋጀ ሥፍራ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">" ገፁማያ ማቆያ አንቃ"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"የመተግበሪያ መረጃ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 9d6051e..9e316ec 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"تم تعيين الموقع بواسطة GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"تنشيط شاشة التوقف"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"معلومات التطبيق"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 433c124..8ce52db 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -141,4 +141,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Месца задана праз GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Выдалiць усе апавяшчэннi."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Актывацыя экраннай застаўкі"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index e5167a5..b78dbc9 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Известия"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth има връзка с тетъринг"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Методи на въвеждане: Настройка"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Физическа клавиатура"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"Да се разреши ли на приложението <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до USB устройството?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Да се разреши ли на приложението <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до аксесоара за USB?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Да се отвори ли <xliff:g id="ACTIVITY">%1$s</xliff:g>, когато това USB устройство е свързано?"</string>
@@ -140,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположението е зададено от GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Активиране на скрийнсейвъра"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 427abce..9eec352 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -141,4 +141,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"S\'ha establert la ubicació per GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Activa el protector de pantalla"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informació de l\'aplicació"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 847bfc4..f5a12e4 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Oznámení"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Datové připojení Bluetooth se sdílí"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavit metody vstupu"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fyzická klávesnice"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení USB?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k perifernímu zařízení USB?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Chcete při připojení tohoto zařízení USB otevřít aplikaci <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string>
@@ -142,4 +141,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavena pomocí systému GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazat všechna oznámení."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktivovat spořič obrazovky"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 6c614cd..4fa113b 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Placeringen er angivet ved hjælp af GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle meddelelser."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktiver pauseskærm"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Oplysninger om appen"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index e3d82b1..39832fc 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -141,4 +141,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Standort durch GPS festgelegt"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Bildschirmschoner aktivieren"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App-Info"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 5511b1a..351c506 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -141,4 +141,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ρύθμιση τοποθεσίας με GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Εκκαθάριση όλων των ειδοποιήσεων."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Ενεργοποίηση προφύλαξης οθόνης"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Πληροφορίες εφαρμογής"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index b20a5f3..7061148 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -139,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Location set by GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Activate screen saver"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 96c8c23..7a5b853 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -141,4 +141,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"La ubicación se estableció por GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas las notificaciones"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Activar el protector de pantalla"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Información de la aplicación"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 0b3e4e4..20a6dee 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ubicación definida por GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Activar salvapantallas"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Información de la aplicación"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 055e3ee..d254792 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS-i määratud asukoht"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Kustuta kõik teatised."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktiveeri ekraanisäästja"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Rakenduse teave"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index df25d5e..b7ad8d9 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"مکان تنظیم شده توسط GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلانها"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"فعال کردن محافظ صفحه نمایش"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"اطلاعات برنامه"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 370d234..0b904e7 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Sijainti määritetty GPS:n avulla"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tyhjennä kaikki ilmoitukset."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Ota näytönsäästäjä käyttöön"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Sovelluksen tiedot"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index c7f307c..a73fa12 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -141,4 +141,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Activer l\'économiseur d\'écran"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informations sur l\'application"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hdpi/dimens.xml b/packages/SystemUI/res/values-hdpi/dimens.xml
index 6b6fd4d..7cd318c 100644
--- a/packages/SystemUI/res/values-hdpi/dimens.xml
+++ b/packages/SystemUI/res/values-hdpi/dimens.xml
@@ -18,9 +18,9 @@
<resources>
<!-- thickness (height) of each notification row, including any separators or padding -->
<!-- Note: this is 64dip + 1px divider = 97px. -->
- <dimen name="notification_height">97px</dimen>
+ <dimen name="notification_height">99px</dimen>
<!-- thickness (height) of dividers between each notification row; see math for
notification_height above -->
- <dimen name="notification_divider_height">1px</dimen>
+ <dimen name="notification_divider_height">4px</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 9805f90..cd98042 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा सेट किया गया स्थान"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सभी सूचनाएं साफ़ करें."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"स्क्रीन सेवर सक्रिय करें"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"एप्लिकेशन जानकारी"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index f3d4043..5cd66d3 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Obavijesti"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth posredno povezan"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Postavljanje načina unosa"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fizička tipkovnica"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"Dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupi ovom USB uređaju?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupi ovom USB dodatku?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Otvoriti <xliff:g id="ACTIVITY">%1$s</xliff:g> kad se spoji ovaj USB uređaj?"</string>
@@ -140,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju utvrdio GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Brisanje svih obavijesti."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktivirajte čuvar zaslona"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 87a9d45..d8af0c3 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"A GPS beállította a helyet"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Minden értesítés törlése"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Képernyővédő aktiválása"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Alkalmazásinformáció"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 267f5e7..3611da25 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Pemberitahuan"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tertambat"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Menyiapkan metode masukan"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Keyboard fisik"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"Izinkan apl <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses perangkat USB?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Izinkan apl <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses aksesori USB?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> ketika perangkat USB ini tersambung?"</string>
@@ -140,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi yang disetel oleh GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktifkan tirai layar"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index a725377..6072697 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -141,4 +141,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posizione stabilita dal GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Cancella tutte le notifiche."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Attiva screensaver"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informazioni applicazione"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 03fba7e..17f5a36 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -139,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"מיקום מוגדר על ידי GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"הפעלת שומר מסך"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 4818ca9..a9aee94 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -141,4 +141,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPSにより現在地が設定されました"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"スクリーンセーバーを有効にする"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"アプリ情報"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 3321912..5350cd1 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -139,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS에서 위치 설정"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"스크린 세이버 활성화"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 831fa41..a30dd5a 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -139,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS nustatyta vieta"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktyvinti ekrano užsklandą"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 158c850..0461ccd 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -139,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS iestatītā atrašanās vieta"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Notīrīt visus paziņojumus"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktivizēt ekrānsaudzētāju"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 899a204..6141732 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi ditetapkan oleh GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktifkan gambar skrin"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Maklumat apl"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index fdd3b10..e6c24a9 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Varslinger"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tilknyttet"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inndatametoder"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fysisk tastatur"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"Vil du gi appen <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til USB-enheten?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vil du gi appen <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til USB-tilbehøret?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vil du åpne <xliff:g id="ACTIVITY">%1$s</xliff:g> når denne USB-enheten er tilkoblet?"</string>
@@ -140,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posisjon angitt av GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Fjern alle varslinger."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktiver skjermbeskytter"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info om app"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index e05e2c9..ff1c02a 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Schermbeveiliging inschakelen"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App-info"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 0618eb5..646993f4 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja ustawiona według GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Włącz wygaszacz ekranu."</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"O aplikacji"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 6a278ba..31e6566 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Localização definida por GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Ativar proteção de ecrã"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informações da aplicação"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 23a2ba5..500ee2b 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -141,4 +141,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Ativar proteção de tela"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 3062d48..917306a 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -248,4 +248,6 @@
<skip />
<!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
<skip />
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index ff6ca3d..0e7509c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificări"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Conectat prin tethering prin Bluetooth"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configuraţi metode de intrare"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Tastatură fizică"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"Permiteţi aplicaţiei <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze dispozitivul USB?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Permiteţi aplicaţiei <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze accesoriul USB?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui dispozitiv USB?"</string>
@@ -140,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Locaţie setată prin GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ştergeţi toate notificările."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Activaţi screensaverul"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 3753309..23eb1d2 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -141,4 +141,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположение установлено с помощью GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Активация заставки экрана"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 599f99c..a729cce 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -141,4 +141,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavená pomocou GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktivovať šetrič obrazovky"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index fb229e2..6da01c7 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -139,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija nastavljena z GPS-om"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Izbriši vsa obvestila."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Vklop ohranjevalnika zaslona"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 3268544..3586b84 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Обавештења"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Веза преко Bluetooth-а"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Подеси методе уноса"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Физичка тастатура"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"Желите ли да дозволите апликацији <xliff:g id="APPLICATION">%1$s</xliff:g> да приступа USB уређају?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Желите ли да дозволите апликацији <xliff:g id="APPLICATION">%1$s</xliff:g> да приступа USB помоћном уређају?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Желите ли да се отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> када се прикључи овај USB уређај?"</string>
@@ -140,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Локацију је подесио GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Обриши сва обавештења."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Активирање чувара екрана"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 8eaa126..ed73106 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -139,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Platsen har identifierats av GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ta bort alla meddelanden."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktivera skärmsläckare"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 19bd4ab..16ccca3 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -137,4 +137,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Mahali pamewekwa na GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Amilisha hifadhi ya skrini"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/colors.xml b/packages/SystemUI/res/values-sw600dp/colors.xml
deleted file mode 100644
index a7a70c3..0000000
--- a/packages/SystemUI/res/values-sw600dp/colors.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <drawable name="status_bar_background">#000000</drawable>
- <drawable name="notification_icon_area_smoke">#aa000000</drawable>
-</resources>
-
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
deleted file mode 100644
index 8c1ac55..0000000
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
-*/
--->
-<resources>
- <!-- The width of the ticker, including the icon -->
- <dimen name="notification_ticker_width">360dp</dimen>
- <!-- Status bar panel bottom offset (height of status bar - overlap) -->
- <dimen name="status_bar_panel_bottom_offset">36dp</dimen>
- <!-- gap on either side of status bar notification icons -->
- <dimen name="status_bar_icon_padding">8dp</dimen>
- <!-- The width of the notification panel window -->
- <dimen name="notification_panel_width">512dp</dimen>
- <!-- The minimum height of the notification panel window -->
- <dimen name="notification_panel_min_height">770dp</dimen>
- <!-- Bottom margin (from display edge) for status bar panels -->
- <dimen name="panel_float">56dp</dimen>
-
- <!-- Recent Applications parameters -->
- <!-- How far the thumbnail for a recent app appears from left edge -->
- <dimen name="status_bar_recents_thumbnail_left_margin">28dp</dimen>
- <!-- Upper width limit for application icon -->
- <dimen name="status_bar_recents_app_icon_max_width">64dp</dimen>
- <!-- Upper height limit for application icon -->
- <dimen name="status_bar_recents_app_icon_max_height">64dp</dimen>
-
- <!-- Size of application icon -->
- <dimen name="status_bar_recents_thumbnail_width">208dp</dimen>
- <dimen name="status_bar_recents_thumbnail_height">130dp</dimen>
-
- <!-- Width of recents panel -->
- <dimen name="status_bar_recents_width">600dp</dimen>
- <!-- Padding for text descriptions -->
- <dimen name="status_bar_recents_text_description_padding">8dp</dimen>
- <!-- Size of application label text -->
- <dimen name="status_bar_recents_app_label_text_size">18dip</dimen>
- <!-- Size of application description text -->
- <dimen name="status_bar_recents_app_description_text_size">18dip</dimen>
- <!-- Width of application label text -->
- <dimen name="status_bar_recents_app_label_width">97dip</dimen>
- <!-- Left margin for application label -->
- <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
- <!-- Size of fading edge for text -->
- <dimen name="status_bar_recents_text_fading_edge_length">20dip</dimen>
- <!-- Size of fading edge for scrolling -->
- <dimen name="status_bar_recents_scroll_fading_edge_length">10dip</dimen>
- <!-- Margin between recents container and glow on the right -->
- <dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
-
- <!-- Where to place the app icon over the thumbnail -->
- <dimen name="status_bar_recents_app_icon_left_margin">0dp</dimen>
- <dimen name="status_bar_recents_app_icon_top_margin">8dp</dimen>
-
- <!-- size at which Notification icons will be drawn in the status bar -->
- <dimen name="status_bar_icon_drawing_size">24dip</dimen>
-
- <!-- opacity at which Notification icons will be drawn in the status bar -->
- <item type="dimen" name="status_bar_icon_drawing_alpha">100%</item>
-
- <!-- The width of the view containing non-menu status bar icons -->
- <dimen name="navigation_key_width">80dip</dimen>
-
- <!-- The width of the view containing the menu status bar icon -->
- <dimen name="navigation_menu_key_width">40dip</dimen>
-</resources>
diff --git a/packages/SystemUI/res/values-sw720dp/config.xml b/packages/SystemUI/res/values-sw720dp/config.xml
index 56b8e54..8af700a 100644
--- a/packages/SystemUI/res/values-sw720dp/config.xml
+++ b/packages/SystemUI/res/values-sw720dp/config.xml
@@ -21,5 +21,13 @@
for different hardware and product builds. -->
<resources>
<integer name="config_maxNotificationIcons">5</integer>
+
+ <!-- Whether we're using the tablet-optimized recents interface (we use this
+ value at runtime for some things) -->
+ <bool name="config_recents_interface_for_tablets">true</bool>
+
+ <!-- Whether recents thumbnails should stretch in both x and y to fill their
+ ImageView -->
+ <bool name="config_recents_thumbnail_image_fits_to_xy">true</bool>
</resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index b16b1e8..36cbabf 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -27,5 +27,59 @@
<!-- The width of the view containing the menu status bar icon -->
<dimen name="navigation_menu_key_width">80dip</dimen>
+
+ <!-- ======================================== -->
+ <!-- The following resources were recently moved from sw600dp; there may
+ be situations where they don't sync up perfectly with
+ PhoneStatusBar/TabletStatusBar. -->
+ <!-- ======================================== -->
+
+ <!-- The width of the ticker, including the icon -->
+ <dimen name="notification_ticker_width">360dp</dimen>
+ <!-- Status bar panel bottom offset (height of status bar - overlap) -->
+ <dimen name="status_bar_panel_bottom_offset">36dp</dimen>
+ <!-- gap on either side of status bar notification icons -->
+ <dimen name="status_bar_icon_padding">8dp</dimen>
+ <!-- The width of the notification panel window -->
+ <dimen name="notification_panel_width">512dp</dimen>
+ <!-- The minimum height of the notification panel window -->
+ <dimen name="notification_panel_min_height">770dp</dimen>
+ <!-- Bottom margin (from display edge) for status bar panels -->
+ <dimen name="panel_float">56dp</dimen>
+
+ <!-- Recent Applications parameters -->
+ <!-- How far the thumbnail for a recent app appears from left edge -->
+ <dimen name="status_bar_recents_thumbnail_left_margin">28dp</dimen>
+ <!-- Upper width limit for application icon -->
+ <dimen name="status_bar_recents_app_icon_max_width">64dp</dimen>
+ <!-- Upper height limit for application icon -->
+ <dimen name="status_bar_recents_app_icon_max_height">64dp</dimen>
+
+ <!-- Size of application icon -->
+ <dimen name="status_bar_recents_thumbnail_width">208dp</dimen>
+ <dimen name="status_bar_recents_thumbnail_height">130dp</dimen>
+
+ <!-- Width of recents panel -->
+ <dimen name="status_bar_recents_width">600dp</dimen>
+ <!-- Padding for text descriptions -->
+ <dimen name="status_bar_recents_text_description_padding">8dp</dimen>
+ <!-- Size of application label text -->
+ <dimen name="status_bar_recents_app_label_text_size">18dip</dimen>
+ <!-- Size of application description text -->
+ <dimen name="status_bar_recents_app_description_text_size">18dip</dimen>
+ <!-- Width of application label text -->
+ <dimen name="status_bar_recents_app_label_width">97dip</dimen>
+ <!-- Left margin for application label -->
+ <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
+ <!-- Size of fading edge for text -->
+ <dimen name="status_bar_recents_text_fading_edge_length">20dip</dimen>
+ <!-- Size of fading edge for scrolling -->
+ <dimen name="status_bar_recents_scroll_fading_edge_length">10dip</dimen>
+ <!-- Margin between recents container and glow on the right -->
+ <dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
+
+ <!-- Where to place the app icon over the thumbnail -->
+ <dimen name="status_bar_recents_app_icon_left_margin">0dp</dimen>
+ <dimen name="status_bar_recents_app_icon_top_margin">8dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/donottranslate.xml b/packages/SystemUI/res/values-sw720dp/donottranslate.xml
similarity index 100%
rename from packages/SystemUI/res/values-sw600dp/donottranslate.xml
rename to packages/SystemUI/res/values-sw720dp/donottranslate.xml
diff --git a/packages/SystemUI/res/values-sw600dp/styles.xml b/packages/SystemUI/res/values-sw720dp/styles.xml
similarity index 100%
rename from packages/SystemUI/res/values-sw600dp/styles.xml
rename to packages/SystemUI/res/values-sw720dp/styles.xml
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 42c4721..0e3344e 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"การแจ้งเตือน"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"บลูทูธที่ปล่อยสัญญาณ"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ตั้งค่าวิธีการป้อนข้อมูล"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"แป้นพิมพ์บนเครื่อง"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"อนุญาตให้แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึงอุปกรณ์ USB นี้หรือไม่"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"อนุญาตให้แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึงอุปกรณ์เสริม USB นี้หรือไม่"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"เปิด <xliff:g id="ACTIVITY">%1$s</xliff:g> เมื่อมีการเชื่อมต่ออุปกรณ์ USB นี้หรือไม่"</string>
@@ -140,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ตำแหน่งที่กำหนดโดย GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ล้างการแจ้งเตือนทั้งหมด"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"เปิดโปรแกรมรักษาหน้าจอ"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 2054121e..7b294ac 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -139,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasyong itinatakda ng GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"I-clear ang lahat ng notification."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"I-activate ang screen saver"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index ca422f7..f0da20e 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -139,4 +139,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Konum GPS ile belirlendi"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Ekran koruyucuyu etkinleştir"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 9a05919..b787dc8 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Сповіщення"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Створено прив\'язку Bluetooth"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Налаштувати методи введення"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Фізична клавіатура"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"Надати програмі <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до пристрою USB?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Надати програмі <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до аксесуара USB?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Відкривати \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\", коли під’єднано пристрій USB?"</string>
@@ -140,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Місцезнаходження встановлено за допомогою GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Очистити всі сповіщення."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Активувати заставку"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Інформація про програму"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 05ab87c..fea33a4 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Vị trí đặt bởi GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Kích hoạt trình bảo vệ màn hình"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Thông tin về ứng dụng"</string>
</resources>
diff --git a/packages/SystemUI/res/values-xhdpi/dimens.xml b/packages/SystemUI/res/values-xhdpi/dimens.xml
index aa75c20..303841a 100644
--- a/packages/SystemUI/res/values-xhdpi/dimens.xml
+++ b/packages/SystemUI/res/values-xhdpi/dimens.xml
@@ -19,9 +19,9 @@
<!-- thickness (height) of each notification row, including any separators or padding -->
<!-- note: this is the same value as in values/dimens.xml; the value is overridden in
values-hdpi/dimens.xml and so we need to re-assert the general value here -->
- <dimen name="notification_height">65dp</dimen>
+ <dimen name="notification_height">68dp</dimen>
<!-- thickness (height) of dividers between each notification row -->
<!-- same as in values/dimens.xml; see note at notification_height -->
- <dimen name="notification_divider_height">1dp</dimen>
+ <dimen name="notification_divider_height">2dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index c862d74..996119c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -141,4 +141,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"已通过 GPS 确定位置"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"激活屏幕保护程序"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index cabc243..d075352 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -48,8 +48,7 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"藍牙網路共用已開"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"設定輸入法"</string>
- <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
- <skip />
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"實體鍵盤"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"允許 <xliff:g id="APPLICATION">%1$s</xliff:g> 應用程式存取 USB 裝置嗎?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"允許 <xliff:g id="APPLICATION">%1$s</xliff:g> 應用程式存取 USB 配件嗎?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"連接這個 USB 裝置時啟用 <xliff:g id="ACTIVITY">%1$s</xliff:g> 嗎?"</string>
@@ -142,4 +141,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS 已定位"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"啟用螢幕保護程式"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 91f6566..dfebfe7 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -139,4 +139,5 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Indawo ihlelwe i-GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Yenza ukuthi iskrini seyiva sisebenze"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Ulwazi lohlelo lokusebenza"</string>
</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 56d1295..48fb21f 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -32,5 +32,8 @@
<declare-styleable name="NotificationRowLayout">
<attr name="rowHeight" format="dimension" />
</declare-styleable>
+ <declare-styleable name="RecentsPanelView">
+ <attr name="recentItemLayout" format="reference" />
+ </declare-styleable>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index c8e3fad..9257195 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -18,8 +18,6 @@
-->
<resources>
<drawable name="notification_number_text_color">#ffffffff</drawable>
- <drawable name="notification_item_background_color">#ff111111</drawable>
- <drawable name="notification_item_background_color_pressed">#ff257390</drawable>
<drawable name="ticker_background_color">#ff1d1d1d</drawable>
<drawable name="status_bar_background">#ff000000</drawable>
<drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
@@ -31,4 +29,9 @@
<drawable name="recents_callout_line">#99ffffff</drawable>
<drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable>
<drawable name="intruder_bg_pressed">#ff33B5E5</drawable>
+
+ <!-- ==================== system bar only ==================== -->
+ <drawable name="system_bar_background">#ff000000</drawable>
+ <!-- the darkening filter applied to notifications -->
+ <drawable name="notification_icon_area_smoke">#aa000000</drawable>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 4441ca6..b8e8fe4 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -50,11 +50,18 @@
<dimen name="navigation_bar_deadzone_size">12dp</dimen>
<!-- thickness (height) of each notification row, including any separators or padding -->
- <dimen name="notification_height">65dp</dimen>
+ <dimen name="notification_height">68dp</dimen>
<!-- Height of notification icons in the status bar -->
<dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
+ <!-- Height of a small notification in the status bar -->
+ <dimen name="notification_min_height">@android:dimen/notification_large_icon_height</dimen>
+
+ <!-- Height of a small notification in the status bar -->
+ <!-- TODO: change this back to 256dp once we deal with actions. -->
+ <dimen name="notification_max_height">320dp</dimen>
+
<!-- size at which Notification icons will be drawn in the status bar -->
<dimen name="status_bar_icon_drawing_size">18dip</dimen>
@@ -65,7 +72,7 @@
<dimen name="status_bar_icon_padding">0dp</dimen>
<!-- thickness (height) of dividers between each notification row -->
- <dimen name="notification_divider_height">1dp</dimen>
+ <dimen name="notification_divider_height">4dp</dimen>
<!-- Notification drawer tuning parameters (phone UI) -->
<!-- Initial velocity of the shade when expanding on its own -->
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
new file mode 100644
index 0000000..2a4c5fd
--- /dev/null
+++ b/packages/SystemUI/res/values/ids.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <item type="id" name="expandable_tag" />
+</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 6dbe9d3..236ca6b 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -365,4 +365,8 @@
<!-- Description of the desk dock action that invokes the Android Dreams screen saver feature -->
<string name="dreams_dock_launcher">Activate screen saver</string>
+
+ <!-- Title shown in notification popup for inspecting the responsible
+ application -->
+ <string name="status_bar_notification_inspect_item_title">App info</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
new file mode 100644
index 0000000..6141ead
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.systemui;
+
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.graphics.RectF;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import com.android.internal.widget.SizeAdaptiveLayout;
+
+public class ExpandHelper implements Gefingerpoken, OnClickListener {
+ public interface Callback {
+ View getChildAtPosition(MotionEvent ev);
+ View getChildAtPosition(float x, float y);
+ boolean canChildBeExpanded(View v);
+ }
+
+ private static final String TAG = "ExpandHelper";
+ protected static final boolean DEBUG = false;
+ private static final long EXPAND_DURATION = 250;
+
+ // amount of overstretch for maximum brightness expressed in U
+ // 2f: maximum brightness is stretching a 1U to 3U, or a 4U to 6U
+ private static final float STRETCH_INTERVAL = 2f;
+
+ // level of glow for a touch, without overstretch
+ // overstretch fills the range (GLOW_BASE, 1.0]
+ private static final float GLOW_BASE = 0.5f;
+
+ @SuppressWarnings("unused")
+ private Context mContext;
+
+ private boolean mStretching;
+ private View mCurrView;
+ private View mCurrViewTopGlow;
+ private View mCurrViewBottomGlow;
+ private float mOldHeight;
+ private float mNaturalHeight;
+ private float mInitialTouchSpan;
+ private Callback mCallback;
+ private ScaleGestureDetector mDetector;
+ private ViewScaler mScaler;
+ private ObjectAnimator mAnimation;
+
+ private int mSmallSize;
+ private int mLargeSize;
+ private float mMaximumStretch;
+
+ private class ViewScaler {
+ View mView;
+ public ViewScaler() {}
+ public void setView(View v) {
+ mView = v;
+ }
+ public void setHeight(float h) {
+ if (DEBUG) Log.v(TAG, "SetHeight: setting to " + h);
+ ViewGroup.LayoutParams lp = mView.getLayoutParams();
+ lp.height = (int)h;
+ mView.setLayoutParams(lp);
+ mView.requestLayout();
+ }
+ public float getHeight() {
+ int height = mView.getLayoutParams().height;
+ if (height < 0) {
+ height = mView.getMeasuredHeight();
+ }
+ return (float) height;
+ }
+ public int getNaturalHeight(int maximum) {
+ ViewGroup.LayoutParams lp = mView.getLayoutParams();
+ if (DEBUG) Log.v(TAG, "Inspecting a child of type: " + mView.getClass().getName());
+ int oldHeight = lp.height;
+ lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mView.setLayoutParams(lp);
+ mView.measure(
+ View.MeasureSpec.makeMeasureSpec(mView.getMeasuredWidth(),
+ View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(maximum,
+ View.MeasureSpec.AT_MOST));
+ lp.height = oldHeight;
+ mView.setLayoutParams(lp);
+ return mView.getMeasuredHeight();
+ }
+ }
+
+ public ExpandHelper(Context context, Callback callback, int small, int large) {
+ mSmallSize = small;
+ mMaximumStretch = mSmallSize * STRETCH_INTERVAL;
+ mLargeSize = large;
+ mContext = context;
+ mCallback = callback;
+ mScaler = new ViewScaler();
+ mDetector =
+ new ScaleGestureDetector(context,
+ new ScaleGestureDetector.SimpleOnScaleGestureListener() {
+ @Override
+ public boolean onScaleBegin(ScaleGestureDetector detector) {
+ if (DEBUG) Log.v(TAG, "onscalebegin()");
+ View v = mCallback.getChildAtPosition(detector.getFocusX(), detector.getFocusY());
+
+ // your fingers have to be somewhat close to the bounds of the view in question
+ mInitialTouchSpan = Math.abs(detector.getCurrentSpanY());
+ if (DEBUG) Log.d(TAG, "got mInitialTouchSpan: " + mInitialTouchSpan);
+
+ mStretching = initScale(v);
+ return mStretching;
+ }
+
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ if (DEBUG) Log.v(TAG, "onscale() on " + mCurrView);
+ float h = Math.abs(detector.getCurrentSpanY());
+ if (DEBUG) Log.d(TAG, "current span is: " + h);
+ h = h + mOldHeight - mInitialTouchSpan;
+ float target = h;
+ if (DEBUG) Log.d(TAG, "target is: " + target);
+ h = h<mSmallSize?mSmallSize:(h>mLargeSize?mLargeSize:h);
+ h = h>mNaturalHeight?mNaturalHeight:h;
+ if (DEBUG) Log.d(TAG, "scale continues: h=" + h);
+ mScaler.setHeight(h);
+ float stretch = (float) Math.abs((target - h) / mMaximumStretch);
+ float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f)));
+ if (DEBUG) Log.d(TAG, "stretch: " + stretch + " strength: " + strength);
+ setGlow(GLOW_BASE + strength * (1f - GLOW_BASE));
+ return true;
+ }
+
+ @Override
+ public void onScaleEnd(ScaleGestureDetector detector) {
+ if (DEBUG) Log.v(TAG, "onscaleend()");
+ // I guess we're alone now
+ if (DEBUG) Log.d(TAG, "scale end");
+ finishScale(false);
+ }
+ });
+ }
+ public void setGlow(float glow) {
+ if (mCurrViewTopGlow != null) {
+ mCurrViewTopGlow.setAlpha(glow);
+ }
+ if (mCurrViewBottomGlow != null) {
+ mCurrViewBottomGlow.setAlpha(glow);
+ }
+ }
+
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (DEBUG) Log.d(TAG, "interceptTouch: act=" + (ev.getAction()) +
+ " stretching=" + mStretching);
+ mDetector.onTouchEvent(ev);
+ return mStretching;
+ }
+
+ public boolean onTouchEvent(MotionEvent ev) {
+ final int action = ev.getAction();
+ if (DEBUG) Log.d(TAG, "touch: act=" + (action) + " stretching=" + mStretching);
+ if (mStretching) {
+ mDetector.onTouchEvent(ev);
+ }
+ switch (action) {
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mStretching = false;
+ clearView();
+ break;
+ }
+ return true;
+ }
+ private boolean initScale(View v) {
+ if (v != null) {
+ if (DEBUG) Log.d(TAG, "scale begins on view: " + v);
+ mStretching = true;
+ setView(v);
+ setGlow(GLOW_BASE);
+ mScaler.setView(v);
+ mOldHeight = mScaler.getHeight();
+ if (mCallback.canChildBeExpanded(v)) {
+ if (DEBUG) Log.d(TAG, "working on an expandable child");
+ mNaturalHeight = mScaler.getNaturalHeight(mLargeSize);
+ } else {
+ if (DEBUG) Log.d(TAG, "working on a non-expandable child");
+ mNaturalHeight = mOldHeight;
+ }
+ if (DEBUG) Log.d(TAG, "got mOldHeight: " + mOldHeight +
+ " mNaturalHeight: " + mNaturalHeight);
+ v.getParent().requestDisallowInterceptTouchEvent(true);
+ }
+ return mStretching;
+ }
+
+ private void finishScale(boolean force) {
+ float h = mScaler.getHeight();
+ final boolean wasClosed = (mOldHeight == mSmallSize);
+ if (wasClosed) {
+ h = (force || h > mSmallSize) ? mNaturalHeight : mSmallSize;
+ } else {
+ h = (force || h < mNaturalHeight) ? mSmallSize : mNaturalHeight;
+ }
+ if (DEBUG && mCurrView != null) mCurrView.setBackgroundColor(0);
+ mAnimation = ObjectAnimator.ofFloat(mScaler, "height", h).setDuration(EXPAND_DURATION);
+ mAnimation.start();
+ mStretching = false;
+ setGlow(0f);
+ clearView();
+ }
+
+ private void clearView() {
+ mCurrView = null;
+ mCurrViewTopGlow = null;
+ mCurrViewBottomGlow = null;
+ }
+
+ private void setView(View v) {
+ mCurrView = null;
+ if (v instanceof ViewGroup) {
+ ViewGroup g = (ViewGroup) v;
+ mCurrViewTopGlow = g.findViewById(R.id.top_glow);
+ mCurrViewBottomGlow = g.findViewById(R.id.bottom_glow);
+ if (DEBUG) {
+ String debugLog = "Looking for glows: " +
+ (mCurrViewTopGlow != null ? "found top " : "didn't find top") +
+ (mCurrViewBottomGlow != null ? "found bottom " : "didn't find bottom");
+ Log.v(TAG, debugLog);
+ }
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ initScale(v);
+ finishScale(true);
+
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java b/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java
new file mode 100644
index 0000000..b2d5c21
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.view.MotionEvent;
+
+// ACHTUNG!
+public interface Gefingerpoken {
+ boolean onInterceptTouchEvent(MotionEvent ev);
+ boolean onTouchEvent(MotionEvent ev);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 724679f..c60c806 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -155,6 +155,11 @@
}
}
+ public DrawableEngine() {
+ super();
+ setFixedSizeAllowed(true);
+ }
+
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
if (DEBUG) {
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 276ca21..414af89 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -23,13 +23,16 @@
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.graphics.RectF;
+import android.os.Handler;
import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
import android.view.animation.LinearInterpolator;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.ViewConfiguration;
-public class SwipeHelper {
+public class SwipeHelper implements Gefingerpoken {
static final String TAG = "com.android.systemui.SwipeHelper";
private static final boolean DEBUG = false;
private static final boolean DEBUG_INVALIDATE = false;
@@ -57,6 +60,7 @@
private float mPagingTouchSlop;
private Callback mCallback;
+ private Handler mHandler;
private int mSwipeDirection;
private VelocityTracker mVelocityTracker;
@@ -67,15 +71,24 @@
private boolean mCanCurrViewBeDimissed;
private float mDensityScale;
+ private boolean mLongPressSent;
+ private View.OnLongClickListener mLongPressListener;
+ private Runnable mWatchLongPress;
+
public SwipeHelper(int swipeDirection, Callback callback, float densityScale,
float pagingTouchSlop) {
mCallback = callback;
+ mHandler = new Handler();
mSwipeDirection = swipeDirection;
mVelocityTracker = VelocityTracker.obtain();
mDensityScale = densityScale;
mPagingTouchSlop = pagingTouchSlop;
}
+ public void setLongPressListener(View.OnLongClickListener listener) {
+ mLongPressListener = listener;
+ }
+
public void setDensityScale(float densityScale) {
mDensityScale = densityScale;
}
@@ -167,12 +180,19 @@
}
}
+ private void removeLongPressCallback() {
+ if (mWatchLongPress != null) {
+ mHandler.removeCallbacks(mWatchLongPress);
+ }
+ }
+
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mDragging = false;
+ mLongPressSent = false;
mCurrView = mCallback.getChildAtPosition(ev);
mVelocityTracker.clear();
if (mCurrView != null) {
@@ -180,10 +200,28 @@
mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
mVelocityTracker.addMovement(ev);
mInitialTouchPos = getPos(ev);
+
+ if (mLongPressListener != null) {
+ if (mWatchLongPress == null) {
+ mWatchLongPress = new Runnable() {
+ @Override
+ public void run() {
+ if (mCurrView != null && !mLongPressSent) {
+ mLongPressSent = true;
+ mCurrView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+ mLongPressListener.onLongClick(mCurrView);
+ }
+ }
+ };
+ }
+ mHandler.postDelayed(mWatchLongPress, ViewConfiguration.getLongPressTimeout());
+ }
+
}
break;
+
case MotionEvent.ACTION_MOVE:
- if (mCurrView != null) {
+ if (mCurrView != null && !mLongPressSent) {
mVelocityTracker.addMovement(ev);
float pos = getPos(ev);
float delta = pos - mInitialTouchPos;
@@ -191,14 +229,19 @@
mCallback.onBeginDrag(mCurrView);
mDragging = true;
mInitialTouchPos = getPos(ev) - getTranslation(mCurrAnimView);
+
+ removeLongPressCallback();
}
}
+
break;
+
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mDragging = false;
mCurrView = null;
mCurrAnimView = null;
+ mLongPressSent = false;
break;
}
return mDragging;
@@ -269,6 +312,10 @@
}
public boolean onTouchEvent(MotionEvent ev) {
+ if (mLongPressSent) {
+ return true;
+ }
+
if (!mDragging) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 5d6e315..f19ab24 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -24,6 +24,7 @@
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Shader.TileMode;
@@ -89,6 +90,7 @@
private TaskDescriptionAdapter mListAdapter;
private int mThumbnailWidth;
private boolean mFitThumbnailToXY;
+ private int mRecentItemLayoutId;
public static interface OnRecentsPanelVisibilityChangedListener {
public void onRecentsPanelVisibilityChanged(boolean visible);
@@ -142,7 +144,7 @@
}
public View createView(ViewGroup parent) {
- View convertView = mInflater.inflate(R.layout.status_bar_recent_item, parent, false);
+ View convertView = mInflater.inflate(mRecentItemLayoutId, parent, false);
ViewHolder holder = new ViewHolder();
holder.thumbnailView = convertView.findViewById(R.id.app_thumbnail);
holder.thumbnailViewImage =
@@ -421,6 +423,11 @@
super(context, attrs, defStyle);
mContext = context;
updateValuesFromResources();
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecentsPanelView,
+ defStyle, 0);
+
+ mRecentItemLayoutId = a.getResourceId(R.styleable.RecentsPanelView_recentItemLayout, 0);
}
public void updateValuesFromResources() {
@@ -432,6 +439,7 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mRecentsContainer = (ViewGroup) findViewById(R.id.recents_container);
mStatusBarTouchProxy = (StatusBarTouchProxy) findViewById(R.id.status_bar_touch_proxy);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 8d7afc8..19306a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -18,31 +18,43 @@
import java.util.ArrayList;
+import android.app.ActivityManagerNative;
+import android.app.KeyguardManager;
+import android.app.PendingIntent;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Rect;
+import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.provider.Settings;
import android.util.Log;
import android.util.Slog;
import android.view.Display;
import android.view.IWindowManager;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
import android.widget.LinearLayout;
+import android.widget.RemoteViews;
+import android.widget.PopupMenu;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.statusbar.StatusBarNotification;
+import com.android.internal.widget.SizeAdaptiveLayout;
import com.android.systemui.SystemUI;
import com.android.systemui.recent.RecentsPanelView;
import com.android.systemui.recent.RecentTasksLoader;
@@ -66,12 +78,15 @@
protected IStatusBarService mBarService;
protected H mHandler = createHandler();
+ // used to notify status bar for suppressing notification LED
+ protected boolean mPanelSlightlyVisible;
+
// Recent apps
protected RecentsPanelView mRecentsPanel;
protected RecentTasksLoader mRecentTasksLoader;
// UI-specific methods
-
+
/**
* Create all windows necessary for the status bar (including navigation, overlay panels, etc)
* and add them to the window manager.
@@ -81,15 +96,15 @@
protected Display mDisplay;
private IWindowManager mWindowManager;
-
+
public IWindowManager getWindowManager() {
return mWindowManager;
}
-
+
public Display getDisplay() {
return mDisplay;
}
-
+
public IStatusBarService getStatusBarService() {
return mBarService;
}
@@ -109,7 +124,7 @@
ArrayList<IBinder> notificationKeys = new ArrayList<IBinder>();
ArrayList<StatusBarNotification> notifications = new ArrayList<StatusBarNotification>();
mCommandQueue = new CommandQueue(this, iconList);
-
+
int[] switches = new int[7];
ArrayList<IBinder> binders = new ArrayList<IBinder>();
try {
@@ -118,7 +133,7 @@
} catch (RemoteException ex) {
// If the system process isn't there we're doomed anyway.
}
-
+
createAndAddWindows();
disable(switches[0]);
@@ -152,7 +167,7 @@
if (DEBUG) {
Slog.d(TAG, String.format(
- "init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x",
+ "init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x",
iconList.size(),
switches[0],
switches[1],
@@ -161,7 +176,7 @@
));
}
}
-
+
protected View updateNotificationVetoButton(View row, StatusBarNotification n) {
View vetoButton = row.findViewById(R.id.veto);
if (n.isClearable()) {
@@ -183,7 +198,7 @@
}
return vetoButton;
}
-
+
protected void applyLegacyRowBackground(StatusBarNotification sbn, View content) {
if (sbn.notification.contentView.getLayoutId() !=
@@ -198,11 +213,44 @@
if (version > 0 && version < Build.VERSION_CODES.GINGERBREAD) {
content.setBackgroundResource(R.drawable.notification_row_legacy_bg);
} else {
- content.setBackgroundResource(R.drawable.notification_row_bg);
+ content.setBackgroundResource(com.android.internal.R.drawable.notification_bg);
}
}
}
+ private void startApplicationDetailsActivity(String packageName) {
+ Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
+ Uri.fromParts("package", packageName, null));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ }
+
+ protected View.OnLongClickListener getNotificationLongClicker() {
+ return new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ final String packageNameF = (String) v.getTag();
+ if (packageNameF == null) return false;
+ PopupMenu popup = new PopupMenu(mContext, v);
+ popup.getMenuInflater().inflate(R.menu.notification_popup_menu, popup.getMenu());
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ if (item.getItemId() == R.id.notification_inspect_item) {
+ startApplicationDetailsActivity(packageNameF);
+ animateCollapse();
+ } else {
+ return false;
+ }
+ return true;
+ }
+ });
+ popup.show();
+
+ return true;
+ }
+ };
+ }
+
public void dismissIntruder() {
// pass
}
@@ -236,7 +284,7 @@
protected abstract WindowManager.LayoutParams getRecentsLayoutParams(
LayoutParams layoutParams);
- protected void updateRecentsPanel() {
+ protected void updateRecentsPanel(int recentsResId) {
// Recents Panel
boolean visible = false;
ArrayList<TaskDescription> recentTasksList = null;
@@ -253,7 +301,7 @@
// Provide RecentsPanelView with a temporary parent to allow layout params to work.
LinearLayout tmpRoot = new LinearLayout(mContext);
mRecentsPanel = (RecentsPanelView) LayoutInflater.from(mContext).inflate(
- R.layout.status_bar_recent_panel, tmpRoot, false);
+ recentsResId, tmpRoot, false);
mRecentsPanel.setRecentTasksLoader(mRecentTasksLoader);
mRecentTasksLoader.setRecentsPanel(mRecentsPanel);
mRecentsPanel.setOnTouchListener(
@@ -323,4 +371,192 @@
return false;
}
}
+
+ protected void workAroundBadLayerDrawableOpacity(View v) {
+ }
+
+ protected boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
+ int minHeight =
+ mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height);
+ int maxHeight =
+ mContext.getResources().getDimensionPixelSize(R.dimen.notification_max_height);
+ StatusBarNotification sbn = entry.notification;
+ RemoteViews oneU = sbn.notification.contentView;
+ RemoteViews large = sbn.notification.bigContentView;
+ if (oneU == null) {
+ return false;
+ }
+
+ // create the row view
+ LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
+
+ // for blaming (see SwipeHelper.setLongPressListener)
+ row.setTag(sbn.pkg);
+
+ // XXX: temporary: while testing big notifications, auto-expand all of them
+ ViewGroup.LayoutParams lp = row.getLayoutParams();
+ Boolean expandable = Boolean.FALSE;
+ if (large != null) {
+ lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ expandable = Boolean.TRUE;
+ } else {
+ lp.height = minHeight;
+ }
+ row.setLayoutParams(lp);
+ row.setTag(R.id.expandable_tag, expandable);
+ workAroundBadLayerDrawableOpacity(row);
+ View vetoButton = updateNotificationVetoButton(row, sbn);
+ vetoButton.setContentDescription(mContext.getString(
+ R.string.accessibility_remove_notification));
+
+ // NB: the large icon is now handled entirely by the template
+
+ // bind the click event to the content area
+ ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
+ ViewGroup adaptive = (ViewGroup)row.findViewById(R.id.adaptive);
+
+ // Ensure that R.id.content is properly set to 64dp high if 1U
+ lp = content.getLayoutParams();
+ if (large == null) {
+ lp.height = minHeight;
+ }
+ content.setLayoutParams(lp);
+
+ content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+
+ PendingIntent contentIntent = sbn.notification.contentIntent;
+ if (contentIntent != null) {
+ final View.OnClickListener listener = new NotificationClicker(contentIntent,
+ sbn.pkg, sbn.tag, sbn.id);
+ content.setOnClickListener(listener);
+ } else {
+ content.setOnClickListener(null);
+ }
+
+ View expandedOneU = null;
+ View expandedLarge = null;
+ Exception exception = null;
+ try {
+ expandedOneU = oneU.apply(mContext, adaptive);
+ if (large != null) {
+ expandedLarge = large.apply(mContext, adaptive);
+ }
+ }
+ catch (RuntimeException e) {
+ exception = e;
+ }
+ if (expandedOneU == null && expandedLarge == null) {
+ final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
+ Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
+ return false;
+ } else {
+ if (expandedOneU != null) {
+ SizeAdaptiveLayout.LayoutParams params =
+ new SizeAdaptiveLayout.LayoutParams(expandedOneU.getLayoutParams());
+ params.minHeight = minHeight;
+ params.maxHeight = minHeight;
+ adaptive.addView(expandedOneU, params);
+ }
+ if (expandedLarge != null) {
+ SizeAdaptiveLayout.LayoutParams params =
+ new SizeAdaptiveLayout.LayoutParams(expandedLarge.getLayoutParams());
+ params.minHeight = minHeight+1;
+ params.maxHeight = SizeAdaptiveLayout.LayoutParams.UNBOUNDED;
+ adaptive.addView(expandedLarge, params);
+ }
+ row.setDrawingCacheEnabled(true);
+ }
+
+ applyLegacyRowBackground(sbn, content);
+
+ entry.row = row;
+ entry.content = content;
+ entry.expanded = expandedOneU;
+ entry.expandedLarge = expandedOneU;
+
+ return true;
+ }
+
+ public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag, int id) {
+ return new NotificationClicker(intent, pkg, tag, id);
+ }
+
+ private class NotificationClicker implements View.OnClickListener {
+ private PendingIntent mIntent;
+ private String mPkg;
+ private String mTag;
+ private int mId;
+
+ NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
+ mIntent = intent;
+ mPkg = pkg;
+ mTag = tag;
+ mId = id;
+ }
+
+ public void onClick(View v) {
+ try {
+ // The intent we are sending is for the application, which
+ // won't have permission to immediately start an activity after
+ // the user switches to home. We know it is safe to do at this
+ // point, so make sure new activity switches are now allowed.
+ ActivityManagerNative.getDefault().resumeAppSwitches();
+ // Also, notifications can be launched from the lock screen,
+ // so dismiss the lock screen when the activity starts.
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (RemoteException e) {
+ }
+
+ if (mIntent != null) {
+ int[] pos = new int[2];
+ v.getLocationOnScreen(pos);
+ Intent overlay = new Intent();
+ overlay.setSourceBounds(
+ new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
+ try {
+ mIntent.send(mContext, 0, overlay);
+ } catch (PendingIntent.CanceledException e) {
+ // the stack trace isn't very helpful here. Just log the exception message.
+ Slog.w(TAG, "Sending contentIntent failed: " + e);
+ }
+
+ KeyguardManager kgm =
+ (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+ if (kgm != null) kgm.exitKeyguardSecurely(null);
+ }
+
+ try {
+ mBarService.onNotificationClick(mPkg, mTag, mId);
+ } catch (RemoteException ex) {
+ // system process is dead if we're here.
+ }
+
+ // close the shade if it was open
+ animateCollapse();
+ visibilityChanged(false);
+
+ // If this click was on the intruder alert, hide that instead
+// mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
+ }
+ }
+ /**
+ * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
+ * This was added last-minute and is inconsistent with the way the rest of the notifications
+ * are handled, because the notification isn't really cancelled. The lights are just
+ * turned off. If any other notifications happen, the lights will turn back on. Steve says
+ * this is what he wants. (see bug 1131461)
+ */
+ protected void visibilityChanged(boolean visible) {
+ if (mPanelSlightlyVisible != visible) {
+ mPanelSlightlyVisible = visible;
+ try {
+ mBarService.onPanelRevealed();
+ } catch (RemoteException ex) {
+ // Won't fail unless the world has ended.
+ }
+ }
+ }
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 6fbcd64..3ff85d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -38,6 +38,7 @@
public View content; // takes the click events and sends the PendingIntent
public View expanded; // the inflated RemoteViews
public ImageView largeIcon;
+ public View expandedLarge;
public Entry() {}
public Entry(IBinder key, StatusBarNotification n, StatusBarIconView ic) {
this.key = key;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 5582b0f..11e067f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -275,11 +275,6 @@
? findViewById(R.id.rot90)
: findViewById(R.id.rot270);
- for (View v : mRotatedViews) {
- // this helps avoid drawing artifacts with glowing navigation keys
- ViewGroup group = (ViewGroup) v.findViewById(R.id.nav_buttons);
- group.setMotionEventSplittingEnabled(false);
- }
mCurrentView = mRotatedViews[Surface.ROTATION_0];
}
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 3f611fc..61500e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -28,14 +28,11 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
-import android.os.Build;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
@@ -50,11 +47,9 @@
import android.view.Gravity;
import android.view.IWindowManager;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
@@ -68,26 +63,25 @@
import android.widget.ScrollView;
import android.widget.TextView;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
-import com.android.systemui.SwipeHelper;
import com.android.systemui.recent.RecentTasksLoader;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.IntruderAlertView;
import com.android.systemui.statusbar.policy.DateView;
+import com.android.systemui.statusbar.policy.IntruderAlertView;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NotificationRowLayout;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
public class PhoneStatusBar extends BaseStatusBar {
static final String TAG = "PhoneStatusBar";
public static final boolean DEBUG = false;
@@ -100,7 +94,7 @@
public static final String ACTION_STATUSBAR_START
= "com.android.internal.policy.statusbar.START";
- private static final boolean ENABLE_INTRUDERS = true;
+ private static final boolean ENABLE_INTRUDERS = false;
static final int EXPANDED_LEAVE_ALONE = -10000;
static final int EXPANDED_FULL_OPEN = -10001;
@@ -224,11 +218,6 @@
private int mNavigationIconHints = 0;
- // TODO(dsandler): codify this stuff in NotificationManager's header somewhere
- private int mDisplayMinScore = Notification.PRIORITY_LOW * 10;
- private int mIntruderMinScore = Notification.PRIORITY_HIGH * 10;
- private int mIntruderInImmersiveMinScore = Notification.PRIORITY_HIGH * 10 + 5;
-
private class ExpandedDialog extends Dialog {
ExpandedDialog(Context context) {
super(context, com.android.internal.R.style.Theme_Translucent_NoTitleBar);
@@ -286,9 +275,11 @@
}
mNotificationPanel = expanded.findViewById(R.id.notification_panel);
- mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
- mIntruderAlertView.setVisibility(View.GONE);
- mIntruderAlertView.setBar(this);
+ if (ENABLE_INTRUDERS) {
+ mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
+ mIntruderAlertView.setVisibility(View.GONE);
+ mIntruderAlertView.setBar(this);
+ }
PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
R.layout.status_bar, null);
@@ -297,6 +288,7 @@
try {
boolean showNav = mWindowManager.hasNavigationBar();
+ if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav);
if (showNav) {
mNavigationBarView =
(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
@@ -318,6 +310,7 @@
mExpandedDialog = new ExpandedDialog(context);
mPile = (NotificationRowLayout)expanded.findViewById(R.id.latestItems);
+ mPile.setLongPressListener(getNotificationLongClicker());
mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
mClearButton = expanded.findViewById(R.id.clear_all_button);
@@ -396,9 +389,8 @@
return lp;
}
- @Override
protected void updateRecentsPanel() {
- super.updateRecentsPanel();
+ super.updateRecentsPanel(R.layout.status_bar_recent_panel);
// Make .03 alpha the minimum so you always see the item a bit-- slightly below
// .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
// a bit jarring
@@ -430,6 +422,7 @@
// For small-screen devices (read: phones) that lack hardware navigation buttons
private void addNavigationBar() {
+ if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
if (mNavigationBarView == null) return;
prepareNavigationBarView();
@@ -526,12 +519,12 @@
}
} catch (RemoteException ex) {
}
+
+ /*
+ * DISABLED due to missing API
if (ENABLE_INTRUDERS && (
// TODO(dsandler): Only if the screen is on
notification.notification.intruderView != null)) {
-// notification.notification.fullScreenIntent != null
-// || (notification.score >= mIntruderInImmersiveMinScore)
-// || (!immersive && (notification.score > mIntruderMinScore)))) {
Slog.d(TAG, "Presenting high-priority notification");
// special new transient ticker mode
// 1. Populate mIntruderAlertView
@@ -560,7 +553,10 @@
if (INTRUDER_ALERT_DECAY_MS > 0) {
mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
}
- } else if (notification.notification.fullScreenIntent != null) {
+ } else
+ */
+
+ if (notification.notification.fullScreenIntent != null) {
// not immersive & a full-screen alert should be shown
Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
try {
@@ -681,7 +677,7 @@
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
// See if we need to update the intruder.
- if (oldNotification == mCurrentlyIntrudingNotification) {
+ if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) {
if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification);
// XXX: this is a hack for Alarms. The real implementation will need to *update*
// the intruder.
@@ -703,7 +699,7 @@
// Recalculate the position of the sliding windows and the titles.
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
- if (old == mCurrentlyIntrudingNotification) {
+ if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) {
mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
}
@@ -832,73 +828,6 @@
}
}
- private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
- StatusBarNotification sbn = entry.notification;
- // XXX: temporary: while testing big notifications, auto-expand all of them
- final boolean big = (sbn.notification.bigContentView != null);
- RemoteViews remoteViews = big ? sbn.notification.bigContentView
- : sbn.notification.contentView;
- if (remoteViews == null) {
- return false;
- }
-
- // create the row view
- LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
- ViewGroup.LayoutParams lp = row.getLayoutParams();
- if (big) {
- lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
- } else {
- lp.height = mContext.getResources().getDimensionPixelSize(R.dimen.notification_height);
- }
- row.setLayoutParams(lp);
- View vetoButton = updateNotificationVetoButton(row, sbn);
- vetoButton.setContentDescription(mContext.getString(
- R.string.accessibility_remove_notification));
-
- // NB: the large icon is now handled entirely by the template
-
- // bind the click event to the content area
- ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
- // XXX: update to allow controls within notification views
- content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
-// content.setOnFocusChangeListener(mFocusChangeListener);
- PendingIntent contentIntent = sbn.notification.contentIntent;
- if (contentIntent != null) {
- final View.OnClickListener listener = new NotificationClicker(contentIntent,
- sbn.pkg, sbn.tag, sbn.id);
- content.setOnClickListener(listener);
- } else {
- content.setOnClickListener(null);
- }
-
- View expanded = null;
- Exception exception = null;
- try {
- expanded = remoteViews.apply(mContext, content);
- }
- catch (RuntimeException e) {
- exception = e;
- }
- if (expanded == null) {
- final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
- Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
- return false;
- } else {
- content.addView(expanded);
- row.setDrawingCacheEnabled(true);
- }
-
- applyLegacyRowBackground(sbn, content);
-
- entry.row = row;
- entry.content = content;
- entry.expanded = expanded;
-
- return true;
- }
-
StatusBarNotification removeNotificationViews(IBinder key) {
NotificationData.Entry entry = mNotificationData.remove(key);
if (entry == null) {
@@ -1520,10 +1449,6 @@
@Override
public void setHardKeyboardStatus(boolean available, boolean enabled) { }
- public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag, int id) {
- return new NotificationClicker(intent, pkg, tag, id);
- }
-
private class NotificationClicker implements View.OnClickListener {
private PendingIntent mIntent;
private String mPkg;
@@ -1538,12 +1463,6 @@
}
public void onClick(View v) {
- if (DEBUG) {
- Slog.v(TAG, "NotificationClicker: intent=" + mIntent
- + " pkg=" + mPkg
- + " tag=" + mTag
- + " id=" + mId);
- }
try {
// The intent we are sending is for the application, which
// won't have permission to immediately start an activity after
@@ -1976,24 +1895,6 @@
}
}
- /**
- * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
- * This was added last-minute and is inconsistent with the way the rest of the notifications
- * are handled, because the notification isn't really cancelled. The lights are just
- * turned off. If any other notifications happen, the lights will turn back on. Steve says
- * this is what he wants. (see bug 1131461)
- */
- void visibilityChanged(boolean visible) {
- if (mPanelSlightlyVisible != visible) {
- mPanelSlightlyVisible = visible;
- try {
- mBarService.onPanelRevealed();
- } catch (RemoteException ex) {
- // Won't fail unless the world has ended.
- }
- }
- }
-
void performDisableActions(int net) {
int old = mDisabled;
int diff = net ^ old;
@@ -2140,6 +2041,7 @@
};
private void setIntruderAlertVisibility(boolean vis) {
+ if (!ENABLE_INTRUDERS) return;
if (DEBUG) {
Slog.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
}
@@ -2226,30 +2128,6 @@
vib.vibrate(250);
}
- public int getScoreThreshold() {
- return mDisplayMinScore;
- }
-
- public void setScoreThreshold(int score) {
- // XXX HAX
- if (mDisplayMinScore != score) {
- this.mDisplayMinScore = score;
- applyScoreThreshold();
- }
- }
-
- private void applyScoreThreshold() {
- int N = mNotificationData.size();
- for (int i=0; i<N; i++) {
- NotificationData.Entry entry = mNotificationData.get(i);
- int vis = (entry.notification.score < mDisplayMinScore)
- ? View.GONE
- : View.VISIBLE;
- entry.row.setVisibility(vis);
- entry.icon.setVisibility(vis);
- }
- }
-
Runnable mStartTracing = new Runnable() {
public void run() {
vibrate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index 9fd89ed..93803d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -34,12 +34,17 @@
import android.view.ViewGroup;
import android.widget.LinearLayout;
+import com.android.systemui.ExpandHelper;
+import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
import com.android.systemui.SwipeHelper;
import java.util.HashMap;
-public class NotificationRowLayout extends LinearLayout implements SwipeHelper.Callback {
+public class NotificationRowLayout
+ extends LinearLayout
+ implements SwipeHelper.Callback, ExpandHelper.Callback
+{
private static final String TAG = "NotificationRowLayout";
private static final boolean DEBUG = false;
private static final boolean SLOW_ANIMATIONS = DEBUG;
@@ -55,6 +60,9 @@
HashMap<View, ValueAnimator> mDisappearingViews = new HashMap<View, ValueAnimator>();
private SwipeHelper mSwipeHelper;
+ private ExpandHelper mExpandHelper;
+
+ private Gefingerpoken mCurrentHelper;
// Flag set during notification removal animation to avoid causing too much work until
// animation is done
@@ -71,6 +79,8 @@
setOrientation(LinearLayout.VERTICAL);
+ setMotionEventSplittingEnabled(false);
+
if (DEBUG) {
setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
@Override
@@ -89,23 +99,65 @@
float densityScale = getResources().getDisplayMetrics().density;
float pagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+ int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
+ int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
+ mExpandHelper = new ExpandHelper(mContext, this, minHeight, maxHeight);
+ }
+
+ public void setLongPressListener(View.OnLongClickListener listener) {
+ mSwipeHelper.setLongPressListener(listener);
}
public void setAnimateBounds(boolean anim) {
mAnimateBounds = anim;
}
+ private void logLayoutTransition() {
+ Log.v(TAG, "layout " +
+ (getLayoutTransition().isChangingLayout() ? "is " : "is not ") +
+ "in transition and animations " +
+ (getLayoutTransition().isRunning() ? "are " : "are not ") +
+ "running.");
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
- return mSwipeHelper.onInterceptTouchEvent(ev) ||
- super.onInterceptTouchEvent(ev);
+ if (DEBUG) logLayoutTransition();
+
+ MotionEvent cancellation = MotionEvent.obtain(ev);
+ cancellation.setAction(MotionEvent.ACTION_CANCEL);
+
+ if (mSwipeHelper.onInterceptTouchEvent(ev)) {
+ if (DEBUG) Log.v(TAG, "will swipe");
+ mCurrentHelper = mSwipeHelper;
+ mExpandHelper.onInterceptTouchEvent(cancellation);
+ return true;
+ } else if (mExpandHelper.onInterceptTouchEvent(ev)) {
+ if (DEBUG) Log.v(TAG, "will stretch");
+ mCurrentHelper = mExpandHelper;
+ mSwipeHelper.onInterceptTouchEvent(cancellation);
+ return true;
+ } else {
+ mCurrentHelper = null;
+ if (super.onInterceptTouchEvent(ev)) {
+ if (DEBUG) Log.v(TAG, "intercepting ourselves");
+ mSwipeHelper.onInterceptTouchEvent(cancellation);
+ mExpandHelper.onInterceptTouchEvent(cancellation);
+ return true;
+ }
+ }
+ return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
- return mSwipeHelper.onTouchEvent(ev) ||
- super.onTouchEvent(ev);
+ if (DEBUG) Log.v(TAG, "onTouchEvent()");
+ if (DEBUG) logLayoutTransition();
+ if (mCurrentHelper != null) {
+ return mCurrentHelper.onTouchEvent(ev);
+ }
+ return super.onTouchEvent(ev);
}
public boolean canChildBeDismissed(View v) {
@@ -113,6 +165,12 @@
return (veto != null && veto.getVisibility() != View.GONE);
}
+ public boolean canChildBeExpanded(View v) {
+ Object isExpandable = v.getTag(R.id.expandable_tag);
+ return isExpandable != null && isExpandable instanceof Boolean &&
+ ((Boolean)isExpandable).booleanValue();
+ }
+
public void onChildDismissed(View v) {
final View veto = v.findViewById(R.id.veto);
if (veto != null && veto.getVisibility() != View.GONE && mRemoveViews) {
@@ -130,10 +188,12 @@
}
public View getChildAtPosition(MotionEvent ev) {
+ return getChildAtPosition(ev.getX(), ev.getY());
+ }
+ public View getChildAtPosition(float touchX, float touchY) {
// find the view under the pointer, accounting for GONE views
final int count = getChildCount();
int y = 0;
- int touchY = (int) ev.getY();
int childIdx = 0;
View slidingChild;
for (; childIdx < count; childIdx++) {
@@ -188,6 +248,7 @@
@Override
public void onDraw(android.graphics.Canvas c) {
super.onDraw(c);
+ if (DEBUG) logLayoutTransition();
if (DEBUG) {
//Slog.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
// + getMeasuredHeight() + "px");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
index 2171329..8924087 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
@@ -225,7 +225,7 @@
}
final CharSequence imiName = getIMIName(imi);
final Drawable icon = getSubtypeIcon(imi, subtype);
- final View view = View.inflate(mContext, R.layout.status_bar_input_methods_item, null);
+ final View view = View.inflate(mContext, R.layout.system_bar_input_methods_item, null);
final ImageView subtypeIcon = (ImageView)view.findViewById(R.id.item_icon);
final TextView itemTitle = (TextView)view.findViewById(R.id.item_title);
final TextView itemSubtitle = (TextView)view.findViewById(R.id.item_subtitle);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 8e58649..b82e1d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -344,7 +344,7 @@
// NB: it will be invisible until you show it
void addSettingsView() {
LayoutInflater infl = LayoutInflater.from(getContext());
- mSettingsView = infl.inflate(R.layout.status_bar_settings_view, mContentFrame, false);
+ mSettingsView = infl.inflate(R.layout.system_bar_settings_view, mContentFrame, false);
mSettingsView.setVisibility(View.GONE);
mContentFrame.addView(mSettingsView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index ba51108..7b3b745 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -16,14 +16,9 @@
package com.android.systemui.statusbar.tablet;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.app.ActivityManagerNative;
-import android.app.KeyguardManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.StatusBarManager;
@@ -32,17 +27,13 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Point;
-import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.inputmethodservice.InputMethodService;
-import android.os.Build;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
@@ -53,7 +44,6 @@
import android.view.Gravity;
import android.view.IWindowManager;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.VelocityTracker;
@@ -84,8 +74,13 @@
import com.android.systemui.statusbar.policy.CompatModeButton;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.NotificationRowLayout;
import com.android.systemui.statusbar.policy.Prefs;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
public class TabletStatusBar extends BaseStatusBar implements
InputMethodsPanel.OnHardKeyboardEnabledChangeListener,
RecentsPanelView.OnRecentsPanelVisibilityChangedListener {
@@ -159,7 +154,7 @@
int mNotificationPeekTapDuration;
int mNotificationFlingVelocity;
- ViewGroup mPile;
+ NotificationRowLayout mPile;
BatteryController mBatteryController;
BluetoothController mBluetoothController;
@@ -187,8 +182,6 @@
private CompatModePanel mCompatModePanel;
private int mSystemUiVisibility = 0;
- // used to notify status bar for suppressing notification LED
- private boolean mPanelSlightlyVisible;
private int mNavigationIconHints = 0;
@@ -232,7 +225,7 @@
// Notification Panel
mNotificationPanel = (NotificationPanel)View.inflate(context,
- R.layout.status_bar_notification_panel, null);
+ R.layout.system_bar_notification_panel, null);
mNotificationPanel.setBar(this);
mNotificationPanel.show(false, false);
mNotificationPanel.setOnTouchListener(
@@ -293,7 +286,7 @@
// Notification preview window
if (NOTIFICATION_PEEK_ENABLED) {
mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context,
- R.layout.status_bar_notification_peek, null);
+ R.layout.system_bar_notification_peek, null);
mNotificationPeekWindow.setBar(this);
mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content);
@@ -337,7 +330,7 @@
// Input methods Panel
mInputMethodsPanel = (InputMethodsPanel) View.inflate(context,
- R.layout.status_bar_input_methods_panel, null);
+ R.layout.system_bar_input_methods_panel, null);
mInputMethodsPanel.setHardKeyboardEnabledChangeListener(this);
mInputMethodsPanel.setOnTouchListener(new TouchOutsideListener(
MSG_CLOSE_INPUT_METHODS_PANEL, mInputMethodsPanel));
@@ -360,7 +353,7 @@
// Compatibility mode selector panel
mCompatModePanel = (CompatModePanel) View.inflate(context,
- R.layout.status_bar_compat_mode_panel, null);
+ R.layout.system_bar_compat_mode_panel, null);
mCompatModePanel.setOnTouchListener(new TouchOutsideListener(
MSG_CLOSE_COMPAT_MODE_PANEL, mCompatModePanel));
mCompatModePanel.setTrigger(mCompatModeButton);
@@ -383,8 +376,9 @@
mRecentButton.setOnTouchListener(mRecentsPanel);
- mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content);
+ mPile = (NotificationRowLayout)mNotificationPanel.findViewById(R.id.content);
mPile.removeAllViews();
+ mPile.setLongPressListener(getNotificationLongClicker());
ScrollView scroller = (ScrollView)mPile.getParent();
scroller.setFillViewport(true);
@@ -471,7 +465,7 @@
loadDimens();
final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
- context, R.layout.status_bar, null);
+ context, R.layout.system_bar, null);
mStatusBarView = sb;
sb.setHandler(mHandler);
@@ -653,7 +647,7 @@
}
protected void updateRecentsPanel() {
- super.updateRecentsPanel();
+ super.updateRecentsPanel(R.layout.system_bar_recent_panel);
mRecentsPanel.setStatusBarView(mStatusBarView);
}
@@ -912,7 +906,7 @@
// update the contentIntent
final PendingIntent contentIntent = notification.notification.contentIntent;
if (contentIntent != null) {
- final View.OnClickListener listener = new NotificationClicker(contentIntent,
+ final View.OnClickListener listener = makeClicker(contentIntent,
notification.pkg, notification.tag, notification.id);
oldEntry.content.setOnClickListener(listener);
} else {
@@ -1105,24 +1099,6 @@
}
}
- /**
- * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
- * This was added last-minute and is inconsistent with the way the rest of the notifications
- * are handled, because the notification isn't really cancelled. The lights are just
- * turned off. If any other notifications happen, the lights will turn back on. Steve says
- * this is what he wants. (see bug 1131461)
- */
- void visibilityChanged(boolean visible) {
- if (mPanelSlightlyVisible != visible) {
- mPanelSlightlyVisible = visible;
- try {
- mBarService.onPanelRevealed();
- } catch (RemoteException ex) {
- // Won't fail unless the world has ended.
- }
- }
- }
-
@Override // CommandQueue
public void setNavigationIconHints(int hints) {
if (hints == mNavigationIconHints) return;
@@ -1364,70 +1340,6 @@
mHandler.sendEmptyMessage(msg);
}
- public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag, int id) {
- return new NotificationClicker(intent, pkg, tag, id);
- }
-
- private class NotificationClicker implements View.OnClickListener {
- private PendingIntent mIntent;
- private String mPkg;
- private String mTag;
- private int mId;
-
- NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
- mIntent = intent;
- mPkg = pkg;
- mTag = tag;
- mId = id;
- }
-
- public void onClick(View v) {
- try {
- // The intent we are sending is for the application, which
- // won't have permission to immediately start an activity after
- // the user switches to home. We know it is safe to do at this
- // point, so make sure new activity switches are now allowed.
- ActivityManagerNative.getDefault().resumeAppSwitches();
- // Also, notifications can be launched from the lock screen,
- // so dismiss the lock screen when the activity starts.
- ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
- } catch (RemoteException e) {
- }
-
- if (mIntent != null) {
- int[] pos = new int[2];
- v.getLocationOnScreen(pos);
- Intent overlay = new Intent();
- overlay.setSourceBounds(
- new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
- try {
- mIntent.send(mContext, 0, overlay);
-
- } catch (PendingIntent.CanceledException e) {
- // the stack trace isn't very helpful here. Just log the exception message.
- Slog.w(TAG, "Sending contentIntent failed: " + e);
- }
-
- KeyguardManager kgm =
- (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
- if (kgm != null) kgm.exitKeyguardSecurely(null);
- }
-
- try {
- mBarService.onNotificationClick(mPkg, mTag, mId);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
-
- // close the shade if it was open
- animateCollapse();
- visibilityChanged(false);
-
- // If this click was on the intruder alert, hide that instead
-// mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
- }
- }
-
StatusBarNotification removeNotificationViews(IBinder key) {
NotificationData.Entry entry = mNotificationData.remove(key);
if (entry == null) {
@@ -1801,7 +1713,8 @@
mNotificationPanel.setNotificationCount(N);
}
- void workAroundBadLayerDrawableOpacity(View v) {
+ @Override
+ protected void workAroundBadLayerDrawableOpacity(View v) {
Drawable bgd = v.getBackground();
if (!(bgd instanceof LayerDrawable)) return;
@@ -1811,64 +1724,6 @@
v.setBackgroundDrawable(d);
}
- private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
- StatusBarNotification sbn = entry.notification;
- RemoteViews remoteViews = sbn.notification.contentView;
- if (remoteViews == null) {
- return false;
- }
-
- // create the row view
- LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
- workAroundBadLayerDrawableOpacity(row);
- View vetoButton = updateNotificationVetoButton(row, entry.notification);
- vetoButton.setContentDescription(mContext.getString(
- R.string.accessibility_remove_notification));
-
- // NB: the large icon is now handled entirely by the template
-
- // bind the click event to the content area
- ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
- // XXX: update to allow controls within notification views
- content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
-// content.setOnFocusChangeListener(mFocusChangeListener);
- PendingIntent contentIntent = sbn.notification.contentIntent;
- if (contentIntent != null) {
- final View.OnClickListener listener = new NotificationClicker(
- contentIntent, sbn.pkg, sbn.tag, sbn.id);
- content.setOnClickListener(listener);
- } else {
- content.setOnClickListener(null);
- }
-
- View expanded = null;
- Exception exception = null;
- try {
- expanded = remoteViews.apply(mContext, content);
- }
- catch (RuntimeException e) {
- exception = e;
- }
- if (expanded == null) {
- final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
- Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
- return false;
- } else {
- content.addView(expanded);
- row.setDrawingCacheEnabled(true);
- }
-
- applyLegacyRowBackground(sbn, content);
-
- entry.row = row;
- entry.content = content;
- entry.expanded = expanded;
-
- return true;
- }
-
public void clearAll() {
try {
mBarService.onClearAllNotifications();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index e93a32b..754441c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -264,7 +264,7 @@
iconId = R.id.left_icon;
}
if (n.tickerView != null) {
- group = (ViewGroup)inflater.inflate(R.layout.status_bar_ticker_panel, null, false);
+ group = (ViewGroup)inflater.inflate(R.layout.system_bar_ticker_panel, null, false);
ViewGroup content = (FrameLayout) group.findViewById(R.id.ticker_expanded);
View expanded = null;
Exception exception = null;
@@ -285,7 +285,7 @@
ViewGroup.LayoutParams.MATCH_PARENT);
content.addView(expanded, lp);
} else if (n.tickerText != null) {
- group = (ViewGroup)inflater.inflate(R.layout.status_bar_ticker_compat, mWindow, false);
+ group = (ViewGroup)inflater.inflate(R.layout.system_bar_ticker_compat, mWindow, false);
final Drawable icon = StatusBarIconView.getIcon(mContext,
new StatusBarIcon(notification.pkg, n.icon, n.iconLevel, 0, n.tickerText));
ImageView iv = (ImageView)group.findViewById(iconId);
diff --git a/policy/src/com/android/internal/policy/impl/BiometricSensorUnlock.java b/policy/src/com/android/internal/policy/impl/BiometricSensorUnlock.java
index d445d5c..c36e148 100644
--- a/policy/src/com/android/internal/policy/impl/BiometricSensorUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/BiometricSensorUnlock.java
@@ -19,9 +19,6 @@
import android.view.View;
interface BiometricSensorUnlock {
- // Returns 'true' if the biometric sensor is available and is selected by user.
- public boolean installedAndSelected();
-
// Returns 'true' if the biometric sensor has started its unlock procedure but has not yet
// accepted or rejected the user.
public boolean isRunning();
@@ -29,6 +26,7 @@
// Show the interface, but don't start the unlock procedure. The interface should disappear
// after the specified timeout. If the timeout is 0, the interface shows until another event,
// such as calling hide(), causes it to disappear.
+ // Called on the UI Thread
public void show(long timeoutMilliseconds);
// Hide the interface, if any, exposing the lockscreen.
@@ -39,6 +37,7 @@
// Start the unlock procedure. Returns ‘false’ if it can’t be started or if the backup should
// be used.
+ // Called on the UI thread.
public boolean start(boolean suppressBiometricUnlock);
// Provide a view to work within.
diff --git a/policy/src/com/android/internal/policy/impl/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
index 7b0a086..ac86141 100644
--- a/policy/src/com/android/internal/policy/impl/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
@@ -77,18 +77,14 @@
mHandler = new Handler(this);
}
- // Indicates whether FaceLock is in use
- public boolean installedAndSelected() {
- return (mLockPatternUtils.usingBiometricWeak() &&
- mLockPatternUtils.isBiometricWeakInstalled());
- }
-
public boolean isRunning() {
return mServiceRunning;
}
// Shows the FaceLock area for a period of time
+ // Called on the UI thread
public void show(long timeoutMillis) {
+ removeAreaDisplayMessages();
showArea();
if (timeoutMillis > 0)
mHandler.sendEmptyMessageDelayed(MSG_HIDE_AREA_VIEW, timeoutMillis);
@@ -104,28 +100,26 @@
// Tells FaceLock to stop and then unbinds from the FaceLock service
public boolean stop() {
boolean wasRunning = false;
- if (installedAndSelected()) {
- stopUi();
+ stopUi();
- if (mBoundToService) {
- wasRunning = true;
- if (DEBUG) Log.d(TAG, "before unbind from FaceLock service");
- if (mService != null) {
- try {
- mService.unregisterCallback(mFaceLockCallback);
- } catch (RemoteException e) {
- // Not much we can do
- }
+ if (mBoundToService) {
+ wasRunning = true;
+ if (DEBUG) Log.d(TAG, "before unbind from FaceLock service");
+ if (mService != null) {
+ try {
+ mService.unregisterCallback(mFaceLockCallback);
+ } catch (RemoteException e) {
+ // Not much we can do
}
- mContext.unbindService(mConnection);
- if (DEBUG) Log.d(TAG, "after unbind from FaceLock service");
- mBoundToService = false;
- } else {
- // This is usually not an error when this happens. Sometimes we will tell it to
- // unbind multiple times because it's called from both onWindowFocusChanged and
- // onDetachedFromWindow.
- if (DEBUG) Log.d(TAG, "Attempt to unbind from FaceLock when not bound");
}
+ mContext.unbindService(mConnection);
+ if (DEBUG) Log.d(TAG, "after unbind from FaceLock service");
+ mBoundToService = false;
+ } else {
+ // This is usually not an error when this happens. Sometimes we will tell it to
+ // unbind multiple times because it's called from both onWindowFocusChanged and
+ // onDetachedFromWindow.
+ if (DEBUG) Log.d(TAG, "Attempt to unbind from FaceLock when not bound");
}
return wasRunning;
@@ -134,6 +128,7 @@
/**
* When screen is turned on and focused, need to bind to FaceLock service if we are using
* FaceLock, but only if we're not dealing with a call
+ * Called on the UI thread
*/
public boolean start(boolean suppressBiometricUnlock) {
final boolean tooManyFaceUnlockTries = mUpdateMonitor.getMaxFaceUnlockAttemptsReached();
@@ -142,16 +137,16 @@
(failedBackupAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
if (tooManyFaceUnlockTries) Log.i(TAG, "tooManyFaceUnlockTries: " + tooManyFaceUnlockTries);
if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
- && installedAndSelected()
&& !suppressBiometricUnlock
&& !tooManyFaceUnlockTries
&& !backupIsTimedOut) {
- bind();
-
// Show FaceLock area, but only for a little bit so lockpattern will become visible if
// FaceLock fails to start or crashes
+ // This must show before bind to guarantee that Face Unlock has a place to display
show(VIEW_AREA_SERVICE_TIMEOUT);
+ bind();
+
// When switching between portrait and landscape view while FaceLock is running, the
// screen will eventually go dark unless we poke the wakelock when FaceLock is
// restarted
@@ -166,13 +161,11 @@
// Takes care of FaceLock area when layout is created
public void initializeAreaView(View topView) {
- if (installedAndSelected()) {
- mAreaView = topView.findViewById(R.id.faceLockAreaView);
- if (mAreaView == null) {
- Log.e(TAG, "Layout does not have areaView and FaceLock is enabled");
- }
+ mAreaView = topView.findViewById(R.id.faceLockAreaView);
+ if (mAreaView == null) {
+ Log.e(TAG, "Layout does not have areaView and FaceLock is enabled");
} else {
- mAreaView = null; // Set to null if not using FaceLock
+ show(0);
}
}
@@ -192,6 +185,14 @@
return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
}
+ // Shows the FaceLock area
+ // Called on the UI thread
+ private void showArea() {
+ if (mAreaView != null) {
+ mAreaView.setVisibility(View.VISIBLE);
+ }
+ }
+
// Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops
// This needs to be done in a handler because the call could be coming from a callback from the
// FaceLock service that is in a thread that can't modify the UI
@@ -199,9 +200,7 @@
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_SHOW_AREA_VIEW:
- if (mAreaView != null) {
- mAreaView.setVisibility(View.VISIBLE);
- }
+ showArea();
break;
case MSG_HIDE_AREA_VIEW:
if (mAreaView != null) {
@@ -221,28 +220,19 @@
mHandler.removeMessages(MSG_HIDE_AREA_VIEW);
}
- // Shows the FaceLock area immediately
- private void showArea() {
- // Remove messages to prevent a delayed hide message from undo-ing the show
- removeAreaDisplayMessages();
- mHandler.sendEmptyMessage(MSG_SHOW_AREA_VIEW);
- }
-
// Binds to FaceLock service. This call does not tell it to start, but it causes the service
// to call the onServiceConnected callback, which then starts FaceLock.
private void bind() {
- if (installedAndSelected()) {
- if (!mBoundToService) {
- if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
- mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
- mConnection,
- Context.BIND_AUTO_CREATE,
- mLockPatternUtils.getCurrentUser());
- if (DEBUG) Log.d(TAG, "after bind to FaceLock service");
- mBoundToService = true;
- } else {
- Log.w(TAG, "Attempt to bind to FaceLock when already bound");
- }
+ if (!mBoundToService) {
+ if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
+ mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
+ mConnection,
+ Context.BIND_AUTO_CREATE,
+ mLockPatternUtils.getCurrentUser());
+ if (DEBUG) Log.d(TAG, "after bind to FaceLock service");
+ mBoundToService = true;
+ } else {
+ Log.w(TAG, "Attempt to bind to FaceLock when already bound");
}
}
@@ -284,41 +274,37 @@
// Tells the FaceLock service to start displaying its UI and perform recognition
private void startUi(IBinder windowToken, int x, int y, int w, int h) {
- if (installedAndSelected()) {
- synchronized (mServiceRunningLock) {
- if (!mServiceRunning) {
- if (DEBUG) Log.d(TAG, "Starting FaceLock");
- try {
- mService.startUi(windowToken, x, y, w, h,
- mLockPatternUtils.isBiometricWeakLivelinessEnabled());
- } catch (RemoteException e) {
- Log.e(TAG, "Caught exception starting FaceLock: " + e.toString());
- return;
- }
- mServiceRunning = true;
- } else {
- if (DEBUG) Log.w(TAG, "startUi() attempted while running");
+ synchronized (mServiceRunningLock) {
+ if (!mServiceRunning) {
+ if (DEBUG) Log.d(TAG, "Starting FaceLock");
+ try {
+ mService.startUi(windowToken, x, y, w, h,
+ mLockPatternUtils.isBiometricWeakLivelinessEnabled());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Caught exception starting FaceLock: " + e.toString());
+ return;
}
+ mServiceRunning = true;
+ } else {
+ if (DEBUG) Log.w(TAG, "startUi() attempted while running");
}
}
}
// Tells the FaceLock service to stop displaying its UI and stop recognition
private void stopUi() {
- if (installedAndSelected()) {
- // Note that attempting to stop FaceLock when it's not running is not an issue.
- // FaceLock can return, which stops it and then we try to stop it when the
- // screen is turned off. That's why we check.
- synchronized (mServiceRunningLock) {
- if (mServiceRunning) {
- try {
- if (DEBUG) Log.d(TAG, "Stopping FaceLock");
- mService.stopUi();
- } catch (RemoteException e) {
- Log.e(TAG, "Caught exception stopping FaceLock: " + e.toString());
- }
- mServiceRunning = false;
+ // Note that attempting to stop FaceLock when it's not running is not an issue.
+ // FaceLock can return, which stops it and then we try to stop it when the
+ // screen is turned off. That's why we check.
+ synchronized (mServiceRunningLock) {
+ if (mServiceRunning) {
+ try {
+ if (DEBUG) Log.d(TAG, "Stopping FaceLock");
+ mService.stopUi();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Caught exception stopping FaceLock: " + e.toString());
}
+ mServiceRunning = false;
}
}
}
@@ -329,7 +315,11 @@
@Override
public void unlock() {
if (DEBUG) Log.d(TAG, "FaceLock unlock()");
- showArea(); // Keep fallback covered
+
+ // Keep fallback covered
+ removeAreaDisplayMessages();
+ mHandler.sendEmptyMessage(MSG_SHOW_AREA_VIEW);
+
stop();
mKeyguardScreenCallback.keyguardDone(true);
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index aeb518c..cd6da85 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -48,6 +48,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
@@ -181,6 +182,11 @@
ShutdownThread.shutdown(mContext, true);
}
+ public boolean onLongPress() {
+ ShutdownThread.rebootSafeMode(mContext, true);
+ return true;
+ }
+
public boolean showDuringKeyguard() {
return true;
}
@@ -242,6 +248,15 @@
final AlertDialog dialog = ab.create();
dialog.getListView().setItemsCanFocus(true);
+ dialog.getListView().setLongClickable(true);
+ dialog.getListView().setOnItemLongClickListener(
+ new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
+ long id) {
+ return mAdapter.getItem(position).onLongPress();
+ }
+ });
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
dialog.setOnDismissListener(this);
@@ -365,6 +380,8 @@
void onPress();
+ public boolean onLongPress();
+
/**
* @return whether this action should appear in the dialog when the keygaurd
* is showing.
@@ -406,6 +423,10 @@
abstract public void onPress();
+ public boolean onLongPress() {
+ return false;
+ }
+
public View create(
Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
View v = inflater.inflate(R.layout.global_actions_item, parent, false);
@@ -530,6 +551,10 @@
changeStateFromPress(nowOn);
}
+ public boolean onLongPress() {
+ return false;
+ }
+
public boolean isEnabled() {
return !mState.inTransition();
}
@@ -599,6 +624,10 @@
public void onPress() {
}
+ public boolean onLongPress() {
+ return false;
+ }
+
public boolean showDuringKeyguard() {
return true;
}
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index c382646..7e2985d 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -111,7 +111,7 @@
private boolean mRequiresSim;
// True if the biometric unlock should not be displayed. For example, if there is an overlay on
// lockscreen or the user is plugging in / unplugging the device.
- private boolean mSupressBiometricUnlock;
+ private boolean mSuppressBiometricUnlock;
//True if a dialog is currently displaying on top of this window
//Unlike other overlays, this does not close with a power button cycle
private boolean mHasDialog = false;
@@ -310,16 +310,18 @@
}
public void takeEmergencyCallAction() {
- mSupressBiometricUnlock = true;
+ mSuppressBiometricUnlock = true;
- if (mBiometricUnlock.installedAndSelected() && mBiometricUnlock.isRunning()) {
- // Continue covering backup lock until dialer comes up or call is resumed
- mBiometricUnlock.show(BIOMETRIC_AREA_EMERGENCY_DIALER_TIMEOUT);
+ if (mBiometricUnlock != null) {
+ if (mBiometricUnlock.isRunning()) {
+ // Continue covering backup lock until dialer comes up or call is resumed
+ mBiometricUnlock.show(BIOMETRIC_AREA_EMERGENCY_DIALER_TIMEOUT);
+ }
+
+ // We must ensure the biometric unlock is stopped when emergency call is pressed
+ mBiometricUnlock.stop();
}
- // The biometric unlock must be stopped if it is running when emergency call is pressed
- mBiometricUnlock.stop();
-
pokeWakelock(EMERGENCY_CALL_TIMEOUT);
if (TelephonyManager.getDefault().getCallState()
== TelephonyManager.CALL_STATE_OFFHOOK) {
@@ -410,6 +412,12 @@
}
};
+ // Indicates whether a biometric unlock method is in use
+ private boolean isBiometricUnlockInstalledAndSelected() {
+ return (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled());
+ }
+
/**
* @param context Used to inflate, and create views.
* @param callback Keyguard callback object for pokewakelock(), etc.
@@ -423,18 +431,23 @@
LockPatternUtils lockPatternUtils, KeyguardWindowController controller) {
super(context, callback);
- mBiometricUnlock = new FaceUnlock(context, updateMonitor, lockPatternUtils,
- mKeyguardScreenCallback);
mConfiguration = context.getResources().getConfiguration();
mEnableFallback = false;
mRequiresSim = TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim"));
mUpdateMonitor = updateMonitor;
mLockPatternUtils = lockPatternUtils;
mWindowController = controller;
- mSupressBiometricUnlock = false;
+ mSuppressBiometricUnlock = false;
mPluggedIn = mUpdateMonitor.isDevicePluggedIn();
mScreenOn = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isScreenOn();
+ // If the biometric unlock is not being used, we don't bother constructing it. Then we can
+ // simply check if it is null when deciding whether we should make calls to it.
+ if (isBiometricUnlockInstalledAndSelected()) {
+ mBiometricUnlock = new FaceUnlock(context, updateMonitor, lockPatternUtils,
+ mKeyguardScreenCallback);
+ }
+
mUpdateMonitor.registerInfoCallback(mInfoCallback);
/**
@@ -530,8 +543,11 @@
if (DEBUG) Log.d(TAG, "screen off");
mScreenOn = false;
mForgotPattern = false;
- mSupressBiometricUnlock =
- mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE || mHasDialog;
+ if (mBiometricUnlock != null) {
+ mSuppressBiometricUnlock =
+ mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE
+ || mHasDialog;
+ }
// Emulate activity life-cycle for both lock and unlock screen.
if (mLockScreen != null) {
@@ -543,8 +559,10 @@
saveWidgetState();
- // The biometric unlock must stop when screen turns off.
- mBiometricUnlock.stop();
+ if (mBiometricUnlock != null) {
+ // The biometric unlock must stop when screen turns off.
+ mBiometricUnlock.stop();
+ }
}
@Override
@@ -561,7 +579,9 @@
restoreWidgetState();
- if (startBiometricUnlock) mBiometricUnlock.start(mSupressBiometricUnlock);
+ if (mBiometricUnlock != null && startBiometricUnlock) {
+ mBiometricUnlock.start(mSuppressBiometricUnlock);
+ }
}
private void saveWidgetState() {
@@ -587,6 +607,7 @@
@Override
public void onWindowFocusChanged (boolean hasWindowFocus) {
if (DEBUG) Log.d(TAG, hasWindowFocus ? "focused" : "unfocused");
+
boolean startBiometricUnlock = false;
// Start the biometric unlock if and only if the screen is both on and focused
synchronized(mBiometricUnlockStartupLock) {
@@ -594,12 +615,16 @@
mWindowFocused = hasWindowFocus;
}
if (!hasWindowFocus) {
- mSupressBiometricUnlock = true;
- mBiometricUnlock.stop();
- mBiometricUnlock.hide();
+ if (mBiometricUnlock != null) {
+ mSuppressBiometricUnlock = true;
+ mBiometricUnlock.stop();
+ mBiometricUnlock.hide();
+ }
} else {
mHasDialog = false;
- if (startBiometricUnlock) mBiometricUnlock.start(mSupressBiometricUnlock);
+ if (mBiometricUnlock != null && startBiometricUnlock) {
+ mBiometricUnlock.start(mSuppressBiometricUnlock);
+ }
}
}
@@ -613,13 +638,7 @@
((KeyguardScreen) mUnlockScreen).onResume();
}
- if (mBiometricUnlock.installedAndSelected() && !mSupressBiometricUnlock) {
- // Note that show() gets called before the screen turns off to set it up for next time
- // it is turned on. We don't want to set a timeout on the biometric unlock here because
- // it may be gone by the time the screen is turned on again. We set the timeout when
- // the screen turns on instead.
- mBiometricUnlock.show(0);
- } else {
+ if (mBiometricUnlock != null && mSuppressBiometricUnlock) {
mBiometricUnlock.hide();
}
}
@@ -654,9 +673,11 @@
removeCallbacks(mRecreateRunnable);
- // When view is hidden, we need to stop the biometric unlock
- // e.g., when device becomes unlocked
- mBiometricUnlock.stop();
+ if (mBiometricUnlock != null) {
+ // When view is hidden, we need to stop the biometric unlock
+ // e.g., when device becomes unlocked
+ mBiometricUnlock.stop();
+ }
super.onDetachedFromWindow();
}
@@ -673,20 +694,22 @@
InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
- /**
- * When somebody plugs in or unplugs the device, we don't want to display the biometric
- * unlock.
- */
@Override
public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn,
int batteryLevel) {
- mSupressBiometricUnlock |= mPluggedIn != pluggedIn;
- mPluggedIn = pluggedIn;
- // If it's already running, don't close it down: the unplug didn't start it
- if (!mBiometricUnlock.isRunning()) {
+ // When someone plugs in or unplugs the device, we hide the biometric sensor area and
+ // suppress its startup for the next onScreenTurnedOn(). Since plugging/unplugging
+ // causes the screen to turn on, the biometric unlock would start if it wasn't
+ // suppressed.
+ //
+ // However, if the biometric unlock is already running, we do not want to interrupt it.
+ if (mBiometricUnlock != null && mPluggedIn != pluggedIn
+ && !mBiometricUnlock.isRunning()) {
mBiometricUnlock.stop();
mBiometricUnlock.hide();
+ mSuppressBiometricUnlock = true;
}
+ mPluggedIn = pluggedIn;
}
@Override
@@ -700,8 +723,8 @@
@Override
public void onPhoneStateChanged(int phoneState) {
if (DEBUG) Log.d(TAG, "phone state: " + phoneState);
- if(phoneState == TelephonyManager.CALL_STATE_RINGING) {
- mSupressBiometricUnlock = true;
+ if (mBiometricUnlock != null && phoneState == TelephonyManager.CALL_STATE_RINGING) {
+ mSuppressBiometricUnlock = true;
mBiometricUnlock.stop();
mBiometricUnlock.hide();
}
@@ -709,7 +732,9 @@
@Override
public void onUserChanged(int userId) {
- mBiometricUnlock.stop();
+ if (mBiometricUnlock != null) {
+ mBiometricUnlock.stop();
+ }
mLockPatternUtils.setCurrentUser(userId);
updateScreen(getInitialMode(), true);
}
@@ -772,7 +797,9 @@
mUnlockScreen = null;
}
mUpdateMonitor.removeCallback(this);
- mBiometricUnlock.cleanUp();
+ if (mBiometricUnlock != null) {
+ mBiometricUnlock.cleanUp();
+ }
}
private boolean isSecure() {
@@ -822,10 +849,13 @@
final UnlockMode unlockMode = getUnlockMode();
if (mode == Mode.UnlockScreen && unlockMode != UnlockMode.Unknown) {
if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
- boolean restartBiometricUnlock = mBiometricUnlock.stop();
+ boolean restartBiometricUnlock = false;
+ if (mBiometricUnlock != null) {
+ restartBiometricUnlock = mBiometricUnlock.stop();
+ }
recreateUnlockScreen(unlockMode);
- if (restartBiometricUnlock) {
- mBiometricUnlock.start(mSupressBiometricUnlock);
+ if (mBiometricUnlock != null && restartBiometricUnlock) {
+ mBiometricUnlock.start(mSuppressBiometricUnlock);
}
}
}
@@ -939,8 +969,10 @@
throw new IllegalArgumentException("unknown unlock mode " + unlockMode);
}
initializeTransportControlView(unlockView);
- // Only shows view if the biometric unlock is enabled
- mBiometricUnlock.initializeAreaView(unlockView);
+
+ if (mBiometricUnlock != null) {
+ mBiometricUnlock.initializeAreaView(unlockView);
+ }
mUnlockScreenMode = unlockMode;
return unlockView;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 897b8d0..cc663c2 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -306,12 +306,14 @@
WindowState mStatusBar = null;
boolean mHasSystemNavBar;
int mStatusBarHeight;
- final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>();
+ final ArrayList<WindowState> mStatusBarSubPanels = new ArrayList<WindowState>();
WindowState mNavigationBar = null;
boolean mHasNavigationBar = false;
boolean mCanHideNavigationBar = false;
- boolean mNavigationBarOnBottom = true;
- int mNavigationBarWidth = 0, mNavigationBarHeight = 0;
+ boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side?
+ boolean mNavigationBarOnBottom = true; // is the navigation bar on the bottom *right now*?
+ int[] mNavigationBarHeightForRotation = new int[4];
+ int[] mNavigationBarWidthForRotation = new int[4];
WindowState mKeyguard = null;
KeyguardViewMediator mKeyguardMediator;
@@ -972,19 +974,38 @@
mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height);
- mNavigationBarHeight = mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_height);
- mNavigationBarWidth = mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_width);
- // Determine whether the status bar can hide based on the size
- // of the screen. We assume sizes >= 600dp are tablets where we
- // will use the system bar.
- // XXX: This will change to 720dp soon.
+ mNavigationBarHeightForRotation[Surface.ROTATION_0] =
+ mNavigationBarHeightForRotation[Surface.ROTATION_90] =
+ mNavigationBarHeightForRotation[Surface.ROTATION_180] =
+ mNavigationBarHeightForRotation[Surface.ROTATION_270] =
+ mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height);
+ mNavigationBarWidthForRotation[Surface.ROTATION_0] =
+ mNavigationBarWidthForRotation[Surface.ROTATION_90] =
+ mNavigationBarWidthForRotation[Surface.ROTATION_180] =
+ mNavigationBarWidthForRotation[Surface.ROTATION_270] =
+ mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_width);
+
+ // SystemUI (status bar) layout policy
int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
- mHasSystemNavBar = shortSizeDp >= 600;
+
+ if (shortSizeDp < 600) {
+ // 0-599dp: "phone" UI with a separate status & navigation bar
+ mHasSystemNavBar = false;
+ mNavigationBarCanMove = true;
+ } else if (shortSizeDp < 720) {
+ // 600-719dp: "phone" UI with modifications for larger screens
+ mHasSystemNavBar = false;
+ mNavigationBarCanMove = false;
+ } else {
+ // 720dp: "tablet" UI with a single combined status & navigation bar
+ mHasSystemNavBar = true;
+ mNavigationBarCanMove = false;
+ }
if (!mHasSystemNavBar) {
mHasNavigationBar = mContext.getResources().getBoolean(
@@ -1007,7 +1028,7 @@
int longSizeDp = longSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
- int barHeightDp = mNavigationBarHeight
+ int barHeightDp = mNavigationBarHeightForRotation[mLandscapeRotation]
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
int aspect = ((shortSizeDp-barHeightDp) * 16) / longSizeDp;
@@ -1354,8 +1375,8 @@
if (mHasNavigationBar) {
// For a basic navigation bar, when we are in landscape mode we place
// the navigation bar to the side.
- if (fullWidth > fullHeight) {
- return fullWidth - mNavigationBarWidth;
+ if (mNavigationBarCanMove && fullWidth > fullHeight) {
+ return fullWidth - mNavigationBarWidthForRotation[rotation];
}
}
return fullWidth;
@@ -1364,13 +1385,13 @@
public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation) {
if (mHasSystemNavBar) {
// For the system navigation bar, we always place it at the bottom.
- return fullHeight - mNavigationBarHeight;
+ return fullHeight - mNavigationBarHeightForRotation[rotation];
}
if (mHasNavigationBar) {
// For a basic navigation bar, when we are in portrait mode we place
// the navigation bar to the bottom.
- if (fullWidth < fullHeight) {
- return fullHeight - mNavigationBarHeight;
+ if (!mNavigationBarCanMove || fullWidth < fullHeight) {
+ return fullHeight - mNavigationBarHeightForRotation[rotation];
}
}
return fullHeight;
@@ -1560,13 +1581,12 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.STATUS_BAR_SERVICE,
"PhoneWindowManager");
- mStatusBarPanels.add(win);
break;
case TYPE_STATUS_BAR_SUB_PANEL:
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.STATUS_BAR_SERVICE,
"PhoneWindowManager");
- mStatusBarPanels.add(win);
+ mStatusBarSubPanels.add(win);
break;
case TYPE_KEYGUARD:
if (mKeyguard != null) {
@@ -1587,7 +1607,7 @@
} else if (mNavigationBar == win) {
mNavigationBar = null;
} else {
- mStatusBarPanels.remove(win);
+ mStatusBarSubPanels.remove(win);
}
}
@@ -2182,10 +2202,10 @@
// size. We need to do this directly, instead of relying on
// it to bubble up from the nav bar, because this needs to
// change atomically with screen rotations.
- mNavigationBarOnBottom = !mHasNavigationBar || displayWidth < displayHeight;
+ mNavigationBarOnBottom = (!mNavigationBarCanMove || displayWidth < displayHeight);
if (mNavigationBarOnBottom) {
// It's a system nav bar or a portrait screen; nav bar goes on bottom.
- int top = displayHeight - mNavigationBarHeight;
+ int top = displayHeight - mNavigationBarHeightForRotation[displayRotation];
if (mHdmiPlugged) {
if (top > mExternalDisplayHeight) {
top = mExternalDisplayHeight;
@@ -2203,7 +2223,7 @@
}
} else {
// Landscape screen; nav bar goes to the right.
- int left = displayWidth - mNavigationBarWidth;
+ int left = displayWidth - mNavigationBarWidthForRotation[displayRotation];
if (mHdmiPlugged) {
if (left > mExternalDisplayWidth) {
left = mExternalDisplayWidth;
@@ -2760,8 +2780,8 @@
}
if (mStatusBar != null && mStatusBar.isVisibleLw()) {
RectF rect = new RectF(mStatusBar.getShownFrameLw());
- for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
- WindowState w = mStatusBarPanels.get(i);
+ for (int i=mStatusBarSubPanels.size()-1; i>=0; i--) {
+ WindowState w = mStatusBarSubPanels.get(i);
if (w.isVisibleLw()) {
rect.union(w.getShownFrameLw());
}
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index c0eb1b9..6ec020c 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -443,11 +443,22 @@
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device && device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->mapKey(
- scanCode, usageCode, outKeycode, outFlags);
- if (err == NO_ERROR) {
- return NO_ERROR;
+ if (device) {
+ // Check the key character map first.
+ sp<KeyCharacterMap> kcm = device->getKeyCharacterMap();
+ if (kcm != NULL) {
+ if (!kcm->mapKey(scanCode, usageCode, outKeycode)) {
+ *outFlags = 0;
+ return NO_ERROR;
+ }
+ }
+
+ // Check the key layout next.
+ if (device->keyMap.haveKeyLayout()) {
+ if (!device->keyMap.keyLayoutMap->mapKey(
+ scanCode, usageCode, outKeycode, outFlags)) {
+ return NO_ERROR;
+ }
}
}
@@ -531,11 +542,26 @@
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
if (device) {
- return device->keyMap.keyCharacterMap;
+ return device->getKeyCharacterMap();
}
return NULL;
}
+bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId,
+ const sp<KeyCharacterMap>& map) {
+ AutoMutex _l(mLock);
+ Device* device = getDeviceLocked(deviceId);
+ if (device) {
+ if (map != device->overlayKeyMap) {
+ device->overlayKeyMap = map;
+ device->combinedKeyMap = KeyCharacterMap::combine(
+ device->keyMap.keyCharacterMap, map);
+ return true;
+ }
+ }
+ return false;
+}
+
void EventHub::vibrate(int32_t deviceId, nsecs_t duration) {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
@@ -1439,6 +1465,8 @@
device->keyMap.keyCharacterMapFile.string());
dump.appendFormat(INDENT3 "ConfigurationFile: %s\n",
device->configurationFile.string());
+ dump.appendFormat(INDENT3 "HaveKeyboardLayoutOverlay: %s\n",
+ toString(device->overlayKeyMap != NULL));
}
} // release lock
}
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index 51d2bac..afc12ef 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -221,6 +221,7 @@
Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0;
virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const = 0;
+ virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) = 0;
/* Control the vibrator. */
virtual void vibrate(int32_t deviceId, nsecs_t duration) = 0;
@@ -283,6 +284,7 @@
Vector<VirtualKeyDefinition>& outVirtualKeys) const;
virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const;
+ virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map);
virtual void vibrate(int32_t deviceId, nsecs_t duration);
virtual void cancelVibrate(int32_t deviceId);
@@ -321,6 +323,9 @@
VirtualKeyMap* virtualKeyMap;
KeyMap keyMap;
+ sp<KeyCharacterMap> overlayKeyMap;
+ sp<KeyCharacterMap> combinedKeyMap;
+
bool ffEffectPlaying;
int16_t ffEffectId; // initially -1
@@ -330,6 +335,13 @@
void close();
inline bool isVirtual() const { return fd < 0; }
+
+ const sp<KeyCharacterMap>& getKeyCharacterMap() const {
+ if (combinedKeyMap != NULL) {
+ return combinedKeyMap;
+ }
+ return keyMap.keyCharacterMap;
+ }
};
status_t openDeviceLocked(const char *devicePath);
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index da3548f..dad4ef4 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -970,14 +970,17 @@
// Give up.
mInputTargetWaitTimeoutExpired = true;
- // Release the touch targets.
- mTouchState.reset();
-
// Input state will not be realistic. Mark it out of sync.
if (inputChannel.get()) {
ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
if (connectionIndex >= 0) {
sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
+ sp<InputWindowHandle> windowHandle = connection->inputWindowHandle;
+
+ if (windowHandle != NULL) {
+ mTouchState.removeWindow(windowHandle);
+ }
+
if (connection->status == Connection::STATUS_NORMAL) {
CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
"application not responding");
@@ -4146,6 +4149,15 @@
touchedWindow.pointerIds = pointerIds;
}
+void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
+ for (size_t i = 0; i < windows.size(); i++) {
+ if (windows.itemAt(i).windowHandle == windowHandle) {
+ windows.removeAt(i);
+ return;
+ }
+ }
+}
+
void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
for (size_t i = 0 ; i < windows.size(); ) {
TouchedWindow& window = windows.editItemAt(i);
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 91f7554..07ca9d5 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -926,6 +926,7 @@
void copyFrom(const TouchState& other);
void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds);
+ void removeWindow(const sp<InputWindowHandle>& windowHandle);
void filterNonAsIsTouchWindows();
sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
bool isSlippery() const;
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 8c37fbb..6022f10 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -918,7 +918,7 @@
getDeviceInfo(& deviceInfo);
dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
- deviceInfo.getName().string());
+ deviceInfo.getDisplayName().string());
dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
@@ -962,6 +962,26 @@
mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
}
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
+ if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
+ sp<KeyCharacterMap> keyboardLayout =
+ mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier.descriptor);
+ if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
+ bumpGeneration();
+ }
+ }
+ }
+
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
+ if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
+ String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
+ if (mAlias != alias) {
+ mAlias = alias;
+ bumpGeneration();
+ }
+ }
+ }
+
size_t numMappers = mMappers.size();
for (size_t i = 0; i < numMappers; i++) {
InputMapper* mapper = mMappers[i];
@@ -1029,7 +1049,7 @@
}
void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
- outDeviceInfo->initialize(mId, mGeneration, mIdentifier.name, mIdentifier.descriptor);
+ outDeviceInfo->initialize(mId, mGeneration, mIdentifier, mAlias);
size_t numMappers = mMappers.size();
for (size_t i = 0; i < numMappers; i++) {
@@ -1282,12 +1302,17 @@
// --- TouchButtonAccumulator ---
TouchButtonAccumulator::TouchButtonAccumulator() :
- mHaveBtnTouch(false) {
+ mHaveBtnTouch(false), mHaveStylus(false) {
clearButtons();
}
void TouchButtonAccumulator::configure(InputDevice* device) {
mHaveBtnTouch = device->hasKey(BTN_TOUCH);
+ mHaveStylus = device->hasKey(BTN_TOOL_PEN)
+ || device->hasKey(BTN_TOOL_RUBBER)
+ || device->hasKey(BTN_TOOL_BRUSH)
+ || device->hasKey(BTN_TOOL_PENCIL)
+ || device->hasKey(BTN_TOOL_AIRBRUSH);
}
void TouchButtonAccumulator::reset(InputDevice* device) {
@@ -1411,6 +1436,10 @@
return mHaveBtnTouch && !mBtnTouch;
}
+bool TouchButtonAccumulator::hasStylus() const {
+ return mHaveStylus;
+}
+
// --- RawPointerAxes ---
@@ -1562,16 +1591,19 @@
// --- MultiTouchMotionAccumulator ---
MultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
- mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false) {
+ mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
+ mHaveStylus(false) {
}
MultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
delete[] mSlots;
}
-void MultiTouchMotionAccumulator::configure(size_t slotCount, bool usingSlotsProtocol) {
+void MultiTouchMotionAccumulator::configure(InputDevice* device,
+ size_t slotCount, bool usingSlotsProtocol) {
mSlotCount = slotCount;
mUsingSlotsProtocol = usingSlotsProtocol;
+ mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
delete[] mSlots;
mSlots = new Slot[slotCount];
@@ -1703,6 +1735,10 @@
}
}
+bool MultiTouchMotionAccumulator::hasStylus() const {
+ return mHaveStylus;
+}
+
// --- MultiTouchMotionAccumulator::Slot ---
@@ -2862,10 +2898,16 @@
&& mConfig.pointerGesturesEnabled) {
mSource = AINPUT_SOURCE_MOUSE;
mDeviceMode = DEVICE_MODE_POINTER;
+ if (hasStylus()) {
+ mSource |= AINPUT_SOURCE_STYLUS;
+ }
} else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
&& mParameters.associatedDisplayId >= 0) {
mSource = AINPUT_SOURCE_TOUCHSCREEN;
mDeviceMode = DEVICE_MODE_DIRECT;
+ if (hasStylus()) {
+ mSource |= AINPUT_SOURCE_STYLUS;
+ }
} else {
mSource = AINPUT_SOURCE_TOUCHPAD;
mDeviceMode = DEVICE_MODE_UNSCALED;
@@ -5776,6 +5818,10 @@
getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
}
+bool SingleTouchInputMapper::hasStylus() const {
+ return mTouchButtonAccumulator.hasStylus();
+}
+
// --- MultiTouchInputMapper ---
@@ -5910,12 +5956,19 @@
getDeviceName().string(), slotCount, MAX_SLOTS);
slotCount = MAX_SLOTS;
}
- mMultiTouchMotionAccumulator.configure(slotCount, true /*usingSlotsProtocol*/);
+ mMultiTouchMotionAccumulator.configure(getDevice(),
+ slotCount, true /*usingSlotsProtocol*/);
} else {
- mMultiTouchMotionAccumulator.configure(MAX_POINTERS, false /*usingSlotsProtocol*/);
+ mMultiTouchMotionAccumulator.configure(getDevice(),
+ MAX_POINTERS, false /*usingSlotsProtocol*/);
}
}
+bool MultiTouchInputMapper::hasStylus() const {
+ return mMultiTouchMotionAccumulator.hasStylus()
+ || mTouchButtonAccumulator.hasStylus();
+}
+
// --- JoystickInputMapper ---
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index ed57596..8257dbce 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -67,6 +67,12 @@
// The visible touches option changed.
CHANGE_SHOW_TOUCHES = 1 << 3,
+ // The keyboard layouts must be reloaded.
+ CHANGE_KEYBOARD_LAYOUTS = 1 << 4,
+
+ // The device name alias supplied by the may have changed for some devices.
+ CHANGE_DEVICE_ALIAS = 1 << 5,
+
// All devices must be reopened.
CHANGE_MUST_REOPEN = 1 << 31,
};
@@ -222,6 +228,12 @@
* and provides information about all current input devices.
*/
virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) = 0;
+
+ /* Gets the keyboard layout for a particular input device. */
+ virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const String8& inputDeviceDescriptor) = 0;
+
+ /* Gets a user-supplied alias for a particular input device, or an empty string if none. */
+ virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
};
@@ -501,6 +513,12 @@
return getEventHub()->hasScanCode(mId, code);
}
+ bool hasAbsoluteAxis(int32_t code) {
+ RawAbsoluteAxisInfo info;
+ getEventHub()->getAbsoluteAxisInfo(mId, code, &info);
+ return info.valid;
+ }
+
bool isKeyPressed(int32_t code) {
return getEventHub()->getScanCodeState(mId, code) == AKEY_STATE_DOWN;
}
@@ -516,6 +534,7 @@
int32_t mId;
int32_t mGeneration;
InputDeviceIdentifier mIdentifier;
+ String8 mAlias;
uint32_t mClasses;
Vector<InputMapper*> mMappers;
@@ -621,9 +640,11 @@
int32_t getToolType() const;
bool isToolActive() const;
bool isHovering() const;
+ bool hasStylus() const;
private:
bool mHaveBtnTouch;
+ bool mHaveStylus;
bool mBtnTouch;
bool mBtnStylus;
@@ -811,10 +832,11 @@
MultiTouchMotionAccumulator();
~MultiTouchMotionAccumulator();
- void configure(size_t slotCount, bool usingSlotsProtocol);
+ void configure(InputDevice* device, size_t slotCount, bool usingSlotsProtocol);
void reset(InputDevice* device);
void process(const RawEvent* rawEvent);
void finishSync();
+ bool hasStylus() const;
inline size_t getSlotCount() const { return mSlotCount; }
inline const Slot* getSlot(size_t index) const { return &mSlots[index]; }
@@ -824,6 +846,7 @@
Slot* mSlots;
size_t mSlotCount;
bool mUsingSlotsProtocol;
+ bool mHaveStylus;
void clearSlots(int32_t initialSlot);
};
@@ -1251,6 +1274,7 @@
virtual void parseCalibration();
virtual void resolveCalibration();
virtual void dumpCalibration(String8& dump);
+ virtual bool hasStylus() const = 0;
virtual void syncTouch(nsecs_t when, bool* outHavePointerIds) = 0;
@@ -1599,6 +1623,7 @@
protected:
virtual void syncTouch(nsecs_t when, bool* outHavePointerIds);
virtual void configureRawPointerAxes();
+ virtual bool hasStylus() const;
private:
SingleTouchMotionAccumulator mSingleTouchMotionAccumulator;
@@ -1616,6 +1641,7 @@
protected:
virtual void syncTouch(nsecs_t when, bool* outHavePointerIds);
virtual void configureRawPointerAxes();
+ virtual bool hasStylus() const;
private:
MultiTouchMotionAccumulator mMultiTouchMotionAccumulator;
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 94d4189..0f755ae 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -170,6 +170,14 @@
virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) {
mInputDevices = inputDevices;
}
+
+ virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const String8& inputDeviceDescriptor) {
+ return NULL;
+ }
+
+ virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) {
+ return String8::empty();
+ }
};
@@ -646,6 +654,10 @@
return NULL;
}
+ virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) {
+ return false;
+ }
+
virtual void vibrate(int32_t deviceId, nsecs_t duration) {
}
@@ -1073,7 +1085,7 @@
ASSERT_EQ(1U, inputDevices.size());
ASSERT_EQ(1, inputDevices[0].getId());
- ASSERT_STREQ("keyboard", inputDevices[0].getName().string());
+ ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string());
ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
@@ -1082,7 +1094,7 @@
inputDevices = mFakePolicy->getInputDevices();
ASSERT_EQ(1U, inputDevices.size());
ASSERT_EQ(1, inputDevices[0].getId());
- ASSERT_STREQ("keyboard", inputDevices[0].getName().string());
+ ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string());
ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
@@ -1303,7 +1315,7 @@
InputDeviceInfo info;
mDevice->getDeviceInfo(&info);
ASSERT_EQ(DEVICE_ID, info.getId());
- ASSERT_STREQ(DEVICE_NAME, info.getName().string());
+ ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.string());
ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
@@ -1373,7 +1385,7 @@
InputDeviceInfo info;
mDevice->getDeviceInfo(&info);
ASSERT_EQ(DEVICE_ID, info.getId());
- ASSERT_STREQ(DEVICE_NAME, info.getName().string());
+ ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.string());
ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index eb024e9..bf958a5 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -28,6 +28,7 @@
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Binder;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Pair;
@@ -260,6 +261,16 @@
return getImplForUser().getAppWidgetViews(appWidgetId);
}
+ @Override
+ public void updateAppWidgetExtras(int appWidgetId, Bundle extras) {
+ getImplForUser().updateAppWidgetExtras(appWidgetId, extras);
+ }
+
+ @Override
+ public Bundle getAppWidgetExtras(int appWidgetId) {
+ return getImplForUser().getAppWidgetExtras(appWidgetId);
+ }
+
static int[] getAppWidgetIds(Provider p) {
int instancesSize = p.instances.size();
int appWidgetIds[] = new int[instancesSize];
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index b24823e..3b43b9b 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -113,6 +113,7 @@
int appWidgetId;
Provider provider;
RemoteViews views;
+ Bundle extras;
Host host;
}
@@ -760,6 +761,38 @@
}
}
+ public void updateAppWidgetExtras(int appWidgetId, Bundle extras) {
+ synchronized (mAppWidgetIds) {
+ ensureStateLoadedLocked();
+ AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
+
+ if (id == null) {
+ return;
+ }
+ Provider p = id.provider;
+ id.extras = extras;
+
+ // send the broacast saying that this appWidgetId has been deleted
+ Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_EXTRAS_CHANGED);
+ intent.setComponent(p.info.provider);
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId);
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_EXTRAS, extras);
+ mContext.sendBroadcast(intent, mUserId);
+ }
+ }
+
+ public Bundle getAppWidgetExtras(int appWidgetId) {
+ synchronized (mAppWidgetIds) {
+ ensureStateLoadedLocked();
+ AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
+ if (id != null && id.extras != null) {
+ return id.extras;
+ } else {
+ return Bundle.EMPTY;
+ }
+ }
+ }
+
public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views) {
if (appWidgetIds == null) {
return;
diff --git a/services/java/com/android/server/ClipboardService.java b/services/java/com/android/server/ClipboardService.java
index 2e2a278..8a6a550 100644
--- a/services/java/com/android/server/ClipboardService.java
+++ b/services/java/com/android/server/ClipboardService.java
@@ -18,12 +18,14 @@
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
+import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.IClipboard;
import android.content.IOnPrimaryClipChangedListener;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -37,6 +39,7 @@
import android.os.UserId;
import android.util.Pair;
import android.util.Slog;
+import android.util.SparseArray;
import java.util.HashSet;
@@ -44,18 +47,31 @@
* Implementation of the clipboard for copy and paste.
*/
public class ClipboardService extends IClipboard.Stub {
+
+ private static final String TAG = "ClipboardService";
+
private final Context mContext;
private final IActivityManager mAm;
private final PackageManager mPm;
private final IBinder mPermissionOwner;
- private final RemoteCallbackList<IOnPrimaryClipChangedListener> mPrimaryClipListeners
- = new RemoteCallbackList<IOnPrimaryClipChangedListener>();
+ private class PerUserClipboard {
+ final int userId;
- private ClipData mPrimaryClip;
+ final RemoteCallbackList<IOnPrimaryClipChangedListener> primaryClipListeners
+ = new RemoteCallbackList<IOnPrimaryClipChangedListener>();
- private final HashSet<String> mActivePermissionOwners
- = new HashSet<String>();
+ ClipData primaryClip;
+
+ final HashSet<String> activePermissionOwners
+ = new HashSet<String>();
+
+ PerUserClipboard(int userId) {
+ this.userId = userId;
+ }
+ }
+
+ private SparseArray<PerUserClipboard> mClipboards = new SparseArray<PerUserClipboard>();
/**
* Instantiates the clipboard.
@@ -71,6 +87,19 @@
Slog.w("clipboard", "AM dead", e);
}
mPermissionOwner = permOwner;
+
+ // Remove the clipboard if a user is removed
+ IntentFilter userFilter = new IntentFilter();
+ userFilter.addAction(Intent.ACTION_USER_REMOVED);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ removeClipboard(intent.getIntExtra(Intent.EXTRA_USERID, 0));
+ }
+ }
+ }, userFilter);
}
@Override
@@ -85,6 +114,28 @@
}
+ private PerUserClipboard getClipboard() {
+ return getClipboard(UserId.getCallingUserId());
+ }
+
+ private PerUserClipboard getClipboard(int userId) {
+ synchronized (mClipboards) {
+ Slog.i(TAG, "Got clipboard for user=" + userId);
+ PerUserClipboard puc = mClipboards.get(userId);
+ if (puc == null) {
+ puc = new PerUserClipboard(userId);
+ mClipboards.put(userId, puc);
+ }
+ return puc;
+ }
+ }
+
+ private void removeClipboard(int userId) {
+ synchronized (mClipboards) {
+ mClipboards.remove(userId);
+ }
+ }
+
public void setPrimaryClip(ClipData clip) {
synchronized (this) {
if (clip != null && clip.getItemCount() <= 0) {
@@ -92,56 +143,59 @@
}
checkDataOwnerLocked(clip, Binder.getCallingUid());
clearActiveOwnersLocked();
- mPrimaryClip = clip;
- final int n = mPrimaryClipListeners.beginBroadcast();
+ PerUserClipboard clipboard = getClipboard();
+ clipboard.primaryClip = clip;
+ final int n = clipboard.primaryClipListeners.beginBroadcast();
for (int i = 0; i < n; i++) {
try {
- mPrimaryClipListeners.getBroadcastItem(i).dispatchPrimaryClipChanged();
+ clipboard.primaryClipListeners.getBroadcastItem(i).dispatchPrimaryClipChanged();
} catch (RemoteException e) {
// The RemoteCallbackList will take care of removing
// the dead object for us.
}
}
- mPrimaryClipListeners.finishBroadcast();
+ clipboard.primaryClipListeners.finishBroadcast();
}
}
public ClipData getPrimaryClip(String pkg) {
synchronized (this) {
addActiveOwnerLocked(Binder.getCallingUid(), pkg);
- return mPrimaryClip;
+ return getClipboard().primaryClip;
}
}
public ClipDescription getPrimaryClipDescription() {
synchronized (this) {
- return mPrimaryClip != null ? mPrimaryClip.getDescription() : null;
+ PerUserClipboard clipboard = getClipboard();
+ return clipboard.primaryClip != null ? clipboard.primaryClip.getDescription() : null;
}
}
public boolean hasPrimaryClip() {
synchronized (this) {
- return mPrimaryClip != null;
+ return getClipboard().primaryClip != null;
}
}
public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) {
synchronized (this) {
- mPrimaryClipListeners.register(listener);
+ getClipboard().primaryClipListeners.register(listener);
}
}
public void removePrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) {
synchronized (this) {
- mPrimaryClipListeners.unregister(listener);
+ getClipboard().primaryClipListeners.unregister(listener);
}
}
public boolean hasClipboardText() {
synchronized (this) {
- if (mPrimaryClip != null) {
- CharSequence text = mPrimaryClip.getItemAt(0).getText();
+ PerUserClipboard clipboard = getClipboard();
+ if (clipboard.primaryClip != null) {
+ CharSequence text = clipboard.primaryClip.getItemAt(0).getText();
return text != null && text.length() > 0;
}
return false;
@@ -153,7 +207,6 @@
return;
}
long ident = Binder.clearCallingIdentity();
- boolean allowed = false;
try {
// This will throw SecurityException for us.
mAm.checkGrantUriPermission(uid, null, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
@@ -212,12 +265,13 @@
} catch (NameNotFoundException e) {
throw new IllegalArgumentException("Unknown package " + pkg, e);
}
- if (mPrimaryClip != null && !mActivePermissionOwners.contains(pkg)) {
- final int N = mPrimaryClip.getItemCount();
+ PerUserClipboard clipboard = getClipboard();
+ if (clipboard.primaryClip != null && !clipboard.activePermissionOwners.contains(pkg)) {
+ final int N = clipboard.primaryClip.getItemCount();
for (int i=0; i<N; i++) {
- grantItemLocked(mPrimaryClip.getItemAt(i), pkg);
+ grantItemLocked(clipboard.primaryClip.getItemAt(i), pkg);
}
- mActivePermissionOwners.add(pkg);
+ clipboard.activePermissionOwners.add(pkg);
}
}
@@ -244,13 +298,14 @@
}
private final void clearActiveOwnersLocked() {
- mActivePermissionOwners.clear();
- if (mPrimaryClip == null) {
+ PerUserClipboard clipboard = getClipboard();
+ clipboard.activePermissionOwners.clear();
+ if (clipboard.primaryClip == null) {
return;
}
- final int N = mPrimaryClip.getItemCount();
+ final int N = clipboard.primaryClip.getItemCount();
for (int i=0; i<N; i++) {
- revokeItemLocked(mPrimaryClip.getItemAt(i));
+ revokeItemLocked(clipboard.primaryClip.getItemAt(i));
}
}
}
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 359074a..722e312b 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -865,27 +865,39 @@
@Override
public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
enforceAccessPermission();
- final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
- if (state != null) {
- try {
- return mPolicyManager.getNetworkQuotaInfo(state);
- } catch (RemoteException e) {
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
+ if (state != null) {
+ try {
+ return mPolicyManager.getNetworkQuotaInfo(state);
+ } catch (RemoteException e) {
+ }
}
+ return null;
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
- return null;
}
@Override
public boolean isActiveNetworkMetered() {
enforceAccessPermission();
- final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
- if (state != null) {
- try {
- return mPolicyManager.isNetworkMetered(state);
- } catch (RemoteException e) {
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
+ if (state != null) {
+ try {
+ return mPolicyManager.isNetworkMetered(state);
+ } catch (RemoteException e) {
+ }
}
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
- return false;
}
public boolean setRadios(boolean turnOn) {
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index d8e3d59..eb33060 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -451,7 +451,7 @@
public DevicePolicyManagerService(Context context) {
mContext = context;
mMonitor = new MyPackageMonitor();
- mMonitor.register(context, true);
+ mMonitor.register(context, null, true);
mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE))
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM");
IntentFilter filter = new IntentFilter();
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index b943c09..0ed5189 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -26,6 +26,7 @@
import android.content.pm.IPackageManager;
import android.os.Binder;
import android.os.Environment;
+import android.os.FileObserver;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
@@ -91,6 +92,7 @@
private Intent mStorageFullIntent;
private Intent mStorageNotFullIntent;
private CachePackageDataObserver mClearCacheObserver;
+ private final CacheFileDeletedObserver mCacheFileDeletedObserver;
private static final int _TRUE = 1;
private static final int _FALSE = 0;
private long mMemLowThreshold;
@@ -324,6 +326,9 @@
mMemLowThreshold = getMemThreshold();
mMemFullThreshold = getMemFullThreshold();
checkMemory(true);
+
+ mCacheFileDeletedObserver = new CacheFileDeletedObserver();
+ mCacheFileDeletedObserver.startWatching();
}
@@ -419,4 +424,15 @@
public boolean isMemoryLow() {
return mLowMemFlag;
}
+
+ public static class CacheFileDeletedObserver extends FileObserver {
+ public CacheFileDeletedObserver() {
+ super(Environment.getDownloadCacheDirectory().getAbsolutePath(), FileObserver.DELETE);
+ }
+
+ @Override
+ public void onEvent(int event, String path) {
+ EventLogTags.writeCacheFileDeleted(path);
+ }
+ }
}
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index 0bcec2e..249513f 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -36,7 +36,7 @@
# ---------------------------
-# DeviceStorageMonitoryService.java
+# DeviceStorageMonitorService.java
# ---------------------------
# The disk space free on the /data partition, in bytes
2744 free_storage_changed (data|2|2)
@@ -44,6 +44,8 @@
2745 low_storage (data|2|2)
# disk space free on the /data, /system, and /cache partitions in bytes
2746 free_storage_left (data|2|2),(system|2|2),(cache|2|2)
+# file on cache partition was deleted
+2748 cache_file_deleted (path|3)
# ---------------------------
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index ca7241c..43c2292 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -118,7 +118,7 @@
public class InputMethodManagerService extends IInputMethodManager.Stub
implements ServiceConnection, Handler.Callback {
static final boolean DEBUG = false;
- static final String TAG = "InputManagerService";
+ static final String TAG = "InputMethodManagerService";
static final int MSG_SHOW_IM_PICKER = 1;
static final int MSG_SHOW_IM_SUBTYPE_PICKER = 2;
@@ -594,7 +594,7 @@
}
mImListManager = new InputMethodAndSubtypeListManager(context, this);
- (new MyPackageMonitor()).register(mContext, true);
+ (new MyPackageMonitor()).register(mContext, null, true);
IntentFilter screenOnOffFilt = new IntentFilter();
screenOnOffFilt.addAction(Intent.ACTION_SCREEN_ON);
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 8cb9d99b..d651111 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -511,7 +511,7 @@
com.android.internal.R.string.config_networkLocationProvider);
mGeocodeProviderPackageName = resources.getString(
com.android.internal.R.string.config_geocodeProvider);
- mPackageMonitor.register(context, true);
+ mPackageMonitor.register(context, null, true);
if (LOCAL_LOGV) {
Slog.v(TAG, "Constructed LocationManager Service");
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index b22be76..1ba7e79 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -16,7 +16,9 @@
package com.android.server;
+import com.android.internal.os.AtomicFile;
import com.android.internal.statusbar.StatusBarNotification;
+import com.android.internal.util.FastXmlSerializer;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
@@ -37,9 +39,10 @@
import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.AudioManager;
+import android.net.NetworkPolicy;
+import android.net.NetworkTemplate;
import android.net.Uri;
import android.os.Binder;
-import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -53,14 +56,36 @@
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
+import android.util.Xml;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
+import java.io.File;
import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import static android.net.NetworkPolicyManager.POLICY_NONE;
+import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeBooleanAttribute;
+import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeIntAttribute;
+import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeLongAttribute;
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
+
/** {@hide} */
public class NotificationManagerService extends INotificationManager.Stub
@@ -81,6 +106,13 @@
private static final int DEFAULT_STREAM_TYPE = AudioManager.STREAM_NOTIFICATION;
private static final boolean SCORE_ONGOING_HIGHER = false;
+ private static final int JUNK_SCORE = -1000;
+ private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10;
+ private static final int SCORE_DISPLAY_THRESHOLD = Notification.PRIORITY_MIN * NOTIFICATION_PRIORITY_MULTIPLIER;
+
+ private static final boolean ENABLE_BLOCKED_NOTIFICATIONS = true;
+ private static final boolean ENABLE_BLOCKED_TOASTS = true;
+
final Context mContext;
final IActivityManager mAm;
final IBinder mForegroundToken = new Binder();
@@ -115,6 +147,144 @@
private ArrayList<NotificationRecord> mLights = new ArrayList<NotificationRecord>();
private NotificationRecord mLedNotification;
+ // Notification control database. For now just contains disabled packages.
+ private AtomicFile mPolicyFile;
+ private HashSet<String> mBlockedPackages = new HashSet<String>();
+
+ private static final int DB_VERSION = 1;
+
+ private static final String TAG_BODY = "notification-policy";
+ private static final String ATTR_VERSION = "version";
+
+ private static final String TAG_BLOCKED_PKGS = "blocked-packages";
+ private static final String TAG_PACKAGE = "package";
+ private static final String ATTR_NAME = "name";
+
+ private void loadBlockDb() {
+ synchronized(mBlockedPackages) {
+ if (mPolicyFile == null) {
+ File dir = new File("/data/system");
+ mPolicyFile = new AtomicFile(new File(dir, "notification_policy.xml"));
+
+ mBlockedPackages.clear();
+
+ FileInputStream infile = null;
+ try {
+ infile = mPolicyFile.openRead();
+ final XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(infile, null);
+
+ int type;
+ String tag;
+ int version = DB_VERSION;
+ while ((type = parser.next()) != END_DOCUMENT) {
+ tag = parser.getName();
+ if (type == START_TAG) {
+ if (TAG_BODY.equals(tag)) {
+ version = Integer.parseInt(parser.getAttributeValue(null, ATTR_VERSION));
+ } else if (TAG_BLOCKED_PKGS.equals(tag)) {
+ while ((type = parser.next()) != END_DOCUMENT) {
+ tag = parser.getName();
+ if (TAG_PACKAGE.equals(tag)) {
+ mBlockedPackages.add(parser.getAttributeValue(null, ATTR_NAME));
+ } else if (TAG_BLOCKED_PKGS.equals(tag) && type == END_TAG) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // No data yet
+ } catch (IOException e) {
+ Log.wtf(TAG, "Unable to read blocked notifications database", e);
+ } catch (NumberFormatException e) {
+ Log.wtf(TAG, "Unable to parse blocked notifications database", e);
+ } catch (XmlPullParserException e) {
+ Log.wtf(TAG, "Unable to parse blocked notifications database", e);
+ } finally {
+ IoUtils.closeQuietly(infile);
+ }
+ }
+ }
+ }
+
+ private void writeBlockDb() {
+ synchronized(mBlockedPackages) {
+ FileOutputStream outfile = null;
+ try {
+ outfile = mPolicyFile.startWrite();
+
+ XmlSerializer out = new FastXmlSerializer();
+ out.setOutput(outfile, "utf-8");
+
+ out.startDocument(null, true);
+
+ out.startTag(null, TAG_BODY); {
+ out.attribute(null, ATTR_VERSION, String.valueOf(DB_VERSION));
+ out.startTag(null, TAG_BLOCKED_PKGS); {
+ // write all known network policies
+ for (String pkg : mBlockedPackages) {
+ out.startTag(null, TAG_PACKAGE); {
+ out.attribute(null, ATTR_NAME, pkg);
+ } out.endTag(null, TAG_PACKAGE);
+ }
+ } out.endTag(null, TAG_BLOCKED_PKGS);
+ } out.endTag(null, TAG_BODY);
+
+ out.endDocument();
+
+ mPolicyFile.finishWrite(outfile);
+ } catch (IOException e) {
+ if (outfile != null) {
+ mPolicyFile.failWrite(outfile);
+ }
+ }
+ }
+ }
+
+ public boolean areNotificationsEnabledForPackage(String pkg) {
+ checkCallerIsSystem();
+ return areNotificationsEnabledForPackageInt(pkg);
+ }
+
+ // Unchecked. Not exposed via Binder, but can be called in the course of enqueue*().
+ private boolean areNotificationsEnabledForPackageInt(String pkg) {
+ final boolean enabled = !mBlockedPackages.contains(pkg);
+ if (DBG) {
+ Slog.v(TAG, "notifications are " + (enabled?"en":"dis") + "abled for " + pkg);
+ }
+ return enabled;
+ }
+
+ public void setNotificationsEnabledForPackage(String pkg, boolean enabled) {
+ checkCallerIsSystem();
+ if (DBG) {
+ Slog.v(TAG, (enabled?"en":"dis") + "abling notifications for " + pkg);
+ }
+ if (enabled) {
+ mBlockedPackages.remove(pkg);
+ } else {
+ mBlockedPackages.add(pkg);
+
+ // Now, cancel any outstanding notifications that are part of a just-disabled app
+ if (ENABLE_BLOCKED_NOTIFICATIONS) {
+ synchronized (mNotificationList) {
+ final int N = mNotificationList.size();
+ for (int i=0; i<N; i++) {
+ final NotificationRecord r = mNotificationList.get(i);
+ if (r.pkg.equals(pkg)) {
+ cancelNotificationLocked(r, false);
+ }
+ }
+ }
+ }
+ // Don't bother canceling toasts, they'll go away soon enough.
+ }
+ writeBlockDb();
+ }
+
+
private static String idDebugString(Context baseContext, String packageName, int id) {
Context c = null;
@@ -405,6 +575,8 @@
mToastQueue = new ArrayList<ToastRecord>();
mHandler = new WorkerHandler();
+ loadBlockDb();
+
mStatusBar = statusBar;
statusBar.setNotificationCallbacks(mNotificationCallbacks);
@@ -465,6 +637,13 @@
return ;
}
+ final boolean isSystemToast = ("android".equals(pkg));
+
+ if (ENABLE_BLOCKED_TOASTS && !isSystemToast && !areNotificationsEnabledForPackageInt(pkg)) {
+ Slog.e(TAG, "Suppressing toast from package " + pkg + " by user request.");
+ return;
+ }
+
synchronized (mToastQueue) {
int callingPid = Binder.getCallingPid();
long callingId = Binder.clearCallingIdentity();
@@ -479,7 +658,7 @@
} else {
// Limit the number of toasts that any given package except the android
// package can enqueue. Prevents DOS attacks and deals with leaks.
- if (!"android".equals(pkg)) {
+ if (!isSystemToast) {
int count = 0;
final int N = mToastQueue.size();
for (int i=0; i<N; i++) {
@@ -675,11 +854,15 @@
public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid,
String tag, int id, Notification notification, int[] idOut)
{
- checkIncomingCall(pkg);
+ if (DBG) {
+ Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
+ }
+ checkCallerIsSystemOrSameApp(pkg);
+ final boolean isSystemNotification = ("android".equals(pkg));
// Limit the number of notifications that any given package except the android
// package can enqueue. Prevents DOS attacks and deals with leaks.
- if (!"android".equals(pkg)) {
+ if (!isSystemNotification) {
synchronized (mNotificationList) {
int count = 0;
final int N = mNotificationList.size();
@@ -717,7 +900,7 @@
}
// === Scoring ===
-
+
// 0. Sanitize inputs
notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN, Notification.PRIORITY_MAX);
// Migrate notification flags to scores
@@ -726,19 +909,27 @@
} else if (SCORE_ONGOING_HIGHER && 0 != (notification.flags & Notification.FLAG_ONGOING_EVENT)) {
if (notification.priority < Notification.PRIORITY_HIGH) notification.priority = Notification.PRIORITY_HIGH;
}
-
+
// 1. initial score: buckets of 10, around the app
- int score = notification.priority * 10; //[-20..20]
+ int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER; //[-20..20]
- // 2. Consult oracles (external heuristics)
- // TODO(dsandler): oracles
+ // 2. Consult external heuristics (TBD)
- // 3. Apply local heuristics & overrides
+ // 3. Apply local rules
// blocked apps
- // TODO(dsandler): add block db
- if (pkg.startsWith("com.test.spammer.")) {
- score = -1000;
+ if (ENABLE_BLOCKED_NOTIFICATIONS && !isSystemNotification && !areNotificationsEnabledForPackageInt(pkg)) {
+ score = JUNK_SCORE;
+ Slog.e(TAG, "Suppressing notification from package " + pkg + " by user request.");
+ }
+
+ if (DBG) {
+ Slog.v(TAG, "Assigned score=" + score + " to " + notification);
+ }
+
+ if (score < SCORE_DISPLAY_THRESHOLD) {
+ // Notification will be blocked because the score is too low.
+ return;
}
synchronized (mNotificationList) {
@@ -1030,7 +1221,7 @@
}
public void cancelNotificationWithTag(String pkg, String tag, int id) {
- checkIncomingCall(pkg);
+ checkCallerIsSystemOrSameApp(pkg);
// Don't allow client applications to cancel foreground service notis.
cancelNotification(pkg, tag, id, 0,
Binder.getCallingUid() == Process.SYSTEM_UID
@@ -1038,14 +1229,22 @@
}
public void cancelAllNotifications(String pkg) {
- checkIncomingCall(pkg);
+ checkCallerIsSystemOrSameApp(pkg);
// Calling from user space, don't allow the canceling of actively
// running foreground services.
cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true);
}
- void checkIncomingCall(String pkg) {
+ void checkCallerIsSystem() {
+ int uid = Binder.getCallingUid();
+ if (uid == Process.SYSTEM_UID || uid == 0) {
+ return;
+ }
+ throw new SecurityException("Disallowed call for uid " + uid);
+ }
+
+ void checkCallerIsSystemOrSameApp(String pkg) {
int uid = Binder.getCallingUid();
if (uid == Process.SYSTEM_UID || uid == 0) {
return;
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index 8014e27..f33bf8b 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -17,6 +17,8 @@
package com.android.server;
import android.content.Context;
+import android.content.ContentResolver;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.nsd.DnsSdServiceInfo;
import android.net.nsd.DnsSdTxtRecord;
@@ -28,6 +30,7 @@
import android.os.Message;
import android.os.Messenger;
import android.os.IBinder;
+import android.provider.Settings;
import android.util.Slog;
import java.io.FileDescriptor;
@@ -41,6 +44,9 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.Protocol;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
import com.android.server.am.BatteryStatsService;
import com.android.server.NativeDaemonConnector.Command;
import com.android.internal.R;
@@ -58,6 +64,8 @@
private static final boolean DBG = true;
private Context mContext;
+ private ContentResolver mContentResolver;
+ private NsdStateMachine mNsdStateMachine;
/**
* Clients receiving asynchronous messages
@@ -69,189 +77,342 @@
private int INVALID_ID = 0;
private int mUniqueId = 1;
- /**
- * Handles client(app) connections
- */
- private class AsyncServiceHandler extends Handler {
+ private static final int BASE = Protocol.BASE_NSD_MANAGER;
+ private static final int CMD_TO_STRING_COUNT = NsdManager.STOP_RESOLVE - BASE + 1;
+ private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
- AsyncServiceHandler(android.os.Looper looper) {
- super(looper);
- }
+ static {
+ sCmdToString[NsdManager.DISCOVER_SERVICES - BASE] = "DISCOVER";
+ sCmdToString[NsdManager.STOP_DISCOVERY - BASE] = "STOP-DISCOVER";
+ sCmdToString[NsdManager.REGISTER_SERVICE - BASE] = "REGISTER";
+ sCmdToString[NsdManager.UNREGISTER_SERVICE - BASE] = "UNREGISTER";
+ sCmdToString[NsdManager.RESOLVE_SERVICE - BASE] = "RESOLVE";
+ sCmdToString[NsdManager.STOP_RESOLVE - BASE] = "STOP-RESOLVE";
+ }
- @Override
- public void handleMessage(Message msg) {
- ClientInfo clientInfo;
- DnsSdServiceInfo servInfo;
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- AsyncChannel c = (AsyncChannel) msg.obj;
- if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
- c.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED);
- ClientInfo cInfo = new ClientInfo(c, msg.replyTo);
- if (mClients.size() == 0) {
- startMDnsDaemon();
- }
- mClients.put(msg.replyTo, cInfo);
- } else {
- Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
- }
- break;
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
- Slog.e(TAG, "Send failed, client connection lost");
- } else {
- if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
- }
- mClients.remove(msg.replyTo);
- if (mClients.size() == 0) {
- stopMDnsDaemon();
- }
- break;
- case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
- AsyncChannel ac = new AsyncChannel();
- ac.connect(mContext, this, msg.replyTo);
- break;
- case NsdManager.DISCOVER_SERVICES:
- if (DBG) Slog.d(TAG, "Discover services");
- servInfo = (DnsSdServiceInfo) msg.obj;
- clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mDiscoveryId != INVALID_ID) {
- //discovery already in progress
- if (DBG) Slog.d(TAG, "discovery in progress");
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.ALREADY_ACTIVE);
- break;
- }
- clientInfo.mDiscoveryId = getUniqueId();
- if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
- } else {
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.ERROR);
- clientInfo.mDiscoveryId = INVALID_ID;
- }
- break;
- case NsdManager.STOP_DISCOVERY:
- if (DBG) Slog.d(TAG, "Stop service discovery");
- clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mDiscoveryId == INVALID_ID) {
- //already stopped
- if (DBG) Slog.d(TAG, "discovery already stopped");
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
- NsdManager.ALREADY_ACTIVE);
- break;
- }
- if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
- clientInfo.mDiscoveryId = INVALID_ID;
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
- } else {
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
- NsdManager.ERROR);
- }
- break;
- case NsdManager.REGISTER_SERVICE:
- if (DBG) Slog.d(TAG, "Register service");
- clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
- if (DBG) Slog.d(TAG, "register service exceeds limit");
- mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.MAX_REGS_REACHED);
- }
-
- int id = getUniqueId();
- if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
- clientInfo.mRegisteredIds.add(id);
- } else {
- mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
- }
- break;
- case NsdManager.UNREGISTER_SERVICE:
- if (DBG) Slog.d(TAG, "unregister service");
- clientInfo = mClients.get(msg.replyTo);
- int regId = msg.arg1;
- if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
- unregisterService(regId)) {
- mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
- } else {
- mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
- }
- break;
- case NsdManager.UPDATE_SERVICE:
- if (DBG) Slog.d(TAG, "Update service");
- //TODO: implement
- mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
- break;
- case NsdManager.RESOLVE_SERVICE:
- if (DBG) Slog.d(TAG, "Resolve service");
- servInfo = (DnsSdServiceInfo) msg.obj;
- clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mResolveId != INVALID_ID) {
- //first cancel existing resolve
- stopResolveService(clientInfo.mResolveId);
- }
-
- clientInfo.mResolveId = getUniqueId();
- if (!resolveService(clientInfo.mResolveId, servInfo)) {
- mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
- NsdManager.ERROR);
- clientInfo.mResolveId = INVALID_ID;
- }
- break;
- case NsdManager.STOP_RESOLVE:
- if (DBG) Slog.d(TAG, "Stop resolve");
- clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mResolveId == INVALID_ID) {
- //already stopped
- if (DBG) Slog.d(TAG, "resolve already stopped");
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
- NsdManager.ALREADY_ACTIVE);
- break;
- }
- if (stopResolveService(clientInfo.mResolveId)) {
- clientInfo.mResolveId = INVALID_ID;
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
- } else {
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
- NsdManager.ERROR);
- }
- break;
- default:
- Slog.d(TAG, "NsdServicehandler.handleMessage ignoring msg=" + msg);
- break;
- }
+ private static String cmdToString(int cmd) {
+ cmd -= BASE;
+ if ((cmd >= 0) && (cmd < sCmdToString.length)) {
+ return sCmdToString[cmd];
+ } else {
+ return null;
}
}
- private AsyncServiceHandler mAsyncServiceHandler;
+
+ private class NsdStateMachine extends StateMachine {
+
+ private DefaultState mDefaultState = new DefaultState();
+ private DisabledState mDisabledState = new DisabledState();
+ private EnabledState mEnabledState = new EnabledState();
+
+ @Override
+ protected String getMessageInfo(Message msg) {
+ return cmdToString(msg.what);
+ }
+
+ NsdStateMachine(String name) {
+ super(name);
+ addState(mDefaultState);
+ addState(mDisabledState, mDefaultState);
+ addState(mEnabledState, mDefaultState);
+ if (isNsdEnabled()) {
+ setInitialState(mEnabledState);
+ } else {
+ setInitialState(mDisabledState);
+ }
+ setProcessedMessagesSize(25);
+ }
+
+ class DefaultState extends State {
+ @Override
+ public boolean processMessage(Message msg) {
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+ AsyncChannel c = (AsyncChannel) msg.obj;
+ if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
+ c.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED);
+ ClientInfo cInfo = new ClientInfo(c, msg.replyTo);
+ mClients.put(msg.replyTo, cInfo);
+ } else {
+ Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
+ }
+ break;
+ case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+ if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
+ Slog.e(TAG, "Send failed, client connection lost");
+ } else {
+ if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
+ }
+ mClients.remove(msg.replyTo);
+ break;
+ case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
+ AsyncChannel ac = new AsyncChannel();
+ ac.connect(mContext, getHandler(), msg.replyTo);
+ break;
+ case NsdManager.DISCOVER_SERVICES:
+ mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.BUSY);
+ break;
+ case NsdManager.STOP_DISCOVERY:
+ mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+ NsdManager.ERROR);
+ break;
+ case NsdManager.REGISTER_SERVICE:
+ mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.ERROR);
+ break;
+ case NsdManager.UNREGISTER_SERVICE:
+ mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+ NsdManager.ERROR);
+ break;
+ case NsdManager.RESOLVE_SERVICE:
+ mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.ERROR);
+ break;
+ case NsdManager.STOP_RESOLVE:
+ mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
+ NsdManager.ERROR);
+ break;
+ default:
+ Slog.e(TAG, "Unhandled " + msg);
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+ }
+
+ class DisabledState extends State {
+ @Override
+ public void enter() {
+ sendNsdStateChangeBroadcast(false);
+ }
+
+ @Override
+ public boolean processMessage(Message msg) {
+ switch (msg.what) {
+ case NsdManager.ENABLE:
+ transitionTo(mEnabledState);
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+ }
+
+ class EnabledState extends State {
+ @Override
+ public void enter() {
+ sendNsdStateChangeBroadcast(true);
+ if (mClients.size() > 0) {
+ startMDnsDaemon();
+ }
+ }
+
+ @Override
+ public void exit() {
+ if (mClients.size() > 0) {
+ stopMDnsDaemon();
+ }
+ }
+
+ @Override
+ public boolean processMessage(Message msg) {
+ ClientInfo clientInfo;
+ DnsSdServiceInfo servInfo;
+ boolean result = HANDLED;
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ //First client
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL &&
+ mClients.size() == 0) {
+ startMDnsDaemon();
+ }
+ result = NOT_HANDLED;
+ break;
+ case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+ //Last client
+ if (mClients.size() == 1) {
+ stopMDnsDaemon();
+ }
+ result = NOT_HANDLED;
+ break;
+ case NsdManager.DISABLE:
+ //TODO: cleanup clients
+ transitionTo(mDisabledState);
+ break;
+ case NsdManager.DISCOVER_SERVICES:
+ if (DBG) Slog.d(TAG, "Discover services");
+ servInfo = (DnsSdServiceInfo) msg.obj;
+ clientInfo = mClients.get(msg.replyTo);
+ if (clientInfo.mDiscoveryId != INVALID_ID) {
+ //discovery already in progress
+ if (DBG) Slog.d(TAG, "discovery in progress");
+ mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.ALREADY_ACTIVE);
+ break;
+ }
+ clientInfo.mDiscoveryId = getUniqueId();
+ if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
+ mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
+ } else {
+ mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.ERROR);
+ clientInfo.mDiscoveryId = INVALID_ID;
+ }
+ break;
+ case NsdManager.STOP_DISCOVERY:
+ if (DBG) Slog.d(TAG, "Stop service discovery");
+ clientInfo = mClients.get(msg.replyTo);
+ if (clientInfo.mDiscoveryId == INVALID_ID) {
+ //already stopped
+ if (DBG) Slog.d(TAG, "discovery already stopped");
+ mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+ NsdManager.ALREADY_ACTIVE);
+ break;
+ }
+ if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
+ clientInfo.mDiscoveryId = INVALID_ID;
+ mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
+ } else {
+ mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+ NsdManager.ERROR);
+ }
+ break;
+ case NsdManager.REGISTER_SERVICE:
+ if (DBG) Slog.d(TAG, "Register service");
+ clientInfo = mClients.get(msg.replyTo);
+ if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
+ if (DBG) Slog.d(TAG, "register service exceeds limit");
+ mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.MAX_REGS_REACHED);
+ }
+
+ int id = getUniqueId();
+ if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
+ clientInfo.mRegisteredIds.add(id);
+ } else {
+ mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.ERROR);
+ }
+ break;
+ case NsdManager.UNREGISTER_SERVICE:
+ if (DBG) Slog.d(TAG, "unregister service");
+ clientInfo = mClients.get(msg.replyTo);
+ int regId = msg.arg1;
+ if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
+ unregisterService(regId)) {
+ mReplyChannel.replyToMessage(msg,
+ NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
+ } else {
+ mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+ NsdManager.ERROR);
+ }
+ break;
+ case NsdManager.UPDATE_SERVICE:
+ if (DBG) Slog.d(TAG, "Update service");
+ //TODO: implement
+ mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
+ break;
+ case NsdManager.RESOLVE_SERVICE:
+ if (DBG) Slog.d(TAG, "Resolve service");
+ servInfo = (DnsSdServiceInfo) msg.obj;
+ clientInfo = mClients.get(msg.replyTo);
+ if (clientInfo.mResolveId != INVALID_ID) {
+ //first cancel existing resolve
+ stopResolveService(clientInfo.mResolveId);
+ }
+
+ clientInfo.mResolveId = getUniqueId();
+ if (!resolveService(clientInfo.mResolveId, servInfo)) {
+ mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.ERROR);
+ clientInfo.mResolveId = INVALID_ID;
+ }
+ break;
+ case NsdManager.STOP_RESOLVE:
+ if (DBG) Slog.d(TAG, "Stop resolve");
+ clientInfo = mClients.get(msg.replyTo);
+ if (clientInfo.mResolveId == INVALID_ID) {
+ //already stopped
+ if (DBG) Slog.d(TAG, "resolve already stopped");
+ mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
+ NsdManager.ALREADY_ACTIVE);
+ break;
+ }
+ if (stopResolveService(clientInfo.mResolveId)) {
+ clientInfo.mResolveId = INVALID_ID;
+ mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
+ } else {
+ mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
+ NsdManager.ERROR);
+ }
+ break;
+ default:
+ result = NOT_HANDLED;
+ break;
+ }
+ return result;
+ }
+ }
+ }
private NativeDaemonConnector mNativeConnector;
private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1);
private NsdService(Context context) {
mContext = context;
-
- HandlerThread nsdThread = new HandlerThread("NsdService");
- nsdThread.start();
- mAsyncServiceHandler = new AsyncServiceHandler(nsdThread.getLooper());
+ mContentResolver = context.getContentResolver();
mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10,
MDNS_TAG, 25);
+
+ mNsdStateMachine = new NsdStateMachine(TAG);
+ mNsdStateMachine.start();
+
Thread th = new Thread(mNativeConnector, MDNS_TAG);
th.start();
}
public static NsdService create(Context context) throws InterruptedException {
NsdService service = new NsdService(context);
- /* service.mNativeDaemonConnected.await(); */
+ service.mNativeDaemonConnected.await();
return service;
}
public Messenger getMessenger() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
"NsdService");
- return new Messenger(mAsyncServiceHandler);
+ return new Messenger(mNsdStateMachine.getHandler());
+ }
+
+ public void setEnabled(boolean enable) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL,
+ "NsdService");
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.NSD_ON, enable ? 1 : 0);
+ if (enable) {
+ mNsdStateMachine.sendMessage(NsdManager.ENABLE);
+ } else {
+ mNsdStateMachine.sendMessage(NsdManager.DISABLE);
+ }
+ }
+
+ private void sendNsdStateChangeBroadcast(boolean enabled) {
+ final Intent intent = new Intent(NsdManager.ACTION_NSD_STATE_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ if (enabled) {
+ intent.putExtra(NsdManager.EXTRA_NSD_STATE, NsdManager.NSD_STATE_ENABLED);
+ } else {
+ intent.putExtra(NsdManager.EXTRA_NSD_STATE, NsdManager.NSD_STATE_DISABLED);
+ }
+ mContext.sendStickyBroadcast(intent);
+ }
+
+ private boolean isNsdEnabled() {
+ boolean ret = Settings.Secure.getInt(mContentResolver, Settings.Secure.NSD_ON, 1) == 1;
+ if (DBG) Slog.d(TAG, "Network service discovery enabled " + ret);
+ return ret;
}
private int getUniqueId() {
@@ -522,7 +683,7 @@
}
@Override
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump ServiceDiscoverService from from pid="
@@ -531,7 +692,12 @@
return;
}
- pw.println("Internal state:");
+ for (ClientInfo client : mClients.values()) {
+ pw.println("Client Info");
+ pw.println(client);
+ }
+
+ mNsdStateMachine.dump(fd, pw, args);
}
private ClientInfo getClientByDiscovery(int discoveryId) {
@@ -579,5 +745,19 @@
mDiscoveryId = mResolveId = INVALID_ID;
if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m);
}
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("mChannel ").append(mChannel).append("\n");
+ sb.append("mMessenger ").append(mMessenger).append("\n");
+ sb.append("mDiscoveryId ").append(mDiscoveryId).append("\n");
+ sb.append("mResolveId ").append(mResolveId).append("\n");
+ sb.append("mResolvedService ").append(mResolvedService).append("\n");
+ for(int regId : mRegisteredIds) {
+ sb.append("regId ").append(regId).append("\n");
+ }
+ return sb.toString();
+ }
}
}
diff --git a/services/java/com/android/server/RecognitionManagerService.java b/services/java/com/android/server/RecognitionManagerService.java
index 85224d8..3567cfc 100644
--- a/services/java/com/android/server/RecognitionManagerService.java
+++ b/services/java/com/android/server/RecognitionManagerService.java
@@ -65,7 +65,7 @@
RecognitionManagerService(Context context) {
mContext = context;
mMonitor = new MyPackageMonitor();
- mMonitor.register(context, true);
+ mMonitor.register(context, null, true);
}
public void systemReady() {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 75dcf8c..d68a1ef 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -51,6 +51,7 @@
import com.android.internal.widget.LockSettingsService;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.am.ActivityManagerService;
+import com.android.server.input.InputManagerService;
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
import com.android.server.pm.PackageManagerService;
@@ -137,6 +138,7 @@
ThrottleService throttle = null;
NetworkTimeUpdateService networkTimeUpdater = null;
CommonTimeManagementService commonTimeMgmtService = null;
+ InputManagerService inputManager = null;
// Critical services...
try {
@@ -224,7 +226,8 @@
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
!firstBoot);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
- ServiceManager.addService(Context.INPUT_SERVICE, wm.getInputManagerService());
+ inputManager = wm.getInputManagerService();
+ ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
ActivityManagerService.self().setWindowManager(wm);
@@ -248,11 +251,9 @@
bluetooth.initAfterA2dpRegistration();
}
- int airplaneModeOn = Settings.System.getInt(mContentResolver,
- Settings.System.AIRPLANE_MODE_ON, 0);
int bluetoothOn = Settings.Secure.getInt(mContentResolver,
Settings.Secure.BLUETOOTH_ON, 0);
- if (airplaneModeOn == 0 && bluetoothOn != 0) {
+ if (bluetoothOn != 0) {
bluetooth.enable();
}
}
@@ -722,6 +723,8 @@
final TextServicesManagerService textServiceManagerServiceF = tsms;
final StatusBarManagerService statusBarF = statusBar;
final DreamManagerService dreamyF = dreamy;
+ final InputManagerService inputManagerF = inputManager;
+ final BluetoothService bluetoothF = bluetooth;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
@@ -833,6 +836,11 @@
} catch (Throwable e) {
reportWtf("making DreamManagerService ready", e);
}
+ try {
+ if (inputManagerF != null) inputManagerF.systemReady(bluetoothF);
+ } catch (Throwable e) {
+ reportWtf("making InputManagerService ready", e);
+ }
}
});
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 106bb3e..499ff7a 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -77,7 +77,7 @@
mSystemReady = false;
mContext = context;
mMonitor = new TextServicesMonitor();
- mMonitor.register(context, true);
+ mMonitor.register(context, null, true);
synchronized (mSpellCheckerMap) {
buildSpellCheckerMapLocked(context, mSpellCheckerList, mSpellCheckerMap);
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 6d83f30..d97d335 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -295,7 +295,7 @@
|| !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
continue;
}
- doPackagesChanged(true, wallpaper);
+ doPackagesChangedLocked(true, wallpaper);
}
}
}
@@ -315,66 +315,68 @@
@Override
public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
- boolean changed = false;
- for (int i = 0; i < mWallpaperMap.size(); i++) {
- WallpaperData wallpaper = mWallpaperMap.valueAt(i);
- boolean res = doPackagesChanged(doit, wallpaper);
- changed |= res;
+ synchronized (mLock) {
+ boolean changed = false;
+ for (int i = 0; i < mWallpaperMap.size(); i++) {
+ WallpaperData wallpaper = mWallpaperMap.valueAt(i);
+ boolean res = doPackagesChangedLocked(doit, wallpaper);
+ changed |= res;
+ }
+ return changed;
}
- return changed;
}
@Override
public void onSomePackagesChanged() {
- for (int i = 0; i < mWallpaperMap.size(); i++) {
- WallpaperData wallpaper = mWallpaperMap.valueAt(i);
- doPackagesChanged(true, wallpaper);
+ synchronized (mLock) {
+ for (int i = 0; i < mWallpaperMap.size(); i++) {
+ WallpaperData wallpaper = mWallpaperMap.valueAt(i);
+ doPackagesChangedLocked(true, wallpaper);
+ }
}
}
- boolean doPackagesChanged(boolean doit, WallpaperData wallpaper) {
+ boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) {
boolean changed = false;
- synchronized (mLock) {
- if (wallpaper.wallpaperComponent != null) {
- int change = isPackageDisappearing(wallpaper.wallpaperComponent
- .getPackageName());
- if (change == PACKAGE_PERMANENT_CHANGE
- || change == PACKAGE_TEMPORARY_CHANGE) {
- changed = true;
- if (doit) {
- Slog.w(TAG, "Wallpaper uninstalled, removing: "
- + wallpaper.wallpaperComponent);
- clearWallpaperLocked(false, wallpaper.userId);
- }
- }
- }
- if (wallpaper.nextWallpaperComponent != null) {
- int change = isPackageDisappearing(wallpaper.nextWallpaperComponent
- .getPackageName());
- if (change == PACKAGE_PERMANENT_CHANGE
- || change == PACKAGE_TEMPORARY_CHANGE) {
- wallpaper.nextWallpaperComponent = null;
- }
- }
- if (wallpaper.wallpaperComponent != null
- && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
- try {
- mContext.getPackageManager().getServiceInfo(
- wallpaper.wallpaperComponent, 0);
- } catch (NameNotFoundException e) {
- Slog.w(TAG, "Wallpaper component gone, removing: "
+ if (wallpaper.wallpaperComponent != null) {
+ int change = isPackageDisappearing(wallpaper.wallpaperComponent
+ .getPackageName());
+ if (change == PACKAGE_PERMANENT_CHANGE
+ || change == PACKAGE_TEMPORARY_CHANGE) {
+ changed = true;
+ if (doit) {
+ Slog.w(TAG, "Wallpaper uninstalled, removing: "
+ wallpaper.wallpaperComponent);
clearWallpaperLocked(false, wallpaper.userId);
}
}
- if (wallpaper.nextWallpaperComponent != null
- && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
- try {
- mContext.getPackageManager().getServiceInfo(
- wallpaper.nextWallpaperComponent, 0);
- } catch (NameNotFoundException e) {
- wallpaper.nextWallpaperComponent = null;
- }
+ }
+ if (wallpaper.nextWallpaperComponent != null) {
+ int change = isPackageDisappearing(wallpaper.nextWallpaperComponent
+ .getPackageName());
+ if (change == PACKAGE_PERMANENT_CHANGE
+ || change == PACKAGE_TEMPORARY_CHANGE) {
+ wallpaper.nextWallpaperComponent = null;
+ }
+ }
+ if (wallpaper.wallpaperComponent != null
+ && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
+ try {
+ mContext.getPackageManager().getServiceInfo(
+ wallpaper.wallpaperComponent, 0);
+ } catch (NameNotFoundException e) {
+ Slog.w(TAG, "Wallpaper component gone, removing: "
+ + wallpaper.wallpaperComponent);
+ clearWallpaperLocked(false, wallpaper.userId);
+ }
+ }
+ if (wallpaper.nextWallpaperComponent != null
+ && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
+ try {
+ mContext.getPackageManager().getServiceInfo(
+ wallpaper.nextWallpaperComponent, 0);
+ } catch (NameNotFoundException e) {
+ wallpaper.nextWallpaperComponent = null;
}
}
return changed;
@@ -387,7 +389,7 @@
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
mMonitor = new MyPackageMonitor();
- mMonitor.register(context, true);
+ mMonitor.register(context, null, true);
WALLPAPER_BASE_DIR.mkdirs();
loadSettingsLocked(0);
}
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index ed2a6c0..e980ccc 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -23,6 +23,7 @@
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.IAccessibilityServiceClient;
+import android.accessibilityservice.IAccessibilityServiceClientCallback;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -36,21 +37,30 @@
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.graphics.Rect;
+import android.hardware.input.InputManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
import android.util.Slog;
import android.util.SparseArray;
import android.view.IWindow;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.View;
import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -59,6 +69,8 @@
import android.view.accessibility.IAccessibilityManagerClient;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.HandlerCaller.Callback;
import com.android.server.accessibility.TouchExplorer.GestureListener;
import com.android.server.wm.WindowManagerService;
@@ -73,6 +85,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* This class is instantiated by the system as a system level service and can be
@@ -92,10 +105,12 @@
private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE =
"registerUiTestAutomationService";
- private static int sIdCounter = 0;
-
private static final int OWN_PROCESS_ID = android.os.Process.myPid();
+ private static final int UNDEFINED = -1;
+
+ private static int sIdCounter = 0;
+
private static int sNextWindowId;
final Context mContext;
@@ -140,6 +155,10 @@
private Service mUiAutomationService;
+ private GestureHandler mGestureHandler;
+
+ private int mDefaultGestureHandlingHelperServiceId = UNDEFINED;
+
/**
* Handler for delayed event dispatch.
*/
@@ -264,11 +283,11 @@
};
// package changes
- monitor.register(context, true);
+ monitor.register(context, null, true);
// boot completed
IntentFilter bootFiler = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
- mContext.registerReceiver(monitor, bootFiler);
+ mContext.registerReceiver(monitor, bootFiler, null, monitor.getRegisteredHandler());
}
/**
@@ -466,26 +485,60 @@
}
@Override
- public void onGesture(int gestureId) {
+ public boolean onGesture(int gestureId) {
+ // Lazily instantiate the gesture handler.
+ if (mGestureHandler == null) {
+ mGestureHandler = new GestureHandler();
+ }
synchronized (mLock) {
- final boolean dispatched = notifyGestureLocked(gestureId, false);
- if (!dispatched) {
- notifyGestureLocked(gestureId, true);
+ boolean handled = notifyGestureLocked(gestureId, false);
+ if (!handled) {
+ handled = notifyGestureLocked(gestureId, true);
}
+ if (!handled) {
+ mGestureHandler.scheduleHandleGestureDefault(gestureId);
+ }
+ return handled;
+ }
+ }
+
+ private Service getDefaultGestureHandlingHelperService() {
+ // Since querying of screen content is done through the
+ // AccessibilityInteractionClient which talks to an
+ // IAccessibilityServiceConnection implementation we create a proxy
+ // Service when necessary to enable interaction with the remote
+ // view tree. Note that this service is just a stateless proxy
+ // that does not get any events or interrupts.
+ if (mDefaultGestureHandlingHelperServiceId == UNDEFINED) {
+ ComponentName name = new ComponentName("android",
+ "DefaultGestureHandlingHelperService");
+ AccessibilityServiceInfo info = new AccessibilityServiceInfo();
+ Service service = new Service(name, info, true);
+ mDefaultGestureHandlingHelperServiceId = service.mId;
+ AccessibilityInteractionClient.getInstance().addConnection(
+ mDefaultGestureHandlingHelperServiceId, service);
+ return service;
+ } else {
+ return (Service) AccessibilityInteractionClient.getInstance()
+ .getConnection(mDefaultGestureHandlingHelperServiceId);
}
}
private boolean notifyGestureLocked(int gestureId, boolean isDefault) {
- final int serviceCount = mServices.size();
- for (int i = 0; i < serviceCount; i++) {
+ // TODO: Now we are giving the gestures to the last enabled
+ // service that can handle them which is the last one
+ // in our list since we write the last enabled as the
+ // last record in the enabled services setting. Ideally,
+ // the user should make the call which service handles
+ // gestures. However, only one service should handle
+ // gestrues to avoid user frustration when different
+ // bahiour is observed from different combinations of
+ // enabled accessibility services.
+ for (int i = mServices.size() - 1; i >= 0; i--) {
Service service = mServices.get(i);
- if (service.mIsDefault == isDefault) {
- try {
- service.mServiceInterface.onGesture(gestureId);
- return true;
- } catch (RemoteException re) {
- Slog.e(LOG_TAG, "Error dispatching gesture.");
- }
+ if (service.mCanHandleGestures && service.mIsDefault == isDefault) {
+ mGestureHandler.scheduleHandleGesture(gestureId, service.mServiceInterface);
+ return true;
}
}
return false;
@@ -930,6 +983,212 @@
}
}
+ class GestureHandler extends IAccessibilityServiceClientCallback.Stub
+ implements Runnable, Callback {
+
+ private static final String THREAD_NAME = "AccessibilityGestureHandler";
+
+ private static final long TIMEOUT_INTERACTION_MILLIS = 5000;
+
+ private static final int MSG_HANDLE_GESTURE = 1;
+
+ private static final int MSG_HANDLE_GESTURE_DEFAULT = 2;
+
+ private final AtomicInteger mInteractionCounter = new AtomicInteger();
+
+ private final Object mGestureLock = new Object();
+
+ private HandlerCaller mHandlerCaller;
+
+ private volatile int mInteractionId = -1;
+
+ private volatile boolean mGestureResult;
+
+ public GestureHandler() {
+ synchronized (mGestureLock) {
+ Thread worker = new Thread(this, THREAD_NAME);
+ worker.start();
+ while (mHandlerCaller == null) {
+ try {
+ mGestureLock.wait();
+ } catch (InterruptedException ie) {
+ /* ignore */
+ }
+ }
+ }
+ }
+
+ @Override
+ public void run() {
+ Looper.prepare();
+ synchronized (mGestureLock) {
+ mHandlerCaller = new HandlerCaller(mContext, Looper.myLooper(), this);
+ mGestureLock.notifyAll();
+ }
+ Looper.loop();
+ }
+
+ @Override
+ public void setGestureResult(int gestureId, boolean handled, int interactionId) {
+ synchronized (mGestureLock) {
+ if (interactionId > mInteractionId) {
+ mGestureResult = handled;
+ mInteractionId = interactionId;
+ }
+ mGestureLock.notifyAll();
+ }
+ }
+
+ @Override
+ public void executeMessage(Message message) {
+ final int type = message.what;
+ switch (type) {
+ case MSG_HANDLE_GESTURE: {
+ IAccessibilityServiceClient service =
+ (IAccessibilityServiceClient) message.obj;
+ final int gestureId = message.arg1;
+ final int interactionId = message.arg2;
+
+ try {
+ service.onGesture(gestureId, this, interactionId);
+ } catch (RemoteException re) {
+ Slog.e(LOG_TAG, "Error dispatching a gesture to a client.", re);
+ return;
+ }
+
+ long waitTimeMillis = 0;
+ final long startTimeMillis = SystemClock.uptimeMillis();
+ synchronized (mGestureLock) {
+ while (true) {
+ try {
+ // Did we get the expected callback?
+ if (mInteractionId == interactionId) {
+ break;
+ }
+ // Did we get an obsolete callback?
+ if (mInteractionId > interactionId) {
+ break;
+ }
+ // Did we time out?
+ final long elapsedTimeMillis =
+ SystemClock.uptimeMillis() - startTimeMillis;
+ waitTimeMillis = TIMEOUT_INTERACTION_MILLIS - elapsedTimeMillis;
+ if (waitTimeMillis <= 0) {
+ break;
+ }
+ mGestureLock.wait(waitTimeMillis);
+ } catch (InterruptedException ie) {
+ /* ignore */
+ }
+ }
+ handleGestureIfNeededAndResetLocked(gestureId);
+ }
+ } break;
+ case MSG_HANDLE_GESTURE_DEFAULT: {
+ final int gestureId = message.arg1;
+ handleGestureDefault(gestureId);
+ } break;
+ default: {
+ throw new IllegalArgumentException("Unknown message type: " + type);
+ }
+ }
+ }
+
+ private void handleGestureIfNeededAndResetLocked(int gestureId) {
+ if (!mGestureResult) {
+ handleGestureDefault(gestureId);
+ }
+ mGestureResult = false;
+ mInteractionId = -1;
+ }
+
+ public void scheduleHandleGesture(int gestureId, IAccessibilityServiceClient service) {
+ final int interactionId = mInteractionCounter.incrementAndGet();
+ mHandlerCaller.obtainMessageIIO(MSG_HANDLE_GESTURE, gestureId, interactionId,
+ service).sendToTarget();
+ }
+
+ public void scheduleHandleGestureDefault(int gestureId) {
+ final int interactionId = mInteractionCounter.incrementAndGet();
+ mHandlerCaller.obtainMessageI(MSG_HANDLE_GESTURE_DEFAULT, gestureId).sendToTarget();
+ }
+
+ private void handleGestureDefault(int gestureId) {
+ Service service = getDefaultGestureHandlingHelperService();
+
+ // Global actions.
+ switch (gestureId) {
+ case AccessibilityService.GESTURE_SWIPE_DOWN_AND_LEFT: {
+ service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
+ } return;
+ case AccessibilityService.GESTURE_SWIPE_DOWN_AND_RIGHT: {
+ service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
+ } return;
+ case AccessibilityService.GESTURE_SWIPE_UP_AND_LEFT: {
+ service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS);
+ } return;
+ case AccessibilityService.GESTURE_SWIPE_UP_AND_RIGHT: {
+ service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS);
+ } return;
+ }
+
+ AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+
+ AccessibilityNodeInfo root = client.getRootInActiveWindow(service.mId);
+ if (root == null) {
+ return;
+ }
+
+ AccessibilityNodeInfo current = root.findFocus(
+ AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
+ if (current == null) {
+ current = root;
+ }
+
+ // Local actions.
+ AccessibilityNodeInfo next = null;
+ switch (gestureId) {
+ case AccessibilityService.GESTURE_SWIPE_UP: {
+ next = current.focusSearch(View.ACCESSIBILITY_FOCUS_OUT);
+ } break;
+ case AccessibilityService.GESTURE_SWIPE_DOWN: {
+ next = current.focusSearch(View.ACCESSIBILITY_FOCUS_IN);
+ } break;
+ case AccessibilityService.GESTURE_SWIPE_LEFT: {
+ // TODO: Implement the RTL support.
+// if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) {
+ next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD);
+// } else { // LAYOUT_DIRECTION_RTL
+// next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD);
+// }
+ } break;
+ case AccessibilityService.GESTURE_SWIPE_RIGHT: {
+ // TODO: Implement the RTL support.
+// if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) {
+ next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD);
+// } else { // LAYOUT_DIRECTION_RTL
+// next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD);
+// }
+ } break;
+ case AccessibilityService.GESTURE_SWIPE_UP_AND_DOWN: {
+ next = current.focusSearch(View.ACCESSIBILITY_FOCUS_UP);
+ } break;
+ case AccessibilityService.GESTURE_SWIPE_DOWN_AND_UP: {
+ next = current.focusSearch(View.ACCESSIBILITY_FOCUS_DOWN);
+ } break;
+ case AccessibilityService.GESTURE_SWIPE_LEFT_AND_RIGHT: {
+ next = current.focusSearch(View.ACCESSIBILITY_FOCUS_LEFT);
+ } break;
+ case AccessibilityService.GESTURE_SWIPE_RIGHT_AND_LEFT: {
+ next = current.focusSearch(View.ACCESSIBILITY_FOCUS_RIGHT);
+ } break;
+ }
+ if (next != null && !next.equals(current)) {
+ next.performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
+ }
+ }
+ }
+
/**
* This class represents an accessibility service. It stores all per service
* data required for the service management, provides API for starting/stopping the
@@ -966,6 +1225,8 @@
boolean mCanRetrieveScreenContent;
+ boolean mCanHandleGestures;
+
boolean mIsAutomation;
final Rect mTempBounds = new Rect();
@@ -982,6 +1243,7 @@
mIsAutomation = isAutomation;
if (!isAutomation) {
mCanRetrieveScreenContent = accessibilityServiceInfo.getCanRetrieveWindowContent();
+ mCanHandleGestures = accessibilityServiceInfo.getCanHandleGestures();
mIntent = new Intent().setComponent(mComponentName);
mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
com.android.internal.R.string.accessibility_binding_label);
@@ -990,6 +1252,7 @@
} else {
mCanRetrieveScreenContent = true;
mIncludeNotImportantViews = true;
+ mCanHandleGestures = true;
}
setDynamicallyConfigurableProperties(accessibilityServiceInfo);
}
@@ -1285,7 +1548,7 @@
@Override
public boolean performAccessibilityAction(int accessibilityWindowId,
- long accessibilityNodeId, int action, int interactionId,
+ long accessibilityNodeId, int action, Bundle arguments, int interactionId,
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) {
final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId);
IAccessibilityInteractionConnection connection = null;
@@ -1301,13 +1564,13 @@
}
}
}
- final int flags = (mIncludeNotImportantViews) ?
- AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
- final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity();
try {
- connection.performAccessibilityAction(accessibilityNodeId, action, interactionId,
- callback, flags, interrogatingPid, interrogatingTid);
+ final int flags = (mIncludeNotImportantViews) ?
+ AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0;
+ final int interrogatingPid = Binder.getCallingPid();
+ connection.performAccessibilityAction(accessibilityNodeId, action, arguments,
+ interactionId, callback, flags, interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error calling performAccessibilityAction()");
@@ -1318,6 +1581,24 @@
return true;
}
+ public boolean performGlobalAction(int action) {
+ switch (action) {
+ case AccessibilityService.GLOBAL_ACTION_BACK: {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK);
+ } return true;
+ case AccessibilityService.GLOBAL_ACTION_HOME: {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME);
+ } return true;
+ case AccessibilityService.GLOBAL_ACTION_RECENTS: {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_APP_SWITCH);
+ } return true;
+ case AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS: {
+ // TODO: Implement when 6346026 is fixed.
+ } return true;
+ }
+ return false;
+ }
+
public void onServiceDisconnected(ComponentName componentName) {
/* do nothing - #binderDied takes care */
}
@@ -1358,6 +1639,30 @@
}
}
+ private void sendDownAndUpKeyEvents(int keyCode) {
+ final long token = Binder.clearCallingIdentity();
+
+ // Inject down.
+ final long downTime = SystemClock.uptimeMillis();
+ KeyEvent down = KeyEvent.obtain(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM,
+ InputDevice.SOURCE_KEYBOARD, null);
+ InputManager.getInstance().injectInputEvent(down,
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ down.recycle();
+
+ // Inject up.
+ final long upTime = SystemClock.uptimeMillis();
+ KeyEvent up = KeyEvent.obtain(downTime, upTime, KeyEvent.ACTION_UP, keyCode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM,
+ InputDevice.SOURCE_KEYBOARD, null);
+ InputManager.getInstance().injectInputEvent(up,
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ up.recycle();
+
+ Binder.restoreCallingIdentity(token);
+ }
+
private IAccessibilityInteractionConnection getConnectionLocked(int windowId) {
if (DEBUG) {
Slog.i(LOG_TAG, "Trying to get interaction connection to windowId: " + windowId);
@@ -1394,7 +1699,9 @@
| AccessibilityNodeInfo.ACTION_SELECT
| AccessibilityNodeInfo.ACTION_CLEAR_SELECTION
| AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS
- | AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+ | AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS
+ | AccessibilityNodeInfo.ACTION_NEXT_AT_GRANULARITY
+ | AccessibilityNodeInfo.ACTION_PREVIOUS_AT_GRANULARITY;
private static final int RETRIEVAL_ALLOWING_EVENT_TYPES =
AccessibilityEvent.TYPE_VIEW_CLICKED
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 5d01c77..39012e6 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -152,7 +152,7 @@
*
* @param gestureId The gesture id.
*/
- public void onGesture(int gestureId);
+ public boolean onGesture(int gestureId);
}
/**
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 2c53186..24bab99 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -16,6 +16,9 @@
package com.android.server.am;
+import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
@@ -2407,9 +2410,11 @@
return err;
}
- final int perm = mService.checkComponentPermission(aInfo.permission, callingPid,
+ final int startAnyPerm = mService.checkPermission(
+ START_ANY_ACTIVITY, callingPid, callingUid);
+ final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
callingUid, aInfo.applicationInfo.uid, aInfo.exported);
- if (perm != PackageManager.PERMISSION_GRANTED) {
+ if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
if (resultRecord != null) {
sendActivityResultLocked(-1,
resultRecord, resultWho, requestCode,
@@ -2944,7 +2949,7 @@
// Collect information about the target of the Intent.
ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
profileFile, profileFd, userId);
- if (mService.isSingleton(aInfo.processName, aInfo.applicationInfo)) {
+ if (aInfo != null && mService.isSingleton(aInfo.processName, aInfo.applicationInfo)) {
userId = 0;
}
aInfo = mService.getActivityInfoForUser(aInfo, userId);
@@ -3946,6 +3951,17 @@
}
}
+ final void updateTransitLocked(int transit, Bundle options) {
+ if (options != null) {
+ ActivityRecord r = topRunningActivityLocked(null);
+ if (r != null && r.state != ActivityState.RESUMED) {
+ r.updateOptionsLocked(options);
+ } else {
+ ActivityOptions.abort(options);
+ }
+ }
+ mService.mWindowManager.prepareAppTransition(transit, false);
+ }
final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) {
if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
@@ -3955,7 +3971,12 @@
if (top < 0 || (mHistory.get(top)).task.taskId == task) {
// nothing to do!
- ActivityOptions.abort(options);
+ if (reason != null &&
+ (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+ ActivityOptions.abort(options);
+ } else {
+ updateTransitLocked(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT, options);
+ }
return;
}
@@ -3999,16 +4020,7 @@
}
ActivityOptions.abort(options);
} else {
- if (options != null) {
- ActivityRecord r = topRunningActivityLocked(null);
- if (r != null && r.state != ActivityState.RESUMED) {
- r.updateOptionsLocked(options);
- } else {
- ActivityOptions.abort(options);
- }
- }
- mService.mWindowManager.prepareAppTransition(
- WindowManagerPolicy.TRANSIT_TASK_TO_FRONT, false);
+ updateTransitLocked(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT, options);
}
mService.mWindowManager.moveAppTokensToTop(moved);
diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java
index e810e3c..ba65f39 100644
--- a/services/java/com/android/server/am/UsageStatsService.java
+++ b/services/java/com/android/server/am/UsageStatsService.java
@@ -656,7 +656,7 @@
}
}
};
- mPackageMonitor.register(mContext, true);
+ mPackageMonitor.register(mContext, null, true);
filterHistoryStats();
}
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 7640eff..189a9c7 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -26,15 +26,20 @@
import org.xmlpull.v1.XmlSerializer;
import android.Manifest;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
@@ -53,6 +58,7 @@
import android.os.RemoteException;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
+import android.server.BluetoothService;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -60,13 +66,11 @@
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputEvent;
-import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.PointerIcon;
import android.view.Surface;
import android.view.ViewConfiguration;
import android.view.WindowManagerPolicy;
-import android.view.KeyCharacterMap.UnavailableException;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -77,13 +81,14 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import libcore.io.IoUtils;
+import libcore.io.Streams;
import libcore.util.Objects;
/*
@@ -91,7 +96,7 @@
*/
public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
static final String TAG = "InputManager";
- static final boolean DEBUG = false;
+ static final boolean DEBUG = true;
private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
@@ -103,6 +108,8 @@
private final Context mContext;
private final Callbacks mCallbacks;
private final InputManagerHandler mHandler;
+ private boolean mSystemReady;
+ private BluetoothService mBluetoothService;
// Persistent data store. Must be locked each time during use.
private final PersistentDataStore mDataStore = new PersistentDataStore();
@@ -163,6 +170,8 @@
private static native void nativeVibrate(int ptr, int deviceId, long[] pattern,
int repeat, int token);
private static native void nativeCancelVibrate(int ptr, int deviceId, int token);
+ private static native void nativeReloadKeyboardLayouts(int ptr);
+ private static native void nativeReloadDeviceAliases(int ptr);
private static native String nativeDump(int ptr);
private static native void nativeMonitor(int ptr);
@@ -212,7 +221,51 @@
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
}
-
+
+ public void systemReady(BluetoothService bluetoothService) {
+ if (DEBUG) {
+ Slog.d(TAG, "System ready.");
+ }
+ mBluetoothService = bluetoothService;
+ mSystemReady = true;
+
+ IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ filter.addDataScheme("package");
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) {
+ Slog.d(TAG, "Packages changed, reloading keyboard layouts.");
+ }
+ reloadKeyboardLayouts();
+ }
+ }, filter, null, mHandler);
+
+ filter = new IntentFilter(BluetoothDevice.ACTION_ALIAS_CHANGED);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) {
+ Slog.d(TAG, "Bluetooth alias changed, reloading device names.");
+ }
+ reloadDeviceAliases();
+ }
+ }, filter, null, mHandler);
+
+ reloadKeyboardLayouts();
+ reloadDeviceAliases();
+ }
+
+ private void reloadKeyboardLayouts() {
+ nativeReloadKeyboardLayouts(mPtr);
+ }
+
+ private void reloadDeviceAliases() {
+ nativeReloadDeviceAliases(mPtr);
+ }
+
public void setDisplaySize(int displayId, int width, int height,
int externalWidth, int externalHeight) {
if (width <= 0 || height <= 0 || externalWidth <= 0 || externalHeight <= 0) {
@@ -528,14 +581,14 @@
@Override // Binder call
public KeyboardLayout[] getKeyboardLayouts() {
- ArrayList<KeyboardLayout> list = new ArrayList<KeyboardLayout>();
-
- final PackageManager pm = mContext.getPackageManager();
- Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_LAYOUTS);
- for (ResolveInfo resolveInfo : pm.queryBroadcastReceivers(intent,
- PackageManager.GET_META_DATA)) {
- loadKeyboardLayouts(pm, resolveInfo.activityInfo, list, null);
- }
+ final ArrayList<KeyboardLayout> list = new ArrayList<KeyboardLayout>();
+ visitAllKeyboardLayouts(new KeyboardLayoutVisitor() {
+ @Override
+ public void visitKeyboardLayout(Resources resources,
+ String descriptor, String label, int kcmResId) {
+ list.add(new KeyboardLayout(descriptor, label));
+ }
+ });
return list.toArray(new KeyboardLayout[list.size()]);
}
@@ -545,37 +598,57 @@
throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
}
- KeyboardLayoutDescriptor d = KeyboardLayoutDescriptor.parse(keyboardLayoutDescriptor);
- if (d == null) {
- return null;
+ final KeyboardLayout[] result = new KeyboardLayout[1];
+ visitKeyboardLayout(keyboardLayoutDescriptor, new KeyboardLayoutVisitor() {
+ @Override
+ public void visitKeyboardLayout(Resources resources,
+ String descriptor, String label, int kcmResId) {
+ result[0] = new KeyboardLayout(descriptor, label);
+ }
+ });
+ if (result[0] == null) {
+ Log.w(TAG, "Could not get keyboard layout with descriptor '"
+ + keyboardLayoutDescriptor + "'.");
}
+ return result[0];
+ }
+ private void visitAllKeyboardLayouts(KeyboardLayoutVisitor visitor) {
final PackageManager pm = mContext.getPackageManager();
- try {
- ActivityInfo receiver = pm.getReceiverInfo(
- new ComponentName(d.packageName, d.receiverName),
- PackageManager.GET_META_DATA);
- return loadKeyboardLayouts(pm, receiver, null, d.keyboardLayoutName);
- } catch (NameNotFoundException ex) {
- Log.w(TAG, "Could not load keyboard layout '" + d.keyboardLayoutName
- + "' from receiver " + d.packageName + "/" + d.receiverName, ex);
- return null;
+ Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_LAYOUTS);
+ for (ResolveInfo resolveInfo : pm.queryBroadcastReceivers(intent,
+ PackageManager.GET_META_DATA)) {
+ visitKeyboardLayoutsInPackage(pm, resolveInfo.activityInfo, null, visitor);
}
}
- private KeyboardLayout loadKeyboardLayouts(
- PackageManager pm, ActivityInfo receiver,
- List<KeyboardLayout> list, String keyboardName) {
+ private void visitKeyboardLayout(String keyboardLayoutDescriptor,
+ KeyboardLayoutVisitor visitor) {
+ KeyboardLayoutDescriptor d = KeyboardLayoutDescriptor.parse(keyboardLayoutDescriptor);
+ if (d != null) {
+ final PackageManager pm = mContext.getPackageManager();
+ try {
+ ActivityInfo receiver = pm.getReceiverInfo(
+ new ComponentName(d.packageName, d.receiverName),
+ PackageManager.GET_META_DATA);
+ visitKeyboardLayoutsInPackage(pm, receiver, d.keyboardLayoutName, visitor);
+ } catch (NameNotFoundException ex) {
+ }
+ }
+ }
+
+ private void visitKeyboardLayoutsInPackage(PackageManager pm, ActivityInfo receiver,
+ String keyboardName, KeyboardLayoutVisitor visitor) {
Bundle metaData = receiver.metaData;
if (metaData == null) {
- return null;
+ return;
}
int configResId = metaData.getInt(InputManager.META_DATA_KEYBOARD_LAYOUTS);
if (configResId == 0) {
Log.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_LAYOUTS
+ "' on receiver " + receiver.packageName + "/" + receiver.name);
- return null;
+ return;
}
try {
@@ -608,12 +681,9 @@
} else {
String descriptor = KeyboardLayoutDescriptor.format(
receiver.packageName, receiver.name, name);
- KeyboardLayout c = new KeyboardLayout(descriptor, label);
- if (keyboardName != null && name.equals(keyboardName)) {
- return c;
- }
- if (list != null) {
- list.add(c);
+ if (keyboardName == null || name.equals(keyboardName)) {
+ visitor.visitKeyboardLayout(resources, descriptor,
+ label, kcmResId);
}
}
} finally {
@@ -629,16 +699,9 @@
parser.close();
}
} catch (Exception ex) {
- Log.w(TAG, "Could not load keyboard layout resource from receiver "
+ Log.w(TAG, "Could not parse keyboard layout resource from receiver "
+ receiver.packageName + "/" + receiver.name, ex);
- return null;
}
- if (keyboardName != null) {
- Log.w(TAG, "Could not load keyboard layout '" + keyboardName
- + "' from receiver " + receiver.packageName + "/" + receiver.name
- + " because it was not declared in the keyboard layout resource.");
- }
- return null;
}
@Override // Binder call
@@ -664,52 +727,24 @@
throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
}
+ final boolean changed;
synchronized (mDataStore) {
try {
- mDataStore.setKeyboardLayout(inputDeviceDescriptor, keyboardLayoutDescriptor);
+ changed = mDataStore.setKeyboardLayout(
+ inputDeviceDescriptor, keyboardLayoutDescriptor);
} finally {
mDataStore.saveIfNeeded();
}
}
+
+ if (changed) {
+ if (DEBUG) {
+ Slog.d(TAG, "Keyboard layout changed, reloading keyboard layouts.");
+ }
+ reloadKeyboardLayouts();
+ }
}
- /**
- * Loads the key character map associated with the keyboard layout.
- *
- * @param pm The package manager.
- * @return The key character map, or null if it could not be loaded for any reason.
- *
- public KeyCharacterMap loadKeyCharacterMap(PackageManager pm) {
- if (pm == null) {
- throw new IllegalArgumentException("pm must not be null");
- }
-
- if (mKeyCharacterMap == null) {
- KeyboardLayoutDescriptor d = InputManager.parseKeyboardLayoutDescriptor(mDescriptor);
- if (d == null) {
- Log.e(InputManager.TAG, "Could not load key character map '" + mDescriptor
- + "' because the descriptor could not be parsed.");
- return null;
- }
-
- CharSequence cs = pm.getText(d.packageName, mKeyCharacterMapResId, null);
- if (cs == null) {
- Log.e(InputManager.TAG, "Could not load key character map '" + mDescriptor
- + "' because its associated resource could not be loaded.");
- return null;
- }
-
- try {
- mKeyCharacterMap = KeyCharacterMap.load(cs);
- } catch (UnavailableException ex) {
- Log.e(InputManager.TAG, "Could not load key character map '" + mDescriptor
- + "' due to an error while parsing.", ex);
- return null;
- }
- }
- return mKeyCharacterMap;
- }*/
-
public void setInputWindows(InputWindowHandle[] windowHandles) {
nativeSetInputWindows(mPtr, windowHandles);
}
@@ -1076,6 +1111,49 @@
return PointerIcon.getDefaultIcon(mContext);
}
+ // Native callback.
+ private String[] getKeyboardLayoutOverlay(String inputDeviceDescriptor) {
+ if (!mSystemReady) {
+ return null;
+ }
+
+ String keyboardLayoutDescriptor = getKeyboardLayoutForInputDevice(inputDeviceDescriptor);
+ if (keyboardLayoutDescriptor == null) {
+ return null;
+ }
+
+ final String[] result = new String[2];
+ visitKeyboardLayout(keyboardLayoutDescriptor, new KeyboardLayoutVisitor() {
+ @Override
+ public void visitKeyboardLayout(Resources resources,
+ String descriptor, String label, int kcmResId) {
+ try {
+ result[0] = descriptor;
+ result[1] = Streams.readFully(new InputStreamReader(
+ resources.openRawResource(kcmResId)));
+ } catch (IOException ex) {
+ } catch (NotFoundException ex) {
+ }
+ }
+ });
+ if (result[0] == null) {
+ Log.w(TAG, "Could not get keyboard layout with descriptor '"
+ + keyboardLayoutDescriptor + "'.");
+ return null;
+ }
+ return result;
+ }
+
+ // Native callback.
+ private String getDeviceAlias(String uniqueId) {
+ if (mBluetoothService != null &&
+ BluetoothAdapter.checkBluetoothAddress(uniqueId)) {
+ return mBluetoothService.getRemoteAlias(uniqueId);
+ }
+ return null;
+ }
+
+
/**
* Callback interface implemented by the Window Manager.
*/
@@ -1169,6 +1247,11 @@
}
}
+ private interface KeyboardLayoutVisitor {
+ void visitKeyboardLayout(Resources resources,
+ String descriptor, String label, int kcmResId);
+ }
+
private final class InputDevicesChangedListenerRecord implements DeathRecipient {
private final int mPid;
private final IInputDevicesChangedListener mListener;
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 1e17067..52d5019 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -30,6 +30,8 @@
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.TYPE_WIMAX;
+import static android.net.ConnectivityManager.isNetworkTypeMobile;
+import static android.net.NetworkPolicy.CYCLE_NONE;
import static android.net.NetworkPolicy.LIMIT_DISABLED;
import static android.net.NetworkPolicy.SNOOZE_NEVER;
import static android.net.NetworkPolicy.WARNING_DISABLED;
@@ -48,6 +50,14 @@
import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.net.wifi.WifiInfo.removeDoubleQuotes;
+import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED;
+import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED;
+import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION;
+import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON;
+import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO;
import static android.telephony.TelephonyManager.SIM_STATE_READY;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static com.android.internal.util.ArrayUtils.appendInt;
@@ -84,10 +94,14 @@
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
import android.net.NetworkIdentity;
+import android.net.NetworkInfo;
import android.net.NetworkPolicy;
import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.NetworkTemplate;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
@@ -355,6 +369,17 @@
mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter,
MANAGE_NETWORK_POLICY, mHandler);
+ // listen for configured wifi networks to be removed
+ final IntentFilter wifiConfigFilter = new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION);
+ mContext.registerReceiver(
+ mWifiConfigReceiver, wifiConfigFilter, CONNECTIVITY_INTERNAL, mHandler);
+
+ // listen for wifi state changes to catch metered hint
+ final IntentFilter wifiStateFilter = new IntentFilter(
+ WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ mContext.registerReceiver(
+ mWifiStateReceiver, wifiStateFilter, CONNECTIVITY_INTERNAL, mHandler);
+
}
private IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
@@ -463,6 +488,73 @@
};
/**
+ * Receiver that watches for {@link WifiConfiguration} to be changed.
+ */
+ private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // on background handler thread, and verified CONNECTIVITY_INTERNAL
+ // permission above.
+
+ final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED);
+ if (reason == CHANGE_REASON_REMOVED) {
+ final WifiConfiguration config = intent.getParcelableExtra(
+ EXTRA_WIFI_CONFIGURATION);
+ final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(
+ removeDoubleQuotes(config.SSID));
+ synchronized (mRulesLock) {
+ if (mNetworkPolicy.containsKey(template)) {
+ mNetworkPolicy.remove(template);
+ writePolicyLocked();
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * Receiver that watches {@link WifiInfo} state changes to infer metered
+ * state. Ignores hints when policy is user-defined.
+ */
+ private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // on background handler thread, and verified CONNECTIVITY_INTERNAL
+ // permission above.
+
+ // ignore when not connected
+ final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO);
+ if (!netInfo.isConnected()) return;
+
+ final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO);
+ final boolean meteredHint = info.getMeteredHint();
+
+ final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(
+ removeDoubleQuotes(info.getSSID()));
+ synchronized (mRulesLock) {
+ NetworkPolicy policy = mNetworkPolicy.get(template);
+ if (policy == null && meteredHint) {
+ // policy doesn't exist, and AP is hinting that it's
+ // metered: create an inferred policy.
+ policy = new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC,
+ WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER,
+ meteredHint, true);
+ addNetworkPolicyLocked(policy);
+
+ } else if (policy != null && policy.inferred) {
+ // policy exists, and was inferred: update its current
+ // metered state.
+ policy.metered = meteredHint;
+
+ // since this is inferred for each wifi session, just update
+ // rules without persisting.
+ updateNetworkRulesLocked();
+ }
+ }
+ }
+ };
+
+ /**
* Observer that watches for {@link INetworkManagementService} alerts.
*/
private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() {
@@ -974,9 +1066,9 @@
final String cycleTimezone = time.timezone;
final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
- mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, cycleTimezone,
- warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true));
- writePolicyLocked();
+ final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone,
+ warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true);
+ addNetworkPolicyLocked(policy);
}
}
@@ -1269,6 +1361,15 @@
}
}
+ private void addNetworkPolicyLocked(NetworkPolicy policy) {
+ mNetworkPolicy.put(policy.template, policy);
+
+ updateNetworkEnabledLocked();
+ updateNetworkRulesLocked();
+ updateNotificationsLocked();
+ writePolicyLocked();
+ }
+
@Override
public NetworkPolicy[] getNetworkPolicies() {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
@@ -1402,6 +1503,10 @@
if (policy != null) {
return policy.metered;
} else {
+ final int type = state.networkInfo.getType();
+ if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) {
+ return true;
+ }
return false;
}
}
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 2a67e02..1c3e24f 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -420,6 +420,7 @@
@Override
public INetworkStatsSession openSession() {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+ assertBandwidthControlEnabled();
// return an IBinder which holds strong references to any loaded stats
// for its lifetime; when caller closes only weak references remain.
@@ -486,6 +487,7 @@
@Override
public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+ assertBandwidthControlEnabled();
return mDevStatsCached.getSummary(template, start, end).getTotalBytes();
}
@@ -494,6 +496,7 @@
if (Binder.getCallingUid() != uid) {
mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
}
+ assertBandwidthControlEnabled();
// TODO: switch to data layer stats once kernel exports
// for now, read network layer stats and flatten across all ifaces
@@ -565,6 +568,7 @@
@Override
public void forceUpdate() {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+ assertBandwidthControlEnabled();
final long token = Binder.clearCallingIdentity();
try {
@@ -1039,12 +1043,21 @@
}
};
+ private void assertBandwidthControlEnabled() {
+ if (!isBandwidthControlEnabled()) {
+ throw new IllegalStateException("Bandwidth module disabled");
+ }
+ }
+
private boolean isBandwidthControlEnabled() {
+ final long token = Binder.clearCallingIdentity();
try {
return mNetworkManager.isBandwidthControlEnabled();
} catch (RemoteException e) {
// ignored; service lives in system_server
return false;
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index b97d7fd..6891b76 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -6067,10 +6067,23 @@
Intent.FLAG_GRANT_READ_URI_PERMISSION);
ret = imcs.copyResource(packageURI, out);
} finally {
- try { if (out != null) out.close(); } catch (IOException e) {}
+ IoUtils.closeQuietly(out);
mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
+ if (isFwdLocked()) {
+ final File destResourceFile = new File(getResourcePath());
+
+ // Copy the public files
+ try {
+ PackageHelper.extractPublicFiles(codeFileName, destResourceFile);
+ } catch (IOException e) {
+ Slog.e(TAG, "Couldn't create a new zip file for the public parts of a"
+ + " forward-locked app.");
+ destResourceFile.delete();
+ return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+ }
+ }
return ret;
}
@@ -6086,21 +6099,29 @@
cleanUp();
return false;
} else {
- // Rename based on packageName
- File codeFile = new File(getCodePath());
- String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
- File desFile = new File(installDir, apkName + ".apk");
- if (!codeFile.renameTo(desFile)) {
+ final File oldCodeFile = new File(getCodePath());
+ final File oldResourceFile = new File(getResourcePath());
+
+ // Rename APK file based on packageName
+ final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
+ final File newCodeFile = new File(installDir, apkName + ".apk");
+ if (!oldCodeFile.renameTo(newCodeFile)) {
return false;
}
- // Reset paths since the file has been renamed.
- codeFileName = desFile.getPath();
+ codeFileName = newCodeFile.getPath();
+
+ // Rename public resource file if it's forward-locked.
+ final File newResFile = new File(getResourcePathFromCodePath());
+ if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) {
+ return false;
+ }
resourceFileName = getResourcePathFromCodePath();
- // Set permissions
+
+ // Attempt to set permissions
if (!setPermissions()) {
- // Failed setting permissions.
return false;
}
+
return true;
}
}
@@ -6116,11 +6137,26 @@
return resourceFileName;
}
- String getResourcePathFromCodePath() {
- String codePath = getCodePath();
- if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
- String apkNameOnly = getApkName(codePath);
- return mAppInstallDir.getPath() + "/" + apkNameOnly + ".zip";
+ private String getResourcePathFromCodePath() {
+ final String codePath = getCodePath();
+ if (isFwdLocked()) {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append(mAppInstallDir.getPath());
+ sb.append('/');
+ sb.append(getApkName(codePath));
+ sb.append(".zip");
+
+ /*
+ * If our APK is a temporary file, mark the resource as a
+ * temporary file as well so it can be cleaned up after
+ * catastrophic failure.
+ */
+ if (codePath.endsWith(".tmp")) {
+ sb.append(".tmp");
+ }
+
+ return sb.toString();
} else {
return codePath;
}
@@ -6941,15 +6977,6 @@
// TODO Gross hack but fix later. Ideally move this to be a post installation
// check after alloting uid.
if (isForwardLocked(newPackage)) {
- File destResourceFile = new File(newPackage.applicationInfo.publicSourceDir);
- try {
- extractPublicFiles(newPackage, destResourceFile);
- } catch (IOException e) {
- Slog.e(TAG, "Couldn't create a new zip file for the public parts of a" +
- " forward-locked app.");
- destResourceFile.delete();
- return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
- }
retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath),
newPackage.applicationInfo.uid);
} else {
@@ -6986,67 +7013,6 @@
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
}
- private void extractPublicFiles(PackageParser.Package newPackage,
- File publicZipFile) throws IOException {
- final FileOutputStream fstr = new FileOutputStream(publicZipFile);
- final ZipOutputStream publicZipOutStream = new ZipOutputStream(fstr);
- try {
- final ZipFile privateZip = new ZipFile(newPackage.mPath);
- try {
- // Copy manifest, resources.arsc and res directory to public zip
-
- final Enumeration<? extends ZipEntry> privateZipEntries = privateZip.entries();
- while (privateZipEntries.hasMoreElements()) {
- final ZipEntry zipEntry = privateZipEntries.nextElement();
- final String zipEntryName = zipEntry.getName();
- if ("AndroidManifest.xml".equals(zipEntryName)
- || "resources.arsc".equals(zipEntryName)
- || zipEntryName.startsWith("res/")) {
- copyZipEntry(zipEntry, privateZip, publicZipOutStream);
- }
- }
- } finally {
- try { privateZip.close(); } catch (IOException e) { }
- }
-
- publicZipOutStream.finish();
- publicZipOutStream.flush();
- FileUtils.sync(fstr);
- publicZipOutStream.close();
- FileUtils.setPermissions(publicZipFile.getAbsolutePath(), FileUtils.S_IRUSR
- | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1);
- } finally {
- IoUtils.closeQuietly(publicZipOutStream);
- }
- }
-
- private static void copyZipEntry(ZipEntry zipEntry,
- ZipFile inZipFile,
- ZipOutputStream outZipStream) throws IOException {
- byte[] buffer = new byte[4096];
- int num;
-
- ZipEntry newEntry;
- if (zipEntry.getMethod() == ZipEntry.STORED) {
- // Preserve the STORED method of the input entry.
- newEntry = new ZipEntry(zipEntry);
- } else {
- // Create a new entry so that the compressed len is recomputed.
- newEntry = new ZipEntry(zipEntry.getName());
- }
- outZipStream.putNextEntry(newEntry);
-
- final InputStream data = inZipFile.getInputStream(zipEntry);
- try {
- while ((num = data.read(buffer)) > 0) {
- outZipStream.write(buffer, 0, num);
- }
- outZipStream.flush();
- } finally {
- IoUtils.closeQuietly(data);
- }
- }
-
private void deleteTempPackageFiles() {
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 35b6bde..d015278 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -2300,12 +2300,15 @@
}
private List<UserInfo> getAllUsers() {
+ long id = Binder.clearCallingIdentity();
try {
return AppGlobals.getPackageManager().getUsers();
} catch (RemoteException re) {
// Local to system process, shouldn't happen
} catch (NullPointerException npe) {
// packagemanager not yet initialized
+ } finally {
+ Binder.restoreCallingIdentity(id);
}
return null;
}
@@ -2347,6 +2350,7 @@
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Date date = new Date();
boolean printedSomething = false;
+ List<UserInfo> users = getAllUsers();
for (final PackageSetting ps : mPackages.values()) {
if (packageName != null && !packageName.equals(ps.realName)
&& !packageName.equals(ps.name)) {
@@ -2447,7 +2451,6 @@
pw.print(" haveGids="); pw.println(ps.haveGids);
pw.print(" pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
pw.print(" installStatus="); pw.print(ps.installStatus);
- List<UserInfo> users = getAllUsers();
for (UserInfo user : users) {
pw.print(" User "); pw.print(user.id); pw.print(": ");
pw.print(" stopped=");
diff --git a/services/java/com/android/server/usb/UsbSettingsManager.java b/services/java/com/android/server/usb/UsbSettingsManager.java
index 0baafbb..7dde340 100644
--- a/services/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/java/com/android/server/usb/UsbSettingsManager.java
@@ -370,7 +370,7 @@
synchronized (mLock) {
readSettingsLocked();
}
- mPackageMonitor.register(context, true);
+ mPackageMonitor.register(context, null, true);
}
private void readPreference(XmlPullParser parser)
diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java
index b08c864..f9f9d1a 100644
--- a/services/java/com/android/server/wm/DimAnimator.java
+++ b/services/java/com/android/server/wm/DimAnimator.java
@@ -42,10 +42,17 @@
DimAnimator (SurfaceSession session) {
if (mDimSurface == null) {
try {
- mDimSurface = new Surface(session, 0,
+ if (WindowManagerService.DEBUG_SURFACE_TRACE) {
+ mDimSurface = new WindowStateAnimator.SurfaceTrace(session, 0,
"DimAnimator",
-1, 16, 16, PixelFormat.OPAQUE,
Surface.FX_SURFACE_DIM);
+ } else {
+ mDimSurface = new Surface(session, 0,
+ "DimAnimator",
+ -1, 16, 16, PixelFormat.OPAQUE,
+ Surface.FX_SURFACE_DIM);
+ }
if (WindowManagerService.SHOW_TRANSACTIONS ||
WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
" DIM " + mDimSurface + ": CREATE");
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 7611a0f..f946f6c 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -75,6 +75,9 @@
DimAnimator mDimAnimator = null;
DimAnimator.Parameters mDimParams = null;
+ static final int WALLPAPER_ACTION_PENDING = 1;
+ int mPendingActions;
+
WindowAnimator(final WindowManagerService service, final Context context,
final WindowManagerPolicy policy) {
mService = service;
@@ -364,7 +367,9 @@
for (int i=unForceHiding.size()-1; i>=0; i--) {
Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding);
if (a != null) {
- unForceHiding.get(i).setAnimation(a);
+ final WindowStateAnimator winAnimator = unForceHiding.get(i);
+ winAnimator.setAnimation(a);
+ winAnimator.mAnimationIsEntrance = true;
}
}
}
@@ -421,13 +426,16 @@
mWindowAnimationBackgroundColor = 0;
updateWindowsAndWallpaperLocked();
+ if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
+ mPendingActions |= WALLPAPER_ACTION_PENDING;
+ }
if (mTokenMayBeDrawn) {
testTokenMayBeDrawnLocked();
}
}
- void animate() {
+ synchronized void animate() {
mPendingLayoutChanges = 0;
mCurrentTime = SystemClock.uptimeMillis();
mBulkUpdateParams = 0;
@@ -554,4 +562,8 @@
mAnimDh = animDh;
}
}
+
+ synchronized void clearPendingActions() {
+ mPendingActions = 0;
+ }
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
old mode 100644
new mode 100755
index 72aab7b..ff41899d
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -34,6 +34,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.app.ShutdownThread;
import com.android.internal.policy.PolicyManager;
import com.android.internal.policy.impl.PhoneWindowManager;
import com.android.internal.view.IInputContext;
@@ -461,6 +462,10 @@
int mCurDisplayHeight = 0;
int mAppDisplayWidth = 0;
int mAppDisplayHeight = 0;
+ int mSmallestDisplayWidth = 0;
+ int mSmallestDisplayHeight = 0;
+ int mLargestDisplayWidth = 0;
+ int mLargestDisplayHeight = 0;
int mRotation = 0;
int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -1625,9 +1630,7 @@
"Found wallpaper activity: #" + i + "=" + w);
foundW = w;
foundI = i;
- if (w == mWallpaperTarget && ((w.mAppToken != null
- && w.mAppToken.mAppAnimator.animation != null)
- || w.mWinAnimator.mAnimation != null)) {
+ if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
// The current wallpaper target is animating, so we'll
// look behind it for another possible target and figure
// out what is going on below.
@@ -3076,6 +3079,43 @@
return null;
}
+ private Animation createExitAnimationLocked(int transit, int duration) {
+ if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN ||
+ transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) {
+ // If we are on top of the wallpaper, we need an animation that
+ // correctly handles the wallpaper staying static behind all of
+ // the animated elements. To do this, will just have the existing
+ // element fade out.
+ Animation a = new AlphaAnimation(1, 0);
+ a.setDetachWallpaper(true);
+ a.setDuration(duration);
+ return a;
+ } else {
+ // For normal animations, the exiting element just holds in place.
+ Animation a = new AlphaAnimation(1, 1);
+ a.setDuration(duration);
+ return a;
+ }
+ }
+
+ /**
+ * Compute the pivot point for an animation that is scaling from a small
+ * rect on screen to a larger rect. The pivot point varies depending on
+ * the distance between the inner and outer edges on both sides. This
+ * function computes the pivot point for one dimension.
+ * @param startPos Offset from left/top edge of outer rectangle to
+ * left/top edge of inner rectangle.
+ * @param finalScale The scaling factor between the size of the outer
+ * and inner rectangles.
+ */
+ private static float computePivot(int startPos, float finalScale) {
+ final float denom = finalScale-1;
+ if (Math.abs(denom) < .0001f) {
+ return startPos;
+ }
+ return -startPos / denom;
+ }
+
private Animation createScaleUpAnimationLocked(int transit, boolean enter) {
Animation a;
// Pick the desired duration. If this is an inter-activity transition,
@@ -3094,11 +3134,12 @@
}
if (enter) {
// Entering app zooms out from the center of the initial rect.
- Animation scale = new ScaleAnimation(
- mNextAppTransitionStartWidth/mAppDisplayWidth, 1,
- mNextAppTransitionStartHeight/mAppDisplayHeight, 1,
- mNextAppTransitionStartX + mNextAppTransitionStartWidth/2,
- mNextAppTransitionStartY + mNextAppTransitionStartHeight/2);
+ float scaleW = mNextAppTransitionStartWidth/(float)mAppDisplayWidth;
+ float scaleH = mNextAppTransitionStartHeight/(float)mAppDisplayHeight;
+ Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
+ computePivot(mNextAppTransitionStartX, scaleW),
+ computePivot(mNextAppTransitionStartY, scaleH));
+ scale.setDuration(duration);
AnimationSet set = new AnimationSet(true);
Animation alpha = new AlphaAnimation(0, 1);
scale.setDuration(duration);
@@ -3107,13 +3148,11 @@
set.addAnimation(alpha);
a = set;
} else {
- // Exiting app just holds in place.
- a = new AlphaAnimation(1, 1);
- a.setDuration(duration);
+ a = createExitAnimationLocked(transit, duration);
}
a.setFillAfter(true);
final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
- com.android.internal.R.interpolator.decelerate_quint);
+ com.android.internal.R.interpolator.decelerate_quad);
a.setInterpolator(interpolator);
a.initialize(mAppDisplayWidth, mAppDisplayHeight,
mAppDisplayWidth, mAppDisplayHeight);
@@ -3123,8 +3162,10 @@
private Animation createThumbnailAnimationLocked(int transit,
boolean enter, boolean thumb) {
Animation a;
- final float thumbWidth = mNextAppTransitionThumbnail.getWidth();
- final float thumbHeight = mNextAppTransitionThumbnail.getHeight();
+ final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+ final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
+ final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+ final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
// Pick the desired duration. If this is an inter-activity transition,
// it is the standard duration for that. Otherwise we use the longer
// task transition duration.
@@ -3142,11 +3183,11 @@
if (thumb) {
// Animation for zooming thumbnail from its initial size to
// filling the screen.
- Animation scale = new ScaleAnimation(
- 1, mAppDisplayWidth/thumbWidth,
- 1, mAppDisplayHeight/thumbHeight,
- mNextAppTransitionStartX + thumbWidth/2,
- mNextAppTransitionStartY + thumbHeight/2);
+ float scaleW = mAppDisplayWidth/thumbWidth;
+ float scaleH = mAppDisplayHeight/thumbHeight;
+ Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
+ computePivot(mNextAppTransitionStartX, 1/scaleW),
+ computePivot(mNextAppTransitionStartY, 1/scaleH));
AnimationSet set = new AnimationSet(true);
Animation alpha = new AlphaAnimation(1, 0);
scale.setDuration(duration);
@@ -3156,20 +3197,18 @@
a = set;
} else if (enter) {
// Entering app zooms out from the center of the thumbnail.
- a = new ScaleAnimation(
- thumbWidth/mAppDisplayWidth, 1,
- thumbHeight/mAppDisplayHeight, 1,
- mNextAppTransitionStartX + thumbWidth/2,
- mNextAppTransitionStartY + thumbHeight/2);
+ float scaleW = thumbWidth/mAppDisplayWidth;
+ float scaleH = thumbHeight/mAppDisplayHeight;
+ a = new ScaleAnimation(scaleW, 1, scaleH, 1,
+ computePivot(mNextAppTransitionStartX, scaleW),
+ computePivot(mNextAppTransitionStartY, scaleH));
a.setDuration(duration);
} else {
- // Exiting app just holds in place.
- a = new AlphaAnimation(1, 1);
- a.setDuration(duration);
+ a = createExitAnimationLocked(transit, duration);
}
a.setFillAfter(true);
final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
- com.android.internal.R.interpolator.decelerate_quint);
+ com.android.internal.R.interpolator.decelerate_quad);
a.setInterpolator(interpolator);
a.initialize(mAppDisplayWidth, mAppDisplayHeight,
mAppDisplayWidth, mAppDisplayHeight);
@@ -3521,17 +3560,7 @@
continue;
}
- if (!haveGroup) {
- // We ignore any hidden applications on the top.
- if (wtoken.hiddenRequested || wtoken.willBeHidden) {
- if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
- + " -- hidden on top");
- continue;
- }
- haveGroup = true;
- curGroup = wtoken.groupId;
- lastOrientation = wtoken.requestedOrientation;
- } else if (curGroup != wtoken.groupId) {
+ if (haveGroup == true && curGroup != wtoken.groupId) {
// If we have hit a new application group, and the bottom
// of the previous group didn't explicitly say to use
// the orientation behind it, and the last app was
@@ -3544,6 +3573,20 @@
return lastOrientation;
}
}
+
+ // We ignore any hidden applications on the top.
+ if (wtoken.hiddenRequested || wtoken.willBeHidden) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
+ + " -- hidden on top");
+ continue;
+ }
+
+ if (!haveGroup) {
+ haveGroup = true;
+ curGroup = wtoken.groupId;
+ lastOrientation = wtoken.requestedOrientation;
+ }
+
int or = wtoken.requestedOrientation;
// If this application is fullscreen, and didn't explicitly say
// to use the orientation behind it, then just take whatever
@@ -6028,12 +6071,21 @@
return config;
}
- private int reduceConfigWidthSize(int curSize, int rotation, float density, int dw, int dh) {
- int size = (int)(mPolicy.getConfigDisplayWidth(dw, dh, rotation) / density);
- if (size < curSize) {
- curSize = size;
+ private void adjustDisplaySizeRanges(int rotation, int dw, int dh) {
+ final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
+ if (width < mSmallestDisplayWidth) {
+ mSmallestDisplayWidth = width;
}
- return curSize;
+ if (width > mLargestDisplayWidth) {
+ mLargestDisplayWidth = width;
+ }
+ final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
+ if (height < mSmallestDisplayHeight) {
+ mSmallestDisplayHeight = height;
+ }
+ if (height > mLargestDisplayHeight) {
+ mLargestDisplayHeight = height;
+ }
}
private int reduceConfigLayout(int curLayout, int rotation, float density,
@@ -6115,7 +6167,7 @@
return curLayout;
}
- private void computeSmallestWidthAndScreenLayout(boolean rotated, int dw, int dh,
+ private void computeSizeRangesAndScreenLayout(boolean rotated, int dw, int dh,
float density, Configuration outConfig) {
// We need to determine the smallest width that will occur under normal
// operation. To this, start with the base screen size and compute the
@@ -6129,17 +6181,21 @@
unrotDw = dw;
unrotDh = dh;
}
- int sw = reduceConfigWidthSize(unrotDw, Surface.ROTATION_0, density, unrotDw, unrotDh);
- sw = reduceConfigWidthSize(sw, Surface.ROTATION_90, density, unrotDh, unrotDw);
- sw = reduceConfigWidthSize(sw, Surface.ROTATION_180, density, unrotDw, unrotDh);
- sw = reduceConfigWidthSize(sw, Surface.ROTATION_270, density, unrotDh, unrotDw);
+ mSmallestDisplayWidth = 1<<30;
+ mSmallestDisplayHeight = 1<<30;
+ mLargestDisplayWidth = 0;
+ mLargestDisplayHeight = 0;
+ adjustDisplaySizeRanges(Surface.ROTATION_0, unrotDw, unrotDh);
+ adjustDisplaySizeRanges(Surface.ROTATION_90, unrotDh, unrotDw);
+ adjustDisplaySizeRanges(Surface.ROTATION_180, unrotDw, unrotDh);
+ adjustDisplaySizeRanges(Surface.ROTATION_270, unrotDh, unrotDw);
int sl = Configuration.SCREENLAYOUT_SIZE_XLARGE
| Configuration.SCREENLAYOUT_LONG_YES;
sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
- outConfig.smallestScreenWidthDp = sw;
+ outConfig.smallestScreenWidthDp = (int)(mSmallestDisplayWidth / density);
outConfig.screenLayout = sl;
}
@@ -6249,7 +6305,7 @@
/ dm.density);
config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
/ dm.density);
- computeSmallestWidthAndScreenLayout(rotated, dw, dh, dm.density, config);
+ computeSizeRangesAndScreenLayout(rotated, dw, dh, dm.density, config);
config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
@@ -6450,6 +6506,13 @@
KeyEvent.KEYCODE_VOLUME_DOWN);
mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
|| volumeDownState > 0;
+ try {
+ if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
+ mSafeMode = true;
+ SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
+ }
+ } catch (IllegalArgumentException e) {
+ }
if (mSafeMode) {
Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
+ " dpad=" + dpadState + " trackball=" + trackballState + ")");
@@ -6561,6 +6624,7 @@
public static final int SET_WALLPAPER_OFFSET = ANIMATOR_WHAT_OFFSET + 2;
public static final int SET_DIM_PARAMETERS = ANIMATOR_WHAT_OFFSET + 3;
public static final int SET_MOVE_ANIMATION = ANIMATOR_WHAT_OFFSET + 4;
+ public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 5;
private Session mLastReportedHold;
@@ -7013,7 +7077,8 @@
}
if (doRequest) {
- requestTraversalLocked();
+ mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
+ performLayoutAndPlaceSurfacesLocked();
}
}
break;
@@ -7054,6 +7119,11 @@
scheduleAnimationLocked();
break;
}
+
+ case CLEAR_PENDING_ACTIONS: {
+ mAnimator.clearPendingActions();
+ break;
+ }
}
if (DEBUG_WINDOW_TRACE) {
Slog.v(TAG, "handleMessage: exit");
@@ -7159,6 +7229,15 @@
}
}
+ public void getCurrentSizeRange(Point smallestSize, Point largestSize) {
+ synchronized(mDisplaySizeLock) {
+ smallestSize.x = mSmallestDisplayWidth;
+ smallestSize.y = mSmallestDisplayHeight;
+ largestSize.x = mLargestDisplayWidth;
+ largestSize.y = mLargestDisplayHeight;
+ }
+ }
+
public void setForcedDisplaySize(int longDimen, int shortDimen) {
synchronized(mWindowMap) {
int width, height;
@@ -8129,7 +8208,7 @@
boolean recoveringMemory) {
if (DEBUG_WINDOW_TRACE) {
Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
- + getCallers(3));
+ + Debug.getCallers(3));
}
if (mDisplay == null) {
Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
@@ -9351,14 +9430,25 @@
pw.println();
if (mDisplay != null) {
pw.print(" Display: init="); pw.print(mInitialDisplayWidth); pw.print("x");
- pw.print(mInitialDisplayHeight); pw.print(" base=");
- pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
+ pw.print(mInitialDisplayHeight);
+ if (mInitialDisplayWidth != mBaseDisplayWidth
+ || mInitialDisplayHeight != mBaseDisplayHeight) {
+ pw.print(" base=");
+ pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
+ }
+ final int rawWidth = mDisplay.getRawWidth();
+ final int rawHeight = mDisplay.getRawHeight();
+ if (rawWidth != mCurDisplayWidth || rawHeight != mCurDisplayHeight) {
+ pw.print(" raw="); pw.print(rawWidth); pw.print("x"); pw.print(rawHeight);
+ }
pw.print(" cur=");
pw.print(mCurDisplayWidth); pw.print("x"); pw.print(mCurDisplayHeight);
pw.print(" app=");
pw.print(mAppDisplayWidth); pw.print("x"); pw.print(mAppDisplayHeight);
- pw.print(" raw="); pw.print(mDisplay.getRawWidth());
- pw.print("x"); pw.println(mDisplay.getRawHeight());
+ pw.print(" rng="); pw.print(mSmallestDisplayWidth);
+ pw.print("x"); pw.print(mSmallestDisplayHeight);
+ pw.print("-"); pw.print(mLargestDisplayWidth);
+ pw.print("x"); pw.println(mLargestDisplayHeight);
} else {
pw.println(" NO DISPLAY");
}
@@ -9621,27 +9711,4 @@
mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams,
pendingLayoutChanges));
}
-
- /**
- * Never call directly. Only call through getCallers(int) or getCaller(). Otherwise
- * the depth will be off.
- * @param depth What level stack to return.
- * @return A String indicating who the caller of the method that calls this is.
- */
- static String getCaller(int depth) {
- StackTraceElement caller = Thread.currentThread().getStackTrace()[5 + depth];
- return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
- }
-
- static String getCallers(final int depth) {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < depth; i++) {
- sb.append(getCaller(i)).append(" ");
- }
- return sb.toString();
- }
-
- static String getCaller() {
- return getCallers(1);
- }
}
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index b61ccbf..74e3304 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -15,6 +15,7 @@
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
+import android.os.Debug;
import android.os.RemoteException;
import android.util.Slog;
import android.view.Surface;
@@ -185,6 +186,7 @@
if (mAnimation != null) {
mAnimation.cancel();
mAnimation = null;
+ mLocalAnimating = false;
destroySurfaceLocked();
}
}
@@ -261,9 +263,6 @@
// If the display is frozen, and there is a pending animation,
// clear it and make sure we run the cleanup code.
mAnimating = true;
- mLocalAnimating = true;
- mAnimation.cancel();
- mAnimation = null;
}
if (!mAnimating && !mLocalAnimating) {
@@ -421,7 +420,7 @@
super(s, pid, display, w, h, format, flags);
mSize = new Point(w, h);
Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
}
public SurfaceTrace(SurfaceSession s,
@@ -431,7 +430,7 @@
mName = name;
mSize = new Point(w, h);
Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
}
@Override
@@ -439,7 +438,7 @@
super.setAlpha(alpha);
mSurfaceTraceAlpha = alpha;
Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
}
@Override
@@ -447,7 +446,7 @@
super.setLayer(zorder);
mLayer = zorder;
Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
sSurfaces.remove(this);
int i;
@@ -465,7 +464,7 @@
super.setPosition(x, y);
mPosition = new PointF(x, y);
Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
}
@Override
@@ -473,7 +472,7 @@
super.setSize(w, h);
mSize = new Point(w, h);
Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
}
@Override
@@ -481,21 +480,21 @@
super.hide();
mShown = false;
Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
}
@Override
public void show() {
super.show();
mShown = true;
Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
}
@Override
public void destroy() {
super.destroy();
Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
sSurfaces.remove(this);
}
@@ -503,7 +502,7 @@
public void release() {
super.release();
Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
- + WindowManagerService.getCallers(3));
+ + Debug.getCallers(3));
sSurfaces.remove(this);
}
@@ -877,11 +876,14 @@
": " + mWin.mShownFrame +
", alpha=" + mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha);
return;
+ } else if (mWin.mIsWallpaper &&
+ (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) {
+ return;
}
if (WindowManagerService.localLOGV) Slog.v(
- TAG, "computeShownFrameLocked: " + this +
- " not attached, mAlpha=" + mAlpha);
+ TAG, "computeShownFrameLocked: " + this +
+ " not attached, mAlpha=" + mAlpha);
mWin.mShownFrame.set(mWin.mFrame);
if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
@@ -919,19 +921,19 @@
mSurfaceH = height;
}
- if (mSurfaceX != w.mShownFrame.left
- || mSurfaceY != w.mShownFrame.top) {
+ final float left = w.mShownFrame.left;
+ final float top = w.mShownFrame.top;
+ if (mSurfaceX != left || mSurfaceY != top) {
try {
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
- "POS " + w.mShownFrame.left
- + ", " + w.mShownFrame.top, null);
- mSurfaceX = w.mShownFrame.left;
- mSurfaceY = w.mShownFrame.top;
- mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
+ "POS " + left + ", " + top, null);
+ mSurfaceX = left;
+ mSurfaceY = top;
+ mSurface.setPosition(left, top);
} catch (RuntimeException e) {
Slog.w(TAG, "Error positioning surface of " + w
- + " pos=(" + w.mShownFrame.left
- + "," + w.mShownFrame.top + ")", e);
+ + " pos=(" + left
+ + "," + top + ")", e);
if (!recoveringMemory) {
mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
}
@@ -1135,17 +1137,15 @@
+ " animating=" + mAnimating
+ " tok animating="
+ (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false));
- if (!showSurfaceRobustlyLocked()) {
- return false;
- }
mService.enableScreenIfNeededLocked();
applyEnterAnimationLocked();
+ // Force the show in the next prepareSurfaceLocked() call.
mLastAlpha = -1;
- mLastHidden = false;
mDrawState = HAS_DRAWN;
+ mService.scheduleAnimationLocked();
int i = mWin.mChildWindows.size();
while (i > 0) {
@@ -1178,12 +1178,7 @@
// will do an animation to reveal it from behind the
// starting window, so there is no need for it to also
// be doing its own stuff.
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
- // Make sure we clean up the animation.
- mAnimating = true;
- }
+ clearAnimation();
mService.mFinishedStarting.add(mWin.mAppToken);
mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
}
@@ -1287,6 +1282,7 @@
if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
"applyAnimation: win=" + this
+ " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
+ + " a=" + a
+ " mAnimation=" + mAnimation
+ " isEntrance=" + isEntrance);
if (a != null) {
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index ac4fd15..e2bd622 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -22,7 +22,8 @@
$(JNI_H_INCLUDE) \
frameworks/base/services \
frameworks/base/core/jni \
- external/skia/include/core
+ external/skia/include/core \
+ libcore/include
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 3795074..b2a2429 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -46,6 +46,9 @@
#include <android_view_PointerIcon.h>
#include <android/graphics/GraphicsJNI.h>
+#include <ScopedLocalRef.h>
+#include <ScopedUtfChars.h>
+
#include "com_android_server_PowerManagerService.h"
#include "com_android_server_input_InputApplicationHandle.h"
#include "com_android_server_input_InputWindowHandle.h"
@@ -79,6 +82,8 @@
jmethodID getLongPressTimeout;
jmethodID getPointerLayer;
jmethodID getPointerIcon;
+ jmethodID getKeyboardLayoutOverlay;
+ jmethodID getDeviceAlias;
} gServiceClassInfo;
static struct {
@@ -185,6 +190,8 @@
virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);
virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices);
+ virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const String8& inputDeviceDescriptor);
+ virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier);
/* --- InputDispatcherPolicyInterface implementation --- */
@@ -522,6 +529,44 @@
checkAndClearExceptionFromCallback(env, "notifyInputDevicesChanged");
}
+sp<KeyCharacterMap> NativeInputManager::getKeyboardLayoutOverlay(
+ const String8& inputDeviceDescriptor) {
+ JNIEnv* env = jniEnv();
+
+ sp<KeyCharacterMap> result;
+ ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.string()));
+ ScopedLocalRef<jobjectArray> arrayObj(env, jobjectArray(env->CallObjectMethod(mServiceObj,
+ gServiceClassInfo.getKeyboardLayoutOverlay, descriptorObj.get())));
+ if (arrayObj.get()) {
+ ScopedLocalRef<jstring> filenameObj(env,
+ jstring(env->GetObjectArrayElement(arrayObj.get(), 0)));
+ ScopedLocalRef<jstring> contentsObj(env,
+ jstring(env->GetObjectArrayElement(arrayObj.get(), 1)));
+ ScopedUtfChars filenameChars(env, filenameObj.get());
+ ScopedUtfChars contentsChars(env, contentsObj.get());
+
+ KeyCharacterMap::loadContents(String8(filenameChars.c_str()),
+ String8(contentsChars.c_str()), KeyCharacterMap::FORMAT_OVERLAY, &result);
+ }
+ checkAndClearExceptionFromCallback(env, "getKeyboardLayoutOverlay");
+ return result;
+}
+
+String8 NativeInputManager::getDeviceAlias(const InputDeviceIdentifier& identifier) {
+ JNIEnv* env = jniEnv();
+
+ ScopedLocalRef<jstring> uniqueIdObj(env, env->NewStringUTF(identifier.uniqueId.string()));
+ ScopedLocalRef<jstring> aliasObj(env, jstring(env->CallObjectMethod(mServiceObj,
+ gServiceClassInfo.getDeviceAlias, uniqueIdObj.get())));
+ String8 result;
+ if (aliasObj.get()) {
+ ScopedUtfChars aliasChars(env, aliasObj.get());
+ result.setTo(aliasChars.c_str());
+ }
+ checkAndClearExceptionFromCallback(env, "getDeviceAlias");
+ return result;
+}
+
void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
int32_t switchValue, uint32_t policyFlags) {
#if DEBUG_INPUT_DISPATCHER_POLICY
@@ -1258,6 +1303,22 @@
im->getInputManager()->getReader()->cancelVibrate(deviceId, token);
}
+static void nativeReloadKeyboardLayouts(JNIEnv* env,
+ jclass clazz, jint ptr) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+ im->getInputManager()->getReader()->requestRefreshConfiguration(
+ InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS);
+}
+
+static void nativeReloadDeviceAliases(JNIEnv* env,
+ jclass clazz, jint ptr) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+ im->getInputManager()->getReader()->requestRefreshConfiguration(
+ InputReaderConfiguration::CHANGE_DEVICE_ALIAS);
+}
+
static jstring nativeDump(JNIEnv* env, jclass clazz, jint ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1323,6 +1384,10 @@
(void*) nativeVibrate },
{ "nativeCancelVibrate", "(III)V",
(void*) nativeCancelVibrate },
+ { "nativeReloadKeyboardLayouts", "(I)V",
+ (void*) nativeReloadKeyboardLayouts },
+ { "nativeReloadDeviceAliases", "(I)V",
+ (void*) nativeReloadDeviceAliases },
{ "nativeDump", "(I)Ljava/lang/String;",
(void*) nativeDump },
{ "nativeMonitor", "(I)V",
@@ -1418,6 +1483,12 @@
GET_METHOD_ID(gServiceClassInfo.getPointerIcon, clazz,
"getPointerIcon", "()Landroid/view/PointerIcon;");
+ GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz,
+ "getKeyboardLayoutOverlay", "(Ljava/lang/String;)[Ljava/lang/String;");
+
+ GET_METHOD_ID(gServiceClassInfo.getDeviceAlias, clazz,
+ "getDeviceAlias", "(Ljava/lang/String;)Ljava/lang/String;");
+
// InputDevice
FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 16ddd91..d3b667f 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -316,7 +316,7 @@
static int cmp(void const* lhs, void const* rhs) {
sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
- return r->timestamp - l->timestamp;
+ return l->timestamp - r->timestamp;
}
};
qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
diff --git a/telephony/java/android/telephony/CellBroadcastMessage.java b/telephony/java/android/telephony/CellBroadcastMessage.java
new file mode 100644
index 0000000..36c238d
--- /dev/null
+++ b/telephony/java/android/telephony/CellBroadcastMessage.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2011 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.telephony;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.Typeface;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.provider.Telephony;
+import android.telephony.SmsCbCmasInfo;
+import android.telephony.SmsCbEtwsInfo;
+import android.telephony.SmsCbLocation;
+import android.telephony.SmsCbMessage;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.format.DateUtils;
+import android.text.style.StyleSpan;
+
+/**
+ * Application wrapper for {@link SmsCbMessage}. This is Parcelable so that
+ * decoded broadcast message objects can be passed between running Services.
+ * New broadcasts are received by the CellBroadcastReceiver app, which exports
+ * the database of previously received broadcasts at "content://cellbroadcasts/".
+ * The "android.permission.READ_CELL_BROADCASTS" permission is required to read
+ * from the ContentProvider, and writes to the database are not allowed.<p>
+ *
+ * Use {@link #createFromCursor} to create CellBroadcastMessage objects from rows
+ * in the database cursor returned by the ContentProvider.
+ *
+ * {@hide}
+ */
+public class CellBroadcastMessage implements Parcelable {
+
+ /** Identifier for getExtra() when adding this object to an Intent. */
+ public static final String SMS_CB_MESSAGE_EXTRA =
+ "com.android.cellbroadcastreceiver.SMS_CB_MESSAGE";
+
+ /** SmsCbMessage. */
+ private final SmsCbMessage mSmsCbMessage;
+
+ private final long mDeliveryTime;
+ private boolean mIsRead;
+
+ public CellBroadcastMessage(SmsCbMessage message) {
+ mSmsCbMessage = message;
+ mDeliveryTime = System.currentTimeMillis();
+ mIsRead = false;
+ }
+
+ private CellBroadcastMessage(SmsCbMessage message, long deliveryTime, boolean isRead) {
+ mSmsCbMessage = message;
+ mDeliveryTime = deliveryTime;
+ mIsRead = isRead;
+ }
+
+ private CellBroadcastMessage(Parcel in) {
+ mSmsCbMessage = new SmsCbMessage(in);
+ mDeliveryTime = in.readLong();
+ mIsRead = (in.readInt() != 0);
+ }
+
+ /** Parcelable: no special flags. */
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ mSmsCbMessage.writeToParcel(out, flags);
+ out.writeLong(mDeliveryTime);
+ out.writeInt(mIsRead ? 1 : 0);
+ }
+
+ public static final Parcelable.Creator<CellBroadcastMessage> CREATOR
+ = new Parcelable.Creator<CellBroadcastMessage>() {
+ public CellBroadcastMessage createFromParcel(Parcel in) {
+ return new CellBroadcastMessage(in);
+ }
+
+ public CellBroadcastMessage[] newArray(int size) {
+ return new CellBroadcastMessage[size];
+ }
+ };
+
+ /**
+ * Create a CellBroadcastMessage from a row in the database.
+ * @param cursor an open SQLite cursor pointing to the row to read
+ * @return the new CellBroadcastMessage
+ * @throws IllegalArgumentException if one of the required columns is missing
+ */
+ public static CellBroadcastMessage createFromCursor(Cursor cursor) {
+ int geoScope = cursor.getInt(
+ cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE));
+ int serialNum = cursor.getInt(
+ cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERIAL_NUMBER));
+ int category = cursor.getInt(
+ cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERVICE_CATEGORY));
+ String language = cursor.getString(
+ cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.LANGUAGE_CODE));
+ String body = cursor.getString(
+ cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_BODY));
+ int format = cursor.getInt(
+ cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_FORMAT));
+ int priority = cursor.getInt(
+ cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_PRIORITY));
+
+ String plmn;
+ int plmnColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.PLMN);
+ if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) {
+ plmn = cursor.getString(plmnColumn);
+ } else {
+ plmn = null;
+ }
+
+ int lac;
+ int lacColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.LAC);
+ if (lacColumn != -1 && !cursor.isNull(lacColumn)) {
+ lac = cursor.getInt(lacColumn);
+ } else {
+ lac = -1;
+ }
+
+ int cid;
+ int cidColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.CID);
+ if (cidColumn != -1 && !cursor.isNull(cidColumn)) {
+ cid = cursor.getInt(cidColumn);
+ } else {
+ cid = -1;
+ }
+
+ SmsCbLocation location = new SmsCbLocation(plmn, lac, cid);
+
+ SmsCbEtwsInfo etwsInfo;
+ int etwsWarningTypeColumn = cursor.getColumnIndex(
+ Telephony.CellBroadcasts.ETWS_WARNING_TYPE);
+ if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) {
+ int warningType = cursor.getInt(etwsWarningTypeColumn);
+ etwsInfo = new SmsCbEtwsInfo(warningType, false, false, null);
+ } else {
+ etwsInfo = null;
+ }
+
+ SmsCbCmasInfo cmasInfo;
+ int cmasMessageClassColumn = cursor.getColumnIndex(
+ Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS);
+ if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) {
+ int messageClass = cursor.getInt(cmasMessageClassColumn);
+
+ int cmasCategory;
+ int cmasCategoryColumn = cursor.getColumnIndex(
+ Telephony.CellBroadcasts.CMAS_CATEGORY);
+ if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) {
+ cmasCategory = cursor.getInt(cmasCategoryColumn);
+ } else {
+ cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN;
+ }
+
+ int responseType;
+ int cmasResponseTypeColumn = cursor.getColumnIndex(
+ Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE);
+ if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) {
+ responseType = cursor.getInt(cmasResponseTypeColumn);
+ } else {
+ responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN;
+ }
+
+ int severity;
+ int cmasSeverityColumn = cursor.getColumnIndex(
+ Telephony.CellBroadcasts.CMAS_SEVERITY);
+ if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) {
+ severity = cursor.getInt(cmasSeverityColumn);
+ } else {
+ severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
+ }
+
+ int urgency;
+ int cmasUrgencyColumn = cursor.getColumnIndex(
+ Telephony.CellBroadcasts.CMAS_URGENCY);
+ if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) {
+ urgency = cursor.getInt(cmasUrgencyColumn);
+ } else {
+ urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
+ }
+
+ int certainty;
+ int cmasCertaintyColumn = cursor.getColumnIndex(
+ Telephony.CellBroadcasts.CMAS_CERTAINTY);
+ if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) {
+ certainty = cursor.getInt(cmasCertaintyColumn);
+ } else {
+ certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
+ }
+
+ cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity,
+ urgency, certainty);
+ } else {
+ cmasInfo = null;
+ }
+
+ SmsCbMessage msg = new SmsCbMessage(format, geoScope, serialNum, location, category,
+ language, body, priority, etwsInfo, cmasInfo);
+
+ long deliveryTime = cursor.getLong(cursor.getColumnIndexOrThrow(
+ Telephony.CellBroadcasts.DELIVERY_TIME));
+ boolean isRead = (cursor.getInt(cursor.getColumnIndexOrThrow(
+ Telephony.CellBroadcasts.MESSAGE_READ)) != 0);
+
+ return new CellBroadcastMessage(msg, deliveryTime, isRead);
+ }
+
+ /**
+ * Return a ContentValues object for insertion into the database.
+ * @return a new ContentValues object containing this object's data
+ */
+ public ContentValues getContentValues() {
+ ContentValues cv = new ContentValues(16);
+ SmsCbMessage msg = mSmsCbMessage;
+ cv.put(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE, msg.getGeographicalScope());
+ SmsCbLocation location = msg.getLocation();
+ if (location.getPlmn() != null) {
+ cv.put(Telephony.CellBroadcasts.PLMN, location.getPlmn());
+ }
+ if (location.getLac() != -1) {
+ cv.put(Telephony.CellBroadcasts.LAC, location.getLac());
+ }
+ if (location.getCid() != -1) {
+ cv.put(Telephony.CellBroadcasts.CID, location.getCid());
+ }
+ cv.put(Telephony.CellBroadcasts.SERIAL_NUMBER, msg.getSerialNumber());
+ cv.put(Telephony.CellBroadcasts.SERVICE_CATEGORY, msg.getServiceCategory());
+ cv.put(Telephony.CellBroadcasts.LANGUAGE_CODE, msg.getLanguageCode());
+ cv.put(Telephony.CellBroadcasts.MESSAGE_BODY, msg.getMessageBody());
+ cv.put(Telephony.CellBroadcasts.DELIVERY_TIME, mDeliveryTime);
+ cv.put(Telephony.CellBroadcasts.MESSAGE_READ, mIsRead);
+ cv.put(Telephony.CellBroadcasts.MESSAGE_FORMAT, msg.getMessageFormat());
+ cv.put(Telephony.CellBroadcasts.MESSAGE_PRIORITY, msg.getMessagePriority());
+
+ SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
+ if (etwsInfo != null) {
+ cv.put(Telephony.CellBroadcasts.ETWS_WARNING_TYPE, etwsInfo.getWarningType());
+ }
+
+ SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo();
+ if (cmasInfo != null) {
+ cv.put(Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS, cmasInfo.getMessageClass());
+ cv.put(Telephony.CellBroadcasts.CMAS_CATEGORY, cmasInfo.getCategory());
+ cv.put(Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE, cmasInfo.getResponseType());
+ cv.put(Telephony.CellBroadcasts.CMAS_SEVERITY, cmasInfo.getSeverity());
+ cv.put(Telephony.CellBroadcasts.CMAS_URGENCY, cmasInfo.getUrgency());
+ cv.put(Telephony.CellBroadcasts.CMAS_CERTAINTY, cmasInfo.getCertainty());
+ }
+
+ return cv;
+ }
+
+ /**
+ * Set or clear the "read message" flag.
+ * @param isRead true if the message has been read; false if not
+ */
+ public void setIsRead(boolean isRead) {
+ mIsRead = isRead;
+ }
+
+ public String getLanguageCode() {
+ return mSmsCbMessage.getLanguageCode();
+ }
+
+ public int getServiceCategory() {
+ return mSmsCbMessage.getServiceCategory();
+ }
+
+ public long getDeliveryTime() {
+ return mDeliveryTime;
+ }
+
+ public String getMessageBody() {
+ return mSmsCbMessage.getMessageBody();
+ }
+
+ public boolean isRead() {
+ return mIsRead;
+ }
+
+ public int getSerialNumber() {
+ return mSmsCbMessage.getSerialNumber();
+ }
+
+ public SmsCbCmasInfo getCmasWarningInfo() {
+ return mSmsCbMessage.getCmasWarningInfo();
+ }
+
+ public SmsCbEtwsInfo getEtwsWarningInfo() {
+ return mSmsCbMessage.getEtwsWarningInfo();
+ }
+
+ /**
+ * Return whether the broadcast is an emergency (PWS) message type.
+ * This includes lower priority test messages and Amber alerts.
+ *
+ * All public alerts show the flashing warning icon in the dialog,
+ * but only emergency alerts play the alert sound and speak the message.
+ *
+ * @return true if the message is PWS type; false otherwise
+ */
+ public boolean isPublicAlertMessage() {
+ return mSmsCbMessage.isEmergencyMessage();
+ }
+
+ /**
+ * Returns whether the broadcast is an emergency (PWS) message type,
+ * including test messages, but excluding lower priority Amber alert broadcasts.
+ *
+ * @return true if the message is PWS type, excluding Amber alerts
+ */
+ public boolean isEmergencyAlertMessage() {
+ if (!mSmsCbMessage.isEmergencyMessage()) {
+ return false;
+ }
+ SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo();
+ if (cmasInfo != null &&
+ cmasInfo.getMessageClass() == SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return whether the broadcast is an ETWS emergency message type.
+ * @return true if the message is ETWS emergency type; false otherwise
+ */
+ public boolean isEtwsMessage() {
+ return mSmsCbMessage.isEtwsMessage();
+ }
+
+ /**
+ * Return whether the broadcast is a CMAS emergency message type.
+ * @return true if the message is CMAS emergency type; false otherwise
+ */
+ public boolean isCmasMessage() {
+ return mSmsCbMessage.isCmasMessage();
+ }
+
+ /**
+ * Return the CMAS message class.
+ * @return the CMAS message class, e.g. {@link SmsCbCmasInfo#CMAS_CLASS_SEVERE_THREAT}, or
+ * {@link SmsCbCmasInfo#CMAS_CLASS_UNKNOWN} if this is not a CMAS alert
+ */
+ public int getCmasMessageClass() {
+ if (mSmsCbMessage.isCmasMessage()) {
+ return mSmsCbMessage.getCmasWarningInfo().getMessageClass();
+ } else {
+ return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
+ }
+ }
+
+ /**
+ * Return whether the broadcast is an ETWS popup alert.
+ * This method checks the message ID and the message code.
+ * @return true if the message indicates an ETWS popup alert
+ */
+ public boolean isEtwsPopupAlert() {
+ SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
+ return etwsInfo != null && etwsInfo.isPopupAlert();
+ }
+
+ /**
+ * Return whether the broadcast is an ETWS emergency user alert.
+ * This method checks the message ID and the message code.
+ * @return true if the message indicates an ETWS emergency user alert
+ */
+ public boolean isEtwsEmergencyUserAlert() {
+ SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
+ return etwsInfo != null && etwsInfo.isEmergencyUserAlert();
+ }
+
+ /**
+ * Return whether the broadcast is an ETWS test message.
+ * @return true if the message is an ETWS test message; false otherwise
+ */
+ public boolean isEtwsTestMessage() {
+ SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
+ return etwsInfo != null &&
+ etwsInfo.getWarningType() == SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE;
+ }
+
+ /**
+ * Return the abbreviated date string for the message delivery time.
+ * @param context the context object
+ * @return a String to use in the broadcast list UI
+ */
+ public String getDateString(Context context) {
+ int flags = DateUtils.FORMAT_NO_NOON_MIDNIGHT | DateUtils.FORMAT_SHOW_TIME |
+ DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE |
+ DateUtils.FORMAT_CAP_AMPM;
+ return DateUtils.formatDateTime(context, mDeliveryTime, flags);
+ }
+
+ /**
+ * Return the date string for the message delivery time, suitable for text-to-speech.
+ * @param context the context object
+ * @return a String for populating the list item AccessibilityEvent for TTS
+ */
+ public String getSpokenDateString(Context context) {
+ int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE;
+ return DateUtils.formatDateTime(context, mDeliveryTime, flags);
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index a124c7f..da03f76 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -209,7 +209,7 @@
protected static final int EVENT_RIL_CONNECTED = BASE + 5;
protected static final int EVENT_DISCONNECT_ALL = BASE + 6;
- private static final int CMD_TO_STRING_COUNT = EVENT_DISCONNECT_ALL + 1;
+ private static final int CMD_TO_STRING_COUNT = EVENT_DISCONNECT_ALL - BASE + 1;
private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
static {
sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT";
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionAc.java b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
index 4744ff0..96419ae 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionAc.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
@@ -82,7 +82,7 @@
public static final int REQ_GET_RECONNECT_INTENT = BASE + 26;
public static final int RSP_GET_RECONNECT_INTENT = BASE + 27;
- private static final int CMD_TO_STRING_COUNT = RSP_GET_RECONNECT_INTENT + 1;
+ private static final int CMD_TO_STRING_COUNT = RSP_GET_RECONNECT_INTENT - BASE + 1;
private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
static {
sCmdToString[REQ_IS_INACTIVE - BASE] = "REQ_IS_INACTIVE";
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 214627d..55f2ca3 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -46,7 +46,6 @@
import com.android.internal.R;
import com.android.internal.telephony.DataConnection.FailCause;
-import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
@@ -58,7 +57,6 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
/**
* {@hide}
@@ -140,7 +138,6 @@
public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 30;
public static final int CMD_SET_DEPENDENCY_MET = BASE + 31;
public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32;
- protected static final int EVENT_ICC_CHANGED = BASE + 33;
/***** Constants *****/
@@ -253,8 +250,6 @@
// member variables
protected PhoneBase mPhone;
- protected UiccController mUiccController;
- protected AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
protected Activity mActivity = Activity.NONE;
protected State mState = State.IDLE;
protected Handler mDataConnectionTracker = null;
@@ -505,8 +500,6 @@
protected DataConnectionTracker(PhoneBase phone) {
super();
mPhone = phone;
- mUiccController = UiccController.getInstance();
- mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
IntentFilter filter = new IntentFilter();
filter.addAction(getActionIntentReconnectAlarm());
@@ -548,7 +541,6 @@
mIsDisposed = true;
mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
mDataRoamingSettingObserver.unregister(mPhone.getContext());
- mUiccController.unregisterForIccChanged(this);
}
protected void broadcastMessenger() {
@@ -671,7 +663,6 @@
protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason);
protected abstract void onCleanUpAllConnections(String cause);
protected abstract boolean isDataPossible(String apnType);
- protected abstract void onUpdateIcc();
protected void onDataStallAlarm(int tag) {
loge("onDataStallAlarm: not impleted tag=" + tag);
@@ -782,10 +773,6 @@
onSetPolicyDataEnabled(enabled);
break;
}
- case EVENT_ICC_CHANGED:
- onUpdateIcc();
- break;
-
default:
Log.e("DATA", "Unidentified event msg=" + msg);
break;
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index 140b7c6..92024cd 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -35,12 +35,10 @@
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.CommandsInterface.RadioState;
-import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.SIMFileHandler;
import com.android.internal.telephony.gsm.SIMRecords;
import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.internal.telephony.cdma.CdmaLteUiccFileHandler;
import com.android.internal.telephony.cdma.CdmaLteUiccRecords;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
@@ -116,6 +114,8 @@
protected static final int EVENT_ICC_LOCKED = 1;
private static final int EVENT_GET_ICC_STATUS_DONE = 2;
protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3;
+ private static final int EVENT_PINPUK_DONE = 4;
+ private static final int EVENT_REPOLL_STATUS_DONE = 5;
protected static final int EVENT_ICC_READY = 6;
private static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7;
private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8;
@@ -178,19 +178,34 @@
return State.UNKNOWN;
}
- public IccCard(PhoneBase phone, IccCardStatus ics, String logTag, boolean dbg) {
+ public IccCard(PhoneBase phone, String logTag, Boolean is3gpp, Boolean dbg) {
mLogTag = logTag;
mDbg = dbg;
- if (mDbg) log("Creating");
- update(phone, ics);
+ if (mDbg) log("[IccCard] Creating card type " + (is3gpp ? "3gpp" : "3gpp2"));
+ mPhone = phone;
+ this.is3gpp = is3gpp;
mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(),
mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
+ if (phone.mCM.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE
+ && phone instanceof CDMALTEPhone) {
+ mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM);
+ mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM);
+ } else {
+ // Correct aid will be set later (when GET_SIM_STATUS returns)
+ mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) :
+ new RuimFileHandler(this, "", mPhone.mCM);
+ mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) :
+ new RuimRecords(this, mPhone.mContext, mPhone.mCM);
+ }
+ mCatService = CatService.getInstance(mPhone.mCM, mIccRecords,
+ mPhone.mContext, mIccFileHandler, this);
mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mPhone.mCM.registerForOn(mHandler, EVENT_RADIO_ON, null);
+ mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_STATUS_CHANGED, null);
}
public void dispose() {
- if (mDbg) log("Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
+ if (mDbg) log("[IccCard] Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
mPhone.mCM.unregisterForIccStatusChanged(mHandler);
mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
mPhone.mCM.unregisterForOn(mHandler);
@@ -200,40 +215,6 @@
mIccFileHandler.dispose();
}
- public void update(PhoneBase phone, IccCardStatus ics) {
- if (phone != mPhone) {
- PhoneBase oldPhone = mPhone;
- mPhone = phone;
- log("Update");
- if (phone instanceof GSMPhone) {
- is3gpp = true;
- } else if (phone instanceof CDMALTEPhone){
- is3gpp = true;
- } else if (phone instanceof CDMAPhone){
- is3gpp = false;
- } else {
- throw new RuntimeException("Update: Unhandled phone type. Critical error!" +
- phone.getPhoneName());
- }
-
-
- if (phone.mCM.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE
- && phone instanceof CDMALTEPhone) {
- mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM);
- mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM);
- } else {
- // Correct aid will be set later (when GET_SIM_STATUS returns)
- mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) :
- new RuimFileHandler(this, "", mPhone.mCM);
- mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) :
- new RuimRecords(this, mPhone.mContext, mPhone.mCM);
- }
- mCatService = CatService.getInstance(mPhone.mCM, mIccRecords, mPhone.mContext,
- mIccFileHandler, this);
- }
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_GET_ICC_STATUS_DONE, ics));
- }
-
protected void finalize() {
if (mDbg) log("[IccCard] Finalized card type " + (is3gpp ? "3gpp" : "3gpp2"));
}
@@ -363,23 +344,27 @@
*/
public void supplyPin (String pin, Message onComplete) {
- mPhone.mCM.supplyIccPin(pin, onComplete);
+ mPhone.mCM.supplyIccPin(pin, mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk (String puk, String newPin, Message onComplete) {
- mPhone.mCM.supplyIccPuk(puk, newPin, onComplete);
+ mPhone.mCM.supplyIccPuk(puk, newPin,
+ mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPin2 (String pin2, Message onComplete) {
- mPhone.mCM.supplyIccPin2(pin2, onComplete);
+ mPhone.mCM.supplyIccPin2(pin2,
+ mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
- mPhone.mCM.supplyIccPuk2(puk2, newPin2, onComplete);
+ mPhone.mCM.supplyIccPuk2(puk2, newPin2,
+ mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyNetworkDepersonalization (String pin, Message onComplete) {
- mPhone.mCM.supplyNetworkDepersonalization(pin, onComplete);
+ mPhone.mCM.supplyNetworkDepersonalization(pin,
+ mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
/**
@@ -509,15 +494,21 @@
*
*/
public String getServiceProviderName () {
- return mIccRecords.getServiceProviderName();
+ return mPhone.mIccRecords.getServiceProviderName();
}
protected void updateStateProperty() {
mPhone.setSystemProperty(TelephonyProperties.PROPERTY_SIM_STATE, getState().toString());
}
- private void getIccCardStatusDone(IccCardStatus ics) {
- handleIccCardStatus(ics);
+ private void getIccCardStatusDone(AsyncResult ar) {
+ if (ar.exception != null) {
+ Log.e(mLogTag,"Error getting ICC status. "
+ + "RIL_REQUEST_GET_ICC_STATUS should "
+ + "never return an error", ar.exception);
+ return;
+ }
+ handleIccCardStatus((IccCardStatus) ar.result);
}
private void handleIccCardStatus(IccCardStatus newCardStatus) {
@@ -593,7 +584,6 @@
if (oldState != State.READY && newState == State.READY &&
(is3gpp || isSubscriptionFromIccCard)) {
mIccFileHandler.setAid(getAid());
- broadcastIccStateChangedIntent(INTENT_VALUE_ICC_READY, null);
mIccRecords.onReady();
}
}
@@ -714,6 +704,7 @@
if (!is3gpp) {
handleCdmaSubscriptionSource();
}
+ mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
break;
case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
handleCdmaSubscriptionSource();
@@ -734,9 +725,30 @@
obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
break;
case EVENT_GET_ICC_STATUS_DONE:
- IccCardStatus cs = (IccCardStatus)msg.obj;
+ ar = (AsyncResult)msg.obj;
- getIccCardStatusDone(cs);
+ getIccCardStatusDone(ar);
+ break;
+ case EVENT_PINPUK_DONE:
+ // a PIN/PUK/PIN2/PUK2/Network Personalization
+ // request has completed. ar.userObj is the response Message
+ // Repoll before returning
+ ar = (AsyncResult)msg.obj;
+ // TODO should abstract these exceptions
+ AsyncResult.forMessage(((Message)ar.userObj)).exception
+ = ar.exception;
+ mPhone.mCM.getIccCardStatus(
+ obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));
+ break;
+ case EVENT_REPOLL_STATUS_DONE:
+ // Finished repolling status after PIN operation
+ // ar.userObj is the response messaeg
+ // ar.userObj.obj is already an AsyncResult with an
+ // appropriate exception filled in if applicable
+
+ ar = (AsyncResult)msg.obj;
+ getIccCardStatusDone(ar);
+ ((Message)ar.userObj).sendToTarget();
break;
case EVENT_QUERY_FACILITY_LOCK_DONE:
ar = (AsyncResult)msg.obj;
@@ -785,6 +797,10 @@
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
+ case EVENT_ICC_STATUS_CHANGED:
+ Log.d(mLogTag, "Received Event EVENT_ICC_STATUS_CHANGED");
+ mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
+ break;
case EVENT_CARD_REMOVED:
onIccSwap(false);
break;
@@ -951,10 +967,6 @@
Log.d(mLogTag, "[IccCard] " + msg);
}
- private void loge(String msg) {
- Log.e(mLogTag, "[IccCard] " + msg);
- }
-
protected int getCurrentApplicationIndex() {
if (is3gpp) {
return mIccCardStatus.getGsmUmtsSubscriptionAppIndex();
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 0e5f2da..45562ca 100644
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -103,23 +103,11 @@
public IccPhoneBookInterfaceManager(PhoneBase phone) {
this.phone = phone;
- IccRecords r = phone.mIccRecords.get();
- if (r != null) {
- adnCache = r.getAdnCache();
- }
}
public void dispose() {
}
- public void updateIccRecords(IccRecords iccRecords) {
- if (iccRecords != null) {
- adnCache = iccRecords.getAdnCache();
- } else {
- adnCache = null;
- }
- }
-
protected void publish() {
//NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
ServiceManager.addService("simphonebook", this);
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index 3c906471a..41c9d5a 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -26,8 +26,6 @@
import com.android.internal.telephony.gsm.UsimServiceTable;
import com.android.internal.telephony.ims.IsimRecords;
-import java.util.concurrent.atomic.AtomicBoolean;
-
/**
* {@hide}
*/
@@ -35,7 +33,7 @@
protected static final boolean DBG = true;
// ***** Instance Variables
- protected AtomicBoolean mDestroyed = new AtomicBoolean(false);
+ protected boolean mDestroyed = false; // set to true once this object needs to be disposed of
protected Context mContext;
protected CommandsInterface mCi;
protected IccFileHandler mFh;
@@ -81,9 +79,9 @@
// ***** Event Constants
protected static final int EVENT_SET_MSISDN_DONE = 30;
- public static final int EVENT_MWI = 0; // Message Waiting indication
- public static final int EVENT_CFI = 1; // Call Forwarding indication
- public static final int EVENT_SPN = 2; // Service Provider Name
+ public static final int EVENT_MWI = 0;
+ public static final int EVENT_CFI = 1;
+ public static final int EVENT_SPN = 2;
public static final int EVENT_GET_ICC_RECORD_DONE = 100;
@@ -115,7 +113,7 @@
* Call when the IccRecords object is no longer going to be used.
*/
public void dispose() {
- mDestroyed.set(true);
+ mDestroyed = true;
mParentCard = null;
mFh = null;
mCi = null;
@@ -130,8 +128,12 @@
return adnCache;
}
+ public IccCard getIccCard() {
+ return mParentCard;
+ }
+
public void registerForRecordsLoaded(Handler h, int what, Object obj) {
- if (mDestroyed.get()) {
+ if (mDestroyed) {
return;
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 0c2f234..2ac9365 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -40,7 +40,6 @@
import com.android.internal.telephony.gsm.UsimServiceTable;
import com.android.internal.telephony.ims.IsimRecords;
import com.android.internal.telephony.test.SimulatedRadioControl;
-import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.gsm.SIMRecords;
import java.io.FileDescriptor;
@@ -111,7 +110,6 @@
protected static final int EVENT_SET_NETWORK_AUTOMATIC = 28;
protected static final int EVENT_NEW_ICC_SMS = 29;
protected static final int EVENT_ICC_RECORD_EVENTS = 30;
- protected static final int EVENT_ICC_CHANGED = 31;
// Key used to read/write current CLIR setting
public static final String CLIR_KEY = "clir_key";
@@ -128,8 +126,7 @@
int mCallRingDelay;
public boolean mIsTheCurrentActivePhone = true;
boolean mIsVoiceCapable = true;
- protected UiccController mUiccController = null;
- public AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
+ public IccRecords mIccRecords;
protected AtomicReference<IccCard> mIccCard = new AtomicReference<IccCard>();
public SmsStorageMonitor mSmsStorageMonitor;
public SmsUsageMonitor mSmsUsageMonitor;
@@ -254,8 +251,6 @@
// Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
mSmsStorageMonitor = new SmsStorageMonitor(this);
mSmsUsageMonitor = new SmsUsageMonitor(context);
- mUiccController = UiccController.getInstance(this);
- mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
}
public void dispose() {
@@ -267,7 +262,6 @@
// Dispose the SMS usage and storage monitors
mSmsStorageMonitor.dispose();
mSmsUsageMonitor.dispose();
- mUiccController.unregisterForIccChanged(this);
}
}
@@ -275,10 +269,9 @@
mSmsStorageMonitor = null;
mSmsUsageMonitor = null;
mSMS = null;
- mIccRecords.set(null);
+ mIccRecords = null;
mIccCard.set(null);
mDataConnectionTracker = null;
- mUiccController = null;
}
/**
@@ -315,10 +308,6 @@
}
break;
- case EVENT_ICC_CHANGED:
- onUpdateIccAvailability();
- break;
-
default:
throw new RuntimeException("unexpected event not handled");
}
@@ -329,9 +318,6 @@
return mContext;
}
- // Will be called when icc changed
- protected abstract void onUpdateIccAvailability();
-
/**
* Disables the DNS check (i.e., allows "0.0.0.0").
* Useful for lab testing environment.
@@ -680,26 +666,22 @@
@Override
public String getIccSerialNumber() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.iccid : "";
+ return mIccRecords.iccid;
}
@Override
public boolean getIccRecordsLoaded() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getRecordsLoaded() : false;
+ return mIccRecords.getRecordsLoaded();
}
@Override
public boolean getMessageWaitingIndicator() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getVoiceMessageWaiting() : false;
+ return mIccRecords.getVoiceMessageWaiting();
}
@Override
public boolean getCallForwardingIndicator() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getVoiceCallForwardingFlag() : false;
+ return mIccRecords.getVoiceCallForwardingFlag();
}
/**
@@ -1153,10 +1135,7 @@
*/
@Override
public void setVoiceMessageWaiting(int line, int countWaiting) {
- IccRecords r = mIccRecords.get();
- if (r != null) {
- r.setVoiceMessageWaiting(line, countWaiting);
- }
+ mIccRecords.setVoiceMessageWaiting(line, countWaiting);
}
/**
@@ -1165,8 +1144,7 @@
*/
@Override
public UsimServiceTable getUsimServiceTable() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getUsimServiceTable() : null;
+ return mIccRecords.getUsimServiceTable();
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index a86b68b..75eb226 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -18,15 +18,12 @@
import android.os.AsyncResult;
import android.os.Handler;
-import android.os.Looper;
import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
-import com.android.internal.telephony.uicc.UiccController;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -36,9 +33,6 @@
public abstract class ServiceStateTracker extends Handler {
protected CommandsInterface cm;
- protected UiccController mUiccController = null;
- protected IccCard mIccCard = null;
- protected IccRecords mIccRecords = null;
public ServiceState ss;
protected ServiceState newSS;
@@ -136,7 +130,7 @@
protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 39;
protected static final int EVENT_CDMA_PRL_VERSION_CHANGED = 40;
protected static final int EVENT_RADIO_ON = 41;
- protected static final int EVENT_ICC_CHANGED = 42;
+
protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
@@ -173,10 +167,7 @@
protected static final String REGISTRATION_DENIED_GEN = "General";
protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
- public ServiceStateTracker(PhoneBase p, CommandsInterface ci) {
- cm = ci;
- mUiccController = UiccController.getInstance();
- mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
+ public ServiceStateTracker() {
}
public boolean getDesiredPowerState() {
@@ -303,10 +294,6 @@
}
break;
- case EVENT_ICC_CHANGED:
- onUpdateIccAvailability();
- break;
-
default:
log("Unhandled message with number: " + msg.what);
break;
@@ -317,7 +304,6 @@
protected abstract void handlePollStateResult(int what, AsyncResult ar);
protected abstract void updateSpnDisplay();
protected abstract void setPowerStateToDesired();
- protected abstract void onUpdateIccAvailability();
protected abstract void log(String s);
protected abstract void loge(String s);
@@ -477,21 +463,6 @@
pollingContext = new int[1];
}
- /**
- * Verifies the current thread is the same as the thread originally
- * used in the initialization of this instance. Throws RuntimeException
- * if not.
- *
- * @exception RuntimeException if the current thread is not
- * the thread that originally obtained this PhoneBase instance.
- */
- protected void checkCorrectThread() {
- if (Thread.currentThread() != getLooper().getThread()) {
- throw new RuntimeException(
- "ServiceStateTracker must be used from within one thread");
- }
- }
-
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("ServiceStateTracker:");
pw.println(" ss=" + ss);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index 24bb814..d99a625 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -29,7 +29,6 @@
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.OperatorInfo;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneNotifier;
@@ -67,6 +66,7 @@
public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
super(context, ci, notifier, false);
m3gppSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
+ mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
}
@Override
@@ -88,6 +88,10 @@
@Override
protected void initSstIcc() {
+ mIccCard.set(UiccController.getInstance(this).getIccCard());
+ mIccRecords = mIccCard.get().getIccRecords();
+ // CdmaLteServiceStateTracker registers with IccCard to know
+ // when the card is ready. So create mIccCard before the ServiceStateTracker
mSST = new CdmaLteServiceStateTracker(this);
}
@@ -96,6 +100,7 @@
synchronized(PhoneProxy.lockForRadioTechnologyChange) {
super.dispose();
m3gppSMS.dispose();
+ mIccRecords.unregisterForNewSms(this);
}
}
@@ -198,12 +203,11 @@
@Override
public boolean updateCurrentCarrierInProvider() {
- IccRecords r = mIccRecords.get();
- if (r != null) {
+ if (mIccRecords != null) {
try {
Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
ContentValues map = new ContentValues();
- String operatorNumeric = r.getOperatorNumeric();
+ String operatorNumeric = mIccRecords.getOperatorNumeric();
map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
if (DBG) log("updateCurrentCarrierInProvider from UICC: numeric=" +
operatorNumeric);
@@ -221,8 +225,7 @@
// return IMSI from USIM as subscriber ID.
@Override
public String getSubscriberId() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getIMSI() : "";
+ return mIccRecords.getIMSI();
}
@Override
@@ -237,14 +240,12 @@
@Override
public IsimRecords getIsimRecords() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getIsimRecords() : null;
+ return mIccRecords.getIsimRecords();
}
@Override
public String getMsisdn() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getMsisdnNumber() : null;
+ return mIccRecords.getMsisdnNumber();
}
@Override
@@ -258,26 +259,6 @@
}
@Override
- protected void registerForRuimRecordEvents() {
- IccRecords r = mIccRecords.get();
- if (r == null) {
- return;
- }
- r.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
- super.registerForRuimRecordEvents();
- }
-
- @Override
- protected void unregisterForRuimRecordEvents() {
- IccRecords r = mIccRecords.get();
- if (r == null) {
- return;
- }
- r.unregisterForNewSms(this);
- super.unregisterForRuimRecordEvents();
- }
-
- @Override
protected void log(String s) {
Log.d(LOG_TAG, "[CDMALTEPhone] " + s);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 7922b3c..9f6ec71 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -50,7 +50,6 @@
import com.android.internal.telephony.IccException;
import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.IccSmsInterfaceManager;
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.MmiCode;
@@ -153,6 +152,10 @@
}
protected void initSstIcc() {
+ mIccCard.set(UiccController.getInstance(this).getIccCard());
+ mIccRecords = mIccCard.get().getIccRecords();
+ // CdmaServiceStateTracker registers with IccCard to know
+ // when the Ruim card is ready. So create mIccCard before the ServiceStateTracker
mSST = new CdmaServiceStateTracker(this);
}
@@ -169,6 +172,7 @@
mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML);
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
+ registerForRuimRecordEvents();
mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mCM.registerForOn(this, EVENT_RADIO_ON, null);
mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
@@ -723,10 +727,7 @@
Message resp;
mVmNumber = voiceMailNumber;
resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
- IccRecords r = mIccRecords.get();
- if (r != null) {
- r.setVoiceMailNumber(alphaTag, mVmNumber, resp);
- }
+ mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
}
public String getVoiceMailNumber() {
@@ -748,8 +749,7 @@
* @hide
*/
public int getVoiceMessageCount() {
- IccRecords r = mIccRecords.get();
- int voicemailCount = (r != null) ? r.getVoiceMessageCount() : 0;
+ int voicemailCount = mIccRecords.getVoiceMessageCount();
// If mRuimRecords.getVoiceMessageCount returns zero, then there is possibility
// that phone was power cycled and would have lost the voicemail count.
// So get the count from preferences.
@@ -1064,39 +1064,6 @@
}
}
- @Override
- protected void onUpdateIccAvailability() {
- if (mUiccController == null ) {
- return;
- }
-
- IccCard newIccCard = mUiccController.getIccCard();
-
- IccCard c = mIccCard.get();
- if (c != newIccCard) {
- if (c != null) {
- log("Removing stale icc objects.");
- if (mIccRecords.get() != null) {
- unregisterForRuimRecordEvents();
- if (mRuimPhoneBookInterfaceManager != null) {
- mRuimPhoneBookInterfaceManager.updateIccRecords(null);
- }
- }
- mIccRecords.set(null);
- mIccCard.set(null);
- }
- if (newIccCard != null) {
- log("New card found");
- mIccCard.set(newIccCard);
- mIccRecords.set(newIccCard.getIccRecords());
- registerForRuimRecordEvents();
- if (mRuimPhoneBookInterfaceManager != null) {
- mRuimPhoneBookInterfaceManager.updateIccRecords(mIccRecords.get());
- }
- }
- }
- }
-
private void processIccRecordEvents(int eventCode) {
switch (eventCode) {
case RuimRecords.EVENT_MWI:
@@ -1495,22 +1462,14 @@
return mEriManager.isEriFileLoaded();
}
- protected void registerForRuimRecordEvents() {
- IccRecords r = mIccRecords.get();
- if (r == null) {
- return;
- }
- r.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
- r.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
+ private void registerForRuimRecordEvents() {
+ mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
+ mIccRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
}
- protected void unregisterForRuimRecordEvents() {
- IccRecords r = mIccRecords.get();
- if (r == null) {
- return;
- }
- r.unregisterForRecordsEvents(this);
- r.unregisterForRecordsLoaded(this);
+ private void unregisterForRuimRecordEvents() {
+ mIccRecords.unregisterForRecordsEvents(this);
+ mIccRecords.unregisterForRecordsLoaded(this);
}
protected void log(String s) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index d05ed624..7e5e707 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -40,8 +40,6 @@
import com.android.internal.telephony.DataConnectionAc;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.Phone;
@@ -112,6 +110,7 @@
p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
+ p.mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
@@ -153,8 +152,7 @@
// Unregister from all events
mPhone.mCM.unregisterForAvailable(this);
mPhone.mCM.unregisterForOffOrNotAvailable(this);
- IccRecords r = mIccRecords.get();
- if (r != null) { r.unregisterForRecordsLoaded(this);}
+ mCdmaPhone.mIccRecords.unregisterForRecordsLoaded(this);
mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
@@ -224,12 +222,11 @@
boolean subscriptionFromNv = (mCdmaSSM.getCdmaSubscriptionSource()
== CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV);
- IccRecords r = mIccRecords.get();
boolean allowed =
(psState == ServiceState.STATE_IN_SERVICE ||
mAutoAttachOnCreation) &&
(subscriptionFromNv ||
- (r != null && r.getRecordsLoaded())) &&
+ mCdmaPhone.mIccRecords.getRecordsLoaded()) &&
(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
mPhone.getState() == Phone.State.IDLE) &&
!roaming &&
@@ -244,7 +241,7 @@
reason += " - psState= " + psState;
}
if (!subscriptionFromNv &&
- !(r != null && r.getRecordsLoaded())) {
+ !mCdmaPhone.mIccRecords.getRecordsLoaded()) {
reason += " - RUIM not loaded";
}
if (!(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
@@ -1009,33 +1006,6 @@
}
@Override
- protected void onUpdateIcc() {
- if (mUiccController == null ) {
- return;
- }
-
- IccCard newIccCard = mUiccController.getIccCard();
- IccRecords newIccRecords = null;
- if (newIccCard != null) {
- newIccRecords = newIccCard.getIccRecords();
- }
-
- IccRecords r = mIccRecords.get();
- if (r != newIccRecords) {
- if (r != null) {
- log("Removing stale icc objects.");
- r.unregisterForRecordsLoaded(this);
- mIccRecords.set(null);
- }
- if (newIccCard != null) {
- log("New card found");
- mIccRecords.set(newIccRecords);
- newIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
- }
- }
- }
-
- @Override
public boolean isDisconnected() {
return ((mState == State.IDLE) || (mState == State.FAILED));
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 9a82f57..ff7a0810 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -65,7 +65,7 @@
handlePollStateResult(msg.what, ar);
break;
case EVENT_RUIM_RECORDS_LOADED:
- CdmaLteUiccRecords sim = (CdmaLteUiccRecords)mIccRecords;
+ CdmaLteUiccRecords sim = (CdmaLteUiccRecords)phone.mIccRecords;
if ((sim != null) && sim.isProvisioned()) {
mMdn = sim.getMdn();
mMin = sim.getMin();
@@ -353,18 +353,16 @@
ss.setOperatorAlphaLong(eriText);
}
- if (mIccCard != null && mIccCard.getState() == IccCard.State.READY &&
- mIccRecords != null) {
+ if (phone.getIccCard().getState() == IccCard.State.READY) {
// SIM is found on the device. If ERI roaming is OFF, and SID/NID matches
// one configfured in SIM, use operator name from CSIM record.
boolean showSpn =
- ((CdmaLteUiccRecords)mIccRecords).getCsimSpnDisplayCondition();
+ ((CdmaLteUiccRecords)phone.mIccRecords).getCsimSpnDisplayCondition();
int iconIndex = ss.getCdmaEriIconIndex();
if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) &&
- isInHomeSidNid(ss.getSystemId(), ss.getNetworkId()) &&
- mIccRecords != null) {
- ss.setOperatorAlphaLong(mIccRecords.getServiceProviderName());
+ isInHomeSidNid(ss.getSystemId(), ss.getNetworkId())) {
+ ss.setOperatorAlphaLong(phone.mIccRecords.getServiceProviderName());
}
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 16ff70e..b694e0a 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -115,6 +115,12 @@
long mSavedTime;
long mSavedAtTime;
+ /**
+ * We can't register for SIM_RECORDS_LOADED immediately because the
+ * SIMRecords object may not be instantiated yet.
+ */
+ private boolean mNeedToRegForRuimLoaded = false;
+
/** Wake lock used while setting time of day. */
private PowerManager.WakeLock mWakeLock;
private static final String WAKELOCK_TAG = "ServiceStateTracker";
@@ -156,10 +162,11 @@
};
public CdmaServiceStateTracker(CDMAPhone phone) {
- super(phone, phone.mCM);
+ super();
this.phone = phone;
cr = phone.getContext().getContentResolver();
+ cm = phone.mCM;
ss = new ServiceState();
newSS = new ServiceState();
cellLoc = new CdmaCellLocation();
@@ -196,17 +203,18 @@
Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true,
mAutoTimeZoneObserver);
setSignalStrengthDefaultValues();
+
+ mNeedToRegForRuimLoaded = true;
}
public void dispose() {
- checkCorrectThread();
// Unregister for all events.
cm.unregisterForRadioStateChanged(this);
cm.unregisterForVoiceNetworkStateChanged(this);
+ phone.getIccCard().unregisterForReady(this);
cm.unregisterForCdmaOtaProvision(this);
phone.unregisterForEriFileLoaded(this);
- if (mIccCard != null) {mIccCard.unregisterForReady(this);}
- if (mIccRecords != null) {mIccRecords.unregisterForRecordsLoaded(this);}
+ phone.mIccRecords.unregisterForRecordsLoaded(this);
cm.unSetOnSignalStrengthUpdate(this);
cm.unSetOnNITZTime(this);
cr.unregisterContentObserver(mAutoTimeObserver);
@@ -277,6 +285,14 @@
case EVENT_RUIM_READY:
// TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST.
// cm.setCurrentPreferredNetworkType();
+
+ // The RUIM is now ready i.e if it was locked it has been
+ // unlocked. At this stage, the radio is already powered on.
+ if (mNeedToRegForRuimLoaded) {
+ phone.mIccRecords.registerForRecordsLoaded(this,
+ EVENT_RUIM_RECORDS_LOADED, null);
+ mNeedToRegForRuimLoaded = false;
+ }
if (DBG) log("Receive EVENT_RUIM_READY and Send Request getCDMASubscription.");
getSubscriptionInfoAndStartPollingThreads();
phone.prepareEri();
@@ -389,16 +405,8 @@
mIsMinInfoReady = true;
updateOtaspState();
- if (mIccCard != null) {
- if (DBG) log("GET_CDMA_SUBSCRIPTION broadcast Icc state changed");
- mIccCard.broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
- null);
- } else {
- if (DBG) {
- log("GET_CDMA_SUBSCRIPTION mIccCard is null (probably NV type device)" +
- " can't broadcast Icc state changed");
- }
- }
+ phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
+ null);
} else {
if (DBG) {
log("GET_CDMA_SUBSCRIPTION: error parsing cdmaSubscription params num="
@@ -490,6 +498,8 @@
if (!isSubscriptionFromRuim) {
// NV is ready when subscription source is NV
sendMessage(obtainMessage(EVENT_NV_READY));
+ } else {
+ phone.getIccCard().registerForReady(this, EVENT_RUIM_READY, null);
}
}
@@ -1685,38 +1695,6 @@
}
@Override
- protected void onUpdateIccAvailability() {
- if (mUiccController == null ) {
- return;
- }
-
- IccCard newIccCard = mUiccController.getIccCard();
-
- if (mIccCard != newIccCard) {
- if (mIccCard != null) {
- log("Removing stale icc objects.");
- mIccCard.unregisterForReady(this);
- if (mIccRecords != null) {
- mIccRecords.unregisterForRecordsLoaded(this);
- }
- mIccRecords = null;
- mIccCard = null;
- }
- if (newIccCard != null) {
- log("New card found");
- mIccCard = newIccCard;
- mIccRecords = mIccCard.getIccRecords();
- if (isSubscriptionFromRuim) {
- mIccCard.registerForReady(this, EVENT_RUIM_READY, null);
- if (mIccRecords != null) {
- mIccRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
- }
- }
- }
- }
- }
-
- @Override
protected void log(String s) {
Log.d(LOG_TAG, "[CdmaSST] " + s);
}
@@ -1749,6 +1727,7 @@
pw.println(" mSavedTimeZone=" + mSavedTimeZone);
pw.println(" mSavedTime=" + mSavedTime);
pw.println(" mSavedAtTime=" + mSavedAtTime);
+ pw.println(" mNeedToRegForRuimLoaded=" + mNeedToRegForRuimLoaded);
pw.println(" mWakeLock=" + mWakeLock);
pw.println(" mCurPlmn=" + mCurPlmn);
pw.println(" mMdn=" + mMdn);
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
index e919245..04ee2dd8 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
@@ -21,7 +21,6 @@
import android.os.Message;
import android.util.Log;
-import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
/**
@@ -35,6 +34,7 @@
public RuimPhoneBookInterfaceManager(CDMAPhone phone) {
super(phone);
+ adnCache = phone.mIccRecords.getAdnCache();
//NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
}
@@ -61,12 +61,8 @@
AtomicBoolean status = new AtomicBoolean(false);
Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
- IccFileHandler fh = phone.getIccFileHandler();
- //IccFileHandler can be null if there is no icc card present.
- if (fh != null) {
- fh.getEFLinearRecordSize(efid, response);
- waitForResult(status);
- }
+ phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
+ waitForResult(status);
}
return recordSize;
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index 80183c6..2fefa3f 100755
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -199,7 +199,7 @@
boolean isRecordLoadResponse = false;
- if (mDestroyed.get()) {
+ if (mDestroyed) {
loge("Received message " + msg +
"[" + msg.what + "] while being destroyed. Ignoring.");
return;
@@ -317,20 +317,18 @@
// One record loaded successfully or failed, In either case
// we need to update the recordsToLoad count
recordsToLoad -= 1;
- if (DBG) log("onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested);
+ if (DBG) log("RuimRecords:onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested);
if (recordsToLoad == 0 && recordsRequested == true) {
onAllRecordsLoaded();
} else if (recordsToLoad < 0) {
- loge("recordsToLoad <0, programmer error suspected");
+ loge("RuimRecords: recordsToLoad <0, programmer error suspected");
recordsToLoad = 0;
}
}
@Override
protected void onAllRecordsLoaded() {
- if (DBG) log("record load complete");
-
// Further records that can be inserted are Operator/OEM dependent
String operator = getRUIMOperatorNumeric();
@@ -350,6 +348,13 @@
@Override
public void onReady() {
+ /* broadcast intent ICC_READY here so that we can make sure
+ READY is sent before IMSI ready
+ */
+
+ mParentCard.broadcastIccStateChangedIntent(
+ IccCard.INTENT_VALUE_ICC_READY, null);
+
fetchRuimRecords();
mCi.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
@@ -359,7 +364,7 @@
private void fetchRuimRecords() {
recordsRequested = true;
- if (DBG) log("fetchRuimRecords " + recordsToLoad);
+ Log.v(LOG_TAG, "RuimRecords:fetchRuimRecords " + recordsToLoad);
mCi.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE));
recordsToLoad++;
@@ -368,7 +373,7 @@
obtainMessage(EVENT_GET_ICCID_DONE));
recordsToLoad++;
- if (DBG) log("fetchRuimRecords " + recordsToLoad + " requested: " + recordsRequested);
+ log("RuimRecords:fetchRuimRecords " + recordsToLoad + " requested: " + recordsRequested);
// Further records that can be inserted are Operator/OEM dependent
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index 8dda74b..6e9cd51 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -59,7 +59,6 @@
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.IccSmsInterfaceManager;
import com.android.internal.telephony.MmiCode;
import com.android.internal.telephony.OperatorInfo;
@@ -138,11 +137,13 @@
if (ci instanceof SimulatedRadioControl) {
mSimulatedRadioControl = (SimulatedRadioControl) ci;
}
+
mCM.setPhoneType(Phone.PHONE_TYPE_GSM);
+ mIccCard.set(UiccController.getInstance(this).getIccCard());
+ mIccRecords = mIccCard.get().getIccRecords();
mCT = new GsmCallTracker(this);
mSST = new GsmServiceStateTracker (this);
mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
-
mDataConnectionTracker = new GsmDataConnectionTracker (this);
if (!unitTestMode) {
mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this);
@@ -151,6 +152,7 @@
}
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
+ registerForSimRecordEvents();
mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mCM.registerForOn(this, EVENT_RADIO_ON, null);
mCM.setOnUSSD(this, EVENT_USSD, null);
@@ -794,8 +796,7 @@
public String getVoiceMailNumber() {
// Read from the SIM. If its null, try reading from the shared preference area.
- IccRecords r = mIccRecords.get();
- String number = (r != null) ? r.getVoiceMailNumber() : "";
+ String number = mIccRecords.getVoiceMailNumber();
if (TextUtils.isEmpty(number)) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
number = sp.getString(VM_NUMBER, null);
@@ -817,9 +818,8 @@
public String getVoiceMailAlphaTag() {
String ret;
- IccRecords r = mIccRecords.get();
- ret = (r != null) ? r.getVoiceMailAlphaTag() : "";
+ ret = mIccRecords.getVoiceMailAlphaTag();
if (ret == null || ret.length() == 0) {
return mContext.getText(
@@ -852,31 +852,24 @@
}
public String getSubscriberId() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getIMSI() : "";
+ return mIccRecords.getIMSI();
}
public String getLine1Number() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getMsisdnNumber() : "";
+ return mIccRecords.getMsisdnNumber();
}
@Override
public String getMsisdn() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getMsisdnNumber() : "";
+ return mIccRecords.getMsisdnNumber();
}
public String getLine1AlphaTag() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.getMsisdnAlphaTag() : "";
+ return mIccRecords.getMsisdnAlphaTag();
}
public void setLine1Number(String alphaTag, String number, Message onComplete) {
- IccRecords r = mIccRecords.get();
- if (r != null) {
- r.setMsisdnNumber(alphaTag, number, onComplete);
- }
+ mIccRecords.setMsisdnNumber(alphaTag, number, onComplete);
}
public void setVoiceMailNumber(String alphaTag,
@@ -886,10 +879,7 @@
Message resp;
mVmNumber = voiceMailNumber;
resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
- IccRecords r = mIccRecords.get();
- if (r != null) {
- r.setVoiceMailNumber(alphaTag, mVmNumber, resp);
- }
+ mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
}
private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) {
@@ -1257,9 +1247,8 @@
case EVENT_SET_CALL_FORWARD_DONE:
ar = (AsyncResult)msg.obj;
- IccRecords r = mIccRecords.get();
- if (ar.exception == null && r != null) {
- r.setVoiceCallForwardingFlag(1, msg.arg1 == 1);
+ if (ar.exception == null) {
+ mIccRecords.setVoiceCallForwardingFlag(1, msg.arg1 == 1);
}
onComplete = (Message) ar.userObj;
if (onComplete != null) {
@@ -1332,41 +1321,12 @@
}
}
- @Override
- protected void onUpdateIccAvailability() {
- if (mUiccController == null ) {
- return;
- }
-
- IccCard newIccCard = mUiccController.getIccCard();
-
- IccCard c = mIccCard.get();
- if (c != newIccCard) {
- if (c != null) {
- if (LOCAL_DEBUG) log("Removing stale icc objects.");
- if (mIccRecords.get() != null) {
- unregisterForSimRecordEvents();
- mSimPhoneBookIntManager.updateIccRecords(null);
- }
- mIccRecords.set(null);
- mIccCard.set(null);
- }
- if (newIccCard != null) {
- if (LOCAL_DEBUG) log("New card found");
- mIccCard.set(newIccCard);
- mIccRecords.set(newIccCard.getIccRecords());
- registerForSimRecordEvents();
- mSimPhoneBookIntManager.updateIccRecords(mIccRecords.get());
- }
- }
- }
-
private void processIccRecordEvents(int eventCode) {
switch (eventCode) {
- case IccRecords.EVENT_CFI:
+ case SIMRecords.EVENT_CFI:
notifyCallForwardingIndicator();
break;
- case IccRecords.EVENT_MWI:
+ case SIMRecords.EVENT_MWI:
notifyMessageWaitingIndicator();
break;
}
@@ -1378,12 +1338,11 @@
* @return true for success; false otherwise.
*/
boolean updateCurrentCarrierInProvider() {
- IccRecords r = mIccRecords.get();
- if (r != null) {
+ if (mIccRecords != null) {
try {
Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
ContentValues map = new ContentValues();
- map.put(Telephony.Carriers.NUMERIC, r.getOperatorNumeric());
+ map.put(Telephony.Carriers.NUMERIC, mIccRecords.getOperatorNumeric());
mContext.getContentResolver().insert(uri, map);
return true;
} catch (SQLException e) {
@@ -1445,19 +1404,16 @@
}
private void handleCfuQueryResult(CallForwardInfo[] infos) {
- IccRecords r = mIccRecords.get();
- if (r != null) {
- if (infos == null || infos.length == 0) {
- // Assume the default is not active
- // Set unconditional CFF in SIM to false
- r.setVoiceCallForwardingFlag(1, false);
- } else {
- for (int i = 0, s = infos.length; i < s; i++) {
- if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) {
- r.setVoiceCallForwardingFlag(1, (infos[i].status == 1));
- // should only have the one
- break;
- }
+ if (infos == null || infos.length == 0) {
+ // Assume the default is not active
+ // Set unconditional CFF in SIM to false
+ mIccRecords.setVoiceCallForwardingFlag(1, false);
+ } else {
+ for (int i = 0, s = infos.length; i < s; i++) {
+ if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) {
+ mIccRecords.setVoiceCallForwardingFlag(1, (infos[i].status == 1));
+ // should only have the one
+ break;
}
}
}
@@ -1516,35 +1472,22 @@
}
public boolean isCspPlmnEnabled() {
- IccRecords r = mIccRecords.get();
- return (r != null) ? r.isCspPlmnEnabled() : false;
+ return mIccRecords.isCspPlmnEnabled();
}
private void registerForSimRecordEvents() {
- IccRecords r = mIccRecords.get();
- if (r == null) {
- return;
- }
- r.registerForNetworkSelectionModeAutomatic(
+ mIccRecords.registerForNetworkSelectionModeAutomatic(
this, EVENT_SET_NETWORK_AUTOMATIC, null);
- r.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
- r.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
- r.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
+ mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
+ mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
+ mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
}
private void unregisterForSimRecordEvents() {
- IccRecords r = mIccRecords.get();
- if (r == null) {
- return;
- }
- r.unregisterForNetworkSelectionModeAutomatic(this);
- r.unregisterForNewSms(this);
- r.unregisterForRecordsEvents(this);
- r.unregisterForRecordsLoaded(this);
- }
-
- protected void log(String s) {
- Log.d(LOG_TAG, "[GSMPhone] " + s);
+ mIccRecords.unregisterForNetworkSelectionModeAutomatic(this);
+ mIccRecords.unregisterForNewSms(this);
+ mIccRecords.unregisterForRecordsEvents(this);
+ mIccRecords.unregisterForRecordsLoaded(this);
}
@Override
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index fec0158..df3278b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -91,8 +91,8 @@
int authType = mApn.authType;
if (authType == -1) {
- authType = (mApn.user != null) ? RILConstants.SETUP_DATA_AUTH_PAP_CHAP :
- RILConstants.SETUP_DATA_AUTH_NONE;
+ authType = TextUtils.isEmpty(mApn.user) ? RILConstants.SETUP_DATA_AUTH_NONE
+ : RILConstants.SETUP_DATA_AUTH_PAP_CHAP;
}
String protocol;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index b44ba0b..40ee58c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -59,8 +59,6 @@
import com.android.internal.telephony.DataConnectionAc;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.RILConstants;
@@ -180,6 +178,7 @@
p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
+ p.mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
p.getCallTracker().registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
p.getCallTracker().registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
@@ -220,8 +219,7 @@
//Unregister for all events
mPhone.mCM.unregisterForAvailable(this);
mPhone.mCM.unregisterForOffOrNotAvailable(this);
- IccRecords r = mIccRecords.get();
- if (r != null) { r.unregisterForRecordsLoaded(this);}
+ mPhone.mIccRecords.unregisterForRecordsLoaded(this);
mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
@@ -622,12 +620,10 @@
int gprsState = mPhone.getServiceStateTracker().getCurrentDataConnectionState();
boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
- IccRecords r = mIccRecords.get();
- boolean recordsLoaded = (r != null) ? r.getRecordsLoaded() : false;
boolean allowed =
(gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
- recordsLoaded &&
+ mPhone.mIccRecords.getRecordsLoaded() &&
(mPhone.getState() == Phone.State.IDLE ||
mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
internalDataEnabled &&
@@ -639,7 +635,7 @@
if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
reason += " - gprs= " + gprsState;
}
- if (!recordsLoaded) reason += " - SIM not loaded";
+ if (!mPhone.mIccRecords.getRecordsLoaded()) reason += " - SIM not loaded";
if (mPhone.getState() != Phone.State.IDLE &&
!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
reason += " - PhoneState= " + mPhone.getState();
@@ -1900,8 +1896,7 @@
log("onRadioAvailable: We're on the simulator; assuming data is connected");
}
- IccRecords r = mIccRecords.get();
- if (r != null && r.getRecordsLoaded()) {
+ if (mPhone.mIccRecords.getRecordsLoaded()) {
notifyOffApnsOfAvailability(null);
}
@@ -2213,8 +2208,7 @@
*/
private void createAllApnList() {
mAllApns = new ArrayList<ApnSetting>();
- IccRecords r = mIccRecords.get();
- String operator = (r != null) ? r.getOperatorNumeric() : "";
+ String operator = mPhone.mIccRecords.getOperatorNumeric();
if (operator != null) {
String selection = "numeric = '" + operator + "'";
// query only enabled apn.
@@ -2325,9 +2319,8 @@
}
}
- IccRecords r = mIccRecords.get();
- String operator = (r != null) ? r.getOperatorNumeric() : "";
- int radioTech = mPhone.getServiceState().getRadioTechnology();
+ String operator = mPhone.mIccRecords.getOperatorNumeric();
+ int networkType = mPhone.getServiceState().getNetworkType();
if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
if (canSetPreferApn && mPreferredApn != null) {
@@ -2336,7 +2329,7 @@
+ mPreferredApn.numeric + ":" + mPreferredApn);
}
if (mPreferredApn.numeric.equals(operator)) {
- if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
+ if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == networkType) {
apnList.add(mPreferredApn);
if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
return apnList;
@@ -2355,7 +2348,7 @@
if (mAllApns != null) {
for (ApnSetting apn : mAllApns) {
if (apn.canHandleType(requestedApnType)) {
- if (apn.bearer == 0 || apn.bearer == radioTech) {
+ if (apn.bearer == 0 || apn.bearer == networkType) {
if (DBG) log("apn info : " +apn.toString());
apnList.add(apn);
}
@@ -2563,33 +2556,6 @@
}
@Override
- protected void onUpdateIcc() {
- if (mUiccController == null ) {
- return;
- }
-
- IccCard newIccCard = mUiccController.getIccCard();
- IccRecords newIccRecords = null;
- if (newIccCard != null) {
- newIccRecords = newIccCard.getIccRecords();
- }
-
- IccRecords r = mIccRecords.get();
- if (r != newIccRecords) {
- if (r != null) {
- log("Removing stale icc objects.");
- r.unregisterForRecordsLoaded(this);
- mIccRecords.set(null);
- }
- if (newIccCard != null) {
- log("New card found");
- mIccRecords.set(newIccRecords);
- newIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
- }
- }
- }
-
- @Override
protected void log(String s) {
Log.d(LOG_TAG, "[GsmDCT] "+ s);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 9e34b6a..9b3d5cd 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -885,10 +885,7 @@
*/
if ((ar.exception == null) && (msg.arg1 == 1)) {
boolean cffEnabled = (msg.arg2 == 1);
- IccRecords r = phone.mIccRecords.get();
- if (r != null) {
- r.setVoiceCallForwardingFlag(1, cffEnabled);
- }
+ phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
}
onSetComplete(ar);
@@ -1206,10 +1203,7 @@
(info.serviceClass & serviceClassMask)
== CommandsInterface.SERVICE_CLASS_VOICE) {
boolean cffEnabled = (info.status == 1);
- IccRecords r = phone.mIccRecords.get();
- if (r != null) {
- r.setVoiceCallForwardingFlag(1, cffEnabled);
- }
+ phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
}
return TextUtils.replace(template, sources, destinations);
@@ -1234,10 +1228,7 @@
sb.append(context.getText(com.android.internal.R.string.serviceDisabled));
// Set unconditional CFF in SIM to false
- IccRecords r = phone.mIccRecords.get();
- if (r != null) {
- r.setVoiceCallForwardingFlag(1, false);
- }
+ phone.mIccRecords.setVoiceCallForwardingFlag(1, false);
} else {
SpannableStringBuilder tb = new SpannableStringBuilder();
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 7c03d03..c0acf5b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -124,6 +124,12 @@
long mSavedTime;
long mSavedAtTime;
+ /**
+ * We can't register for SIM_RECORDS_LOADED immediately because the
+ * SIMRecords object may not be instantiated yet.
+ */
+ private boolean mNeedToRegForSimLoaded;
+
/** Started the recheck process after finding gprs should registered but not. */
private boolean mStartedGprsRegCheck = false;
@@ -186,9 +192,10 @@
};
public GsmServiceStateTracker(GSMPhone phone) {
- super(phone, phone.mCM);
+ super();
this.phone = phone;
+ cm = phone.mCM;
ss = new ServiceState();
newSS = new ServiceState();
cellLoc = new GsmCellLocation();
@@ -206,6 +213,7 @@
cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
+ phone.getIccCard().registerForReady(this, EVENT_SIM_READY, null);
// system setting property AIRPLANE_MODE_ON is set in Settings.
int airplaneMode = Settings.System.getInt(
@@ -222,6 +230,7 @@
mAutoTimeZoneObserver);
setSignalStrengthDefaultValues();
+ mNeedToRegForSimLoaded = true;
// Monitor locale change
IntentFilter filter = new IntentFilter();
@@ -233,13 +242,12 @@
}
public void dispose() {
- checkCorrectThread();
// Unregister for all events.
cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
cm.unregisterForVoiceNetworkStateChanged(this);
- if (mIccCard != null) {mIccCard.unregisterForReady(this);}
- if (mIccRecords != null) {mIccRecords.unregisterForRecordsLoaded(this);}
+ phone.getIccCard().unregisterForReady(this);
+ phone.mIccRecords.unregisterForRecordsLoaded(this);
cm.unSetOnSignalStrengthUpdate(this);
cm.unSetOnRestrictedStateChanged(this);
cm.unSetOnNITZTime(this);
@@ -277,6 +285,15 @@
// Set the network type, in case the radio does not restore it.
cm.setCurrentPreferredNetworkType();
+ // The SIM is now ready i.e if it was locked
+ // it has been unlocked. At this stage, the radio is already
+ // powered on.
+ if (mNeedToRegForSimLoaded) {
+ phone.mIccRecords.registerForRecordsLoaded(this,
+ EVENT_SIM_RECORDS_LOADED, null);
+ mNeedToRegForSimLoaded = false;
+ }
+
boolean skipRestoringSelection = phone.getContext().getResources().getBoolean(
com.android.internal.R.bool.skip_restoring_network_selection);
@@ -478,11 +495,8 @@
}
protected void updateSpnDisplay() {
- if (mIccRecords == null) {
- return;
- }
- int rule = mIccRecords.getDisplayRule(ss.getOperatorNumeric());
- String spn = mIccRecords.getServiceProviderName();
+ int rule = phone.mIccRecords.getDisplayRule(ss.getOperatorNumeric());
+ String spn = phone.mIccRecords.getServiceProviderName();
String plmn = ss.getOperatorAlphaLong();
// For emergency calls only, pass the EmergencyCallsOnly string via EXTRA_PLMN
@@ -1131,7 +1145,7 @@
((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
//ignore the normal call and data restricted state before SIM READY
- if (mIccCard.getState() == IccCard.State.READY) {
+ if (phone.getIccCard().getState() == IccCard.State.READY) {
newRs.setCsNormalRestricted(
((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
@@ -1658,35 +1672,6 @@
}
@Override
- protected void onUpdateIccAvailability() {
- if (mUiccController == null ) {
- return;
- }
-
- IccCard newIccCard = mUiccController.getIccCard();
-
- if (mIccCard != newIccCard) {
- if (mIccCard != null) {
- log("Removing stale icc objects.");
- mIccCard.unregisterForReady(this);
- if (mIccRecords != null) {
- mIccRecords.unregisterForRecordsLoaded(this);
- }
- mIccRecords = null;
- mIccCard = null;
- }
- if (newIccCard != null) {
- log("New card found");
- mIccCard = newIccCard;
- mIccRecords = mIccCard.getIccRecords();
- mIccCard.registerForReady(this, EVENT_SIM_READY, null);
- if (mIccRecords != null) {
- mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
- }
- }
- }
- }
- @Override
protected void log(String s) {
Log.d(LOG_TAG, "[GsmSST] " + s);
}
@@ -1726,6 +1711,7 @@
pw.println(" mSavedTimeZone=" + mSavedTimeZone);
pw.println(" mSavedTime=" + mSavedTime);
pw.println(" mSavedAtTime=" + mSavedAtTime);
+ pw.println(" mNeedToRegForSimLoaded=" + mNeedToRegForSimLoaded);
pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck);
pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg);
pw.println(" mNotification=" + mNotification);
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 3077995..80988fd 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -521,7 +521,7 @@
boolean isRecordLoadResponse = false;
- if (mDestroyed.get()) {
+ if (mDestroyed) {
loge("Received message " + msg + "[" + msg.what + "] " +
" while being destroyed. Ignoring.");
return;
@@ -1299,6 +1299,12 @@
@Override
public void onReady() {
+ /* broadcast intent SIM_READY here so that we can make sure
+ READY is sent before IMSI ready
+ */
+ mParentCard.broadcastIccStateChangedIntent(
+ IccCard.INTENT_VALUE_ICC_READY, null);
+
fetchSimRecords();
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
index 37f9a4f..35ba0d1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
@@ -21,7 +21,6 @@
import android.os.Message;
import android.util.Log;
-import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
/**
@@ -35,6 +34,7 @@
public SimPhoneBookInterfaceManager(GSMPhone phone) {
super(phone);
+ adnCache = phone.mIccRecords.getAdnCache();
//NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
}
@@ -61,11 +61,8 @@
AtomicBoolean status = new AtomicBoolean(false);
Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
- IccFileHandler fh = phone.getIccFileHandler();
- if (fh != null) {
- fh.getEFLinearRecordSize(efid, response);
- waitForResult(status);
- }
+ phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
+ waitForResult(status);
}
return recordSize;
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
index 0243522..5c4b446 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -461,8 +461,4 @@
notifyPhoneStateChanged();
}
}
-
- @Override
- protected void onUpdateIccAvailability() {
- }
}
diff --git a/telephony/java/com/android/internal/telephony/uicc/UiccController.java b/telephony/java/com/android/internal/telephony/uicc/UiccController.java
index 4e12d6d..5961efd 100644
--- a/telephony/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/telephony/java/com/android/internal/telephony/uicc/UiccController.java
@@ -16,150 +16,78 @@
package com.android.internal.telephony.uicc;
-import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccCardStatus;
-import com.android.internal.telephony.IccCardStatus.CardState;
import com.android.internal.telephony.PhoneBase;
+import com.android.internal.telephony.cdma.CDMALTEPhone;
+import com.android.internal.telephony.cdma.CDMAPhone;
+import com.android.internal.telephony.gsm.GSMPhone;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
import android.util.Log;
/* This class is responsible for keeping all knowledge about
* ICCs in the system. It is also used as API to get appropriate
* applications to pass them to phone and service trackers.
*/
-public class UiccController extends Handler {
+public class UiccController {
private static final boolean DBG = true;
private static final String LOG_TAG = "RIL_UiccController";
- private static final int EVENT_ICC_STATUS_CHANGED = 1;
- private static final int EVENT_GET_ICC_STATUS_DONE = 2;
-
private static UiccController mInstance;
private PhoneBase mCurrentPhone;
- private CommandsInterface mCi;
+ private boolean mIsCurrentCard3gpp;
private IccCard mIccCard;
- private boolean mRegisteredWithCi = false;
-
- private RegistrantList mIccChangedRegistrants = new RegistrantList();
public static synchronized UiccController getInstance(PhoneBase phone) {
if (mInstance == null) {
mInstance = new UiccController(phone);
- } else if (phone != null) {
+ } else {
mInstance.setNewPhone(phone);
}
return mInstance;
}
- // This method is not synchronized as getInstance(PhoneBase) is.
- public static UiccController getInstance() {
- return getInstance(null);
- }
-
- public synchronized IccCard getIccCard() {
+ public IccCard getIccCard() {
return mIccCard;
}
- //Notifies when card status changes
- public void registerForIccChanged(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mIccChangedRegistrants.add(r);
- //Notify registrant right after registering, so that it will get the latest ICC status,
- //otherwise which may not happen until there is an actual change in ICC status.
- r.notifyRegistrant();
- }
- public void unregisterForIccChanged(Handler h) {
- mIccChangedRegistrants.remove(h);
- }
-
- @Override
- public void handleMessage (Message msg) {
- switch (msg.what) {
- case EVENT_ICC_STATUS_CHANGED:
- if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
- mCi.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
- break;
- case EVENT_GET_ICC_STATUS_DONE:
- if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE");
- AsyncResult ar = (AsyncResult)msg.obj;
- onGetIccCardStatusDone(ar);
- break;
- default:
- Log.e(LOG_TAG, " Unknown Event " + msg.what);
- }
- }
-
private UiccController(PhoneBase phone) {
if (DBG) log("Creating UiccController");
setNewPhone(phone);
}
- private synchronized void onGetIccCardStatusDone(AsyncResult ar) {
- if (ar.exception != null) {
- Log.e(LOG_TAG,"Error getting ICC status. "
- + "RIL_REQUEST_GET_ICC_STATUS should "
- + "never return an error", ar.exception);
+ private void setNewPhone(PhoneBase phone) {
+ mCurrentPhone = phone;
+ if (phone instanceof GSMPhone) {
+ if (DBG) log("New phone is GSMPhone");
+ updateCurrentCard(IccCard.CARD_IS_3GPP);
+ } else if (phone instanceof CDMALTEPhone){
+ if (DBG) log("New phone type is CDMALTEPhone");
+ updateCurrentCard(IccCard.CARD_IS_3GPP);
+ } else if (phone instanceof CDMAPhone){
+ if (DBG) log("New phone type is CDMAPhone");
+ updateCurrentCard(IccCard.CARD_IS_NOT_3GPP);
+ } else {
+ Log.e(LOG_TAG, "Unhandled phone type. Critical error!");
+ }
+ }
+
+ private void updateCurrentCard(boolean isNewCard3gpp) {
+ if (mIsCurrentCard3gpp == isNewCard3gpp && mIccCard != null) {
return;
}
- IccCardStatus status = (IccCardStatus)ar.result;
-
- //Update already existing card
- if (mIccCard != null && status.getCardState() == CardState.CARDSTATE_PRESENT) {
- mIccCard.update(mCurrentPhone, status);
- }
-
- //Dispose of removed card
- if (mIccCard != null && status.getCardState() != CardState.CARDSTATE_PRESENT) {
+ if (mIccCard != null) {
mIccCard.dispose();
mIccCard = null;
}
- //Create new card
- if (mIccCard == null && status.getCardState() == CardState.CARDSTATE_PRESENT) {
- mIccCard = new IccCard(mCurrentPhone, status, mCurrentPhone.getPhoneName(), true);
- }
-
- if (DBG) log("Notifying IccChangedRegistrants");
- mIccChangedRegistrants.notifyRegistrants();
- }
-
- private void setNewPhone(PhoneBase phone) {
- if (phone == null) {
- throw new RuntimeException("Phone can't be null in UiccController");
- }
-
- if (DBG) log("setNewPhone");
- if (mCurrentPhone != phone) {
- if (mIccCard != null) {
- // Refresh card if phone changed
- // TODO: Remove once card is simplified
- if (DBG) log("Disposing card since phone object changed");
- mIccCard.dispose();
- mIccCard = null;
- }
- sendMessage(obtainMessage(EVENT_ICC_STATUS_CHANGED));
- mCurrentPhone = phone;
-
- if (!mRegisteredWithCi) {
- // This needs to be done only once after we have valid phone object
- mCi = mCurrentPhone.mCM;
- mCi.registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, null);
- // TODO remove this once modem correctly notifies the unsols
- mCi.registerForOn(this, EVENT_ICC_STATUS_CHANGED, null);
- mRegisteredWithCi = true;
- }
- }
+ mIsCurrentCard3gpp = isNewCard3gpp;
+ mIccCard = new IccCard(mCurrentPhone, mCurrentPhone.getPhoneName(),
+ isNewCard3gpp, DBG);
}
private void log(String string) {
Log.d(LOG_TAG, string);
}
-}
+}
\ No newline at end of file
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
index 740f544..d74f5f7 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
@@ -487,7 +487,7 @@
}
public void setAppCacheMaximumSize(long size) {
- WebStorage.getInstance().setAppCacheMaximumSize(size);
+ android.webkit.WebStorageClassic.getInstance().setAppCacheMaximumSize(size);
}
public void setCanOpenWindows() {
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index 77c0a3f..bbfbfc4 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -257,12 +257,14 @@
builder.setMessage("All tests finished. Exit?")
.setCancelable(false)
.setPositiveButton("Yes", new OnClickListener(){
- public void onClick(DialogInterface dialog, int which) {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
TestShellActivity.this.finish();
}
})
.setNegativeButton("No", new OnClickListener(){
- public void onClick(DialogInterface dialog, int which) {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
@@ -370,6 +372,7 @@
// .......................................
// LayoutTestController Functions
+ @Override
public void dumpAsText(boolean enablePixelTests) {
// Added after webkit update to r63859. See trac.webkit.org/changeset/63730.
if (enablePixelTests) {
@@ -384,6 +387,7 @@
}
}
+ @Override
public void dumpChildFramesAsText() {
mDumpDataType = DumpDataType.DUMP_AS_TEXT;
mDumpChildFramesAsText = true;
@@ -393,12 +397,14 @@
}
}
+ @Override
public void waitUntilDone() {
mWaitUntilDone = true;
String url = mWebView.getUrl();
Log.v(LOGTAG, "waitUntilDone called: " + url);
}
+ @Override
public void notifyDone() {
String url = mWebView.getUrl();
Log.v(LOGTAG, "notifyDone called: " + url);
@@ -410,15 +416,18 @@
}
}
+ @Override
public void display() {
mWebView.invalidate();
}
+ @Override
public void clearBackForwardList() {
mWebView.clearHistory();
}
+ @Override
public void dumpBackForwardList() {
//printf("\n============== Back Forward List ==============\n");
// mWebHistory
@@ -426,21 +435,25 @@
}
+ @Override
public void dumpChildFrameScrollPositions() {
// TODO Auto-generated method stub
}
+ @Override
public void dumpEditingCallbacks() {
// TODO Auto-generated method stub
}
+ @Override
public void dumpSelectionRect() {
// TODO Auto-generated method stub
}
+ @Override
public void dumpTitleChanges() {
if (!mDumpTitleChanges) {
mTitleChanges = new StringBuffer();
@@ -448,6 +461,7 @@
mDumpTitleChanges = true;
}
+ @Override
public void keepWebHistory() {
if (!mKeepWebHistory) {
mWebHistory = new Vector();
@@ -455,59 +469,71 @@
mKeepWebHistory = true;
}
+ @Override
public void queueBackNavigation(int howfar) {
// TODO Auto-generated method stub
}
+ @Override
public void queueForwardNavigation(int howfar) {
// TODO Auto-generated method stub
}
+ @Override
public void queueLoad(String Url, String frameTarget) {
// TODO Auto-generated method stub
}
+ @Override
public void queueReload() {
mWebView.reload();
}
+ @Override
public void queueScript(String scriptToRunInCurrentContext) {
mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext);
}
+ @Override
public void repaintSweepHorizontally() {
// TODO Auto-generated method stub
}
+ @Override
public void setAcceptsEditing(boolean b) {
// TODO Auto-generated method stub
}
+ @Override
public void setMainFrameIsFirstResponder(boolean b) {
// TODO Auto-generated method stub
}
+ @Override
public void setWindowIsKey(boolean b) {
// This is meant to show/hide the window. The best I can find
// is setEnabled()
mWebView.setEnabled(b);
}
+ @Override
public void testRepaint() {
mWebView.invalidate();
}
+ @Override
public void dumpDatabaseCallbacks() {
Log.v(LOGTAG, "dumpDatabaseCallbacks called.");
mDumpDatabaseCallbacks = true;
}
+ @Override
public void setCanOpenWindows() {
Log.v(LOGTAG, "setCanOpenWindows called.");
mCanOpenWindows = true;
@@ -516,6 +542,7 @@
/**
* Sets the Geolocation permission state to be used for all future requests.
*/
+ @Override
public void setGeolocationPermission(boolean allow) {
mIsGeolocationPermissionSet = true;
mGeolocationPermission = allow;
@@ -532,12 +559,14 @@
}
}
+ @Override
public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
WebViewClassic.fromWebView(mWebView).setMockDeviceOrientation(canProvideAlpha, alpha,
canProvideBeta, beta, canProvideGamma, gamma);
}
+ @Override
public void overridePreference(String key, boolean value) {
// TODO: We should look up the correct WebView for the frame which
// called the layoutTestController method. Currently, we just use the
@@ -554,6 +583,7 @@
}
}
+ @Override
public void setXSSAuditorEnabled (boolean flag) {
mWebViewClassic.getSettings().setXSSAuditorEnabled(flag);
}
@@ -754,6 +784,7 @@
&& mWaitUntilDone && mStopOnRefError) {
Log.w(LOGTAG, "Terminating test case on uncaught ReferenceError or TypeError.");
mHandler.postDelayed(new Runnable() {
+ @Override
public void run() {
notifyDone();
}
@@ -860,6 +891,8 @@
settings.setXSSAuditorEnabled(false);
settings.setPageCacheCapacity(0);
settings.setProperty("use_minimal_memory", "false");
+ settings.setAllowUniversalAccessFromFileURLs(true);
+ settings.setAllowFileAccessFromFileURLs(true);
}
private WebViewClassic mWebViewClassic;
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
index e608e2d..d0c59d3 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
@@ -66,7 +66,7 @@
public void setAppCacheMaximumSize(long size) {
Log.i(LOG_TAG, "setAppCacheMaximumSize() called with: " + size);
- WebStorage.getInstance().setAppCacheMaximumSize(size);
+ android.webkit.WebStorageClassic.getInstance().setAppCacheMaximumSize(size);
}
public void setCanOpenWindows() {
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/LayoutInsetsTest.java b/tests/GridLayoutTest/src/com/android/test/layout/LayoutInsetsTest.java
index 74daccc..1a4c36d 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/LayoutInsetsTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/LayoutInsetsTest.java
@@ -36,6 +36,13 @@
{
Button c = new Button(context);
c.setBackgroundResource(R.drawable.btn_default);
+ c.setText("Test");
+ p.addView(c);
+ }
+
+ {
+ Button c = new Button(context);
+ c.setBackgroundResource(R.drawable.btn_default);
c.setText("Manual setup");
p.addView(c);
c.setOnClickListener(new OnClickListener() {
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 5eac1f2..a90af15 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -24,6 +24,7 @@
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
+import android.os.Bundle;
import android.os.Environment;
import android.os.Vibrator;
import android.os.Handler;
@@ -44,10 +45,10 @@
private final static String TAG = "NotificationTestList";
NotificationManager mNM;
- Vibrator mVibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
+ Vibrator mVibrator;
Handler mHandler = new Handler();
- long mActivityCreateTime = System.currentTimeMillis();
+ long mActivityCreateTime;
long mChronometerBase = 0;
boolean mProgressDone = true;
@@ -67,6 +68,13 @@
final int kUnnumberedIconResID = R.drawable.notificationx;
@Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mVibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
+ mActivityCreateTime = System.currentTimeMillis();
+ }
+
+ @Override
protected String tag() {
return TAG;
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 9ebec61..1382641 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -36,6 +36,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
/**
* Delegate implementing the native methods of android.graphics.Paint
@@ -91,6 +92,8 @@
private MaskFilter_Delegate mMaskFilter;
private Rasterizer_Delegate mRasterizer;
+ private Locale mLocale = Locale.getDefault();
+
// ---- Public Helper methods ----
@@ -254,6 +257,8 @@
return delegate.mFlags;
}
+
+
@LayoutlibDelegate
/*package*/ static void setFlags(Paint thisPaint, int flags) {
// get the delegate from the native int.
@@ -904,6 +909,17 @@
}
@LayoutlibDelegate
+ /*package*/ static void native_setTextLocale(int native_object, String locale) {
+ // get the delegate from the native int.
+ Paint_Delegate delegate = sManager.getDelegate(native_object);
+ if (delegate == null) {
+ return;
+ }
+
+ delegate.setTextLocale(locale);
+ }
+
+ @LayoutlibDelegate
/*package*/ static int native_getTextWidths(int native_object, char[] text, int index,
int count, float[] widths) {
// get the delegate from the native int.
@@ -1243,7 +1259,9 @@
return 0;
}
-
+ private void setTextLocale(String locale) {
+ mLocale = new Locale(locale);
+ }
private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
// get the delegate from the native int.
@@ -1258,4 +1276,5 @@
delegate.mFlags &= ~flagMask;
}
}
+
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index 44d28fa..85b67d5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -78,6 +78,10 @@
}
@Override
+ public void getCurrentSizeRange(Point smallestSize, Point largestSize) {
+ }
+
+ @Override
public void getDisplaySize(Point arg0) throws RemoteException {
}
diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath
index 734ebdc..dbc4cfd 100644
--- a/tools/layoutlib/create/.classpath
+++ b/tools/layoutlib/create/.classpath
@@ -4,6 +4,6 @@
<classpathentry excluding="mock_android/" kind="src" path="tests"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
- <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-4.0.jar"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/asm-tools/asm-4.0.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index 563225e..91e4fda 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -89,7 +89,8 @@
case FILETYPE_KEYCHARACTERMAP: {
sp<KeyCharacterMap> map;
- status_t status = KeyCharacterMap::load(String8(filename), &map);
+ status_t status = KeyCharacterMap::load(String8(filename),
+ KeyCharacterMap::FORMAT_ANY, &map);
if (status) {
fprintf(stderr, "Error %d parsing key character map file.\n\n", status);
return false;
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 7bb927b..30e4a20 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -68,9 +68,14 @@
private int mLinkSpeed;
private InetAddress mIpAddress;
-
private String mMacAddress;
+ /**
+ * Flag indicating that AP has hinted that upstream connection is metered,
+ * and sensitive to heavy data transfers.
+ */
+ private boolean mMeteredHint;
+
WifiInfo() {
mSSID = null;
mBSSID = null;
@@ -96,6 +101,7 @@
mLinkSpeed = source.mLinkSpeed;
mIpAddress = source.mIpAddress;
mMacAddress = source.mMacAddress;
+ mMeteredHint = source.mMeteredHint;
}
}
@@ -168,6 +174,16 @@
return mMacAddress;
}
+ /** {@hide} */
+ public void setMeteredHint(boolean meteredHint) {
+ mMeteredHint = meteredHint;
+ }
+
+ /** {@hide} */
+ public boolean getMeteredHint() {
+ return mMeteredHint;
+ }
+
void setNetworkId(int id) {
mNetworkId = id;
}
@@ -248,6 +264,15 @@
}
}
+ /** {@hide} */
+ public static String removeDoubleQuotes(String string) {
+ final int length = string.length();
+ if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
+ return string.substring(1, length - 1);
+ }
+ return string;
+ }
+
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -260,7 +285,8 @@
append(mSupplicantState == null ? none : mSupplicantState).
append(", RSSI: ").append(mRssi).
append(", Link speed: ").append(mLinkSpeed).
- append(", Net ID: ").append(mNetworkId);
+ append(", Net ID: ").append(mNetworkId).
+ append(", Metered hint: ").append(mMeteredHint);
return sb.toString();
}
@@ -284,6 +310,7 @@
dest.writeString(getSSID());
dest.writeString(mBSSID);
dest.writeString(mMacAddress);
+ dest.writeInt(mMeteredHint ? 1 : 0);
mSupplicantState.writeToParcel(dest, flags);
}
@@ -303,6 +330,7 @@
info.setSSID(in.readString());
info.mBSSID = in.readString();
info.mMacAddress = in.readString();
+ info.mMeteredHint = in.readInt() != 0;
info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
return info;
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 2f14098..705e3c7 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1642,6 +1642,7 @@
mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
mWifiInfo.setRssi(MIN_RSSI);
mWifiInfo.setLinkSpeed(-1);
+ mWifiInfo.setMeteredHint(false);
setNetworkDetailedState(DetailedState.DISCONNECTED);
mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
@@ -1713,6 +1714,7 @@
mWifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
InetAddress addr = NetworkUtils.numericToInetAddress(dhcpInfoInternal.ipAddress);
mWifiInfo.setInetAddress(addr);
+ mWifiInfo.setMeteredHint(dhcpInfoInternal.hasMeteredHint());
if (getNetworkDetailedState() == DetailedState.CONNECTED) {
//DHCP renewal in connected state
LinkProperties linkProperties = dhcpInfoInternal.makeLinkProperties();
@@ -1735,6 +1737,7 @@
loge("IP configuration failed");
mWifiInfo.setInetAddress(null);
+ mWifiInfo.setMeteredHint(false);
/**
* If we've exceeded the maximum number of retries for DHCP
* to a given network, disable the network
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index c34c4645..bfb91e2 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -141,7 +141,7 @@
@Override
public void setPolicyDataEnable(boolean enabled) {
- Slog.w(TAG, "ignoring setPolicyDataEnable(" + enabled + ")");
+ // ignored
}
/**
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index df14bb9..018e0a8 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -415,8 +415,8 @@
/**
* Passed with {@link ActionListener#onFailure}.
* Indicates that the {@link #discoverServices} failed because no service
- * requests are set.
- * @hide
+ * requests are added. Use {@link #addServiceRequest} to add a service
+ * request.
*/
public static final int NO_SERVICE_REQUESTS = 3;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 314e33e..6168f0e 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -1500,8 +1500,7 @@
int key;
WifiP2pServiceRequest req;
for (int i=0; i < c.mReqList.size(); i++) {
- key = c.mReqList.keyAt(i);
- req = c.mReqList.get(key);
+ req = c.mReqList.valueAt(i);
if (req != null) {
sb.append(req.getSupplicantQuery());
}
@@ -1539,7 +1538,10 @@
return false;
}
- req.setTransactionId(++mServiceTransactionId);
+ ++mServiceTransactionId;
+ //The Wi-Fi p2p spec says transaction id should be non-zero
+ if (mServiceTransactionId == 0) ++mServiceTransactionId;
+ req.setTransactionId(mServiceTransactionId);
clientInfo.mReqList.put(mServiceTransactionId, req);
if (mServiceDiscReqId == null) {
@@ -1550,13 +1552,23 @@
}
private void removeServiceRequest(Messenger m, WifiP2pServiceRequest req) {
-
ClientInfo clientInfo = getClientInfo(m, false);
if (clientInfo == null) {
return;
}
- clientInfo.mReqList.remove(req.getTransactionId());
+ //Application does not have transaction id information
+ //go through stored requests to remove
+ boolean removed = false;
+ for (int i=0; i < clientInfo.mReqList.size(); i++) {
+ if (req.equals(clientInfo.mReqList.valueAt(i))) {
+ removed = true;
+ clientInfo.mReqList.removeAt(i);
+ break;
+ }
+ }
+
+ if (!removed) return;
if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
if (DBG) logd("remove client information from framework");
@@ -1670,6 +1682,7 @@
} catch (RemoteException e) {
if (DBG) logd("detect dead channel");
clearClientInfo(c.mMessenger);
+ return;
}
}
}
@@ -1683,6 +1696,8 @@
* TODO: This can be done better with full async channels.
*/
private void clearClientDeadChannels() {
+ ArrayList<Messenger> deadClients = new ArrayList<Messenger>();
+
for (ClientInfo c : mClientInfoList.values()) {
Message msg = Message.obtain();
msg.what = WifiP2pManager.PING;
@@ -1693,9 +1708,13 @@
c.mMessenger.send(msg);
} catch (RemoteException e) {
if (DBG) logd("detect dead channel");
- clearClientInfo(c.mMessenger);
+ deadClients.add(c.mMessenger);
}
}
+
+ for (Messenger m : deadClients) {
+ clearClientInfo(m);
+ }
}
/**